From 6a9e1db2ab447d98df56d880a3ad0a5658c1de35 Mon Sep 17 00:00:00 2001 From: Louis Bompart Date: Fri, 31 Jul 2020 17:18:24 -0400 Subject: [PATCH] feat(SFINT-3353): Ensure UserActionPanel state is updated first (#89) --- src/components/UserActions/UserActions.ts | 4 +-- .../UserActions/UserActions.spec.ts | 27 ++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/components/UserActions/UserActions.ts b/src/components/UserActions/UserActions.ts index 06c3c70a..8e6fae64 100644 --- a/src/components/UserActions/UserActions.ts +++ b/src/components/UserActions/UserActions.ts @@ -157,9 +157,9 @@ export class UserActions extends Component { */ public hide() { if (this.isOpened) { + this.isOpened = false; (get(this.root, UserProfileModel) as UserProfileModel).deleteActions(this.options.userId); this.root.classList.remove(UserActions.USER_ACTION_OPENED); - this.isOpened = false; this.element.dispatchEvent(new CustomEvent(UserActions.Events.Hide)); } } @@ -169,10 +169,10 @@ export class UserActions extends Component { */ public async show() { if (!this.isOpened) { + this.isOpened = true; this.element.dispatchEvent(new CustomEvent(UserActions.Events.Show)); this.bindings.usageAnalytics.logCustomEvent({ name: 'openUserActions', type: 'User Actions' }, {}, this.element); this.root.classList.add(UserActions.USER_ACTION_OPENED); - this.isOpened = true; try { const userActions = await (get(this.root, UserProfileModel) as UserProfileModel).getActions(this.options.userId); diff --git a/tests/components/UserActions/UserActions.spec.ts b/tests/components/UserActions/UserActions.spec.ts index 0b8b9fb4..00db1667 100644 --- a/tests/components/UserActions/UserActions.spec.ts +++ b/tests/components/UserActions/UserActions.spec.ts @@ -3,7 +3,7 @@ import { UserActions } from '../../../src/components/UserActions/UserActions'; import { Logger, Initialization, QueryEvents, ResultListEvents, IQueryResult, l } from 'coveo-search-ui'; import { createSandbox, SinonSandbox, SinonStub, SinonStubbedInstance } from 'sinon'; import { UserAction, UserProfileModel } from '../../../src/models/UserProfileModel'; -import { fakeUserProfileModel } from '../../utils'; +import { fakeUserProfileModel, waitForPromiseCompletion } from '../../utils'; import { ClickedDocumentList, QueryList, UserActivity } from '../../../src/Index'; import { UserActionType } from '../../../src/rest/UserProfilingEndpoint'; import { ResponsiveUserActions } from '../../../src/components/UserActions/ResponsiveUserActions'; @@ -454,6 +454,19 @@ describe('UserActions', () => { expect(spyDispatchEvent.firstCall.args.length).toBe(1); expect(spyDispatchEvent.firstCall.args[0].type).toBe('userActionsPanelShow'); }); + + it('should trigger a single event even if an event listener on userActionsPanelShow call `show`', async () => { + mock.cmp.element.addEventListener('userActionsPanelShow', () => { + mock.cmp.show(); + }); + const spyDispatchEvent = sandbox.spy(mock.cmp.element, 'dispatchEvent'); + + await mock.cmp.show(); + // Because show is asynchronous, the event completion is not awaited. waitForPromiseCompletion ensure everything is settled. + await waitForPromiseCompletion(); + + expect(spyDispatchEvent.calledOnce).toBeTrue(); + }); }); describe('hide', () => { @@ -518,6 +531,18 @@ describe('UserActions', () => { expect(spyDispatchEvent.firstCall.args.length).toBe(1); expect(spyDispatchEvent.firstCall.args[0].type).toBe('userActionsPanelHide'); }); + + it('should trigger a single event even if an event listener on userActionsPanelHide call `hide`', async () => { + await mock.cmp.show(); + mock.cmp.element.addEventListener('userActionsPanelHide', () => { + mock.cmp.hide(); + }); + + const spyDispatchEvent = sandbox.spy(mock.cmp.element, 'dispatchEvent'); + mock.cmp.hide(); + + expect(spyDispatchEvent.calledOnce).toBeTrue(); + }); }); describe('tagViewsOfUser', () => {