From 1ff9939a80ad02ef50c3dadefc453da4f0b751c1 Mon Sep 17 00:00:00 2001 From: "Aswin Dev P.S" Date: Tue, 31 Aug 2021 15:12:05 +0530 Subject: [PATCH] feat: Ability to remove inbox avatar (#2885) * Delete inbox avatar 1) New API endpoint added for deleting inbox avatar. 2) Delete avatar button in the inbox settings page. Co-authored-by: Sojan Jose Co-authored-by: Muhsin Keloth --- .../api/v1/accounts/inboxes_controller.rb | 5 ++ app/javascript/dashboard/api/inboxes.js | 4 ++ .../dashboard/api/specs/inboxes.spec.js | 7 +++ .../widgets/forms/AvatarUploader.vue | 52 +++++++++++++++---- .../dashboard/i18n/locale/en/inboxMgmt.json | 5 +- .../dashboard/settings/inbox/Settings.vue | 19 +++++++ .../dashboard/store/modules/inboxes.js | 7 +++ .../modules/specs/inboxes/actions.spec.js | 15 ++++++ app/policies/inbox_policy.rb | 4 ++ config/routes.rb | 1 + .../v1/accounts/inboxes_controller_spec.rb | 36 +++++++++++++ 11 files changed, 143 insertions(+), 12 deletions(-) diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb index 2621a4a338ce..d492b0d9e401 100644 --- a/app/controllers/api/v1/accounts/inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/inboxes_controller.rb @@ -15,6 +15,11 @@ def campaigns @campaigns = @inbox.campaigns end + def avatar + @inbox.avatar.attachment.destroy! if @inbox.avatar.attached? + head :ok + end + def create ActiveRecord::Base.transaction do channel = create_channel diff --git a/app/javascript/dashboard/api/inboxes.js b/app/javascript/dashboard/api/inboxes.js index b6d8ab8607b4..1cf6ba113c7e 100644 --- a/app/javascript/dashboard/api/inboxes.js +++ b/app/javascript/dashboard/api/inboxes.js @@ -13,6 +13,10 @@ class Inboxes extends ApiClient { getCampaigns(inboxId) { return axios.get(`${this.url}/${inboxId}/campaigns`); } + + deleteInboxAvatar(inboxId) { + return axios.delete(`${this.url}/${inboxId}/avatar`); + } } export default new Inboxes(); diff --git a/app/javascript/dashboard/api/specs/inboxes.spec.js b/app/javascript/dashboard/api/specs/inboxes.spec.js index 6c5cf38ea075..b261bb930bd9 100644 --- a/app/javascript/dashboard/api/specs/inboxes.spec.js +++ b/app/javascript/dashboard/api/specs/inboxes.spec.js @@ -27,5 +27,12 @@ describe('#InboxesAPI', () => { '/api/v1/inboxes/2/campaigns' ); }); + + it('#deleteInboxAvatar', () => { + inboxesAPI.deleteInboxAvatar(2); + expect(context.axiosMock.delete).toHaveBeenCalledWith( + '/api/v1/inboxes/2/avatar' + ); + }); }); }); diff --git a/app/javascript/dashboard/components/widgets/forms/AvatarUploader.vue b/app/javascript/dashboard/components/widgets/forms/AvatarUploader.vue index 9af6b4029f58..89ca4f56aa69 100644 --- a/app/javascript/dashboard/components/widgets/forms/AvatarUploader.vue +++ b/app/javascript/dashboard/components/widgets/forms/AvatarUploader.vue @@ -1,16 +1,31 @@ + + diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json index 3731e79a9e00..603ec58e9647 100644 --- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json @@ -232,6 +232,7 @@ }, "DELETE": { "BUTTON_TEXT": "Delete", + "AVATAR_DELETE_BUTTON_TEXT": "Delete Avatar", "CONFIRM": { "TITLE": "Confirm Deletion", "MESSAGE": "Are you sure to delete ", @@ -241,7 +242,9 @@ }, "API": { "SUCCESS_MESSAGE": "Inbox deleted successfully", - "ERROR_MESSAGE": "Could not delete inbox. Please try again later." + "ERROR_MESSAGE": "Could not delete inbox. Please try again later.", + "AVATAR_SUCCESS_MESSAGE": "Inbox avatar deleted successfully", + "AVATAR_ERROR_MESSAGE": "Could not delete the inbox avatar. Please try again later." } }, "TABS": { diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue index b41c13a97b85..6357f67fd103 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue @@ -22,7 +22,9 @@ { + try { + await InboxesAPI.deleteInboxAvatar(inboxId); + } catch (error) { + throw new Error(error); + } + }, }; export const mutations = { diff --git a/app/javascript/dashboard/store/modules/specs/inboxes/actions.spec.js b/app/javascript/dashboard/store/modules/specs/inboxes/actions.spec.js index c2d32976c45b..da3424267328 100644 --- a/app/javascript/dashboard/store/modules/specs/inboxes/actions.spec.js +++ b/app/javascript/dashboard/store/modules/specs/inboxes/actions.spec.js @@ -128,4 +128,19 @@ describe('#actions', () => { ]); }); }); + + describe('#deleteInboxAvatar', () => { + it('sends correct actions if API is success', async () => { + axios.delete.mockResolvedValue(); + await expect( + actions.deleteInboxAvatar({}, inboxList[0].id) + ).resolves.toBe(); + }); + it('sends correct actions if API is error', async () => { + axios.delete.mockRejectedValue({ message: 'Incorrect header' }); + await expect( + actions.deleteInboxAvatar({}, inboxList[0].id) + ).rejects.toThrow(Error); + }); + }); }); diff --git a/app/policies/inbox_policy.rb b/app/policies/inbox_policy.rb index dd3aa930595d..851cac7d025c 100644 --- a/app/policies/inbox_policy.rb +++ b/app/policies/inbox_policy.rb @@ -53,4 +53,8 @@ def destroy? def set_agent_bot? @account_user.administrator? end + + def avatar? + @account_user.administrator? + end end diff --git a/config/routes.rb b/config/routes.rb index a4a2f545901f..d89332be4689 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -102,6 +102,7 @@ get :campaigns, on: :member get :agent_bot, on: :member post :set_agent_bot, on: :member + delete :avatar, on: :member end resources :inbox_members, only: [:create, :show], param: :inbox_id resources :labels, only: [:index, :show, :create, :update, :destroy] diff --git a/spec/controllers/api/v1/accounts/inboxes_controller_spec.rb b/spec/controllers/api/v1/accounts/inboxes_controller_spec.rb index 1a5c31088ef4..1b7262ba86b3 100644 --- a/spec/controllers/api/v1/accounts/inboxes_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/inboxes_controller_spec.rb @@ -113,6 +113,42 @@ end end + describe 'DELETE /api/v1/accounts/{account.id}/inboxes/{inbox.id}/avatar' do + let(:inbox) { create(:inbox, account: account) } + + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/avatar" + + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an authenticated user' do + before do + create(:inbox_member, user: agent, inbox: inbox) + inbox.avatar.attach(io: File.open(Rails.root.join('spec/assets/avatar.png')), filename: 'avatar.png', content_type: 'image/png') + end + + it 'delete inbox avatar for administrator user' do + delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/avatar", + headers: admin.create_new_auth_token, + as: :json + + expect { inbox.avatar.attachment.reload }.to raise_error(ActiveRecord::RecordNotFound) + expect(response).to have_http_status(:success) + end + + it 'returns unauthorized for agent user' do + delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}/avatar", + headers: agent.create_new_auth_token, + as: :json + + expect(response).to have_http_status(:unauthorized) + end + end + end + describe 'DELETE /api/v1/accounts/{account.id}/inboxes/:id' do let(:inbox) { create(:inbox, account: account) }