diff --git a/package-lock.json b/package-lock.json index 78f4f44bd..a9bc65e5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "business-filings-ui", - "version": "6.4.1", + "version": "6.4.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "business-filings-ui", - "version": "6.4.1", + "version": "6.4.2", "dependencies": { "@babel/compat-data": "^7.19.1", "@bcrs-shared-components/breadcrumb": "2.1.11", diff --git a/package.json b/package.json index 7aaedc8a3..7eecaa56c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "business-filings-ui", - "version": "6.4.1", + "version": "6.4.2", "private": true, "appName": "Filings UI", "sbcName": "SBC Common Components", diff --git a/src/components/EntityInfo/EntityMenu.vue b/src/components/EntityInfo/EntityMenu.vue index fe4be11b7..a2fc51162 100644 --- a/src/components/EntityInfo/EntityMenu.vue +++ b/src/components/EntityInfo/EntityMenu.vue @@ -39,26 +39,6 @@ - - - - - Dissolving the business will make this business historical - and it will be struck from the corporate registry. - - - @@ -94,6 +74,59 @@ Manage the digital credentials generated for the business. + + + + + + + + + + + + Dissolving the business will make this business historical + and it will be struck from the corporate registry. + + + + + + Submit a Consent to Continue Out of the province of B.C. + + + + + @@ -118,11 +151,15 @@ export default class EntityMenu extends Vue { @Getter(useConfigurationStore) getEditUrl!: string @Getter(useBusinessStore) getIdentifier!: string @Getter(useRootStore) getReasonText!: string + @Getter(useBusinessStore) isBenBcCccUlc!: boolean + @Getter(useBusinessStore) isCoop!: boolean @Getter(useBusinessStore) isFirm!: boolean @Getter(useBusinessStore) isGoodStanding!: boolean @Getter(useBusinessStore) isHistorical!: boolean @Getter(useRootStore) isPendingDissolution!: boolean + expand = false + // enums for template readonly axios = axios readonly AllowableActions = AllowableActions @@ -136,7 +173,7 @@ export default class EntityMenu extends Vue { * Emits an event to display NIGS dialog if company is not in good standing. * Otherwise, navigates to the Edit UI to view or change company information. */ - protected promptChangeCompanyInfo (): void { + promptChangeCompanyInfo (): void { if (!this.isGoodStanding) { this.emitNotInGoodStanding(NigsMessage.CHANGE_COMPANY_INFO) } else { @@ -157,7 +194,7 @@ export default class EntityMenu extends Vue { * Emits an event to display NIGS dialog if company is not in good standing. * Otherwise, emits an event to prompt user to confirm voluntary dissolution. */ - protected promptDissolve (): void { + promptDissolve (): void { if (!this.isGoodStanding) { this.emitNotInGoodStanding(NigsMessage.DISSOLVE) return @@ -171,7 +208,7 @@ export default class EntityMenu extends Vue { /** Emits an event to download the business summary. */ @Emit('downloadBusinessSummary') - private emitDownloadBusinessSummary (): void {} + emitDownloadBusinessSummary (): void {} /** Emits an event to indicate business is not in good standing. */ @Emit('notInGoodStanding') @@ -180,11 +217,16 @@ export default class EntityMenu extends Vue { /** Emits an event to view / add digital credentials. */ @Emit('viewAddDigitalCredentials') - private emitViewAddDigitalCredentials (): void {} + emitViewAddDigitalCredentials (): void {} } diff --git a/src/mixins/allowable-actions-mixin.ts b/src/mixins/allowable-actions-mixin.ts index 78f478ea9..d613e587f 100644 --- a/src/mixins/allowable-actions-mixin.ts +++ b/src/mixins/allowable-actions-mixin.ts @@ -59,7 +59,8 @@ export default class AllowableActionsMixin extends Vue { } case AllowableActions.CONSENT_CONTINUATION_OUT: { - return this.isAllowedFiling(FilingTypes.CONSENT_CONTINUATION_OUT) + const ff = !!GetFeatureFlag('supported-consent-continuation-out-entities')?.includes(this.getLegalType) + return (ff && this.isAllowedFiling(FilingTypes.CONSENT_CONTINUATION_OUT)) } case AllowableActions.CORRECTION: { diff --git a/src/utils/feature-flags.ts b/src/utils/feature-flags.ts index b4498ec02..8f6fd7775 100644 --- a/src/utils/feature-flags.ts +++ b/src/utils/feature-flags.ts @@ -14,7 +14,8 @@ const defaultFlagSet: LDFlagSet = { 'show-alert-phone-numbers-firm': false, 'supported-business-summary-entities': [], 'supported-correction-entities': [], - 'supported-dissolution-entities': [] + 'supported-dissolution-entities': [], + 'supported-consent-continuation-out-entities': [] } /** diff --git a/tests/unit/EntityMenu.spec.ts b/tests/unit/EntityMenu.spec.ts index e3e071713..9434f3ae7 100644 --- a/tests/unit/EntityMenu.spec.ts +++ b/tests/unit/EntityMenu.spec.ts @@ -18,6 +18,9 @@ const businessStore = useBusinessStore() const configurationStore = useConfigurationStore() const rootStore = useRootStore() +// Prevent the warning "[Vuetify] Unable to locate target [data-app]" +document.body.setAttribute('data-app', 'true') + describe('Entity Menu - entities', () => { const router = mockRouter.mock() @@ -41,7 +44,7 @@ describe('Entity Menu - entities', () => { expect(wrapper.findComponent(StaffComments).exists()).toBe(false) expect(wrapper.find('#historical-chip').exists()).toBe(false) expect(wrapper.find('#company-information-button').exists()).toBe(false) - expect(wrapper.find('#dissolution-button').exists()).toBe(false) + expect(wrapper.find('.menu-btn').exists()).toBe(false) expect(wrapper.find('#download-summary-button').exists()).toBe(false) expect(wrapper.find('#view-add-digital-credentials-button').exists()).toBe(false) @@ -77,7 +80,7 @@ describe('Entity Menu - entities', () => { expect(wrapper.findComponent(StaffComments).exists()).toBe(true) expect(wrapper.find('#historical-chip').exists()).toBe(false) expect(wrapper.find('#company-information-button').exists()).toBe(true) - expect(wrapper.find('#dissolution-button').exists()).toBe(true) + expect(wrapper.find('.menu-btn').exists()).toBe(true) expect(wrapper.find('#download-summary-button').exists()).toBe(true) expect(wrapper.find('#view-add-digital-credentials-button').exists()).toBe(false) @@ -112,7 +115,7 @@ describe('Entity Menu - entities', () => { expect(wrapper.findComponent(StaffComments).exists()).toBe(false) expect(wrapper.find('#historical-chip').exists()).toBe(false) expect(wrapper.find('#company-information-button').exists()).toBe(false) - expect(wrapper.find('#dissolution-button').exists()).toBe(false) + expect(wrapper.find('.menu-btn').exists()).toBe(false) expect(wrapper.find('#download-summary-button').exists()).toBe(false) expect(wrapper.find('#view-add-digital-credentials-button').exists()).toBe(false) @@ -329,34 +332,38 @@ describe('Entity Menu - Dissolve this Business click tests', () => { mixins: [{ methods: { isAllowed: () => true } }], propsData: { businessId: 'BC1234567' } }) - await Vue.nextTick() - const button = wrapper.find('#dissolution-button') - expect(button.exists()).toBe(true) - expect(button.text()).toBe('Dissolve this Business') - expect(button.classes()).not.toContain('v-btn--disabled') // enabled + await wrapper.find('.menu-btn').trigger('click') + expect(wrapper.find('#dissolution-list-item').exists()).toBe(true) + expect(wrapper.find('#dissolution-list-item').text()).toBe('Dissolve this Business') + expect(wrapper.find('#dissolution-list-item').classes()).not.toContain('v-btn--disabled') // enabled wrapper.destroy() }) - it('does not display the button if not a business', async () => { + it('emits Confirm Dissolution event if in good standing', async () => { + businessStore.setGoodStanding(true) businessStore.setState(EntityState.ACTIVE) // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { vuetify, mixins: [{ methods: { isAllowed: () => true } }], - propsData: { businessId: null } + propsData: { businessId: 'BC1234567' } }) - await Vue.nextTick() - expect(wrapper.find('#dissolution-button').exists()).toBe(false) + await wrapper.find('.menu-btn').trigger('click') + + // click the button and verify emitted event + await wrapper.find('#dissolution-list-item').trigger('click') + expect(wrapper.emitted().confirmDissolution).toEqual([[]]) wrapper.destroy() }) - it('does not display the button if historical', async () => { - businessStore.setState(EntityState.HISTORICAL) + it('emits Not In Good Standing event if not in good standing', async () => { + businessStore.setGoodStanding(false) + businessStore.setState(EntityState.ACTIVE) // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { @@ -364,35 +371,35 @@ describe('Entity Menu - Dissolve this Business click tests', () => { mixins: [{ methods: { isAllowed: () => true } }], propsData: { businessId: 'BC1234567' } }) - await Vue.nextTick() - expect(wrapper.find('#dissolution-button').exists()).toBe(false) + await wrapper.find('.menu-btn').trigger('click') + + // click the button and verify emitted event + await wrapper.find('#dissolution-list-item').trigger('click') + expect(wrapper.emitted().notInGoodStanding).toEqual([['dissolve']]) wrapper.destroy() }) +}) - it('displays the button as disabled if not allowed', async () => { - businessStore.setState(EntityState.ACTIVE) - +describe('Entity Menu - Business Summary click tests', () => { + it('displays the Business Summary button', async () => { // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { vuetify, - mixins: [{ methods: { isAllowed: () => false } }], + mixins: [{ methods: { isAllowed: () => true } }], propsData: { businessId: 'BC1234567' } }) await Vue.nextTick() - const button = wrapper.find('#dissolution-button') + const button = wrapper.find('#download-summary-button') expect(button.exists()).toBe(true) - expect(button.classes()).toContain('v-btn--disabled') + expect(button.text()).toBe('Business Summary') wrapper.destroy() }) - it('emits Confirm Dissolution event if in good standing', async () => { - businessStore.setGoodStanding(true) - businessStore.setState(EntityState.ACTIVE) - + it('emits Download Business Summary event', async () => { // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { vuetify, @@ -402,16 +409,15 @@ describe('Entity Menu - Dissolve this Business click tests', () => { await Vue.nextTick() // click the button and verify emitted event - await wrapper.find('#dissolution-button').trigger('click') - expect(wrapper.emitted().confirmDissolution).toEqual([[]]) + await wrapper.find('#download-summary-button').trigger('click') + expect(wrapper.emitted().downloadBusinessSummary).toEqual([[]]) wrapper.destroy() }) +}) - it('emits Not In Good Standing event if not in good standing', async () => { - businessStore.setGoodStanding(false) - businessStore.setState(EntityState.ACTIVE) - +describe('Entity Menu - Business Digital Credentials click tests', () => { + it('displays the Business Digital Credentials button', async () => { // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { vuetify, @@ -420,16 +426,14 @@ describe('Entity Menu - Dissolve this Business click tests', () => { }) await Vue.nextTick() - // click the button and verify emitted event - await wrapper.find('#dissolution-button').trigger('click') - expect(wrapper.emitted().notInGoodStanding).toEqual([['dissolve']]) + const button = wrapper.find('#view-add-digital-credentials-button') + expect(button.exists()).toBe(true) + expect(button.text()).toBe('Business Digital Credentials') wrapper.destroy() }) -}) -describe('Entity Menu - Business Summary click tests', () => { - it('displays the Business Summary button', async () => { + it('emits View Add Digital Credentials event', async () => { // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { vuetify, @@ -438,59 +442,81 @@ describe('Entity Menu - Business Summary click tests', () => { }) await Vue.nextTick() - const button = wrapper.find('#download-summary-button') - expect(button.exists()).toBe(true) - expect(button.text()).toBe('Business Summary') + // click the button and verify emitted event + await wrapper.find('#view-add-digital-credentials-button').trigger('click') + expect(wrapper.emitted().viewAddDigitalCredentials).toEqual([[]]) wrapper.destroy() }) +}) - it('emits Download Business Summary event', async () => { +describe('Entity Menu - More actions click tests', () => { + it('renders More actions correctly', async () => { // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { vuetify, mixins: [{ methods: { isAllowed: () => true } }], propsData: { businessId: 'BC1234567' } }) - await Vue.nextTick() - // click the button and verify emitted event - await wrapper.find('#download-summary-button').trigger('click') - expect(wrapper.emitted().downloadBusinessSummary).toEqual([[]]) + expect(wrapper.find('.menu-btn').text()).toBe('More Actions') wrapper.destroy() }) -}) -describe('Entity Menu - Business Digital Credentials click tests', () => { - it('displays the Business Digital Credentials button', async () => { - // mount the component and wait for everything to stabilize + it('does not render More actions if historical', async () => { + businessStore.setState(EntityState.HISTORICAL) + const wrapper = mount(EntityMenu, { vuetify, - mixins: [{ methods: { isAllowed: () => true } }], + mixins: [{ methods: { isAllowed: () => false } }], propsData: { businessId: 'BC1234567' } }) - await Vue.nextTick() - const button = wrapper.find('#view-add-digital-credentials-button') - expect(button.exists()).toBe(true) - expect(button.text()).toBe('Business Digital Credentials') + expect(wrapper.find('.menu-btn').exists()).toBe(false) + wrapper.destroy() + }) + + it('does not render More actions if not a business', async () => { + const wrapper = mount(EntityMenu, { + vuetify, + mixins: [{ methods: { isAllowed: () => true } }], + propsData: { businessId: null } + }) + expect(wrapper.find('.menu-btn').exists()).toBe(false) wrapper.destroy() }) +}) + +describe('Entity Menu - Consent to Continuation click tests', () => { + const { assign } = window.location + + beforeAll(() => { + // mock the window.location.assign function + delete window.location + window.location = { assign: jest.fn() } as any + }) + + afterAll(() => { + window.location.assign = assign + }) + + it('displays the Consent to Continuation button', async () => { + businessStore.setLegalType(CorpTypeCd.BC_COMPANY) + businessStore.setState(EntityState.ACTIVE) - it('emits View Add Digital Credentials event', async () => { // mount the component and wait for everything to stabilize const wrapper = mount(EntityMenu, { vuetify, mixins: [{ methods: { isAllowed: () => true } }], propsData: { businessId: 'BC1234567' } }) - await Vue.nextTick() - // click the button and verify emitted event - await wrapper.find('#view-add-digital-credentials-button').trigger('click') - expect(wrapper.emitted().viewAddDigitalCredentials).toEqual([[]]) + await wrapper.find('.menu-btn').trigger('click') + expect(wrapper.find('#cco-list-item').exists()).toBe(true) + expect(wrapper.find('#cco-list-item').text()).toBe('Consent to Continue Out') + expect(wrapper.find('#cco-list-item').classes()).not.toContain('v-btn--disabled') // enabled wrapper.destroy() })