From f3b8e7019202840a32453d6b0d3594658d5e1875 Mon Sep 17 00:00:00 2001
From: Severin Beauvais <severin.beauvais@gov.bc.ca>
Date: Wed, 17 Jan 2024 16:42:42 -0800
Subject: [PATCH] - app version = 5.6.41 - added rest of unit tests

---
 package-lock.json                         |   4 +-
 package.json                              |   2 +-
 tests/unit/AmalgamatingBusinesses.spec.ts | 406 ++++++++++++++++++++--
 3 files changed, 378 insertions(+), 34 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 8aa9d0b2e..99218187e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "business-create-ui",
-  "version": "5.6.40",
+  "version": "5.6.41",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "business-create-ui",
-      "version": "5.6.40",
+      "version": "5.6.41",
       "dependencies": {
         "@babel/compat-data": "^7.21.5",
         "@bcrs-shared-components/approval-type": "1.0.19",
diff --git a/package.json b/package.json
index c82e5e437..ad24adf0a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "business-create-ui",
-  "version": "5.6.40",
+  "version": "5.6.41",
   "private": true,
   "appName": "Create UI",
   "sbcName": "SBC Common Components",
diff --git a/tests/unit/AmalgamatingBusinesses.spec.ts b/tests/unit/AmalgamatingBusinesses.spec.ts
index e8c96af2d..3809dea00 100644
--- a/tests/unit/AmalgamatingBusinesses.spec.ts
+++ b/tests/unit/AmalgamatingBusinesses.spec.ts
@@ -1,11 +1,15 @@
 /* eslint-disable max-len */
+import Vue from 'vue'
 import Vuetify from 'vuetify'
 import { createPinia, setActivePinia } from 'pinia'
 import { useStore } from '@/store/store'
 import { mount } from '@vue/test-utils'
 import AmalgamatingBusinesses from '@/components/Amalgamation/AmalgamatingBusinesses.vue'
 import BusinessTable from '@/components/Amalgamation/BusinessTable.vue'
-import { AmlRoles, AmlTypes } from '@/enums/amalgamationEnums'
+import { AmlRoles, AmlTypes, FilingStatus } from '@/enums'
+import { CorpTypeCd } from '@bcrs-shared-components/corp-type-module'
+import { EntityStates, RestorationTypes } from '@bcrs-shared-components/enums'
+import { AuthServices, LegalServices } from '@/services'
 
 const vuetify = new Vuetify({})
 setActivePinia(createPinia())
@@ -24,7 +28,8 @@ describe('Amalgamating Businesses - components and validity', () => {
 
   it('renders as staff', async () => {
     // set state
-    await store.setKeycloakRoles(['staff'])
+    store.setKeycloakRoles(['staff'])
+    await Vue.nextTick()
 
     // verify components
     expect(wrapper.findComponent(AmalgamatingBusinesses).exists()).toBe(true)
@@ -38,7 +43,8 @@ describe('Amalgamating Businesses - components and validity', () => {
 
   it('renders as non-staff', async () => {
     // set state
-    await store.setKeycloakRoles([])
+    store.setKeycloakRoles([])
+    await Vue.nextTick()
 
     // verify components
     expect(wrapper.findComponent(AmalgamatingBusinesses).exists()).toBe(true)
@@ -64,14 +70,14 @@ describe('Amalgamating Businesses - components and validity', () => {
   for (let i = 0; i < tests.length; i++) {
     const { businessTableValid, isAddingAmalgamatingBusiness, isAddingAmalgamatingForeignBusiness, expected } = tests[i]
     it(`validates component - test ${i}`, async () => {
-      // set data and validate validity
+      // set data and verify validity
       await wrapper.setData({ businessTableValid, isAddingAmalgamatingBusiness, isAddingAmalgamatingForeignBusiness })
       expect(store.stateModel.amalgamation.amalgamatingBusinessesValid).toBe(expected)
     })
   }
 })
 
-describe.skip('Amalgamating Businesses - add amalgamating business', () => {
+describe('Amalgamating Businesses - add amalgamating business', () => {
   let wrapper: any
 
   beforeEach(() => {
@@ -87,15 +93,368 @@ describe.skip('Amalgamating Businesses - add amalgamating business', () => {
   })
 
   it('conditionally renders the amalgamating business panel', async () => {
+    // verify panel not yet rendered
+    expect(wrapper.find('#add-amalgamating-business-panel').exists()).toBe(false)
+
+    // verify Add button is enabled
+    const addAmalgamatingButton = wrapper.find('#add-amalgamating-business-button')
+    expect(addAmalgamatingButton.classes()).not.toContain('v-btn--disabled')
+
+    // verify Add button and click it
+    expect(addAmalgamatingButton.text()).toBe('Add an Amalgamating Business')
+    await addAmalgamatingButton.trigger('click')
+
+    // verify Add button is now disabled
+    expect(addAmalgamatingButton.classes()).toContain('v-btn--disabled')
+
+    // verify panel is now rendered
+    expect(wrapper.find('#add-amalgamating-business-panel').exists()).toBe(true)
+
+    // verify Cancel button and click it
+    const cancelButton = wrapper.find('#app-cancel-btn')
+    expect(cancelButton.text()).toBe('Cancel')
+    await cancelButton.trigger('click')
+
+    // verify panel is no longer rendered
+    expect(wrapper.find('#add-amalgamating-business-panel').exists()).toBe(false)
+  })
+
+  it('saves an amalgamating business - Extra Pro', async () => {
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // simulate saving an extra pro business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.EXTRA_PRO_A,
+      name: 'Extra Pro Business',
+      identifier: 'A1234567'
+    })
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
+    const business = store.stateModel.amalgamation.amalgamatingBusinesses[0] as any
+    expect(business.type).toBe(AmlTypes.FOREIGN)
+    expect(business.role).toBe(AmlRoles.AMALGAMATING)
+    expect(business.foreignJurisdiction).toEqual({ country: 'CA', region: 'British Columbia' })
+    expect(business.legalName).toBe('Extra Pro Business')
+    expect(business.corpNumber).toBe('A1234567')
+
+    // verify panel is now closed
+    expect(wrapper.vm.isAddingAmalgamatingBusiness).toBe(false)
+  })
+
+  it('saves an amalgamating business - BC - unaffiliated - non-staff', async () => {
+    // set state
+    store.setKeycloakRoles([])
+    await Vue.nextTick()
+
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // mock services functions
+    vi.spyOn((AuthServices as any), 'fetchAuthInfo').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchBusinessInfo').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchAddresses').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchFirstOrOnlyFiling').mockImplementation(() => null)
+
+    // simulate saving a BC business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.BC_COMPANY,
+      name: 'My BC Business',
+      identifier: 'BC1234567'
+    })
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
+    const business = store.stateModel.amalgamation.amalgamatingBusinesses[0] as any
+    expect(business.type).toBe(AmlTypes.LEAR)
+    expect(business.role).toBe(AmlRoles.AMALGAMATING)
+    expect(business.identifier).toBe('BC1234567')
+    expect(business.name).toBe('My BC Business')
+
+    // verify panel is now closed
+    expect(wrapper.vm.isAddingAmalgamatingBusiness).toBe(false)
+
+    vi.resetAllMocks()
+  })
+
+  it('doesn\'t save an amalgamating business - BC - unaffiliated - staff', async () => {
+    // set state
+    store.setKeycloakRoles(['staff'])
+    await Vue.nextTick()
+
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // mock services functions
+    vi.spyOn((AuthServices as any), 'fetchAuthInfo').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchBusinessInfo').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchAddresses').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchFirstOrOnlyFiling').mockImplementation(() => null)
+
+    // simulate saving a BC business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.BC_COMPANY,
+      name: 'My BC Business',
+      identifier: 'BC1234567'
+    })
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(0)
+
+    // verify snackbar is displayed
+    expect(wrapper.vm.snackbar).toBe(true)
+    expect(wrapper.vm.snackbarText).toBe('Business doesn\'t exist in LEAR.')
+
+    vi.resetAllMocks()
+  })
+
+  it('doesn\'t save an amalgamating business - BC - missing business info', async () => {
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // mock services functions
+    vi.spyOn((AuthServices as any), 'fetchAuthInfo').mockImplementation(() => ({}))
+    vi.spyOn((LegalServices as any), 'fetchBusinessInfo').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchAddresses').mockImplementation(() => ({}))
+    vi.spyOn((LegalServices as any), 'fetchFirstOrOnlyFiling').mockImplementation(() => ({}))
+
+    // simulate saving a BC business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.BC_COMPANY,
+      name: 'My BC Business',
+      identifier: 'BC1234567'
+    })
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(0)
+
+    // verify snackbar is displayed
+    expect(wrapper.vm.snackbar).toBe(true)
+    expect(wrapper.vm.snackbarText).toBe('Unable to add that business.')
+
+    vi.resetAllMocks()
+  })
+
+  it('doesn\'t save an amalgamating business - BC - missing addresses', async () => {
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // mock services functions
+    vi.spyOn((AuthServices as any), 'fetchAuthInfo').mockImplementation(() => ({}))
+    vi.spyOn((LegalServices as any), 'fetchBusinessInfo').mockImplementation(() => ({}))
+    vi.spyOn((LegalServices as any), 'fetchAddresses').mockImplementation(() => null)
+    vi.spyOn((LegalServices as any), 'fetchFirstOrOnlyFiling').mockImplementation(() => ({}))
+
+    // simulate saving a BC business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.BC_COMPANY,
+      name: 'My BC Business',
+      identifier: 'BC1234567'
+    })
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(0)
+
+    // verify snackbar is displayed
+    expect(wrapper.vm.snackbar).toBe(true)
+    expect(wrapper.vm.snackbarText).toBe('Unable to add that business.')
+
+    vi.resetAllMocks()
+  })
+
+  it('doesn\'t save an amalgamating business - BC - missing first filing', async () => {
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // mock services functions
+    vi.spyOn((AuthServices as any), 'fetchAuthInfo').mockImplementation(() => ({}))
+    vi.spyOn((LegalServices as any), 'fetchBusinessInfo').mockImplementation(() => ({}))
+    vi.spyOn((LegalServices as any), 'fetchAddresses').mockImplementation(() => ({}))
+    vi.spyOn((LegalServices as any), 'fetchFirstOrOnlyFiling').mockImplementation(() => null)
+
+    // simulate saving a BC business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.BC_COMPANY,
+      name: 'My BC Business',
+      identifier: 'BC1234567'
+    })
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(0)
+
+    // verify snackbar is displayed
+    expect(wrapper.vm.snackbar).toBe(true)
+    expect(wrapper.vm.snackbarText).toBe('Unable to add that business.')
+
+    vi.resetAllMocks()
   })
 
-  it('saves an amalgamating business', async () => {
+  it('doesn\'t save a duplicate amalgamating business - Extra Pro', async () => {
+    // pre-populate an extra pro business
+    store.stateModel.amalgamation.amalgamatingBusinesses = [
+      {
+        type: AmlTypes.FOREIGN,
+        role: AmlRoles.AMALGAMATING,
+        foreignJurisdiction: { country: 'CA', region: 'British Columbia' },
+        legalName: 'Extra Pro Business',
+        corpNumber: 'A1234567'
+      }
+    ]
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
+
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // verify snackbar is not displayed
+    expect(wrapper.vm.snackbar).toBe(false)
+
+    // try to save a duplicate extra pro business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.EXTRA_PRO_A,
+      name: 'Extra Pro Business',
+      identifier: 'A1234567'
+    })
+
+    // verify snackbar is displayed
+    expect(wrapper.vm.snackbar).toBe(true)
+    expect(wrapper.vm.snackbarText).toBe('Business is already in table.')
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
+
+    // verify panel is now closed
+    expect(wrapper.vm.isAddingAmalgamatingBusiness).toBe(false)
   })
 
-  it('saves an amalgamating business', async () => {
+  it('save an amalgamating business - BC', async () => {
+    // set state
+    store.setCurrentDate('2023-01-01')
+    await Vue.nextTick()
+
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // mock services functions
+    vi.spyOn((AuthServices as any), 'fetchAuthInfo').mockImplementation(() => ({
+      contacts: [{ email: 'email@example.com' }]
+    }))
+    vi.spyOn((LegalServices as any), 'fetchBusinessInfo').mockImplementation(() => ({
+      identifier: 'BC1234567',
+      legalName: 'My BC Business',
+      legalType: CorpTypeCd.BC_COMPANY,
+      goodStanding: true,
+      adminFreeze: false,
+      state: EntityStates.ACTIVE,
+      stateFiling: 'mock_url',
+      restorationExpiryDate: '2023-01-18'
+    }))
+    vi.spyOn((LegalServices as any), 'fetchAddresses').mockImplementation(() => ({
+      registeredOffice: { mailingAddress: { streetAddress: '123 Main St' } }
+    }))
+    vi.spyOn((LegalServices as any), 'fetchFirstOrOnlyFiling').mockImplementation(() => ({
+      isFutureEffective: false,
+      status: FilingStatus.COMPLETED
+    }))
+    // in this case, return a promise so that ".catch()" is defined on the implementation
+    vi.spyOn((LegalServices as any), 'fetchFiling').mockImplementation(() =>
+      Promise.resolve({
+        restoration: { type: RestorationTypes.FULL }
+      })
+    )
+
+    // simulate saving a BC business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.BC_COMPANY,
+      name: 'My BC Business',
+      identifier: 'BC1234567'
+    })
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
+    const business = store.stateModel.amalgamation.amalgamatingBusinesses[0] as any
+    expect(business.type).toBe(AmlTypes.LEAR)
+    expect(business.role).toBe(AmlRoles.AMALGAMATING)
+    expect(business.identifier).toBe('BC1234567')
+    expect(business.name).toBe('My BC Business')
+    expect(business.email).toBe('email@example.com')
+    expect(business.legalType).toBe(CorpTypeCd.BC_COMPANY)
+    expect(business.address.streetAddress).toBe('123 Main St')
+    expect(business.isNotInGoodStanding).toBe(false)
+    expect(business.isFrozen).toBe(false)
+    expect(business.isFutureEffective).toBe(false)
+    expect(business.isPendingFiling).toBe(false)
+    expect(business.isLimitedRestoration).toBe(false)
+    expect(business.isHistorical).toBe(false)
+
+    // verify panel is now closed
+    expect(wrapper.vm.isAddingAmalgamatingBusiness).toBe(false)
+
+    vi.resetAllMocks()
   })
 
-  it('doesn\'t add a duplicate amalgamating business', async () => {
+  it('doesn\'t save a duplicate amalgamating business - BC', async () => {
+    // pre-populate a BC business
+    store.stateModel.amalgamation.amalgamatingBusinesses = [
+      {
+        // this is the minimum data needed
+        type: AmlTypes.LEAR,
+        role: AmlRoles.AMALGAMATING,
+        identifier: 'BC1234567'
+      }
+    ]
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
+
+    // open panel
+    await wrapper.setData({ isAddingAmalgamatingBusiness: true })
+
+    // verify snackbar is not displayed
+    expect(wrapper.vm.snackbar).toBe(false)
+
+    // mock services functions
+    vi.spyOn((AuthServices as any), 'fetchAuthInfo').mockImplementation(() => ({
+      contacts: [{ email: 'email@example.com' }]
+    }))
+    vi.spyOn((LegalServices as any), 'fetchBusinessInfo').mockImplementation(() => ({
+      identifier: 'BC1234567',
+      legalName: 'My BC Business',
+      legalType: CorpTypeCd.BC_COMPANY,
+      goodStanding: true,
+      adminFreeze: false,
+      state: EntityStates.ACTIVE,
+      stateFiling: 'mock_url',
+      restorationExpiryDate: '2023-01-18'
+    }))
+    vi.spyOn((LegalServices as any), 'fetchAddresses').mockImplementation(() => ({
+      registeredOffice: { mailingAddress: { streetAddress: '123 Main St' } }
+    }))
+    vi.spyOn((LegalServices as any), 'fetchFirstOrOnlyFiling').mockImplementation(() => ({
+      isFutureEffective: false,
+      status: FilingStatus.COMPLETED
+    }))
+    // in this case, return a promise so that ".catch()" is defined on the implementation
+    vi.spyOn((LegalServices as any), 'fetchFiling').mockImplementation(() =>
+      Promise.resolve({
+        restoration: { type: RestorationTypes.FULL }
+      })
+    )
+
+    // try to save a duplicate BC business
+    await wrapper.vm.saveAmalgamatingBusiness({
+      legalType: CorpTypeCd.BC_COMPANY,
+      name: 'My BC Business',
+      identifier: 'BC1234567'
+    })
+
+    // verify snackbar is displayed
+    expect(wrapper.vm.snackbar).toBe(true)
+    expect(wrapper.vm.snackbarText).toBe('Business is already in table.')
+
+    // verify data
+    expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
+
+    // verify panel is now closed
+    expect(wrapper.vm.isAddingAmalgamatingBusiness).toBe(false)
   })
 })
 
@@ -118,7 +477,7 @@ describe('Amalgamating Businesses - add amalgamating foreign business', () => {
     // verify panel not yet rendered
     expect(wrapper.find('#add-foreign-business-panel').exists()).toBe(false)
 
-    // verify Add buttons are enabled
+    // verify Add buttons
     const addAmalgamatingButton = wrapper.find('#add-amalgamating-business-button')
     const addForeignButton = wrapper.find('#add-foreign-business-button')
     expect(addAmalgamatingButton.classes()).not.toContain('v-btn--disabled')
@@ -150,9 +509,7 @@ describe('Amalgamating Businesses - add amalgamating foreign business', () => {
 
   it('saves a foreign business', async () => {
     // open panel
-    await wrapper.setData({
-      isAddingAmalgamatingForeignBusiness: true
-    })
+    await wrapper.setData({ isAddingAmalgamatingForeignBusiness: true })
 
     // simulate form data
     await wrapper.setData({
@@ -181,13 +538,13 @@ describe('Amalgamating Businesses - add amalgamating foreign business', () => {
     expect(wrapper.vm.isAddingAmalgamatingForeignBusiness).toBe(false)
   })
 
-  it('doesn\'t add a duplicate foreign business', async () => {
+  it('doesn\'t save a duplicate foreign business', async () => {
     // pre-populate a foreign business
     store.stateModel.amalgamation.amalgamatingBusinesses = [
       {
         type: AmlTypes.FOREIGN,
         role: AmlRoles.AMALGAMATING,
-        foreignJurisdiction: { country: 'CA', region: 'BC' },
+        foreignJurisdiction: { country: 'CA', region: 'British Columbia' },
         legalName: 'Foreign Business',
         corpNumber: 'ABC-123'
       }
@@ -195,14 +552,12 @@ describe('Amalgamating Businesses - add amalgamating foreign business', () => {
     expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
 
     // open panel
-    await wrapper.setData({
-      isAddingAmalgamatingForeignBusiness: true
-    })
+    await wrapper.setData({ isAddingAmalgamatingForeignBusiness: true })
 
     // simulate form data
     await wrapper.setData({
       isCan: true,
-      jurisdiction: { text: 'BC', value: 'CA' },
+      jurisdiction: { text: 'British Columbia', value: 'CA' },
       legalName: 'Foreign Business',
       corpNumber: 'ABC-123'
     })
@@ -210,11 +565,12 @@ describe('Amalgamating Businesses - add amalgamating foreign business', () => {
     // verify snackbar is not displayed
     expect(wrapper.vm.snackbar).toBe(false)
 
-    // simulate Save button action
+    // try to save a duplicate foreign business
     wrapper.vm.saveAmalgamatingForeignBusiness()
 
     // verify snackbar is displayed
     expect(wrapper.vm.snackbar).toBe(true)
+    expect(wrapper.vm.snackbarText).toBe('Business is already in table.')
 
     // verify data
     expect(store.stateModel.amalgamation.amalgamatingBusinesses.length).toBe(1)
@@ -317,15 +673,3 @@ describe('Amalgamating Businesses - add amalgamating foreign business', () => {
     expect(wrapper.vm.isMrasJurisdiction).toBe(false)
   })
 })
-
-describe.skip('Amalgamating Businesses - foreign business form', () => {
-  let wrapper: any
-
-  beforeEach(() => {
-    wrapper = mount(AmalgamatingBusinesses, { vuetify })
-  })
-
-  afterEach(() => {
-    wrapper.destroy()
-  })
-})