chore: Enhance contact merge action for identified users (#4886)
- Discard conflicting keys - Do not merge if there is already an identified contact Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
@@ -48,13 +48,22 @@ describe ::ContactIdentifyAction do
|
||||
|
||||
context 'when contact with same email exists' do
|
||||
it 'merges the current contact to email contact' do
|
||||
existing_email_contact = create(:contact, account: account, email: 'test@test.com')
|
||||
params = { email: 'test@test.com' }
|
||||
existing_email_contact = create(:contact, account: account, email: 'test@test.com', name: 'old name')
|
||||
params = { name: 'new name', email: 'test@test.com' }
|
||||
result = described_class.new(contact: contact, params: params).perform
|
||||
expect(result.id).to eq existing_email_contact.id
|
||||
expect(result.name).to eq existing_email_contact.name
|
||||
expect(result.name).to eq 'new name'
|
||||
expect { contact.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
it 'will not merge the current contact to email contact if identifier of email contact is different' do
|
||||
existing_email_contact = create(:contact, account: account, identifier: '1', email: 'test@test.com')
|
||||
params = { identifier: '2', email: 'test@test.com' }
|
||||
result = described_class.new(contact: contact, params: params).perform
|
||||
expect(result.id).not_to eq existing_email_contact.id
|
||||
expect(result.identifier).to eq params[:identifier]
|
||||
expect(result.email).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when contact with same phone_number exists' do
|
||||
@@ -66,6 +75,24 @@ describe ::ContactIdentifyAction do
|
||||
expect(result.name).to eq existing_phone_number_contact.name
|
||||
expect { contact.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
it 'will not merge the current contact to phone contact if identifier of phone contact is different' do
|
||||
existing_phone_number_contact = create(:contact, account: account, identifier: '1', phone_number: '+919999888877')
|
||||
params = { identifier: '2', phone_number: '+919999888877' }
|
||||
result = described_class.new(contact: contact, params: params).perform
|
||||
expect(result.id).not_to eq existing_phone_number_contact.id
|
||||
expect(result.identifier).to eq params[:identifier]
|
||||
expect(result.email).to eq nil
|
||||
end
|
||||
|
||||
it 'will not overide the phone contacts email when params contains different email' do
|
||||
existing_phone_number_contact = create(:contact, account: account, email: '1@test.com', phone_number: '+919999888877')
|
||||
params = { email: '2@test.com', phone_number: '+919999888877' }
|
||||
result = described_class.new(contact: contact, params: params).perform
|
||||
expect(result.id).not_to eq existing_phone_number_contact.id
|
||||
expect(result.email).to eq params[:email]
|
||||
expect(result.phone_number).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when contacts with blank identifiers exist and identify action is called with blank identifier' do
|
||||
@@ -77,5 +104,16 @@ describe ::ContactIdentifyAction do
|
||||
expect(result.name).to eq 'new name'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when retain_original_contact_name is set to true' do
|
||||
it 'will not update the name of the existing contact' do
|
||||
existing_email_contact = create(:contact, account: account, name: 'old name', email: 'test@test.com')
|
||||
params = { email: 'test@test.com', name: 'new name' }
|
||||
result = described_class.new(contact: contact, params: params, retain_original_contact_name: true).perform
|
||||
expect(result.id).to eq existing_email_contact.id
|
||||
expect(result.name).to eq 'old name'
|
||||
expect { contact.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -82,12 +82,34 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH /api/v1/widget/contact/set_user' do
|
||||
let(:params) { { website_token: web_widget.website_token, identifier: 'test' } }
|
||||
let(:web_widget) { create(:channel_widget, account: account, hmac_mandatory: true) }
|
||||
let(:correct_identifier_hash) { OpenSSL::HMAC.hexdigest('sha256', web_widget.hmac_token, params[:identifier].to_s) }
|
||||
let(:incorrect_identifier_hash) { 'test' }
|
||||
|
||||
context 'when the current contact identifier is different from param identifier' do
|
||||
before do
|
||||
contact.update(identifier: 'random')
|
||||
end
|
||||
|
||||
it 'return a new contact for the provided identifier' do
|
||||
patch '/api/v1/widget/contact/set_user',
|
||||
params: params.merge(identifier_hash: correct_identifier_hash),
|
||||
headers: { 'X-Auth-Token' => token },
|
||||
as: :json
|
||||
|
||||
body = JSON.parse(response.body)
|
||||
expect(body['id']).not_to eq(contact.id)
|
||||
expect(body['widget_auth_token']).not_to eq(nil)
|
||||
expect(Contact.find(body['id']).contact_inboxes.first.hmac_verified?).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with mandatory hmac' do
|
||||
let(:identify_action) { double }
|
||||
let(:web_widget) { create(:channel_widget, account: account, hmac_mandatory: true) }
|
||||
let(:correct_identifier_hash) { OpenSSL::HMAC.hexdigest('sha256', web_widget.hmac_token, params[:identifier].to_s) }
|
||||
let(:incorrect_identifier_hash) { 'test' }
|
||||
|
||||
before do
|
||||
allow(ContactIdentifyAction).to receive(:new).and_return(identify_action)
|
||||
@@ -95,7 +117,7 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
||||
end
|
||||
|
||||
it 'returns success when correct identifier hash is provided' do
|
||||
patch '/api/v1/widget/contact',
|
||||
patch '/api/v1/widget/contact/set_user',
|
||||
params: params.merge(identifier_hash: correct_identifier_hash),
|
||||
headers: { 'X-Auth-Token' => token },
|
||||
as: :json
|
||||
@@ -104,7 +126,7 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
||||
end
|
||||
|
||||
it 'returns error when incorrect identifier hash is provided' do
|
||||
patch '/api/v1/widget/contact',
|
||||
patch '/api/v1/widget/contact/set_user',
|
||||
params: params.merge(identifier_hash: incorrect_identifier_hash),
|
||||
headers: { 'X-Auth-Token' => token },
|
||||
as: :json
|
||||
@@ -113,7 +135,7 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
||||
end
|
||||
|
||||
it 'returns error when identifier hash is blank' do
|
||||
patch '/api/v1/widget/contact',
|
||||
patch '/api/v1/widget/contact/set_user',
|
||||
params: params.merge(identifier_hash: ''),
|
||||
headers: { 'X-Auth-Token' => token },
|
||||
as: :json
|
||||
@@ -122,7 +144,7 @@ RSpec.describe '/api/v1/widget/contacts', type: :request do
|
||||
end
|
||||
|
||||
it 'returns error when identifier hash is not provided' do
|
||||
patch '/api/v1/widget/contact',
|
||||
patch '/api/v1/widget/contact/set_user',
|
||||
params: params,
|
||||
headers: { 'X-Auth-Token' => token },
|
||||
as: :json
|
||||
|
||||
Reference in New Issue
Block a user