media_attachment_spec.rb 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. require 'rails_helper'
  2. RSpec.describe MediaAttachment, type: :model do
  3. describe 'local?' do
  4. let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url) }
  5. subject { media_attachment.local? }
  6. context 'remote_url is blank' do
  7. let(:remote_url) { '' }
  8. it 'returns true' do
  9. is_expected.to be true
  10. end
  11. end
  12. context 'remote_url is present' do
  13. let(:remote_url) { 'remote_url' }
  14. it 'returns false' do
  15. is_expected.to be false
  16. end
  17. end
  18. end
  19. describe 'needs_redownload?' do
  20. let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url, file: file) }
  21. subject { media_attachment.needs_redownload? }
  22. context 'file is blank' do
  23. let(:file) { nil }
  24. context 'remote_url is present' do
  25. let(:remote_url) { 'remote_url' }
  26. it 'returns true' do
  27. is_expected.to be true
  28. end
  29. end
  30. end
  31. context 'file is present' do
  32. let(:file) { attachment_fixture('avatar.gif') }
  33. context 'remote_url is blank' do
  34. let(:remote_url) { '' }
  35. it 'returns false' do
  36. is_expected.to be false
  37. end
  38. end
  39. context 'remote_url is present' do
  40. let(:remote_url) { 'remote_url' }
  41. it 'returns true' do
  42. is_expected.to be false
  43. end
  44. end
  45. end
  46. end
  47. describe '#to_param' do
  48. let(:media_attachment) { Fabricate(:media_attachment, shortcode: shortcode) }
  49. let(:shortcode) { nil }
  50. context 'when media attachment has a shortcode' do
  51. let(:shortcode) { 'foo' }
  52. it 'returns shortcode' do
  53. expect(media_attachment.to_param).to eq shortcode
  54. end
  55. end
  56. context 'when media attachment does not have a shortcode' do
  57. let(:shortcode) { nil }
  58. it 'returns string representation of id' do
  59. expect(media_attachment.to_param).to eq media_attachment.id.to_s
  60. end
  61. end
  62. end
  63. describe 'animated gif conversion' do
  64. let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('avatar.gif')) }
  65. it 'sets type to gifv' do
  66. expect(media.type).to eq 'gifv'
  67. end
  68. it 'converts original file to mp4' do
  69. expect(media.file_content_type).to eq 'video/mp4'
  70. end
  71. it 'sets meta' do
  72. expect(media.file.meta["original"]["width"]).to eq 128
  73. expect(media.file.meta["original"]["height"]).to eq 128
  74. end
  75. end
  76. describe 'non-animated gif non-conversion' do
  77. fixtures = [
  78. { filename: 'attachment.gif', width: 600, height: 400, aspect: 1.5 },
  79. { filename: 'mini-static.gif', width: 32, height: 32, aspect: 1.0 },
  80. ]
  81. fixtures.each do |fixture|
  82. context fixture[:filename] do
  83. let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture(fixture[:filename])) }
  84. it 'sets type to image' do
  85. expect(media.type).to eq 'image'
  86. end
  87. it 'leaves original file as-is' do
  88. expect(media.file_content_type).to eq 'image/gif'
  89. end
  90. it 'sets meta' do
  91. expect(media.file.meta["original"]["width"]).to eq fixture[:width]
  92. expect(media.file.meta["original"]["height"]).to eq fixture[:height]
  93. expect(media.file.meta["original"]["aspect"]).to eq fixture[:aspect]
  94. end
  95. end
  96. end
  97. end
  98. describe 'ogg with cover art' do
  99. let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('boop.ogg')) }
  100. it 'detects it as an audio file' do
  101. expect(media.type).to eq 'audio'
  102. end
  103. it 'sets meta for the duration' do
  104. expect(media.file.meta['original']['duration']).to be_within(0.05).of(0.235102)
  105. end
  106. it 'extracts thumbnail' do
  107. expect(media.thumbnail.present?).to eq true
  108. end
  109. it 'extracts colors from thumbnail' do
  110. expect(media.file.meta['colors']['background']).to eq '#3088d4'
  111. end
  112. it 'gives the file a random name' do
  113. expect(media.file_file_name).to_not eq 'boop.ogg'
  114. end
  115. end
  116. describe 'mp3 with large cover art' do
  117. let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('boop.mp3')) }
  118. it 'detects it as an audio file' do
  119. expect(media.type).to eq 'audio'
  120. end
  121. it 'sets meta for the duration' do
  122. expect(media.file.meta['original']['duration']).to be_within(0.05).of(0.235102)
  123. end
  124. it 'extracts thumbnail' do
  125. expect(media.thumbnail.present?).to be true
  126. end
  127. it 'gives the file a random name' do
  128. expect(media.file_file_name).to_not eq 'boop.mp3'
  129. end
  130. end
  131. describe 'jpeg' do
  132. let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) }
  133. it 'sets meta for different style' do
  134. expect(media.file.meta["original"]["width"]).to eq 600
  135. expect(media.file.meta["original"]["height"]).to eq 400
  136. expect(media.file.meta["original"]["aspect"]).to eq 1.5
  137. expect(media.file.meta["small"]["width"]).to eq 490
  138. expect(media.file.meta["small"]["height"]).to eq 327
  139. expect(media.file.meta["small"]["aspect"]).to eq 490.0 / 327
  140. end
  141. it 'gives the file a random name' do
  142. expect(media.file_file_name).to_not eq 'attachment.jpg'
  143. end
  144. end
  145. describe 'base64-encoded jpeg' do
  146. let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('attachment.jpg').read)}" }
  147. let(:media) { MediaAttachment.create(account: Fabricate(:account), file: base64_attachment) }
  148. it 'saves media attachment' do
  149. expect(media.persisted?).to be true
  150. expect(media.file).to_not be_nil
  151. end
  152. it 'gives the file a file name' do
  153. expect(media.file_file_name).to_not be_blank
  154. end
  155. end
  156. it 'is invalid without file' do
  157. media = MediaAttachment.new(account: Fabricate(:account))
  158. expect(media.valid?).to be false
  159. end
  160. describe 'size limit validation' do
  161. it 'rejects video files that are too large' do
  162. stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes
  163. stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte
  164. expect { MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm')) }.to raise_error(ActiveRecord::RecordInvalid)
  165. end
  166. it 'accepts video files that are small enough' do
  167. stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte
  168. stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes
  169. media = MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm'))
  170. expect(media.valid?).to be true
  171. end
  172. it 'rejects image files that are too large' do
  173. stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte
  174. stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes
  175. expect { MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) }.to raise_error(ActiveRecord::RecordInvalid)
  176. end
  177. it 'accepts image files that are small enough' do
  178. stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes
  179. stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte
  180. media = MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg'))
  181. expect(media.valid?).to be true
  182. end
  183. end
  184. end