2020-05-04 17:37:56 +00:00
|
|
|
require 'rails_helper'
|
|
|
|
|
|
|
|
RSpec.describe '/api/v1/widget/conversations/toggle_typing', type: :request do
|
|
|
|
let(:account) { create(:account) }
|
|
|
|
let(:web_widget) { create(:channel_widget, account: account) }
|
|
|
|
let(:contact) { create(:contact, account: account, email: nil) }
|
|
|
|
let(:contact_inbox) { create(:contact_inbox, contact: contact, inbox: web_widget.inbox) }
|
2022-04-06 08:24:55 +00:00
|
|
|
let(:second_session) { create(:contact_inbox, contact: contact, inbox: web_widget.inbox) }
|
2020-05-04 17:37:56 +00:00
|
|
|
let!(:conversation) { create(:conversation, contact: contact, account: account, inbox: web_widget.inbox, contact_inbox: contact_inbox) }
|
|
|
|
let(:payload) { { source_id: contact_inbox.source_id, inbox_id: web_widget.inbox.id } }
|
|
|
|
let(:token) { ::Widget::TokenService.new(payload: payload).generate_token }
|
2022-04-06 08:24:55 +00:00
|
|
|
let(:token_without_conversation) do
|
|
|
|
::Widget::TokenService.new(payload: { source_id: second_session.source_id, inbox_id: web_widget.inbox.id }).generate_token
|
|
|
|
end
|
2020-05-04 17:37:56 +00:00
|
|
|
|
2020-07-07 18:34:44 +00:00
|
|
|
describe 'GET /api/v1/widget/conversations' do
|
|
|
|
context 'with a conversation' do
|
|
|
|
it 'returns the correct conversation params' do
|
|
|
|
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
|
|
|
get '/api/v1/widget/conversations',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: { website_token: web_widget.website_token },
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:success)
|
|
|
|
json_response = JSON.parse(response.body)
|
|
|
|
|
|
|
|
expect(json_response['id']).to eq(conversation.display_id)
|
|
|
|
expect(json_response['status']).to eq(conversation.status)
|
|
|
|
end
|
|
|
|
end
|
2021-03-27 06:57:48 +00:00
|
|
|
|
|
|
|
context 'with a conversation but invalid source id' do
|
|
|
|
it 'returns the correct conversation params' do
|
|
|
|
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
|
|
|
|
|
|
|
payload = { source_id: 'invalid source id', inbox_id: web_widget.inbox.id }
|
|
|
|
token = ::Widget::TokenService.new(payload: payload).generate_token
|
|
|
|
get '/api/v1/widget/conversations',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: { website_token: web_widget.website_token },
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
|
|
end
|
|
|
|
end
|
2020-07-07 18:34:44 +00:00
|
|
|
end
|
|
|
|
|
2021-02-15 18:44:13 +00:00
|
|
|
describe 'POST /api/v1/widget/conversations' do
|
|
|
|
it 'creates a conversation' do
|
|
|
|
post '/api/v1/widget/conversations',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: {
|
|
|
|
website_token: web_widget.website_token,
|
|
|
|
contact: {
|
|
|
|
name: 'contact-name',
|
2022-04-11 08:36:44 +00:00
|
|
|
email: 'contact-email@chatwoot.com',
|
|
|
|
phone_number: '+919745313456'
|
2021-02-15 18:44:13 +00:00
|
|
|
},
|
|
|
|
message: {
|
|
|
|
content: 'This is a test message'
|
2022-04-11 08:36:44 +00:00
|
|
|
},
|
|
|
|
custom_attributes: { order_id: '12345' }
|
2021-02-15 18:44:13 +00:00
|
|
|
},
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:success)
|
|
|
|
json_response = JSON.parse(response.body)
|
2022-07-15 02:51:59 +00:00
|
|
|
expect(json_response['id']).not_to be_nil
|
2021-02-15 18:44:13 +00:00
|
|
|
expect(json_response['contact']['email']).to eq 'contact-email@chatwoot.com'
|
2022-04-11 08:36:44 +00:00
|
|
|
expect(json_response['contact']['phone_number']).to eq '+919745313456'
|
2022-05-25 07:08:23 +00:00
|
|
|
expect(json_response['contact']['name']).to eq 'contact-name'
|
|
|
|
expect(json_response['custom_attributes']['order_id']).to eq '12345'
|
|
|
|
expect(json_response['messages'][0]['content']).to eq 'This is a test message'
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not update the name if the contact already exist' do
|
|
|
|
existing_contact = create(:contact, account: account)
|
|
|
|
|
|
|
|
post '/api/v1/widget/conversations',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: {
|
|
|
|
website_token: web_widget.website_token,
|
|
|
|
contact: {
|
|
|
|
name: 'contact-name',
|
|
|
|
email: existing_contact.email,
|
|
|
|
phone_number: '+919745313456'
|
|
|
|
},
|
|
|
|
message: {
|
|
|
|
content: 'This is a test message'
|
|
|
|
},
|
|
|
|
custom_attributes: { order_id: '12345' }
|
|
|
|
},
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:success)
|
|
|
|
json_response = JSON.parse(response.body)
|
2022-07-15 02:51:59 +00:00
|
|
|
expect(json_response['id']).not_to be_nil
|
2022-05-25 07:08:23 +00:00
|
|
|
expect(json_response['contact']['email']).to eq existing_contact.email
|
|
|
|
expect(json_response['contact']['name']).not_to eq 'contact-name'
|
|
|
|
expect(json_response['contact']['phone_number']).to eq '+919745313456'
|
2022-04-11 08:36:44 +00:00
|
|
|
expect(json_response['custom_attributes']['order_id']).to eq '12345'
|
2021-02-15 18:44:13 +00:00
|
|
|
expect(json_response['messages'][0]['content']).to eq 'This is a test message'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-05-04 17:37:56 +00:00
|
|
|
describe 'POST /api/v1/widget/conversations/toggle_typing' do
|
|
|
|
context 'with a conversation' do
|
|
|
|
it 'dispatches the correct typing status' do
|
|
|
|
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
|
|
|
post '/api/v1/widget/conversations/toggle_typing',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: { typing_status: 'on', website_token: web_widget.website_token },
|
|
|
|
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: contact })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-05-09 16:32:43 +00:00
|
|
|
|
2020-07-07 18:34:44 +00:00
|
|
|
describe 'POST /api/v1/widget/conversations/update_last_seen' do
|
2020-05-09 16:32:43 +00:00
|
|
|
context 'with a conversation' do
|
|
|
|
it 'returns the correct conversation params' do
|
|
|
|
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
2022-07-15 02:51:59 +00:00
|
|
|
expect(conversation.contact_last_seen_at).to be_nil
|
2020-07-07 18:34:44 +00:00
|
|
|
|
|
|
|
post '/api/v1/widget/conversations/update_last_seen',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: { website_token: web_widget.website_token },
|
|
|
|
as: :json
|
2020-05-09 16:32:43 +00:00
|
|
|
|
|
|
|
expect(response).to have_http_status(:success)
|
|
|
|
|
2022-07-15 02:51:59 +00:00
|
|
|
expect(conversation.reload.contact_last_seen_at).not_to be_nil
|
2020-05-09 16:32:43 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-08-17 05:55:13 +00:00
|
|
|
|
|
|
|
describe 'POST /api/v1/widget/conversations/transcript' do
|
|
|
|
context 'with a conversation' do
|
|
|
|
it 'sends transcript email' do
|
2021-06-08 17:15:01 +00:00
|
|
|
mailer = double
|
|
|
|
allow(ConversationReplyMailer).to receive(:with).and_return(mailer)
|
|
|
|
allow(mailer).to receive(:conversation_transcript)
|
2020-08-17 05:55:13 +00:00
|
|
|
|
|
|
|
post '/api/v1/widget/conversations/transcript',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: { website_token: web_widget.website_token, email: 'test@test.com' },
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:success)
|
2021-06-08 17:15:01 +00:00
|
|
|
expect(mailer).to have_received(:conversation_transcript).with(conversation, 'test@test.com')
|
2020-08-17 05:55:13 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2022-03-15 16:37:30 +00:00
|
|
|
|
|
|
|
describe 'GET /api/v1/widget/conversations/toggle_status' do
|
|
|
|
context 'when user end conversation from widget' do
|
|
|
|
it 'resolves the conversation' do
|
|
|
|
expect(conversation.open?).to be true
|
2022-03-18 08:13:02 +00:00
|
|
|
|
2022-03-15 16:37:30 +00:00
|
|
|
get '/api/v1/widget/conversations/toggle_status',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: { website_token: web_widget.website_token },
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:success)
|
|
|
|
expect(conversation.reload.resolved?).to be true
|
2022-03-18 08:13:02 +00:00
|
|
|
expect(Conversations::ActivityMessageJob).to have_been_enqueued.at_least(:once).with(
|
|
|
|
conversation,
|
|
|
|
{
|
|
|
|
account_id: conversation.account_id,
|
|
|
|
inbox_id: conversation.inbox_id,
|
|
|
|
message_type: :activity,
|
|
|
|
content: "Conversation was resolved by #{contact.name}"
|
|
|
|
}
|
|
|
|
)
|
2022-03-15 16:37:30 +00:00
|
|
|
end
|
|
|
|
end
|
2022-04-06 08:24:55 +00:00
|
|
|
|
|
|
|
context 'when end conversation is not permitted' do
|
|
|
|
before do
|
|
|
|
web_widget.end_conversation = false
|
|
|
|
web_widget.save!
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns action not permitted status' do
|
|
|
|
expect(conversation.open?).to be true
|
|
|
|
|
|
|
|
get '/api/v1/widget/conversations/toggle_status',
|
|
|
|
headers: { 'X-Auth-Token' => token },
|
|
|
|
params: { website_token: web_widget.website_token },
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden)
|
|
|
|
expect(conversation.reload.resolved?).to be false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a token without any conversation is used' do
|
|
|
|
it 'returns not found status' do
|
|
|
|
get '/api/v1/widget/conversations/toggle_status',
|
|
|
|
headers: { 'X-Auth-Token' => token_without_conversation },
|
|
|
|
params: { website_token: web_widget.website_token },
|
|
|
|
as: :json
|
|
|
|
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
|
|
end
|
|
|
|
end
|
2022-03-15 16:37:30 +00:00
|
|
|
end
|
2020-05-04 17:37:56 +00:00
|
|
|
end
|