media_spec.rb 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe 'Media' do
  4. let(:user) { Fabricate(:user) }
  5. let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
  6. let(:scopes) { 'write:media' }
  7. let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
  8. describe 'GET /api/v1/media/:id' do
  9. subject do
  10. get "/api/v1/media/#{media.id}", headers: headers
  11. end
  12. let(:media) { Fabricate(:media_attachment, account: user.account) }
  13. it_behaves_like 'forbidden for wrong scope', 'read'
  14. it 'returns http success with media information' do
  15. subject
  16. expect(response).to have_http_status(200)
  17. expect(response.content_type)
  18. .to start_with('application/json')
  19. expect(response.parsed_body).to match(
  20. a_hash_including(
  21. id: media.id.to_s,
  22. description: media.description,
  23. type: media.type
  24. )
  25. )
  26. end
  27. context 'when the media is still being processed' do
  28. before do
  29. media.update(processing: :in_progress)
  30. end
  31. it 'returns http partial content' do
  32. subject
  33. expect(response).to have_http_status(206)
  34. expect(response.content_type)
  35. .to start_with('application/json')
  36. end
  37. end
  38. context 'when the media belongs to somebody else' do
  39. let(:media) { Fabricate(:media_attachment) }
  40. it 'returns http not found' do
  41. subject
  42. expect(response).to have_http_status(404)
  43. expect(response.content_type)
  44. .to start_with('application/json')
  45. end
  46. end
  47. context 'when media is attached to a status' do
  48. let(:media) { Fabricate(:media_attachment, account: user.account, status: Fabricate.build(:status)) }
  49. it 'returns http not found' do
  50. subject
  51. expect(response).to have_http_status(404)
  52. expect(response.content_type)
  53. .to start_with('application/json')
  54. end
  55. end
  56. end
  57. describe 'POST /api/v1/media' do
  58. subject do
  59. post '/api/v1/media', headers: headers, params: params
  60. end
  61. let(:params) { {} }
  62. shared_examples 'a successful media upload' do |media_type|
  63. it 'uploads the file successfully and returns correct media content', :aggregate_failures do
  64. subject
  65. expect(response).to have_http_status(200)
  66. expect(response.content_type)
  67. .to start_with('application/json')
  68. expect(MediaAttachment.first).to be_present
  69. expect(MediaAttachment.first).to have_attached_file(:file)
  70. expect(response.parsed_body).to match(
  71. a_hash_including(id: MediaAttachment.first.id.to_s, description: params[:description], type: media_type)
  72. )
  73. end
  74. end
  75. it_behaves_like 'forbidden for wrong scope', 'read read:media'
  76. describe 'when paperclip errors occur' do
  77. let(:media_attachments) { double }
  78. let(:params) { { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } }
  79. before do
  80. allow(User).to receive(:find).with(token.resource_owner_id).and_return(user)
  81. allow(user.account).to receive(:media_attachments).and_return(media_attachments)
  82. end
  83. context 'when imagemagick cannot identify the file type' do
  84. it 'returns http unprocessable entity' do
  85. allow(media_attachments).to receive(:create!).and_raise(Paperclip::Errors::NotIdentifiedByImageMagickError)
  86. subject
  87. expect(response).to have_http_status(422)
  88. expect(response.content_type)
  89. .to start_with('application/json')
  90. end
  91. end
  92. context 'when there is a generic error' do
  93. it 'returns http 500' do
  94. allow(media_attachments).to receive(:create!).and_raise(Paperclip::Error)
  95. subject
  96. expect(response).to have_http_status(500)
  97. expect(response.content_type)
  98. .to start_with('application/json')
  99. end
  100. end
  101. end
  102. context 'with image/jpeg', :attachment_processing do
  103. let(:params) { { file: fixture_file_upload('attachment.jpg', 'image/jpeg'), description: 'jpeg image' } }
  104. it_behaves_like 'a successful media upload', 'image'
  105. end
  106. context 'with image/gif', :attachment_processing do
  107. let(:params) { { file: fixture_file_upload('attachment.gif', 'image/gif') } }
  108. it_behaves_like 'a successful media upload', 'image'
  109. end
  110. context 'with video/webm', :attachment_processing do
  111. let(:params) { { file: fixture_file_upload('attachment.webm', 'video/webm') } }
  112. it_behaves_like 'a successful media upload', 'gifv'
  113. end
  114. end
  115. describe 'PUT /api/v1/media/:id' do
  116. subject do
  117. put "/api/v1/media/#{media.id}", headers: headers, params: params
  118. end
  119. let(:params) { {} }
  120. let(:media) { Fabricate(:media_attachment, status: status, account: user.account, description: 'old') }
  121. it_behaves_like 'forbidden for wrong scope', 'read read:media'
  122. context 'when the media belongs to somebody else' do
  123. let(:media) { Fabricate(:media_attachment, status: nil) }
  124. let(:params) { { description: 'Lorem ipsum!!!' } }
  125. it 'returns http not found' do
  126. subject
  127. expect(response).to have_http_status(404)
  128. expect(response.content_type)
  129. .to start_with('application/json')
  130. end
  131. end
  132. context 'when the requesting user owns the media' do
  133. let(:status) { nil }
  134. let(:params) { { description: 'Lorem ipsum!!!' } }
  135. it 'updates the description' do
  136. expect { subject }.to change { media.reload.description }.from('old').to('Lorem ipsum!!!')
  137. end
  138. context 'when the media is attached to a status' do
  139. let(:status) { Fabricate(:status, account: user.account) }
  140. it 'returns http not found' do
  141. subject
  142. expect(response).to have_http_status(404)
  143. expect(response.content_type)
  144. .to start_with('application/json')
  145. end
  146. end
  147. end
  148. end
  149. end