diff --git a/app/controllers/api/v1/accounts/conversations/direct_uploads_controller.rb b/app/controllers/api/v1/accounts/conversations/direct_uploads_controller.rb index 83c0170a8..1a481687d 100644 --- a/app/controllers/api/v1/accounts/conversations/direct_uploads_controller.rb +++ b/app/controllers/api/v1/accounts/conversations/direct_uploads_controller.rb @@ -1,6 +1,8 @@ class Api::V1::Accounts::Conversations::DirectUploadsController < ActiveStorage::DirectUploadsController include EnsureCurrentAccountHelper include AccessTokenAuthHelper + include RequestExceptionHandler + before_action :authenticate_access_token! before_action :prevent_read_only_access_token! before_action :current_account before_action :conversation diff --git a/spec/controllers/api/v1/accounts/conversations/direct_uploads_controller_spec.rb b/spec/controllers/api/v1/accounts/conversations/direct_uploads_controller_spec.rb index ad62e56b0..bd006f2ad 100644 --- a/spec/controllers/api/v1/accounts/conversations/direct_uploads_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/conversations/direct_uploads_controller_spec.rb @@ -7,43 +7,56 @@ RSpec.describe '/api/v1/accounts/:account_id/conversations/:conversation_id/dire let(:contact) { create(:contact, account: account, email: nil) } let(:contact_inbox) { create(:contact_inbox, contact: contact, inbox: web_widget.inbox) } let(:conversation) { create(:conversation, contact: contact, account: account, inbox: web_widget.inbox, contact_inbox: contact_inbox) } + let(:blob_params) do + { + blob: { + filename: 'avatar.png', + byte_size: '1234', + checksum: 'dsjbsdhbfif3874823mnsdbf', + content_type: 'image/png' + } + } + end + + def upload(headers: {}) + post api_v1_account_conversation_direct_uploads_path(account_id: account.id, conversation_id: conversation.display_id), + params: blob_params, + headers: headers, + as: :json + end describe 'POST /api/v1/accounts/:account_id/conversations/:conversation_id/direct_uploads' do - context 'when post request is made' do - it 'creates attachment message in conversation' do - contact - - post api_v1_account_conversation_direct_uploads_path(account_id: account.id, conversation_id: conversation.display_id), - params: { - blob: { - filename: 'avatar.png', - byte_size: '1234', - checksum: 'dsjbsdhbfif3874823mnsdbf', - content_type: 'image/png' - } - }, - headers: { api_access_token: agent.access_token.token }, - as: :json + context 'with a valid full-scope access token' do + it 'creates the direct upload blob' do + expect { upload(headers: { api_access_token: agent.access_token.token }) } + .to change(ActiveStorage::Blob, :count).by(1) expect(response).to have_http_status(:success) - json_response = response.parsed_body - expect(json_response['content_type']).to eq('image/png') + expect(response.parsed_body['content_type']).to eq('image/png') end + end - it 'rejects requests made with a read-only access token' do - read_only_token = agent.read_only_access_token + context 'without an access token' do + it 'returns unauthorized without creating a blob' do + expect { upload }.not_to change(ActiveStorage::Blob, :count) - post api_v1_account_conversation_direct_uploads_path(account_id: account.id, conversation_id: conversation.display_id), - params: { - blob: { - filename: 'avatar.png', - byte_size: '1234', - checksum: 'dsjbsdhbfif3874823mnsdbf', - content_type: 'image/png' - } - }, - headers: { api_access_token: read_only_token.token }, - as: :json + expect(response).to have_http_status(:unauthorized) + end + end + + context 'with an invalid access token' do + it 'returns unauthorized without creating a blob' do + expect { upload(headers: { api_access_token: 'invalid-token' }) } + .not_to change(ActiveStorage::Blob, :count) + + expect(response).to have_http_status(:unauthorized) + end + end + + context 'with a read-only access token' do + it 'returns forbidden without creating a blob' do + expect { upload(headers: { api_access_token: agent.read_only_access_token.token }) } + .not_to change(ActiveStorage::Blob, :count) expect(response).to have_http_status(:forbidden) end