diff --git a/app/controllers/api/v1/accounts/contacts_controller.rb b/app/controllers/api/v1/accounts/contacts_controller.rb index fcb1de831..76fd206f4 100644 --- a/app/controllers/api/v1/accounts/contacts_controller.rb +++ b/app/controllers/api/v1/accounts/contacts_controller.rb @@ -81,11 +81,6 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController def update @contact.assign_attributes(contact_update_params) @contact.save! - rescue ActiveRecord::RecordInvalid => e - render json: { - message: e.record.errors.full_messages.join(', '), - contact: Current.account.contacts.find_by(email: contact_params[:email]) - }, status: :unprocessable_entity end def destroy diff --git a/app/controllers/concerns/request_exception_handler.rb b/app/controllers/concerns/request_exception_handler.rb index 3ce486012..1f96de737 100644 --- a/app/controllers/concerns/request_exception_handler.rb +++ b/app/controllers/concerns/request_exception_handler.rb @@ -37,7 +37,8 @@ module RequestExceptionHandler def render_record_invalid(exception) render json: { - message: exception.record.errors.full_messages.join(', ') + message: exception.record.errors.full_messages.join(', '), + attributes: exception.record.errors.attribute_names }, status: :unprocessable_entity end diff --git a/app/javascript/dashboard/i18n/locale/en/contact.json b/app/javascript/dashboard/i18n/locale/en/contact.json index 018a2acc1..baa7c8d7d 100644 --- a/app/javascript/dashboard/i18n/locale/en/contact.json +++ b/app/javascript/dashboard/i18n/locale/en/contact.json @@ -103,13 +103,15 @@ }, "EMAIL_ADDRESS": { "PLACEHOLDER": "Enter the email address of the contact", - "LABEL": "Email Address" + "LABEL": "Email Address", + "DUPLICATE": "This email address is in use for another contact." }, "PHONE_NUMBER": { "PLACEHOLDER": "Enter the phone number of the contact", "LABEL": "Phone Number", "HELP": "Phone number should be of E.164 format eg: +1415555555 [+][country code][area code][local phone number]", - "ERROR": "Phone number should be either empty or of E.164 format" + "ERROR": "Phone number should be either empty or of E.164 format", + "DUPLICATE": "This phone number is in use for another contact." }, "LOCATION": { "PLACEHOLDER": "Enter the location of the contact", @@ -139,7 +141,6 @@ } }, "SUCCESS_MESSAGE": "Contact saved successfully", - "CONTACT_ALREADY_EXIST": "This email address is in use for another contact.", "ERROR_MESSAGE": "There was an error, please try again" }, "NEW_CONVERSATION": { diff --git a/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactForm.vue b/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactForm.vue index 0fe9a1a4d..2b3dae832 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactForm.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/contact/ContactForm.vue @@ -121,8 +121,6 @@ export default { }, data() { return { - hasADuplicateContact: false, - duplicateContact: {}, companyName: '', description: '', email: '', @@ -201,12 +199,7 @@ export default { }, }; }, - resetDuplicate() { - this.hasADuplicateContact = false; - this.duplicateContact = {}; - }, async handleSubmit() { - this.resetDuplicate(); this.$v.$touch(); if (this.$v.$invalid) { @@ -218,9 +211,13 @@ export default { this.showAlert(this.$t('CONTACT_FORM.SUCCESS_MESSAGE')); } catch (error) { if (error instanceof DuplicateContactException) { - this.hasADuplicateContact = true; - this.duplicateContact = error.data; - this.showAlert(this.$t('CONTACT_FORM.CONTACT_ALREADY_EXIST')); + if (error.data.includes('email')) { + this.showAlert( + this.$t('CONTACT_FORM.FORM.EMAIL_ADDRESS.DUPLICATE') + ); + } else if (error.data.includes('phone_number')) { + this.showAlert(this.$t('CONTACT_FORM.FORM.PHONE_NUMBER.DUPLICATE')); + } } else if (error instanceof ExceptionWithMessage) { this.showAlert(error.data); } else { diff --git a/app/javascript/dashboard/store/modules/contacts/actions.js b/app/javascript/dashboard/store/modules/contacts/actions.js index 44bef1144..0e9961834 100644 --- a/app/javascript/dashboard/store/modules/contacts/actions.js +++ b/app/javascript/dashboard/store/modules/contacts/actions.js @@ -60,8 +60,8 @@ export const actions = { commit(types.SET_CONTACT_UI_FLAG, { isUpdating: false }); } catch (error) { commit(types.SET_CONTACT_UI_FLAG, { isUpdating: false }); - if (error.response?.data?.contact) { - throw new DuplicateContactException(error.response.data.contact); + if (error.response?.status === 422) { + throw new DuplicateContactException(error.response.data.attributes); } else { throw new Error(error); } diff --git a/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js b/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js index 08b1b2067..b435318e3 100644 --- a/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js +++ b/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js @@ -94,9 +94,10 @@ describe('#actions', () => { it('sends correct actions if duplicate contact is found', async () => { axios.patch.mockRejectedValue({ response: { + status: 422, data: { message: 'Incorrect header', - contact: { id: 1, name: 'contact-name' }, + attributes: ['email'], }, }, }); diff --git a/app/javascript/shared/helpers/specs/CustomErrors.spec.js b/app/javascript/shared/helpers/specs/CustomErrors.spec.js index 83b12da1d..cfa57dbce 100644 --- a/app/javascript/shared/helpers/specs/CustomErrors.spec.js +++ b/app/javascript/shared/helpers/specs/CustomErrors.spec.js @@ -3,15 +3,11 @@ const { DuplicateContactException } = require('../CustomErrors'); describe('DuplicateContactException', () => { it('returns correct exception', () => { const exception = new DuplicateContactException({ - id: 1, - name: 'contact-name', - email: 'email@example.com', + attributes: ['email'], }); expect(exception.message).toEqual('DUPLICATE_CONTACT'); expect(exception.data).toEqual({ - id: 1, - name: 'contact-name', - email: 'email@example.com', + attributes: ['email'], }); }); }); diff --git a/spec/controllers/api/v1/accounts/contacts_controller_spec.rb b/spec/controllers/api/v1/accounts/contacts_controller_spec.rb index b74ee44ed..6975fa015 100644 --- a/spec/controllers/api/v1/accounts/contacts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/contacts_controller_spec.rb @@ -448,7 +448,19 @@ RSpec.describe 'Contacts API', type: :request do as: :json expect(response).to have_http_status(:unprocessable_entity) - expect(JSON.parse(response.body)['contact']['id']).to eq(other_contact.id) + expect(JSON.parse(response.body)['attributes']).to include('email') + end + + it 'prevents updating with an existing phone number' do + other_contact = create(:contact, account: account, phone_number: '+12000000') + + patch "/api/v1/accounts/#{account.id}/contacts/#{contact.id}", + headers: admin.create_new_auth_token, + params: valid_params[:contact].merge({ phone_number: other_contact.phone_number }), + as: :json + + expect(response).to have_http_status(:unprocessable_entity) + expect(JSON.parse(response.body)['attributes']).to include('phone_number') end end end