require 'rails_helper' RSpec.describe 'Conversations API', type: :request do let(:account) { create(:account) } describe 'GET /api/v1/accounts/{account.id}/conversations' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do get "/api/v1/accounts/#{account.id}/conversations" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } let(:conversation) { create(:conversation, account: account) } before do create(:inbox_member, user: agent, inbox: conversation.inbox) end it 'returns all conversations with messages' do message = create(:message, conversation: conversation, account: account) get "/api/v1/accounts/#{account.id}/conversations", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) body = JSON.parse(response.body, symbolize_names: true) expect(body[:data][:meta][:all_count]).to eq(1) expect(body[:data][:payload].first[:messages].first[:id]).to eq(message.id) end it 'returns conversations with empty messages array for conversations with out messages ' do get "/api/v1/accounts/#{account.id}/conversations", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) body = JSON.parse(response.body, symbolize_names: true) expect(body[:data][:meta][:all_count]).to eq(1) expect(body[:data][:payload].first[:messages]).to eq([]) end end end describe 'GET /api/v1/accounts/{account.id}/conversations/meta' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do get "/api/v1/accounts/#{account.id}/conversations/meta" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } before do conversation = create(:conversation, account: account) create(:inbox_member, user: agent, inbox: conversation.inbox) end it 'returns all conversations counts' do get "/api/v1/accounts/#{account.id}/conversations/meta", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) expect(JSON.parse(response.body, symbolize_names: true)[:meta][:all_count]).to eq(1) end end end describe 'GET /api/v1/accounts/{account.id}/conversations/search' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do get "/api/v1/accounts/#{account.id}/conversations/search", params: { q: 'test' } expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } before do conversation = create(:conversation, account: account) create(:message, conversation: conversation, account: account, content: 'test1') create(:message, conversation: conversation, account: account, content: 'test2') create(:inbox_member, user: agent, inbox: conversation.inbox) end it 'returns all conversations with messages containing the search query' do get "/api/v1/accounts/#{account.id}/conversations/search", headers: agent.create_new_auth_token, params: { q: 'test1' }, as: :json expect(response).to have_http_status(:success) response_data = JSON.parse(response.body, symbolize_names: true) expect(response_data[:meta][:all_count]).to eq(1) expect(response_data[:payload].first[:messages].first[:content]).to eq 'test1' end end end describe 'GET /api/v1/accounts/{account.id}/conversations/:id' do let(:conversation) { create(:conversation, account: account) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do get "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } it 'shows the conversation' do get "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) expect(JSON.parse(response.body, symbolize_names: true)[:id]).to eq(conversation.display_id) end end end describe 'POST /api/v1/accounts/{account.id}/conversations' do let(:contact) { create(:contact, account: account) } let(:inbox) { create(:inbox, account: account) } let(:contact_inbox) { create(:contact_inbox, contact: contact, inbox: inbox) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do post "/api/v1/accounts/#{account.id}/conversations", params: { source_id: contact_inbox.source_id }, as: :json expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } it 'creates a new conversation' do allow(Rails.configuration.dispatcher).to receive(:dispatch) post "/api/v1/accounts/#{account.id}/conversations", headers: agent.create_new_auth_token, params: { source_id: contact_inbox.source_id }, as: :json expect(response).to have_http_status(:success) response_data = JSON.parse(response.body, symbolize_names: true) expect(response_data[:additional_attributes]).to eq({}) end end end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/toggle_status' do let(:conversation) { create(:conversation, account: account) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } it 'toggles the conversation status' do expect(conversation.status).to eq('open') post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) expect(conversation.reload.status).to eq('resolved') end it 'toggles the conversation status to open from bot' do conversation.update!(status: 'bot') post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) expect(conversation.reload.status).to eq('open') end it 'toggles the conversation status to specific status when parameter is passed' do expect(conversation.status).to eq('open') post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status", headers: agent.create_new_auth_token, params: { status: 'bot' }, as: :json expect(response).to have_http_status(:success) expect(conversation.reload.status).to eq('bot') end end end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/toggle_typing_status' do let(:conversation) { create(:conversation, account: account) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_typing_status" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } it 'toggles the conversation status' do allow(Rails.configuration.dispatcher).to receive(:dispatch) post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_typing_status", headers: agent.create_new_auth_token, params: { typing_status: 'on' }, as: :json expect(response).to have_http_status(:success) expect(Rails.configuration.dispatcher).to have_received(:dispatch) .with(Conversation::CONVERSATION_TYPING_ON, kind_of(Time), { conversation: conversation, user: agent }) end end end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/update_last_seen' do let(:conversation) { create(:conversation, account: account) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } it 'updates last seen' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) expect(conversation.reload.agent_last_seen_at).not_to eq nil end end end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/mute' do let(:conversation) { create(:conversation, account: account) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/mute" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } it 'mutes conversation' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/mute", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) expect(conversation.reload.resolved?).to eq(true) expect(conversation.reload.muted?).to eq(true) end end end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/unmute' do let(:conversation) { create(:conversation, account: account).tap(&:mute!) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/unmute" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } it 'unmutes conversation' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/unmute", headers: agent.create_new_auth_token, as: :json expect(response).to have_http_status(:success) expect(conversation.reload.muted?).to eq(false) end end end describe 'POST /api/v1/accounts/{account.id}/conversations/:id/transcript' do let(:conversation) { create(:conversation, account: account) } context 'when it is an unauthenticated user' do it 'returns unauthorized' do post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/transcript" expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do let(:agent) { create(:user, account: account, role: :agent) } let(:params) { { email: 'test@test.com' } } it 'mutes conversation' do allow(ConversationReplyMailer).to receive(:conversation_transcript) post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/transcript", headers: agent.create_new_auth_token, params: params, as: :json expect(response).to have_http_status(:success) expect(ConversationReplyMailer).to have_received(:conversation_transcript).with(conversation, 'test@test.com') end end end end