From b98c50657a851ac1591af965fbcbe079038ade0b Mon Sep 17 00:00:00 2001 From: Le Date: Tue, 5 Dec 2023 11:10:26 -0800 Subject: [PATCH 1/7] add MessageView unit test - initial commit --- frontend/test/views/MessageView.test.js | 63 +++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 frontend/test/views/MessageView.test.js diff --git a/frontend/test/views/MessageView.test.js b/frontend/test/views/MessageView.test.js new file mode 100644 index 00000000..11a2db8f --- /dev/null +++ b/frontend/test/views/MessageView.test.js @@ -0,0 +1,63 @@ +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' + +import { describe, test } from 'vitest' + +import MessagingView from '@/views/MessagingView.vue' +import { createTestingPinia } from '@pinia/testing' +import { createVuetify } from 'vuetify' +import { mount } from '@vue/test-utils' +import { useMessagesStore } from '@/stores/messages' +import { useNotificationsStore } from '@/stores/notifications' + +const vuetify = createVuetify({ components, directives }) + +describe('MessagingView', () => { + const global = { global: { plugins: [createTestingPinia(), vuetify] } } + const messagesStore = useMessagesStore() + const notificationsStore = useNotificationsStore() + + messagesStore.assistanceRequests = [ + { + assistanceRequestId: '1', + categoryName: 'Funding Agreement', + contactMethod: 2, + description: 'Test #1', + lastOpenedTime: null, + lastConversationTime: '2023-11-16T06:15:13Z', + isRead: false, + phone: '1111111111', + referenceNumber: 'REQ-000001', + requestFacilities: Array[0], + stateCode: 0, + status: 'Open', + statusCode: 2, + subject: 'Test #1 - Funding Agreement', + }, + { + assistanceRequestId: '2', + categoryName: 'Intake & Renewal', + contactMethod: 1, + description: 'Test #2', + lastOpenedTime: null, + lastConversationTime: '2023-11-14T06:15:13Z', + isRead: false, + phone: null, + referenceNumber: 'REQ-000002', + requestFacilities: Array[0], + stateCode: 0, + status: 'Open', + statusCode: 2, + subject: 'Test #2 - Funding Agreement', + }, + ] + + notificationsStore.notifications = [] + + test('Count of unread messages in the Messages tab ', async () => { + const wrapper = mount(MessagingView, global) + + const messagesBadge = wrapper.get('#messages-tab-badge') + expect(messagesBadge.attributes().content).toEqual('2') + }) +}) From 73a468f7fcccd51113ea7bf613a1c2b1dcc712ba Mon Sep 17 00:00:00 2001 From: Le Date: Fri, 29 Dec 2023 14:03:11 -0800 Subject: [PATCH 2/7] unit test - add MessagingView unit test --- .../src/components/messages/MessagesTab.vue | 6 +- .../notifications/NotificationsTab.vue | 2 +- frontend/src/views/MessagingView.vue | 8 +- .../components/messages/MessagesTab.test.js | 243 ++++++++++++++++++ frontend/test/views/MessageView.test.js | 63 ----- frontend/test/views/MessagingView.test.js | 243 ++++++++++++++++++ 6 files changed, 494 insertions(+), 71 deletions(-) create mode 100644 frontend/test/components/messages/MessagesTab.test.js delete mode 100644 frontend/test/views/MessageView.test.js create mode 100644 frontend/test/views/MessagingView.test.js diff --git a/frontend/src/components/messages/MessagesTab.vue b/frontend/src/components/messages/MessagesTab.vue index 1c29db3a..ddbbb97e 100644 --- a/frontend/src/components/messages/MessagesTab.vue +++ b/frontend/src/components/messages/MessagesTab.vue @@ -4,7 +4,7 @@
- + mdi-email-plus-outline New message @@ -28,10 +28,10 @@ - + - + - - diff --git a/frontend/src/components/TheNavBar.vue b/frontend/src/components/TheNavBar.vue deleted file mode 100644 index 6620f53a..00000000 --- a/frontend/src/components/TheNavBar.vue +++ /dev/null @@ -1,209 +0,0 @@ - - - - - diff --git a/frontend/src/components/account-mgmt/DuplicateUserDialog.vue b/frontend/src/components/account-mgmt/DuplicateUserDialog.vue new file mode 100644 index 00000000..70aa8853 --- /dev/null +++ b/frontend/src/components/account-mgmt/DuplicateUserDialog.vue @@ -0,0 +1,57 @@ + + + diff --git a/frontend/src/components/account-mgmt/EditFacilityContacts.vue b/frontend/src/components/account-mgmt/EditFacilityContacts.vue new file mode 100644 index 00000000..9b6bfb0f --- /dev/null +++ b/frontend/src/components/account-mgmt/EditFacilityContacts.vue @@ -0,0 +1,241 @@ + + + + diff --git a/frontend/src/components/account-mgmt/ManageUserDialog.vue b/frontend/src/components/account-mgmt/ManageUserDialog.vue index 20446b5e..df2bbada 100644 --- a/frontend/src/components/account-mgmt/ManageUserDialog.vue +++ b/frontend/src/components/account-mgmt/ManageUserDialog.vue @@ -10,8 +10,8 @@ BCeID: - - + + {{ user.userName }} @@ -83,7 +83,19 @@ :rules="rules.required" :disabled="isLoading || isSameUser" density="compact" - variant="outlined"> + variant="outlined"> + + @@ -105,6 +117,7 @@ + @@ -119,12 +132,13 @@ import AppDialog from '@/components/ui/AppDialog.vue' import AppLabel from '@/components/ui/AppLabel.vue' import rules from '@/utils/rules' import { ApiRoutes } from '@/utils/constants' +import DuplicateUserDialog from '@/components/account-mgmt/DuplicateUserDialog.vue' const ADD_USER_SUCCESS_MSG = 'User account created. Click "Next" to assign a facility to the new user.' export default { name: 'ManageUserDialog', - components: { AppButton, AppDialog, AppLabel }, + components: { AppButton, AppDialog, AppLabel, DuplicateUserDialog }, mixins: [alertMixin], props: { show: { @@ -152,6 +166,9 @@ export default { facilitiesUser: [], userOperationType: '', // Can be 'add', 'update' wasNewUserAdded: false, + errorMessages: [], + showDuplicateUserDialog: false, + continueSaveConfirmed: false, } }, computed: { @@ -169,6 +186,12 @@ export default { isSameUser() { return this.user.userName === this.userInfo.userName }, + allFacilitiesSelected() { + return this.selectedFacilityIds?.length === this.facilitiesToAdminister?.length + }, + someFacilitiesSelected() { + return this.selectedFacilityIds?.length > 0 + }, }, watch: { show: { @@ -225,11 +248,26 @@ export default { } }, + /** + * Close the duplicate user dialog and save the user. + */ + async closeDialogAndSaveUser() { + this.continueSaveConfirmed = true + this.toggleDuplicateUserDialog() + this.saveUser() + }, + /** * Create a new user and emit success/fail event. */ async createUser() { try { + // Check if user already exists, if so, prompt to confirm they wish to continue + const userExists = await this.doesUserExist(this.user.firstName, this.user.lastName, this.user.email) + if (!this.continueSaveConfirmed && userExists) { + this.toggleDuplicateUserDialog() + return + } this.user.organizationId = this.userInfo.organizationId const response = await ApiService.apiAxios.post(ApiRoutes.USER + '/create', this.user) this.user = response.data @@ -258,7 +296,7 @@ export default { */ async getUserFacilities(contactId, onlyWithPortalAccess) { try { - const res = await ApiService.apiAxios.get(`${ApiRoutes.USER_FACILITIES.replace(':contactId', contactId)}?onlyWithPortalAccess=${onlyWithPortalAccess}`); + const res = await ApiService.apiAxios.get(`${ApiRoutes.USER}${ApiRoutes.USER_FACILITIES.replace(':contactId', contactId)}?onlyWithPortalAccess=${onlyWithPortalAccess}`) return this.sortFacilities(res.data) } catch (error) { this.setFailureAlert('Failed to get the list of facilities by contact id: ' + this.userInfo.contactId, error) @@ -296,7 +334,7 @@ export default { if (selectedFacilityIds?.length !== userFacilities?.length) { return true } - return selectedFacilityIds.some((facilityId) => !userFacilities.includes(facilityId)) + return selectedFacilityIds?.some((facilityId) => !userFacilities?.includes(facilityId)) }, /** @@ -328,7 +366,7 @@ export default { * Filter facilities to administer. */ getSelectedFacilitiesByIds(selectedFacilityIds) { - return this.facilitiesToAdminister.filter((facility) => selectedFacilityIds.includes(facility.facilityId)) + return this.facilitiesToAdminister?.filter((facility) => selectedFacilityIds?.includes(facility.facilityId)) }, /** @@ -357,6 +395,51 @@ export default { } }) }, + toggleFacilitiesToAdminister() { + if (this.allFacilitiesSelected) { + this.selectedFacilityIds = [] + } else { + this.selectedFacilityIds = this.facilitiesToAdminister?.map((facility) => facility.facilityId) + } + }, + + /** + * Check if BCeID exists in provider organization, if so raise error message. + */ + async checkBCeIDExists(userName) { + try { + if (this.user.userName) { + const res = await ApiService.apiAxios.get(`${ApiRoutes.USER}/${userName}?providerProfile=false`) + this.errorMessages = (res.data.length >= 1) ? ['A user with this BCeID already exists.'] : [] + } + } catch (error) { + this.setFailureAlert('Failed to check if BCeID already exists in provider organization: ' + userName, error) + } + }, + + /** + * Check if user already exists in provider organization by first name, last name, and email. + */ + async doesUserExist(firstName, lastName, email) { + try { + const res = await ApiService.apiAxios.get(`${ApiRoutes.ORGANIZATIONS}${ApiRoutes.ORGANIZATIONS_USERS.replace(':organizationId', this.userInfo.organizationId)}?firstName=${firstName}&lastName=${lastName}&email=${email}`); + if (Array.isArray(res.data) && res.data.length >= 1) { + return true + } + this.errorMessages = []; + return false + } catch (error) { + this.setFailureAlert('Failed to check if user already exists in provider organization', error) + } + }, + + /** + * Toggle the duplicate user dialog. + */ + toggleDuplicateUserDialog() { + this.showDuplicateUserDialog = !this.showDuplicateUserDialog + }, + }, } diff --git a/frontend/src/components/applications/ApplicationNavBar.vue b/frontend/src/components/applications/ApplicationNavBar.vue index 72e5922c..68fd9311 100644 --- a/frontend/src/components/applications/ApplicationNavBar.vue +++ b/frontend/src/components/applications/ApplicationNavBar.vue @@ -65,7 +65,7 @@ export default { } }, computed: { - ...mapState(useApplicationsStore, ['currentApplication']), + ...mapState(useApplicationsStore, ['currentApplication', 'isFacilityDetailsComplete', 'isLicencesComplete', 'isOperatingCostsComplete', 'isStaffingComplete', 'isSubmitApplicationComplete']), isSelectFacilityPage() { return this.$route.name === 'select-facility' @@ -101,19 +101,19 @@ export default { getNavIcon(item) { if (this.isSelectFacilityPage) { - return `mdi-numeric-${item.id}-circle` + return 'mdi-circle' } switch (item.routeName) { case 'facility-details': - return this.currentApplication?.isFacilityDetailsComplete ? 'mdi-check-circle' : `mdi-numeric-${item.id}-circle` + return this.isFacilityDetailsComplete ? 'mdi-check-circle' : 'mdi-circle' case 'licences': - return this.currentApplication?.isLicencesComplete ? 'mdi-check-circle' : `mdi-numeric-${item.id}-circle` + return this.isLicencesComplete ? 'mdi-check-circle' : 'mdi-circle' case 'operating-costs': - return this.currentApplication?.isOperatingCostsComplete ? 'mdi-check-circle' : `mdi-numeric-${item.id}-circle` + return this.isOperatingCostsComplete ? 'mdi-check-circle' : 'mdi-circle' case 'staffing': - return this.currentApplication?.isStaffingComplete ? 'mdi-check-circle' : `mdi-numeric-${item.id}-circle` + return this.isStaffingComplete ? 'mdi-check-circle' : 'mdi-circle' case 'submit-application': - return this.currentApplication?.isSubmitApplicationComplete ? 'mdi-check-circle' : `mdi-numeric-${item.id}-circle` + return this.isSubmitApplicationComplete ? 'mdi-check-circle' : 'mdi-circle' } }, }, diff --git a/frontend/src/components/applications/ContactInfo.vue b/frontend/src/components/applications/ContactInfo.vue new file mode 100644 index 00000000..e91c37e0 --- /dev/null +++ b/frontend/src/components/applications/ContactInfo.vue @@ -0,0 +1,91 @@ + + + diff --git a/frontend/src/components/applications/YearlyFacilityCost.vue b/frontend/src/components/applications/YearlyFacilityCost.vue new file mode 100644 index 00000000..63e06c05 --- /dev/null +++ b/frontend/src/components/applications/YearlyFacilityCost.vue @@ -0,0 +1,208 @@ + + + + diff --git a/frontend/src/components/applications/YearlyOperatingCost.vue b/frontend/src/components/applications/YearlyOperatingCost.vue new file mode 100644 index 00000000..9a213056 --- /dev/null +++ b/frontend/src/components/applications/YearlyOperatingCost.vue @@ -0,0 +1,184 @@ + + + + diff --git a/frontend/src/components/facilities/FacilityInfo.vue b/frontend/src/components/facilities/FacilityInfo.vue index 7ae6e50f..324a97bc 100644 --- a/frontend/src/components/facilities/FacilityInfo.vue +++ b/frontend/src/components/facilities/FacilityInfo.vue @@ -1,5 +1,5 @@ diff --git a/frontend/src/components/messages/NewRequestDialog.vue b/frontend/src/components/messages/NewRequestDialog.vue index f64a06e5..466e3254 100644 --- a/frontend/src/components/messages/NewRequestDialog.vue +++ b/frontend/src/components/messages/NewRequestDialog.vue @@ -25,7 +25,7 @@ - + - - - - - Organization legal name: - - {{ organizationInfo?.name }} - - - - - - - - - - - - - - Doing business as: - - - {{ organizationInfo?.businessType }} - - - - - - - Email address: - - - {{ organizationInfo?.email }} - - - - - - - - - Phone (landline): - - - {{ organizationInfo?.phoneLandline }} - - - - - - - Phone (cell): - - - {{ organizationInfo?.phoneCell }} - - - - - - - - -

Physical address

-
- - - - - Street address 1: - - - {{ organizationInfo?.streetAddress1 }} + + + + + + + Organization legal name: + + + - - - - - Street address 2: + + + Doing business as: - - {{ organizationInfo?.streetAddress2 }} + + + - - - - - - - City: + + + Email address: + + + + + + + + + Phone (landline): - - {{ organizationInfo?.city }} + + + - - - - - Province: + + + Phone (cell): - - {{ organizationInfo?.province }} + + + - - - - - Postal code: +
+
+ + + + + Mailing Address: - - {{ organizationInfo?.postalCode }} + + + + + - - -
- - - - - -

Mailing address

-
- - - - - Street address 1: - - - {{ organizationInfo?.isMailingAddressDifferent ? organizationInfo?.mailingStreetAddress1 : organizationInfo?.streetAddress1 }} + + + Street Address 1: + + + + - - - - - Street address 2: + + + Street Address 2: - - {{ organizationInfo?.isMailingAddressDifferent ? organizationInfo?.mailingStreetAddress2 : organizationInfo?.streetAddress2 }} + + + - - - - - - + + City: - - {{ organizationInfo?.isMailingAddressDifferent ? organizationInfo?.mailingCity : organizationInfo?.city }} + + + + + + Prov: + + + + + + + Postal Code: + + + + + + + + + + Physical Address: - - - - - Province: + + + Street Address 1: - - {{ organizationInfo?.isMailingAddressDifferent ? organizationInfo?.mailingProvince : organizationInfo?.province }} + + + - - - - - Postal code: + + + Street Address 2: - - {{ organizationInfo?.isMailingAddressDifferent ? organizationInfo?.mailingPostalCode : organizationInfo?.postalCode }} + + + - - - - + + + City: + + + + + + + Prov: + + + + + + + Postal Code: + + + + + + + + + + + + Cancel + Save + + + @@ -197,39 +204,73 @@ import { useAuthStore } from '@/stores/auth' import alertMixin from '@/mixins/alertMixin' import OrganizationService from '@/services/organizationService' import AppLabel from '@/components/ui/AppLabel.vue' +import AppButton from '@/components/ui/AppButton.vue' +import rules from '@/utils/rules' export default { - components: { AppLabel }, + components: { AppButton, AppLabel }, mixins: [alertMixin], props: { editable: { type: Boolean, default: false, }, + organization: { + type: Object, + required: true, + default: () => { + return {} + }, + }, + loading: { + type: Boolean, + default: false, + }, }, data() { return { - organizationInfo: undefined, - loading: false, + isFormComplete: false, + organizationReadOnly: undefined, + organizationEdit: undefined, + localLoading: false, + rules, + editMode: false, } }, computed: { ...mapState(useAuthStore, ['userInfo']), }, - async created() { - await this.loadOrganizationInfo() + async updated() { + this.organizationReadOnly = JSON.parse(JSON.stringify(this.organization)) }, methods: { - async loadOrganizationInfo() { + async update() { + this.$refs.organizationForm?.validate() + if (!this.isFormComplete) { + return + } try { - this.loading = true - this.organizationInfo = await OrganizationService.getOrganization(this.userInfo?.organizationId) + this.localLoading = true + await OrganizationService.updateOrganization(this.userInfo?.organizationId, this.organizationEdit) + this.organizationReadOnly = { ...this.organizationEdit } + this.editMode = false + this.setSuccessAlert('Organization information updated successfully') } catch (error) { this.setFailureAlert('Failed to get your organization information', error) } finally { - this.loading = false + this.localLoading = false } }, + + toggleEditMode() { + this.organizationEdit = JSON.parse(JSON.stringify(this.organization)) + this.editMode = !this.editMode + }, + + isLoading() { + return this.loading || this.localLoading + }, + }, } diff --git a/frontend/src/components/ui/AppBackButton.vue b/frontend/src/components/ui/AppBackButton.vue new file mode 100644 index 00000000..22564063 --- /dev/null +++ b/frontend/src/components/ui/AppBackButton.vue @@ -0,0 +1,15 @@ + + diff --git a/frontend/src/components/ui/AppButton.vue b/frontend/src/components/ui/AppButton.vue index 587c542f..c014d7ae 100644 --- a/frontend/src/components/ui/AppButton.vue +++ b/frontend/src/components/ui/AppButton.vue @@ -1,6 +1,6 @@ @@ -21,7 +21,7 @@ export default { props: { primary: { type: Boolean, - default: 'primary', + default: true, }, }, } diff --git a/frontend/src/components/ui/AppDocumentUpload.vue b/frontend/src/components/ui/AppDocumentUpload.vue index 70959f27..33c9986b 100644 --- a/frontend/src/components/ui/AppDocumentUpload.vue +++ b/frontend/src/components/ui/AppDocumentUpload.vue @@ -2,9 +2,10 @@
The maximum file size is 4MB for each document. Accepted file types are jpg, jpeg, heic, png, pdf, docx, doc, xls, and xlsx.
+ Add File
- + + @update:modelValue="validateFile(item.id)"> - + - + mdi-delete
- - mdi-plus - Add - +
+ Uploaded Documents + + + + +
+ diff --git a/frontend/src/components/ui/AppNavButtons.vue b/frontend/src/components/ui/AppNavButtons.vue index fce55dc4..17eac0cc 100644 --- a/frontend/src/components/ui/AppNavButtons.vue +++ b/frontend/src/components/ui/AppNavButtons.vue @@ -2,14 +2,20 @@ - ← Back + + mdi-arrow-left + Back + Cancel Save - Next → + + Next + mdi-arrow-right + Submit diff --git a/frontend/src/components/ui/AppNumberInput.vue b/frontend/src/components/ui/AppNumberInput.vue new file mode 100644 index 00000000..55116be6 --- /dev/null +++ b/frontend/src/components/ui/AppNumberInput.vue @@ -0,0 +1,36 @@ + + diff --git a/frontend/src/mixins/rolesMixin.js b/frontend/src/mixins/rolesMixin.js index c3f1888d..d76b84cf 100644 --- a/frontend/src/mixins/rolesMixin.js +++ b/frontend/src/mixins/rolesMixin.js @@ -1,6 +1,3 @@ -import { mapState } from 'pinia' - -import { useAppStore } from '@/stores/app' import { ROLES } from '@/utils/constants.js' export default { diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index b99113f0..aa093a69 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -1,8 +1,7 @@ import { createRouter, createWebHistory } from 'vue-router' -import { useAppStore } from '@/stores/app' import { useAuthStore } from '@/stores/auth' -import { PAGE_TITLES, ROLES } from '@/utils/constants' +import { ROLES } from '@/utils/constants' import BackendSessionExpiredView from '@/views/BackendSessionExpiredView.vue' import DocumentsView from '@/views/DocumentsView.vue' import EmptyRouterView from '@/views/EmptyRouterView.vue' @@ -41,7 +40,6 @@ const router = createRouter({ name: 'home', component: HomeView, meta: { - pageTitle: PAGE_TITLES.DASHBOARD, requiresAuth: true, showHeroImage: true, }, @@ -51,7 +49,6 @@ const router = createRouter({ name: 'login', component: LoginView, meta: { - pageTitle: PAGE_TITLES.LOGIN, requiresAuth: false, showHeroImage: true, }, @@ -61,7 +58,6 @@ const router = createRouter({ name: 'ministry login', component: MinistryLoginView, meta: { - pageTitle: PAGE_TITLES.LOGIN, requiresAuth: false, showHeroImage: true, }, @@ -79,7 +75,6 @@ const router = createRouter({ name: 'impersonate', component: ImpersonateView, meta: { - pageTitle: 'Impersonate a BCeID User', requiresAuth: true, }, }, @@ -88,7 +83,6 @@ const router = createRouter({ name: 'messaging', component: MessagingView, meta: { - pageTitle: 'Messaging', requiresAuth: true, }, }, @@ -97,7 +91,6 @@ const router = createRouter({ name: 'reporting', component: ReportingView, meta: { - pageTitle: 'Reporting', requiresAuth: true, }, }, @@ -106,7 +99,6 @@ const router = createRouter({ name: 'funding', component: FundingView, meta: { - pageTitle: 'Funding', requiresAuth: true, }, }, @@ -115,7 +107,6 @@ const router = createRouter({ name: 'documents', component: DocumentsView, meta: { - pageTitle: 'Documents', requiresAuth: true, }, }, @@ -124,7 +115,6 @@ const router = createRouter({ name: 'applications-history', component: ApplicationsHistoryView, meta: { - pageTitle: 'Applications History', requiresAuth: true, }, }, @@ -166,7 +156,6 @@ const router = createRouter({ }, ], meta: { - pageTitle: 'Application', requiresAuth: true, }, }, @@ -175,7 +164,6 @@ const router = createRouter({ name: 'resources', component: ResourcesView, meta: { - pageTitle: 'Resources', requiresAuth: true, }, }, @@ -184,7 +172,6 @@ const router = createRouter({ name: 'manage-users', component: ManageUsersView, meta: { - pageTitle: 'Manage Users', requiresAuth: true, role: ROLES.ACCOUNT_MANAGEMENT, showFacility: false, @@ -266,14 +253,6 @@ const router = createRouter({ }) router.beforeEach((to, _from, next) => { - // this section is to set page title in vue store - const appStore = useAppStore() - if (to && to.meta.pageTitle) { - appStore.setPageTitle(to.meta.pageTitle) - } else { - appStore.setPageTitle('') - } - // TODO (weskubo-cgi) // 1. Don't allow access to Logout page if not logged in // 2. Don't allow access to Login if Logged in @@ -293,7 +272,7 @@ router.beforeEach((to, _from, next) => { .then(() => { if (!authStore.isMinistryUser) { // Validate Provider roles - if (!authStore.hasRoles) { + if (!authStore.userInfo?.role) { return next('unauthorized') } // Validate Provider facilities diff --git a/frontend/src/services/applicationService.js b/frontend/src/services/applicationService.js index 099c6abc..fc6dbbee 100644 --- a/frontend/src/services/applicationService.js +++ b/frontend/src/services/applicationService.js @@ -1,6 +1,7 @@ import { isEmpty } from 'lodash' import ApiService from '@/common/apiService' +import { useApplicationsStore } from '@/stores/applications' import { useAuthStore } from '@/stores/auth' import { ApiRoutes } from '@/utils/constants' @@ -52,9 +53,16 @@ export default { } }, + isApplicationUpdated(updatedApplication) { + const applicationsStore = useApplicationsStore() + const currentApplication = applicationsStore?.currentApplication + const index = Object.entries(updatedApplication)?.findIndex(([key, value]) => key in currentApplication && currentApplication[key] != value) + return index > -1 + }, + async updateApplication(applicationId, payload) { try { - if (!applicationId || isEmpty(payload)) return + if (!applicationId || isEmpty(payload) || !this.isApplicationUpdated(payload)) return const response = await ApiService.apiAxios.put(ApiRoutes.APPLICATIONS + '/' + applicationId, payload) return response } catch (error) { diff --git a/frontend/src/services/documentService.js b/frontend/src/services/documentService.js index 79edb253..097bdac7 100644 --- a/frontend/src/services/documentService.js +++ b/frontend/src/services/documentService.js @@ -1,8 +1,8 @@ -import { getFileExtensionWithDot, isHeicFile, updateHeicFileNameToJpg } from '@/utils/file' +import { isEmpty } from 'lodash' -import { ApiRoutes } from '@/utils/constants' import ApiService from '@/common/apiService' -import { isEmpty } from 'lodash' +import { ApiRoutes } from '@/utils/constants' +import { getFileExtensionWithDot, isHeicFile, updateHeicFileNameToJpg } from '@/utils/file' function mapDocumentFileObjectForBack(documents) { let formData = new FormData() @@ -35,7 +35,26 @@ function addEntityIdToDocument(documents, entityId) { return documents } +function sortDocuments(documents) { + documents?.sort((doc1, doc2) => { + return new Date(doc1.lastUpdatedTime) - new Date(doc2.lastUpdatedTime) + }) + return documents +} + export default { + // regardingId (entityId) is the id of the entity link to the document (e.g.: assistanceRequestId, applicationId, facilityId, etc.) + async getDocuments(regardingId) { + try { + if (!regardingId) return + const response = await ApiService.apiAxios.get(`${ApiRoutes.DOCUMENTS}?regardingId=${regardingId}`) + return sortDocuments(response?.data) + } catch (error) { + console.log(`Failed to get the list of documents by regarding id - ${error}`) + throw error + } + }, + async createDocuments(documents, entityId) { const updatedDocuments = addEntityIdToDocument(documents, entityId) const payload = mapDocumentFileObjectForBack(updatedDocuments) @@ -48,4 +67,13 @@ export default { throw error } }, + + async deleteDocument(documentId) { + try { + await ApiService.apiAxios.delete(`${ApiRoutes.DOCUMENTS}/${documentId}`) + } catch (error) { + console.log(`Failed to delete document - ${error}`) + throw error + } + }, } diff --git a/frontend/src/services/facilityService.js b/frontend/src/services/facilityService.js index a20f4f30..91847240 100644 --- a/frontend/src/services/facilityService.js +++ b/frontend/src/services/facilityService.js @@ -1,6 +1,12 @@ import ApiService from '@/common/apiService' import { ApiRoutes } from '@/utils/constants' +function sortContactsByName(contacts) { + return contacts?.sort(function (a, b) { + return a.lastName?.localeCompare(b.lastName) + }) +} + export default { async getFacility(accountId) { try { @@ -17,7 +23,7 @@ export default { try { if (!facilityId) return const response = await ApiService.apiAxios.get(ApiRoutes.FACILITIES_CONTACTS.replace(':facilityId', facilityId)) - return response?.data + return sortContactsByName(response?.data) } catch (error) { console.log(`Failed to get the contacts by facilityId - ${error}`) throw error @@ -34,4 +40,15 @@ export default { throw error } }, + + async updateFacilityPrimaryContact(facilityId, primaryContactId) { + try { + if (!facilityId) return + const response = await ApiService.apiAxios.put(`${ApiRoutes.FACILITIES}/${facilityId}`, primaryContactId) + return response?.data + } catch (error) { + console.log(`Failed to update facility primary contact by facility/account id - ${error}`) + throw error + } + }, } diff --git a/frontend/src/services/organizationService.js b/frontend/src/services/organizationService.js index fbb479cd..ab3ec517 100644 --- a/frontend/src/services/organizationService.js +++ b/frontend/src/services/organizationService.js @@ -23,4 +23,15 @@ export default { throw error } }, + + async updateOrganization(organizationId, organization) { + try { + if (!organizationId) return + const response = await ApiService.apiAxios.put(ApiRoutes.ORGANIZATIONS + '/' + organizationId, organization) + return response?.data + } catch (error) { + console.log(`Failed to update organization by organization/account id - ${error}`) + throw error + } + }, } diff --git a/frontend/src/stores/app.js b/frontend/src/stores/app.js index e92808e6..e21c3cac 100644 --- a/frontend/src/stores/app.js +++ b/frontend/src/stores/app.js @@ -5,12 +5,11 @@ import ApiService from '@/common/apiService' export const useAppStore = defineStore('app', { namespaced: true, state: () => ({ + // TODO (weskubo-cgi) Remove unused state request: {}, selectedRequest: null, messages: [], - pageTitle: '', subtitleBanner: '', - showNavBar: false, stickyInfoPanelHeight: null, // Alert Notifications @@ -22,6 +21,7 @@ export const useAppStore = defineStore('app', { requestCategories: {}, userRoles: {}, healthAuthorities: {}, + facilityTypes: {}, config: '', }), @@ -41,6 +41,7 @@ export const useAppStore = defineStore('app', { this.requestCategories = lookupInfo?.data?.requestCategories this.userRoles = lookupInfo?.data?.userRoles this.healthAuthorities = lookupInfo?.data?.healthAuthorities + this.facilityTypes = lookupInfo?.data?.facilityTypes } }, async setConfig(config) { @@ -58,9 +59,6 @@ export const useAppStore = defineStore('app', { async setMessages(messages) { this.messages = messages || [] }, - async setPageTitle(pageTitle) { - this.pageTitle = pageTitle - }, async setStickyInfoPanelHeight(stickyInfoPanelHeight) { this.stickyInfoPanelHeight = stickyInfoPanelHeight }, @@ -76,21 +74,6 @@ export const useAppStore = defineStore('app', { this.alertNotification = true } }, - async getCodes() { - if (localStorage.getItem('jwtToken')) { - // DONT Call api if there is not token. - /*TODO: get application code lists from backend i.e.... - if (this.activeSchools.length === 0) { - const response = await ApiService.getActiveSchools(); - await this.setActiveSchools(response.data); - } - if(this.districtMap.size === 0) { - const response = await ApiService.getDistricts(); - await this.setDistricts(response.data); - } - */ - } - }, async getConfig() { const response = await ApiService.getConfig() await this.setConfig(response.data) diff --git a/frontend/src/stores/applications.js b/frontend/src/stores/applications.js index d91273e6..73844651 100644 --- a/frontend/src/stores/applications.js +++ b/frontend/src/stores/applications.js @@ -1,16 +1,72 @@ import { defineStore } from 'pinia' import ApplicationService from '@/services/applicationService' +import DocumentService from '@/services/documentService' +import { FACILITY_TYPES } from '@/utils/constants' + +function checkFacilityDetailsComplete(application) { + return application?.primaryContactId +} + +function checkStaffingComplete(application) { + const totalStaffs = + application?.staffingInfantECEducatorFullTime + + application?.staffingInfantECEducatorPartTime + + application?.staffingECEducatorFullTime + + application?.staffingECEducatorPartTime + + application?.staffingECEducatorAssistantFullTime + + application?.staffingECEducatorAssistantPartTime + + application?.staffingResponsibleAdultFullTime + + application?.staffingResponsibleAdultPartTime + return ( + totalStaffs > 0 && + application?.staffingInfantECEducatorFullTime >= 0 && + application?.staffingInfantECEducatorFullTime <= 99 && + application?.staffingInfantECEducatorPartTime >= 0 && + application?.staffingInfantECEducatorPartTime <= 99 && + application?.staffingECEducatorFullTime >= 0 && + application?.staffingECEducatorFullTime <= 99 && + application?.staffingECEducatorPartTime >= 0 && + application?.staffingECEducatorPartTime <= 99 && + application?.staffingECEducatorAssistantFullTime >= 0 && + application?.staffingECEducatorAssistantFullTime <= 99 && + application?.staffingECEducatorAssistantPartTime >= 0 && + application?.staffingECEducatorAssistantPartTime <= 99 && + application?.staffingResponsibleAdultFullTime >= 0 && + application?.staffingResponsibleAdultFullTime <= 99 && + application?.staffingResponsibleAdultPartTime >= 0 && + application?.staffingResponsibleAdultPartTime <= 99 + ) +} + +function checkOperatingCostsComplete(application) { + const isDocumentUploaded = application?.facilityType != FACILITY_TYPES.RENT_LEASE || (application?.facilityType === FACILITY_TYPES.RENT_LEASE && application?.uploadedDocuments?.length > 0) + return application?.facilityType && isDocumentUploaded && application?.totalYearlyOperatingCosts + application?.totalYearlyFacilityCosts > 0 +} export const useApplicationsStore = defineStore('applications', { namespaced: true, state: () => ({ currentApplication: undefined, + isFacilityDetailsComplete: false, + isLicencesComplete: false, + isOperatingCostsComplete: false, + isStaffingComplete: false, + isSubmitApplicationComplete: false, }), actions: { + checkApplicationComplete() { + this.isFacilityDetailsComplete = checkFacilityDetailsComplete(this.currentApplication) + this.isStaffingComplete = checkStaffingComplete(this.currentApplication) + this.isOperatingCostsComplete = checkOperatingCostsComplete(this.currentApplication) + }, + async getApplication(applicationId) { try { this.currentApplication = await ApplicationService.getApplication(applicationId) + if (this.currentApplication?.facilityType === FACILITY_TYPES.RENT_LEASE) { + this.currentApplication.uploadedDocuments = await DocumentService.getDocuments(applicationId) + } } catch (error) { console.log(`Failed to get the application by application id - ${error}`) throw error diff --git a/frontend/src/stores/auth.js b/frontend/src/stores/auth.js index 033689a6..f4fe310f 100644 --- a/frontend/src/stores/auth.js +++ b/frontend/src/stores/auth.js @@ -16,10 +16,9 @@ export const useAuthStore = defineStore('auth', { }), getters: { isActingProvider: (state) => !state.isMinistryUser || state.isImpersonating, - hasRoles: (state) => state.userInfo?.roles?.length > 0, hasFacilities: (state) => state.userInfo?.facilities?.length > 0, hasRole: (state) => { - return (role) => state.userInfo?.roles?.includes(role) + return (role) => state.userInfo?.role === role }, }, actions: { diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 9fd8da1c..2f208c88 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -13,8 +13,8 @@ export const AuthRoutes = Object.freeze({ export const ApiRoutes = Object.freeze({ USER: baseRoot + '/user', - USER_PERMISSIONS_FACILITIES: baseRoot + '/user/permissions/facilities', - USER_FACILITIES: baseRoot + '/user/:contactId/facilities', + USER_FACILITIES: '/:contactId/facilities', + USER_PERMISSIONS_FACILITIES: baseRoot + '/user/permissions-facilities', MESSAGES: baseRoot + '/messages', LOOKUP: baseRoot + '/config/lookup', NOTIFICATIONS: baseRoot + '/notifications', @@ -23,21 +23,11 @@ export const ApiRoutes = Object.freeze({ ORGANIZATIONS: baseRoot + '/organizations', FACILITIES: baseRoot + '/facilities', ORGANIZATIONS_FACILITIES: baseRoot + '/organizations/:organizationId/facilities', + ORGANIZATIONS_USERS: '/:organizationId/users', FACILITIES_CONTACTS: baseRoot + '/facilities/:facilityId/contacts', FACILITIES_LICENCES: baseRoot + '/facilities/:facilityId/licences', }) -// TODO (weskubo-cgi) Remove this if not using page titles in UI -export const PAGE_TITLES = Object.freeze({ - LOGIN: 'Login', - INTAKE: 'Intake', - CONTRACT_MANAGEMENT: 'Contract Management', - PAYMENTS: 'Payments', - REPORTING: 'Reporting', - ACCOUNT_MAINTENANCE: 'Account Maintenance', - MAINTENANCE_REQUEST_EXCEPTION_STREAM: 'Maint Request Exp Stream', -}) - export const ASSISTANCE_REQUEST_STATUS_CODES = Object.freeze({ ASSIGNED: 2, WITH_PROVIDER: 3, @@ -66,6 +56,13 @@ export const APPLICATION_STATUS_CODES = Object.freeze({ APPROVED: 5, }) +export const FACILITY_TYPES = Object.freeze({ + RENT_LEASE: 1, + OWNED_WITH_MORTGAGE: 2, + OWNED_WITHOUT_MORTGAGE: 3, + PROVIDED_FREE_OF_CHARGE: 4, +}) + export const ASSISTANCE_REQUEST_REPLY_DISABLED_TEXT = 'Your request is still in the queue. If this is an urgent request, you can call the program at 1-888-338-6622 (Option 7).' export const OFM_PROGRAM = 'OFM Program' diff --git a/frontend/src/utils/constants/Roles.js b/frontend/src/utils/constants/Roles.js deleted file mode 100644 index dfcdb82d..00000000 --- a/frontend/src/utils/constants/Roles.js +++ /dev/null @@ -1,8 +0,0 @@ -export const ROLE = Object.freeze( - { - EDX_DISTRICT_ADMIN: 'EDX_DISTRICT_ADMIN', - - EDX_SCHOOL_ADMIN: 'EDX_SCHOOL_ADMIN' - } -); - diff --git a/frontend/src/utils/rules.js b/frontend/src/utils/rules.js index 704cf286..c51d0085 100644 --- a/frontend/src/utils/rules.js +++ b/frontend/src/utils/rules.js @@ -17,10 +17,10 @@ const rules = { YYYY: [(v) => (v > 1900 && v < 2100) || 'A valid year is required'], notRequired: [() => true], max(number) { - return (v) => !v || v <= number || 'Max exceeded' + return (v) => !v || v <= number || `Max exceeded: ${number.toLocaleString('en-ca')}` }, min(number) { - return (v) => !v || v >= number || 'Min exceeded' + return (v) => !v || v >= number || `Min exceeded: ${number.toLocaleString('en-ca')}` }, maxLength(number) { return (v) => !v || v.length <= number || 'Max length exceeded' diff --git a/frontend/src/views/MessagingView.vue b/frontend/src/views/MessagingView.vue index 37e697b2..ae81d708 100644 --- a/frontend/src/views/MessagingView.vue +++ b/frontend/src/views/MessagingView.vue @@ -24,7 +24,7 @@ - ← Back to Home + Home diff --git a/frontend/src/views/account-mgmt/ManageFacilityView.vue b/frontend/src/views/account-mgmt/ManageFacilityView.vue index ee33ac81..dff47711 100644 --- a/frontend/src/views/account-mgmt/ManageFacilityView.vue +++ b/frontend/src/views/account-mgmt/ManageFacilityView.vue @@ -7,8 +7,8 @@
- - + + @@ -29,10 +29,10 @@ Current licences: - + - Licence Number: + Licence Number: {{ item.licence }} @@ -69,77 +69,53 @@ - -

Expense Authority

+ +

Primary Contact

+
 (You can only have one primary contact)
- - + + -
- - - Current expense authority: - - - - - - - - - - - Name: - - - {{ item.firstName }} {{ item.lastName }} - +
+ + - Role: + Change primary contact: - - {{ getRoleNameById(item.role) }} + + + -
- - - -
- - -

Primary Contact

-
-
- - - - -
- - Current primary contact info: + + - - - + + + - - - Name: - - - {{ item.firstName }} {{ item.lastName }} - - - Role: - - - {{ getRoleNameById(item.role) }} + + + + Cancel + Save +
@@ -147,16 +123,24 @@
+ + - ← Back to Account Management - - - - - Cancel - Save + Organization Information @@ -164,46 +148,68 @@ diff --git a/frontend/src/views/account-mgmt/ManageOrganizationView.vue b/frontend/src/views/account-mgmt/ManageOrganizationView.vue index bfa4119a..679b64a2 100644 --- a/frontend/src/views/account-mgmt/ManageOrganizationView.vue +++ b/frontend/src/views/account-mgmt/ManageOrganizationView.vue @@ -8,7 +8,7 @@ - + @@ -22,10 +22,7 @@ - {{ item.name }} + {{ item.name }} @@ -36,19 +33,18 @@ - - ← Back to Account Management + Account Management diff --git a/frontend/src/views/account-mgmt/ManageUsersView.vue b/frontend/src/views/account-mgmt/ManageUsersView.vue index 9317e72a..1d90cfa5 100644 --- a/frontend/src/views/account-mgmt/ManageUsersView.vue +++ b/frontend/src/views/account-mgmt/ManageUsersView.vue @@ -41,7 +41,7 @@ {{ getRoleNameById(item.role) }} diff --git a/frontend/src/views/applications/OperatingCostsView.vue b/frontend/src/views/applications/OperatingCostsView.vue index f6cab925..12b9b3d8 100644 --- a/frontend/src/views/applications/OperatingCostsView.vue +++ b/frontend/src/views/applications/OperatingCostsView.vue @@ -1,43 +1,72 @@ diff --git a/frontend/src/views/applications/SelectFacilityView.vue b/frontend/src/views/applications/SelectFacilityView.vue index f55e5d7e..7e2831f8 100644 --- a/frontend/src/views/applications/SelectFacilityView.vue +++ b/frontend/src/views/applications/SelectFacilityView.vue @@ -7,7 +7,7 @@ mdi-information-slab-circle-outline Please review the following pre-populated information for correctness and contact your organization's account manager to make updates if required.
- +
@@ -45,6 +45,7 @@ import { mapState, mapActions } from 'pinia' import rules from '@/utils/rules' import OrganizationInfo from '@/components/organizations/OrganizationInfo.vue' import ApplicationService from '@/services/applicationService' +import OrganizationService from '@/services/organizationService' import alertMixin from '@/mixins/alertMixin' export default { @@ -72,6 +73,7 @@ export default { loading: false, facilityId: undefined, isFormComplete: false, + organization: undefined, } }, computed: { @@ -96,6 +98,9 @@ export default { this.$emit('process', true) const payload = { facilityId: this.facilityId, + organizationId: this.organization?.organizationId, + providerType: this.organization?.providerType, + ownership: this.organization?.ownership, } const response = await ApplicationService.createApplication(payload) await this.getApplication(response?.applicationId) @@ -109,13 +114,24 @@ export default { }, }, }, - created() { + async created() { if (this.userInfo?.facilities?.length === 1) { this.facilityId = this.userInfo?.facilities[0].facilityId } + await this.getOrganization() }, methods: { ...mapActions(useApplicationsStore, ['getApplication']), + async getOrganization() { + try { + this.loading = true + this.organization = await OrganizationService.getOrganization(this.userInfo?.organizationId) + } catch (error) { + this.setFailureAlert('Failed to get your organization information', error) + } finally { + this.loading = false + } + }, }, } diff --git a/frontend/src/views/applications/StaffingView.vue b/frontend/src/views/applications/StaffingView.vue index 6703d748..c14a937f 100644 --- a/frontend/src/views/applications/StaffingView.vue +++ b/frontend/src/views/applications/StaffingView.vue @@ -1,43 +1,147 @@ + diff --git a/frontend/test/components/TheMenu.test.js b/frontend/test/components/TheMenu.test.js deleted file mode 100644 index dc82f4cd..00000000 --- a/frontend/test/components/TheMenu.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import { describe, test } from 'vitest' -import { createVuetify } from 'vuetify' -import * as components from 'vuetify/components' -import * as directives from 'vuetify/directives' - -import TheMenu from '@/components/TheMenu.vue' -import { useAuthStore } from '@/stores/auth.js' -import { createTestingPinia } from '@pinia/testing' -import { mount } from '@vue/test-utils' - -const vuetify = createVuetify({ components, directives }) - -describe('TheMenu', () => { - const global = { global: { plugins: [createTestingPinia(), vuetify] } } - const authStore = useAuthStore() - authStore.isAuthenticated = true - authStore.currentFacility = { facilityName: 'UT Facility' } - - // Tests that all Menu Items display for a user with all roles - test('all menu items visible', async () => { - authStore.userInfo = { - organizationName: 'UT Org', - roles: [1, 2, 3, 4], - } - const wrapper = mount(TheMenu, global) - expect(wrapper.text()).toContain('Home') - expect(wrapper.text()).toContain('Messaging') - expect(wrapper.text()).toContain('Reporting') - expect(wrapper.text()).toContain('Funding') - expect(wrapper.text()).toContain('Documents') - expect(wrapper.text()).toContain('Applications') - expect(wrapper.text()).toContain('Resources') - expect(wrapper.text()).toContain('Settings') - expect(wrapper.html()).toMatchSnapshot() - }) - - // Tests that the Settings Menu Item isn't displayed - // for a user without 2 = 'Account Management' - test('Settings menu item hidden', async () => { - authStore.userInfo = { - organizationName: 'UT Org', - roles: [1, 3, 4], - } - const wrapper = mount(TheMenu, global) - expect(wrapper.text()).toContain('Home') - expect(wrapper.text()).toContain('Messaging') - expect(wrapper.text()).toContain('Reporting') - expect(wrapper.text()).toContain('Funding') - expect(wrapper.text()).toContain('Documents') - expect(wrapper.text()).toContain('Applications') - expect(wrapper.text()).toContain('Resources') - expect(wrapper.text()).not.toContain('Settings') - }) -}) From d57801b156ff59ecaf3bc9dd353ae4af157b35a3 Mon Sep 17 00:00:00 2001 From: Le Date: Tue, 6 Feb 2024 09:09:57 -0800 Subject: [PATCH 6/7] Unit Test - add Mock requests, Applications view unit tests --- frontend/package-lock.json | 1221 ++++++++++++++++- frontend/package.json | 1 + .../components/messages/MessagesTab.test.js | 243 ---- frontend/test/utils/mockResponses.js | 41 - frontend/test/utils/mockResponses/app.js | 94 ++ .../test/utils/mockResponses/applications.js | 81 ++ frontend/test/utils/mockResponses/auth.js | 47 + .../test/utils/mockResponses/documents.js | 42 + .../test/utils/mockResponses/facilities.js | 73 + frontend/test/utils/mockResponses/messages.js | 111 ++ .../test/utils/mockResponses/notifications.js | 37 + .../test/utils/mockResponses/organizations.js | 25 + frontend/test/utils/setupTests.js | 32 +- frontend/test/views/MessagingView.test.js | 215 +-- .../applications/ApplicationView.test.js | 47 + .../ApplicationsHistoryView.test.js | 85 +- .../applications/FacilityDetailsView.test.js | 114 ++ .../applications/OperatingCostsView.test.js | 63 + .../applications/SelectFacilityView.test.js | 67 + .../views/applications/StaffingView.test.js | 56 + 20 files changed, 2132 insertions(+), 563 deletions(-) delete mode 100644 frontend/test/components/messages/MessagesTab.test.js delete mode 100644 frontend/test/utils/mockResponses.js create mode 100644 frontend/test/utils/mockResponses/app.js create mode 100644 frontend/test/utils/mockResponses/applications.js create mode 100644 frontend/test/utils/mockResponses/auth.js create mode 100644 frontend/test/utils/mockResponses/documents.js create mode 100644 frontend/test/utils/mockResponses/facilities.js create mode 100644 frontend/test/utils/mockResponses/messages.js create mode 100644 frontend/test/utils/mockResponses/notifications.js create mode 100644 frontend/test/utils/mockResponses/organizations.js create mode 100644 frontend/test/views/applications/ApplicationView.test.js create mode 100644 frontend/test/views/applications/FacilityDetailsView.test.js create mode 100644 frontend/test/views/applications/OperatingCostsView.test.js create mode 100644 frontend/test/views/applications/SelectFacilityView.test.js create mode 100644 frontend/test/views/applications/StaffingView.test.js diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 19aac6e3..3b2e2dbb 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -16,6 +16,7 @@ "http-status-codes": "^2.2.0", "lodash": "^4.17.21", "moment": "^2.29.4", + "msw": "^2.1.5", "pinia": "^2.1.6", "regenerator-runtime": "^0.14.0", "rfdc": "^1.3.0", @@ -69,6 +70,22 @@ "resolved": "https://registry.npmjs.org/@bcgov/bc-sans/-/bc-sans-2.0.0.tgz", "integrity": "sha512-hgCYDEwVWZ0t/yzmo802D1oF3hhzDjsjpgB82EZcDEiLPxjV2x9qALv4mBNKAiWDK4ezvBL1VrD99NnIbxG5Vw==" }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "dependencies": { + "cookie": "^0.5.0" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dependencies": { + "statuses": "^2.0.1" + } + }, "node_modules/@coders-tm/vue-number-format": { "version": "3.34.1", "resolved": "https://registry.npmjs.org/@coders-tm/vue-number-format/-/vue-number-format-3.34.1.tgz", @@ -583,6 +600,30 @@ "integrity": "sha512-e//lmkmpFUMZKhmCY9zdjRe4zNXfbOIJnn6xveHbaV2kSw5aJ5dLXUxcRt1Gxfi7ZYpFLUWlkG2MGSFAiqAu7w==", "dev": true }, + "node_modules/@mswjs/cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-1.1.0.tgz", + "integrity": "sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.25.15", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.25.15.tgz", + "integrity": "sha512-s4jdyxmq1eeftfDXJ7MUiK/jlvYaU8Sr75+42hHCVBrYez0k51RHbMitKIKdmsF92Q6gwhp8Sm1MmvdA9llpcg==", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -624,6 +665,25 @@ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", "dev": true }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==" + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==" + }, "node_modules/@pinia/testing": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@pinia/testing/-/testing-0.1.3.tgz", @@ -692,6 +752,11 @@ "@types/chai": "*" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "node_modules/@types/eslint": { "version": "8.44.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", @@ -729,6 +794,11 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.4.tgz", "integrity": "sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA==" }, + "node_modules/@types/statuses": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.4.tgz", + "integrity": "sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==" + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -1295,11 +1365,35 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -1308,7 +1402,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1367,6 +1460,25 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1375,6 +1487,16 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -1434,6 +1556,29 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1500,7 +1645,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1512,6 +1656,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", @@ -1570,11 +1719,77 @@ "node": ">=6.0" } }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -1585,8 +1800,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -1626,6 +1840,14 @@ "proto-list": "~1.2.1" } }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1697,6 +1919,17 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1783,6 +2016,11 @@ "integrity": "sha512-P38NO8eOuWOKY1sQk5yE0crNtrjgjJj6r3NrbIKtG18KzCHmHE2Bt+aQA7/y0w3uYsHWxDa6icOohzjLJ4vJ4A==", "peer": true }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -1854,7 +2092,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "peer": true, "engines": { "node": ">=6" } @@ -2057,6 +2294,30 @@ "node": ">=0.8.x" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2082,6 +2343,28 @@ "reusify": "^1.0.4" } }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2207,6 +2490,14 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", @@ -2281,6 +2572,14 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/happy-dom": { "version": "12.8.0", "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-12.8.0.tgz", @@ -2303,6 +2602,11 @@ "node": ">=8" } }, + "node_modules/headers-polyfill": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.2.tgz", + "integrity": "sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==" + }, "node_modules/http-status-codes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", @@ -2320,6 +2624,25 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2372,8 +2695,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.8", @@ -2381,6 +2703,31 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2400,6 +2747,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2411,6 +2766,19 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==" + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2428,6 +2796,17 @@ "node": ">=8" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2618,6 +2997,21 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loupe": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", @@ -2697,6 +3091,14 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2734,6 +3136,66 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/msw": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.1.5.tgz", + "integrity": "sha512-r39AZk4taMmUEYwtzDAgFy38feqJy1yaKykvo0QE8q7H7c28yH/WIlOmE7oatjkC3dMgpTYfND8MaxeywgU+Yg==", + "hasInstallScript": true, + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@mswjs/cookies": "^1.1.0", + "@mswjs/interceptors": "^0.25.15", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "chokidar": "^3.4.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "inquirer": "^8.2.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.2.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.7.x <= 5.3.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz", + "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -2812,6 +3274,20 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -2829,6 +3305,41 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outvariant": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.2.tgz", + "integrity": "sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2905,6 +3416,11 @@ "node": ">=8" } }, + "node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, "node_modules/pathe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", @@ -3200,6 +3716,19 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3216,6 +3745,14 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3225,6 +3762,18 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3270,6 +3819,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -3293,6 +3850,14 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3310,14 +3875,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { "version": "1.66.1", @@ -3440,6 +4003,11 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3473,17 +4041,50 @@ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.4.3.tgz", "integrity": "sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==", "dev": true }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3519,7 +4120,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -3594,6 +4194,11 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, "node_modules/tinybench": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", @@ -3618,6 +4223,17 @@ "node": ">=14.0.0" } }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3629,6 +4245,11 @@ "node": ">=8.0" } }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3718,8 +4339,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/uuid": { "version": "8.3.2", @@ -4030,6 +4650,14 @@ "node": ">=10.13.0" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -4169,6 +4797,19 @@ "node": ">=8" } }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4184,12 +4825,45 @@ "node": ">=12" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -4220,6 +4894,22 @@ "resolved": "https://registry.npmjs.org/@bcgov/bc-sans/-/bc-sans-2.0.0.tgz", "integrity": "sha512-hgCYDEwVWZ0t/yzmo802D1oF3hhzDjsjpgB82EZcDEiLPxjV2x9qALv4mBNKAiWDK4ezvBL1VrD99NnIbxG5Vw==" }, + "@bundled-es-modules/cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", + "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "requires": { + "cookie": "^0.5.0" + } + }, + "@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "requires": { + "statuses": "^2.0.1" + } + }, "@coders-tm/vue-number-format": { "version": "3.34.1", "resolved": "https://registry.npmjs.org/@coders-tm/vue-number-format/-/vue-number-format-3.34.1.tgz", @@ -4492,6 +5182,24 @@ "integrity": "sha512-e//lmkmpFUMZKhmCY9zdjRe4zNXfbOIJnn6xveHbaV2kSw5aJ5dLXUxcRt1Gxfi7ZYpFLUWlkG2MGSFAiqAu7w==", "dev": true }, + "@mswjs/cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-1.1.0.tgz", + "integrity": "sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==" + }, + "@mswjs/interceptors": { + "version": "0.25.15", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.25.15.tgz", + "integrity": "sha512-s4jdyxmq1eeftfDXJ7MUiK/jlvYaU8Sr75+42hHCVBrYez0k51RHbMitKIKdmsF92Q6gwhp8Sm1MmvdA9llpcg==", + "requires": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.5.1" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4524,6 +5232,25 @@ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", "dev": true }, + "@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==" + }, + "@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "requires": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==" + }, "@pinia/testing": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@pinia/testing/-/testing-0.1.3.tgz", @@ -4569,6 +5296,11 @@ "@types/chai": "*" } }, + "@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "@types/eslint": { "version": "8.44.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", @@ -4606,6 +5338,11 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.4.tgz", "integrity": "sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA==" }, + "@types/statuses": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.4.tgz", + "integrity": "sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==" + }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -5063,17 +5800,30 @@ "peer": true, "requires": {} }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + } + } + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -5120,11 +5870,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -5161,6 +5926,15 @@ "update-browserslist-db": "^1.0.11" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -5204,12 +5978,16 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", @@ -5250,11 +6028,55 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "peer": true }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==" + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -5262,8 +6084,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "combined-stream": { "version": "1.0.8", @@ -5300,6 +6121,11 @@ "proto-list": "~1.2.1" } }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5351,6 +6177,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "requires": { + "clone": "^1.0.2" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5415,6 +6249,11 @@ "integrity": "sha512-P38NO8eOuWOKY1sQk5yE0crNtrjgjJj6r3NrbIKtG18KzCHmHE2Bt+aQA7/y0w3uYsHWxDa6icOohzjLJ4vJ4A==", "peer": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -5469,8 +6308,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "peer": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-string-regexp": { "version": "4.0.0", @@ -5611,6 +6449,26 @@ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "peer": true }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5636,6 +6494,21 @@ "reusify": "^1.0.4" } }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + } + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5716,6 +6589,11 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", @@ -5772,6 +6650,11 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "graphql": { + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==" + }, "happy-dom": { "version": "12.8.0", "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-12.8.0.tgz", @@ -5791,6 +6674,11 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "headers-polyfill": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.2.tgz", + "integrity": "sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==" + }, "http-status-codes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", @@ -5805,6 +6693,11 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -5845,8 +6738,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.8", @@ -5854,6 +6746,28 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + } + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -5867,6 +6781,11 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5875,6 +6794,16 @@ "is-extglob": "^2.1.1" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + }, + "is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==" + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5886,6 +6815,11 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6033,6 +6967,15 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, "loupe": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", @@ -6093,6 +7036,11 @@ "mime-db": "1.52.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6124,6 +7072,43 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "msw": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.1.5.tgz", + "integrity": "sha512-r39AZk4taMmUEYwtzDAgFy38feqJy1yaKykvo0QE8q7H7c28yH/WIlOmE7oatjkC3dMgpTYfND8MaxeywgU+Yg==", + "requires": { + "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/statuses": "^1.0.1", + "@mswjs/cookies": "^1.1.0", + "@mswjs/interceptors": "^0.25.15", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "chalk": "^4.1.2", + "chokidar": "^3.4.2", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "inquirer": "^8.2.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.2", + "path-to-regexp": "^6.2.0", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.9.0", + "yargs": "^17.7.2" + }, + "dependencies": { + "type-fest": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz", + "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==" + } + } + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -6178,6 +7163,14 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -6192,6 +7185,32 @@ "type-check": "^0.4.0" } }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + }, + "outvariant": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.2.tgz", + "integrity": "sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==" + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6241,6 +7260,11 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, "pathe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", @@ -6422,6 +7446,16 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6435,12 +7469,26 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -6469,6 +7517,11 @@ "fsevents": "~2.3.2" } }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6478,17 +7531,23 @@ "queue-microtask": "^1.2.2" } }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "peer": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { "version": "1.66.1", @@ -6558,6 +7617,11 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6585,17 +7649,44 @@ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, "std-env": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.4.3.tgz", "integrity": "sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==", "dev": true }, + "strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -6619,7 +7710,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -6661,6 +7751,11 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, "tinybench": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", @@ -6679,6 +7774,14 @@ "integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==", "dev": true }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6687,6 +7790,11 @@ "is-number": "^7.0.0" } }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6740,8 +7848,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "uuid": { "version": "8.3.2", @@ -6887,6 +7994,14 @@ "graceful-fs": "^4.1.2" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "requires": { + "defaults": "^1.0.3" + } + }, "webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -6983,6 +8098,16 @@ "stackback": "0.0.2" } }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -6995,12 +8120,36 @@ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 9cddc901..cb42fa4a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,6 +21,7 @@ "http-status-codes": "^2.2.0", "lodash": "^4.17.21", "moment": "^2.29.4", + "msw": "^2.1.5", "pinia": "^2.1.6", "regenerator-runtime": "^0.14.0", "rfdc": "^1.3.0", diff --git a/frontend/test/components/messages/MessagesTab.test.js b/frontend/test/components/messages/MessagesTab.test.js deleted file mode 100644 index a3e270fb..00000000 --- a/frontend/test/components/messages/MessagesTab.test.js +++ /dev/null @@ -1,243 +0,0 @@ -import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' -import { createVuetify } from 'vuetify' -import * as components from 'vuetify/components' -import * as directives from 'vuetify/directives' - -import MessagesTab from '@/components/messages/MessagesTab.vue' -import NewRequestDialog from '@/components/messages/NewRequestDialog.vue' -import AppDialog from '@/components/ui/AppDialog.vue' -import { useAppStore } from '@/stores/app' -import { useAuthStore } from '@/stores/auth' -import { useMessagesStore } from '@/stores/messages' -import { createTestingPinia } from '@pinia/testing' -import { mount } from '@vue/test-utils' - -const vuetify = createVuetify({ components, directives }) -vi.mock('vue-router') - -describe('MessagesTab', () => { - const global = { global: { plugins: [createTestingPinia(), vuetify] } } - const authStore = useAuthStore() - const appStore = useAppStore() - const messagesStore = useMessagesStore() - - beforeEach(() => { - // create teleport target - const el = document.createElement(AppDialog) - el.id = 'modal' - document.body.appendChild(el) - }) - - afterEach(() => { - // clean up - document.body.outerHTML = '' - }) - - /* - =============================================== - Data Setup - =============================================== - */ - appStore.requestCategories = [ - { - categoryName: 'Intake & Renewal', - categoryId: '1e5bedc2-7377-ee11-8179-000d3a09d132', - }, - { - categoryName: 'Reporting', - categoryId: '01839dc9-7377-ee11-8179-000d3a09d132', - }, - { - categoryName: 'Account Maintenance', - categoryId: 'a640abcf-7377-ee11-8179-000d3a09d132', - }, - { - categoryName: 'Funding Agreement', - categoryId: '1eb0aad5-7377-ee11-8179-000d3a09d132', - }, - { - categoryName: 'Payments and Funding', - categoryId: 'aa2ba7e1-7377-ee11-8179-000d3a09d132', - }, - { - categoryName: 'Policy Question', - categoryId: '3a2ca7e1-7377-ee11-8179-000d3a09d132', - }, - { - categoryName: 'Technical Support', - categoryId: '4f749fe7-7377-ee11-8179-000d3a09d132', - }, - { - categoryName: 'Other', - categoryId: '64ce97ed-7377-ee11-8179-000d3a09d132', - }, - ] - - authStore.userInfo = { - facilities: [ - { - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityAccountNumber: 'Test-Facility-1', - facilityName: 'Test Facility #1', - facilityType: 0, - facilityStateCode: 0, - facilityStatusCode: 1, - }, - { - facilityId: '6df8623a-447d-ee11-8179-000d3a09d499', - facilityAccountNumber: 'Viet-Facility-2', - facilityName: 'Test Facility #2', - facilityType: 0, - facilityStateCode: 0, - facilityStatusCode: 1, - }, - { - facilityId: '064effc8-437d-ee11-8179-000d3a09d132', - facilityAccountNumber: 'Viet-Facility-3', - facilityName: 'Test Facility #3', - facilityType: 0, - facilityStateCode: 0, - facilityStatusCode: 1, - }, - { - facilityId: '40390ee5-be7d-ee11-8179-000d3a09d499', - facilityAccountNumber: 'Viet-Facility-4', - facilityName: 'Test Facility #4', - facilityType: 0, - facilityStateCode: 1, - facilityStatusCode: 2, - }, - ], - } - - authStore.currentFacility = authStore.userInfo.facilities[0] - // messagesStore.assistanceRequests = [ - // { - // assistanceRequestId: '2c1c29c7-c984-ee11-8179-000d3a09d4d4', - // subject: 'Test Message #1', - // referenceNumber: 'REQ-23000076', - // statusCode: 6, - // stateCode: 1, - // categoryName: 'Reporting', - // lastUpdatedTime: '2023-12-13T18:17:33Z', - // isRead: false, - // status: 'Open', - // priority: 1, - // requestFacilities: [ - // { - // facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - // facilityName: 'Viet OFM Active Facility Number 1', - // }, - // ], - // lastConversationTime: '2023-11-16T21:47:56Z', - // }, - // { - // assistanceRequestId: 'c54ff934-9a93-ee11-be37-000d3a09d4d4', - // subject: 'Test Message #2', - // referenceNumber: 'REQ-23000272', - // statusCode: 2, - // stateCode: 0, - // categoryName: 'Account Maintenance', - // lastUpdatedTime: '2023-12-12T21:32:29Z', - // isRead: false, - // status: 'Open', - // priority: 2, - // requestFacilities: [ - // { - // facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - // facilityName: 'Viet OFM Active Facility Number 1', - // }, - // ], - // lastConversationTime: '2023-12-05T18:17:41Z', - // }, - // { - // assistanceRequestId: 'af0c869f-5f95-ee11-be37-000d3a09d699', - // subject: 'Test Message #3', - // referenceNumber: 'REQ-23000277', - // statusCode: 3, - // stateCode: 0, - // categoryName: 'Reporting', - // lastUpdatedTime: '2023-12-13T18:15:53Z', - // isRead: true, - // status: 'Action required', - // priority: 3, - // requestFacilities: [ - // { - // facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - // facilityName: 'Viet OFM Active Facility Number 1', - // }, - // ], - // lastConversationTime: '2023-12-12T20:47:51Z', - // }, - // { - // assistanceRequestId: '2d2ca51e-9a88-ee11-8179-000d3af4865d', - // subject: 'Test Message #4', - // referenceNumber: 'REQ-23000116', - // statusCode: 5, - // stateCode: 1, - // categoryName: 'Intake & Renewal', - // lastUpdatedTime: '2023-12-13T18:17:33Z', - // isRead: true, - // status: 'Closed', - // priority: 1, - // requestFacilities: [ - // { - // facilityId: '064effc8-437d-ee11-8179-000d3a09d132', - // facilityName: 'Viet OFM This is Active Facility #2', - // }, - // ], - // lastConversationTime: '2023-11-21T18:17:14Z', - // }, - // ] - - // messagesStore.assistanceRequestConversation = [ - // { - // conversationId: '3cc21980-4784-ee11-8179-000d3af4865d', - // subject: 'MSG-23000051', - // from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', - // sentDate: '2023-11-16T06:15:13Z', - // message: 'Final 3rd message from CRM', - // ofmSourceSystem: false, - // requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', - // statusCode: 1, - // }, - // { - // conversationId: '29626e3e-4784-ee11-8179-000d3af4865d', - // subject: 'MSG-23000050', - // from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', - // sentDate: '2023-11-16T06:13:27Z', - // message: 'This is 2nd message from CRM', - // ofmSourceSystem: false, - // requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', - // statusCode: 1, - // }, - // { - // conversationId: 'f0e7fe8c-1b84-ee11-8179-000d3af4865d', - // subject: 'MSG-23000041', - // from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', - // sentDate: '2023-11-16T01:00:42Z', - // message: 'This is 1st message from Portal', - // ofmSourceSystem: false, - // requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', - // statusCode: 1, - // }, - // ] - - test('Create a new assistance request/message', async () => { - const wrapper = mount(MessagesTab, global) - // console.log(wrapper.html()) - - await wrapper.get('#new-message-button').trigger('click') - console.log('==================AFTER===================') - console.log(wrapper.html()) - - expect(document.querySelector('#new-request-dialog')).not.toBeNull() - // const newRequestDialog = wrapper.getComponent(NewRequestDialog) - // await newRequestDialog.get('input').setValue('valid_username') - // console.log(newRequestDialog.html()) - // await newRequestDialog.get('input').setValue('valid_username') - // console.log(newRequestDialog.text()) - // expect(newRequestDialog.emitted().newRequestDialog[0]).toEqual(['valid_username']) - // expect(wrapper.text()).toContain('Supporting documents (optional)') - }) -}) diff --git a/frontend/test/utils/mockResponses.js b/frontend/test/utils/mockResponses.js deleted file mode 100644 index e35339c8..00000000 --- a/frontend/test/utils/mockResponses.js +++ /dev/null @@ -1,41 +0,0 @@ -export const getApplicationsResponse = [ - { - applicationId: '128b9ba9-be9e-ee11-a569-000d3a09d132', - referenceNumber: 'APP-23000066', - submittedDate: null, - ministryLastUpdated: '2023-12-22T20:40:48Z', - providerLastUpdated: '2023-12-22T20:35:45Z', - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityName: 'Test OFM Facility #1', - statusCode: 1, - stateCode: 0, - status: 'Draft', - latestActivity: '2023-12-22T20:40:48.000Z', - }, - { - applicationId: 'c8609cc5-0fa1-ee11-a569-000d3a09d499', - referenceNumber: 'APP-23000070', - submittedDate: null, - ministryLastUpdated: null, - providerLastUpdated: '2023-12-22T21:19:21Z', - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityName: 'Test OFM Facility #1', - statusCode: 1, - stateCode: 0, - status: 'Draft', - latestActivity: '2023-12-22T21:19:21.000Z', - }, - { - applicationId: 'b2b7f374-2995-ee11-be37-000d3a09d4d4', - referenceNumber: 'APP-23000031', - submittedDate: '2023-12-19T18:07:38Z', - ministryLastUpdated: '2023-12-19T18:07:38Z', - providerLastUpdated: null, - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityName: 'Test OFM Facility #1', - statusCode: 3, - stateCode: 0, - status: 'Submitted', - latestActivity: '2023-12-19T18:07:38.000Z', - }, -] diff --git a/frontend/test/utils/mockResponses/app.js b/frontend/test/utils/mockResponses/app.js new file mode 100644 index 00000000..bba12b16 --- /dev/null +++ b/frontend/test/utils/mockResponses/app.js @@ -0,0 +1,94 @@ +export const getLookupInfoResponse = { + requestCategories: [ + { + categoryName: 'Intake & Renewal', + categoryId: '1e5bedc2-7377-ee11-8179-000d3a09d132', + }, + { + categoryName: 'Reporting', + categoryId: '01839dc9-7377-ee11-8179-000d3a09d132', + }, + { + categoryName: 'Account Maintenance', + categoryId: 'a640abcf-7377-ee11-8179-000d3a09d132', + }, + { + categoryName: 'Funding Agreement', + categoryId: '1eb0aad5-7377-ee11-8179-000d3a09d132', + }, + { + categoryName: 'Payments and Funding', + categoryId: 'aa2ba7e1-7377-ee11-8179-000d3a09d132', + }, + { + categoryName: 'Policy Question', + categoryId: '3a2ca7e1-7377-ee11-8179-000d3a09d132', + }, + { + categoryName: 'Technical Support', + categoryId: '4f749fe7-7377-ee11-8179-000d3a09d132', + }, + { + categoryName: 'Other', + categoryId: '64ce97ed-7377-ee11-8179-000d3a09d132', + }, + ], + userRoles: [ + { + id: 1, + description: 'Admin', + }, + { + id: 2, + description: 'Account Management', + }, + { + id: 3, + description: 'Financial', + }, + { + id: 4, + description: 'Reporting', + }, + ], + healthAuthorities: [ + { + id: 1, + description: 'Fraser Health', + }, + { + id: 2, + description: 'Interior Health', + }, + { + id: 3, + description: 'Island Health', + }, + { + id: 4, + description: 'Northern Health', + }, + { + id: 5, + description: 'Vancouver Coastal Health', + }, + ], + facilityTypes: [ + { + id: 1, + description: 'Rent/Lease', + }, + { + id: 2, + description: 'Owned With Mortgage', + }, + { + id: 3, + description: 'Owned Without Mortgage', + }, + { + id: 4, + description: 'Provided Free of Charge', + }, + ], +} diff --git a/frontend/test/utils/mockResponses/applications.js b/frontend/test/utils/mockResponses/applications.js new file mode 100644 index 00000000..a109924b --- /dev/null +++ b/frontend/test/utils/mockResponses/applications.js @@ -0,0 +1,81 @@ +export const getApplicationsResponse = [ + { + applicationId: '128b9ba9-be9e-ee11-a569-000d3a09d132', + referenceNumber: 'APP-23000066', + submittedDate: null, + ministryLastUpdated: '2023-12-22T20:40:48Z', + providerLastUpdated: '2023-12-22T20:35:45Z', + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM - Facility Number 1', + statusCode: 1, + stateCode: 0, + status: 'Draft', + latestActivity: '2023-12-22T20:40:48.000Z', + }, + { + applicationId: 'c8609cc5-0fa1-ee11-a569-000d3a09d499', + referenceNumber: 'APP-23000070', + submittedDate: null, + ministryLastUpdated: null, + providerLastUpdated: '2023-12-22T21:19:21Z', + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM - Facility Number 1', + statusCode: 1, + stateCode: 0, + status: 'Draft', + latestActivity: '2023-12-22T21:19:21.000Z', + }, + { + applicationId: 'b2b7f374-2995-ee11-be37-000d3a09d4d4', + referenceNumber: 'APP-23000031', + submittedDate: '2023-12-19T18:07:38Z', + ministryLastUpdated: '2023-12-19T18:07:38Z', + providerLastUpdated: null, + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM - Facility Number 1', + statusCode: 3, + stateCode: 0, + status: 'Submitted', + latestActivity: '2023-12-19T18:07:38.000Z', + }, +] + +export const getApplicationResponse = { + applicationId: 'b2b7f374-2995-ee11-be37-000d3a09d4d4', + referenceNumber: 'APP-23000031', + submittedDate: null, + ministryLastUpdated: null, + providerLastUpdated: '2024-01-31T20:00:58Z', + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM - Facility Number 1', + statusCode: 1, + stateCode: 0, + status: 'Draft', + staffingInfantECEducatorFullTime: 1, + staffingInfantECEducatorPartTime: 2, + staffingECEducatorFullTime: 3, + staffingECEducatorPartTime: 4, + staffingECEducatorAssistantFullTime: 5, + staffingECEducatorAssistantPartTime: 6, + staffingResponsibleAdultFullTime: 7, + staffingResponsibleAdultPartTime: 8, + primaryContactId: '7e35f2ba-9fb1-ee11-a569-000d3a09d4d4', + secondaryContactId: 'b4cc209f-edab-ee11-a569-000d3a09d699', + providerType: 1, + ownership: 2, + facilityType: 1, + insuranceCost: 0.3, + upkeepLabourCost: 4.13, + suppliesCost: 6.11, + utilitiesCost: 1.44, + maintenanceRepairsCost: 5.12, + furnitureEquipmentsCost: 1.46, + totalYearlyOperatingCosts: 18.56, + rentLeaseCost: 0, + mortgageCost: 0, + propertyTax: 0, + strataFee: 0, + applicableFee: 0, + totalYearlyFacilityCosts: 0, + latestActivity: '2024-01-31T20:00:58.000Z', +} diff --git a/frontend/test/utils/mockResponses/auth.js b/frontend/test/utils/mockResponses/auth.js new file mode 100644 index 00000000..c1a9dc06 --- /dev/null +++ b/frontend/test/utils/mockResponses/auth.js @@ -0,0 +1,47 @@ +export const getUserInfoResponse = { + displayName: 'ofmqa03', + userName: 'ofmqa03', + businessName: 'QA03, CCOF', + isMinistryUser: false, + serverTime: '2024-02-06T07:18:03.096Z', + unreadMessages: false, + facilities: [ + { + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityAccountNumber: 'Test-Facility-1', + facilityName: 'Test OFM - Facility Number 1', + facilityType: 0, + facilityStateCode: 0, + facilityStatusCode: 1, + }, + { + facilityId: '6df8623a-447d-ee11-8179-000d3a09d499', + facilityAccountNumber: 'Test-Facility-2', + facilityName: 'Test OFM - Facility #2', + facilityType: 0, + facilityStateCode: 0, + facilityStatusCode: 1, + }, + { + facilityId: '064effc8-437d-ee11-8179-000d3a09d132', + facilityAccountNumber: 'Test-Facility-3', + facilityName: 'Test OFM - Facility Number 3', + facilityType: 0, + facilityStateCode: 0, + facilityStatusCode: 1, + }, + ], + contactId: 'dd2f008d-ff6d-ee11-8179-000d3a09d499', + userId: 'E1F829C63C33480B86A2C14B8FAF382C', + email: 'test@email.com', + firstName: 'Captain', + lastName: 'America', + role: 2, + phone: '604-555-1234', + organizationId: 'b26aeb95-427d-ee11-8179-000d3a09d132', + organizationAccountNumber: 'VL123456', + organizationAccountType: 100000000, + organizationName: 'Test OFM Organization', + organizationStateCode: 0, + organizationStatus: 1, +} diff --git a/frontend/test/utils/mockResponses/documents.js b/frontend/test/utils/mockResponses/documents.js new file mode 100644 index 00000000..371f773a --- /dev/null +++ b/frontend/test/utils/mockResponses/documents.js @@ -0,0 +1,42 @@ +export const getDocumentsResponse = [ + { + documentId: 'c659e942-2bc1-ee11-9079-000d3a09d132', + referenceNumber: 'DOC-2400000067', + fileName: 'anothercat.png', + subject: 'anothercat.png', + description: 'this is the cat', + statusCode: 1, + stateCode: 0, + lastUpdatedTime: '2024-02-01T17:56:50Z', + }, + { + documentId: 'ccb4f548-2bc1-ee11-9079-000d3a09d132', + referenceNumber: 'DOC-2400000068', + fileName: 'Random.pdf', + subject: 'Random.pdf', + description: 'random pdf file', + statusCode: 1, + stateCode: 0, + lastUpdatedTime: '2024-02-01T17:57:02Z', + }, + { + documentId: 'd0f37a8f-10c5-ee11-9079-000d3a09d4d4', + referenceNumber: 'DOC-2400000087', + fileName: 'blackbox.jpg', + subject: 'blackbox.jpg', + description: 'black box', + statusCode: 1, + stateCode: 0, + lastUpdatedTime: '2024-02-06T16:55:50Z', + }, + { + documentId: 'd5f37a8f-10c5-ee11-9079-000d3a09d4d4', + referenceNumber: 'DOC-2400000088', + fileName: 'random.xlsx', + subject: 'random.xlsx', + description: 'excel file', + statusCode: 1, + stateCode: 0, + lastUpdatedTime: '2024-02-06T16:55:50Z', + }, +] diff --git a/frontend/test/utils/mockResponses/facilities.js b/frontend/test/utils/mockResponses/facilities.js new file mode 100644 index 00000000..e443905f --- /dev/null +++ b/frontend/test/utils/mockResponses/facilities.js @@ -0,0 +1,73 @@ +export const getFacilityResponse = { + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + accountNumber: 'Test-Facility-1', + name: 'Test OFM Facility Number 1', + phoneLandline: '111-111-1111', + phoneCell: '999-999-9999', + email: 'test@gmail.com', + streetAddress1: '123 Random Street', + streetAddress2: '456 Street Address 2', + city: 'Victoria', + postalCode: 'V8V1V1', + province: 'BC', + isMailingAddressDifferent: true, + mailingStreetAddress1: '999 Mailing Address', + mailingStreetAddress2: '415 Mailing 2', + mailingCity: 'Vancouver', + mailingPostalCode: 'T2J3J3', + mailingProvince: 'BC', + stateCode: 0, + statusCode: 1, + primaryContactId: 'dd2f008d-ff6d-ee11-8179-000d3a09d499', +} + +export const getContactsResponse = [ + { + bceidFacilityId: '8d35f2ba-9fb1-ee11-a569-000d3a09d4d4', + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM - Facility Number 1', + stateCode: 0, + statusCode: 1, + isExpenseAuthority: true, + isAdditionalContact: false, + contactId: '7e35f2ba-9fb1-ee11-a569-000d3a09d4d4', + firstName: 'Iron', + lastName: 'Man', + email: 'test@user.com', + phone: '123-333-4444', + userName: 'TestOFMTest5', + role: 2, + }, + { + bceidFacilityId: 'bdcc209f-edab-ee11-a569-000d3a09d699', + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM - Facility Number 1', + stateCode: 0, + statusCode: 1, + isExpenseAuthority: false, + isAdditionalContact: true, + contactId: 'b4cc209f-edab-ee11-a569-000d3a09d699', + firstName: 'Black', + lastName: 'Widow', + email: 'test@gmail.com', + phone: '123-456-7899', + userName: 'TestOFMTest1', + role: 3, + }, + { + bceidFacilityId: 'b7808e68-9eb1-ee11-a569-000d3a09d699', + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM - Facility Number 1', + stateCode: 0, + statusCode: 1, + isExpenseAuthority: false, + isAdditionalContact: false, + contactId: 'dd2f008d-ff6d-ee11-8179-000d3a09d499', + firstName: 'Captain', + lastName: 'America', + email: 'test@user.com', + phone: '123-566-7899', + userName: 'TestOFMTest4', + role: 1, + }, +] diff --git a/frontend/test/utils/mockResponses/messages.js b/frontend/test/utils/mockResponses/messages.js new file mode 100644 index 00000000..c2a3ff47 --- /dev/null +++ b/frontend/test/utils/mockResponses/messages.js @@ -0,0 +1,111 @@ +export const getAssistanceRequestsResponse = [ + { + assistanceRequestId: '2c1c29c7-c984-ee11-8179-000d3a09d4d4', + subject: 'Test Message #1', + referenceNumber: 'REQ-23000076', + statusCode: 6, + stateCode: 1, + categoryName: 'Reporting', + lastUpdatedTime: '2023-12-13T18:17:33Z', + isRead: false, + status: 'Open', + priority: 1, + requestFacilities: [ + { + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM Active Facility Number 1', + }, + ], + lastConversationTime: '2023-11-16T21:47:56Z', + }, + { + assistanceRequestId: 'c54ff934-9a93-ee11-be37-000d3a09d4d4', + subject: 'Test Message #2', + referenceNumber: 'REQ-23000272', + statusCode: 2, + stateCode: 0, + categoryName: 'Account Maintenance', + lastUpdatedTime: '2023-12-12T21:32:29Z', + isRead: false, + status: 'Open', + priority: 2, + requestFacilities: [ + { + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM Active Facility Number 1', + }, + ], + lastConversationTime: '2023-12-05T18:17:41Z', + }, + { + assistanceRequestId: 'af0c869f-5f95-ee11-be37-000d3a09d699', + subject: 'Test Message #3', + referenceNumber: 'REQ-23000277', + statusCode: 3, + stateCode: 0, + categoryName: 'Reporting', + lastUpdatedTime: '2023-12-13T18:15:53Z', + isRead: true, + status: 'Action required', + priority: 3, + requestFacilities: [ + { + facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM Active Facility Number 1', + }, + ], + lastConversationTime: '2023-12-12T20:47:51Z', + }, + { + assistanceRequestId: '2d2ca51e-9a88-ee11-8179-000d3af4865d', + subject: 'Test Message #4', + referenceNumber: 'REQ-23000116', + statusCode: 5, + stateCode: 1, + categoryName: 'Intake & Renewal', + lastUpdatedTime: '2023-12-13T18:17:33Z', + isRead: true, + status: 'Closed', + priority: 1, + requestFacilities: [ + { + facilityId: '064effc8-437d-ee11-8179-000d3a09d132', + facilityName: 'Test OFM This is Active Facility #2', + }, + ], + lastConversationTime: '2023-11-21T18:17:14Z', + }, +] + +export const getAssistanceRequestConversation = [ + { + conversationId: '3cc21980-4784-ee11-8179-000d3af4865d', + subject: 'MSG-23000051', + from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', + sentDate: '2023-11-16T06:15:13Z', + message: 'Final 3rd message from CRM', + ofmSourceSystem: false, + requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', + statusCode: 1, + }, + { + conversationId: '29626e3e-4784-ee11-8179-000d3af4865d', + subject: 'MSG-23000050', + from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', + sentDate: '2023-11-16T06:13:27Z', + message: 'This is 2nd message from CRM', + ofmSourceSystem: false, + requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', + statusCode: 1, + }, + { + conversationId: 'f0e7fe8c-1b84-ee11-8179-000d3af4865d', + subject: 'MSG-23000041', + from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', + sentDate: '2023-11-16T01:00:42Z', + message: 'This is 1st message from Portal', + ofmSourceSystem: false, + requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', + statusCode: 1, + }, +] diff --git a/frontend/test/utils/mockResponses/notifications.js b/frontend/test/utils/mockResponses/notifications.js new file mode 100644 index 00000000..7b4bcf22 --- /dev/null +++ b/frontend/test/utils/mockResponses/notifications.js @@ -0,0 +1,37 @@ +export const getNotificationsResponse = [ + { + notificationId: 'ef908c0e-8c94-ee11-be37-000d3a09d699', + subject: 'Test notification #1', + dateReceived: '2023-12-06T23:06:20Z', + notificationContent: '
This is a demo email #1
', + lastOpenedTime: '2023-12-13T18:14:50Z', + isRead: false, + }, + { + notificationId: 'd108df71-8c94-ee11-be37-000d3a09d699', + subject: 'Test notification #2', + dateReceived: '2023-12-06T23:09:03Z', + notificationContent: + '
This is another demo email #2
\n
Updating the notes
', + lastOpenedTime: '2023-12-13T18:14:49Z', + isRead: false, + }, + { + notificationId: 'f333cd71-8c94-ee11-be37-000d3a09d999', + subject: 'Test notification #3', + dateReceived: '2023-12-07T23:09:03Z', + notificationContent: + '
This is another demo email #3
\n
Updating the notes
', + lastOpenedTime: '2023-12-13T18:14:49Z', + isRead: true, + }, + { + notificationId: 'd108df71-8c94-ee11-be37-333f1b02d222', + subject: 'Test notification #4', + dateReceived: '2023-12-09T23:09:03Z', + notificationContent: + '
This is another demo email
\n
Updating the notes
', + lastOpenedTime: '2023-12-13T18:14:49Z', + isRead: false, + }, +] diff --git a/frontend/test/utils/mockResponses/organizations.js b/frontend/test/utils/mockResponses/organizations.js new file mode 100644 index 00000000..3e9a483e --- /dev/null +++ b/frontend/test/utils/mockResponses/organizations.js @@ -0,0 +1,25 @@ +export const getOrganizationResponse = { + organizationId: 'b26aeb95-427d-ee11-8179-000d3a09d132', + accountNumber: 'VL123456', + name: 'Test OFM Organization', + email: 'orgTest@gmail.com', + businessTypeCode: 1, + businessType: 'Registered Company', + phoneLandline: '1234567899', + phoneCell: '9876543211', + streetAddress1: '123 Random Street', + streetAddress2: '456 Street address #2', + city: 'Victoria', + postalCode: 'V8V1V1', + province: 'BC', + isMailingAddressDifferent: true, + mailingStreetAddress1: '999 Mailing Address', + mailingStreetAddress2: '415 Mailing 2', + mailingCity: 'Vancouver', + mailingPostalCode: 'T2J3J3', + mailingProvince: 'BC', + stateCode: 0, + statusCode: 1, + providerType: 1, + ownership: 2, +} diff --git a/frontend/test/utils/setupTests.js b/frontend/test/utils/setupTests.js index 619b56a9..f916ccfa 100644 --- a/frontend/test/utils/setupTests.js +++ b/frontend/test/utils/setupTests.js @@ -1,24 +1,34 @@ -import { HttpResponse, graphql, http } from 'msw' +import { HttpResponse, http } from 'msw' import { setupServer } from 'msw/node' import { afterAll, afterEach, beforeAll } from 'vitest' -import { getApplicationsResponse } from './test/utils/mockResponses' +import { getApplicationResponse, getApplicationsResponse } from './mockResponses/applications' +import { getDocumentsResponse } from './mockResponses/documents' +import { getContactsResponse, getFacilityResponse } from './mockResponses/facilities' +import { getOrganizationResponse } from './mockResponses/organizations' export const restHandlers = [ - http.get('https://rest-endpoint.example/path/to/posts', () => { + http.get('/api/organizations/b26aeb95-427d-ee11-8179-000d3a09d132', () => { + return HttpResponse.json(getOrganizationResponse) + }), + http.get('/api/applications', () => { return HttpResponse.json(getApplicationsResponse) }), -] - -const graphqlHandlers = [ - graphql.query('ListPosts', () => { - return HttpResponse.json({ - data: { getApplicationsResponse }, - }) + http.get('/api/applications/*', () => { + return HttpResponse.json(getApplicationResponse) + }), + http.get('/api/facilities/c9ecef6c-437d-ee11-8179-000d3a09d132', () => { + return HttpResponse.json(getFacilityResponse) + }), + http.get('/api/facilities/c9ecef6c-437d-ee11-8179-000d3a09d132/contacts', () => { + return HttpResponse.json(getContactsResponse) + }), + http.get('/api/documents', () => { + return HttpResponse.json(getDocumentsResponse) }), ] -const server = setupServer(...restHandlers, ...graphqlHandlers) +const server = setupServer(...restHandlers) // Start server before all tests beforeAll(() => server.listen({ onUnhandledRequest: 'error' })) diff --git a/frontend/test/views/MessagingView.test.js b/frontend/test/views/MessagingView.test.js index d96aca2d..42f02bf2 100644 --- a/frontend/test/views/MessagingView.test.js +++ b/frontend/test/views/MessagingView.test.js @@ -1,5 +1,5 @@ -import { beforeEach, describe, expect, test, vi } from 'vitest' -import { useRouter } from 'vue-router' +import moment from 'moment' +import { describe, expect, test } from 'vitest' import { createVuetify } from 'vuetify' import * as components from 'vuetify/components' import * as directives from 'vuetify/directives' @@ -10,181 +10,17 @@ import MessagingView from '@/views/MessagingView.vue' import { createTestingPinia } from '@pinia/testing' import { mount } from '@vue/test-utils' +import { getAssistanceRequestConversation, getAssistanceRequestsResponse } from '../utils/mockResponses/messages' +import { getNotificationsResponse } from '../utils/mockResponses/notifications' + const vuetify = createVuetify({ components, directives }) -vi.mock('vue-router') -describe('MessagingView', () => { +describe('Notifications Tab', () => { const global = { global: { plugins: [createTestingPinia(), vuetify] } } - const messagesStore = useMessagesStore() const notificationsStore = useNotificationsStore() - useRouter.mockReturnValue({ - push: vi.fn(), - }) - - beforeEach(() => { - useRouter().push.mockReset() - }) - - /* - =============================================== - Data Setup - =============================================== - */ - messagesStore.assistanceRequests = [ - { - assistanceRequestId: '2c1c29c7-c984-ee11-8179-000d3a09d4d4', - subject: 'Test Message #1', - referenceNumber: 'REQ-23000076', - statusCode: 6, - stateCode: 1, - categoryName: 'Reporting', - lastUpdatedTime: '2023-12-13T18:17:33Z', - isRead: false, - status: 'Open', - priority: 1, - requestFacilities: [ - { - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityName: 'Viet OFM Active Facility Number 1', - }, - ], - lastConversationTime: '2023-11-16T21:47:56Z', - }, - { - assistanceRequestId: 'c54ff934-9a93-ee11-be37-000d3a09d4d4', - subject: 'Test Message #2', - referenceNumber: 'REQ-23000272', - statusCode: 2, - stateCode: 0, - categoryName: 'Account Maintenance', - lastUpdatedTime: '2023-12-12T21:32:29Z', - isRead: false, - status: 'Open', - priority: 2, - requestFacilities: [ - { - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityName: 'Viet OFM Active Facility Number 1', - }, - ], - lastConversationTime: '2023-12-05T18:17:41Z', - }, - { - assistanceRequestId: 'af0c869f-5f95-ee11-be37-000d3a09d699', - subject: 'Test Message #3', - referenceNumber: 'REQ-23000277', - statusCode: 3, - stateCode: 0, - categoryName: 'Reporting', - lastUpdatedTime: '2023-12-13T18:15:53Z', - isRead: true, - status: 'Action required', - priority: 3, - requestFacilities: [ - { - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityName: 'Viet OFM Active Facility Number 1', - }, - ], - lastConversationTime: '2023-12-12T20:47:51Z', - }, - { - assistanceRequestId: '2d2ca51e-9a88-ee11-8179-000d3af4865d', - subject: 'Test Message #4', - referenceNumber: 'REQ-23000116', - statusCode: 5, - stateCode: 1, - categoryName: 'Intake & Renewal', - lastUpdatedTime: '2023-12-13T18:17:33Z', - isRead: true, - status: 'Closed', - priority: 1, - requestFacilities: [ - { - facilityId: '064effc8-437d-ee11-8179-000d3a09d132', - facilityName: 'Viet OFM This is Active Facility #2', - }, - ], - lastConversationTime: '2023-11-21T18:17:14Z', - }, - ] - messagesStore.assistanceRequestConversation = [ - { - conversationId: '3cc21980-4784-ee11-8179-000d3af4865d', - subject: 'MSG-23000051', - from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', - sentDate: '2023-11-16T06:15:13Z', - message: 'Final 3rd message from CRM', - ofmSourceSystem: false, - requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', - statusCode: 1, - }, - { - conversationId: '29626e3e-4784-ee11-8179-000d3af4865d', - subject: 'MSG-23000050', - from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', - sentDate: '2023-11-16T06:13:27Z', - message: 'This is 2nd message from CRM', - ofmSourceSystem: false, - requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', - statusCode: 1, - }, - { - conversationId: 'f0e7fe8c-1b84-ee11-8179-000d3af4865d', - subject: 'MSG-23000041', - from: 'd8ea4465-1777-ed11-81ac-000d3af4fa76', - sentDate: '2023-11-16T01:00:42Z', - message: 'This is 1st message from Portal', - ofmSourceSystem: false, - requestValue: 'f9293b70-1584-ee11-8179-000d3a09d699', - statusCode: 1, - }, - ] + notificationsStore.notifications = getNotificationsResponse - notificationsStore.notifications = [ - { - notificationId: 'ef908c0e-8c94-ee11-be37-000d3a09d699', - subject: 'Test notification #1', - dateReceived: '2023-12-06T23:06:20Z', - notificationContent: '
This is a demo email #1
', - lastOpenedTime: '2023-12-13T18:14:50Z', - isRead: false, - }, - { - notificationId: 'd108df71-8c94-ee11-be37-000d3a09d699', - subject: 'Test notification #2', - dateReceived: '2023-12-06T23:09:03Z', - notificationContent: - '
This is another demo email #2
\n
Updating the notes
', - lastOpenedTime: '2023-12-13T18:14:49Z', - isRead: false, - }, - { - notificationId: 'f333cd71-8c94-ee11-be37-000d3a09d999', - subject: 'Test notification #3', - dateReceived: '2023-12-07T23:09:03Z', - notificationContent: - '
This is another demo email #3
\n
Updating the notes
', - lastOpenedTime: '2023-12-13T18:14:49Z', - isRead: true, - }, - { - notificationId: 'd108df71-8c94-ee11-be37-333f1b02d222', - subject: 'Test notification #4', - dateReceived: '2023-12-09T23:09:03Z', - notificationContent: - '
This is another demo email
\n
Updating the notes
', - lastOpenedTime: '2023-12-13T18:14:49Z', - isRead: false, - }, - ] - - /* - =============================================== - Notifications Tab - =============================================== - */ test('Count of unread notifications in the Notifications tab ', async () => { const wrapper = mount(MessagingView, global) const actualUnreadNotificationsCount = wrapper.get('#unread-notifications-count')?.text() @@ -192,29 +28,34 @@ describe('MessagingView', () => { expect(actualUnreadNotificationsCount).toEqual(`(${expectedUnreadNotificationsCount})`) }) - test('Open the Notifications tab', async () => { + test('Open the Notifications tab, then verify Notifications table', async () => { const wrapper = mount(MessagingView, global) await wrapper.get('#notifications-tab').trigger('click') const notificationsTab = wrapper.text() expect(notificationsTab).toContain('Mark unread') expect(notificationsTab).toContain('Mark read') - expect(notificationsTab).toContain('Test notification #1') - expect(notificationsTab).toContain('2023-Dec-06') + expect(notificationsTab).toContain('Back to Home') + getNotificationsResponse.forEach((notification) => { + expect(notificationsTab).toContain(notification.subject) + expect(notificationsTab).toContain(moment(notification.dateReceived).format('YYYY-MMM-DD')) + }) }) - test('Open a notification', async () => { + test('Open a notification to read details', async () => { const wrapper = mount(MessagingView, global) await wrapper.get('#notifications-tab').trigger('click') await wrapper.get('.v-data-table__tr').trigger('click') const notificationDetails = wrapper.get('#notification-details')?.text() expect(notificationDetails).toContain('This is a demo email #1') }) +}) + +describe('Messages Tab', () => { + const global = { global: { plugins: [createTestingPinia(), vuetify] } } + const messagesStore = useMessagesStore() + messagesStore.assistanceRequests = getAssistanceRequestsResponse + messagesStore.assistanceRequestConversation = getAssistanceRequestConversation - /* - =============================================== - Messages Tab - =============================================== - */ test('Count of unread messages in the Messages tab ', async () => { const wrapper = mount(MessagingView, global) const actualUnreadMessagesCount = wrapper.get('#unread-messages-count')?.text() @@ -222,18 +63,24 @@ describe('MessagingView', () => { expect(actualUnreadMessagesCount).toEqual(`(${expectedUnreadMessagesCount})`) }) - test('Open the Messages tab', async () => { + test('Open the Messages tab, then verify Messages/Assistance Requests table', async () => { const wrapper = mount(MessagingView, global) await wrapper.get('#messages-tab').trigger('click') const messagesTab = wrapper.text() expect(messagesTab).toContain('New message') expect(messagesTab).toContain('Mark unread') expect(messagesTab).toContain('Mark read') - expect(messagesTab).toContain('Test Message #1') - expect(messagesTab).toContain('Action required') + expect(messagesTab).toContain('Back to Home') + getAssistanceRequestsResponse.forEach((message) => { + expect(messagesTab).toContain(message.status) + expect(messagesTab).toContain(message.subject) + expect(messagesTab).toContain(message.categoryName) + expect(messagesTab).toContain(message.categoryName) + expect(messagesTab).toContain(moment(message.lastConversationTime).format('YYYY-MMM-DD')) + }) }) - test('Open a message', async () => { + test('Open a message to read conversations', async () => { const wrapper = mount(MessagingView, global) await wrapper.get('#messages-tab').trigger('click') await wrapper.get('.v-data-table__tr').trigger('click') diff --git a/frontend/test/views/applications/ApplicationView.test.js b/frontend/test/views/applications/ApplicationView.test.js new file mode 100644 index 00000000..1f8486da --- /dev/null +++ b/frontend/test/views/applications/ApplicationView.test.js @@ -0,0 +1,47 @@ +import { describe, expect, test } from 'vitest' +import { createVuetify } from 'vuetify' +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' + +import { useAuthStore } from '@/stores/auth' +import ApplicationView from '@/views/applications/ApplicationView.vue' +import { createTestingPinia } from '@pinia/testing' +import { flushPromises, mount } from '@vue/test-utils' + +import { getUserInfoResponse } from '../../utils/mockResponses/auth' + +const vuetify = createVuetify({ components, directives }) + +describe('Application View', () => { + const global = { + global: { + plugins: [createTestingPinia(), vuetify], + mocks: { + $route: { + params: { + path: '/applications/b2b7f374-2995-ee11-be37-000d3a09d4d4/facility-details', + }, + }, + }, + }, + } + const authStore = useAuthStore() + + /* + =============================================== + Data Setup + =============================================== + */ + authStore.userInfo = getUserInfoResponse + + /* + =============================================== + TESTS + =============================================== + */ + test('Verify Applications History table after getApplications() requests is called', async () => { + const wrapper = mount(ApplicationView, global) + await flushPromises() + console.log(wrapper.text()) + }) +}) diff --git a/frontend/test/views/applications/ApplicationsHistoryView.test.js b/frontend/test/views/applications/ApplicationsHistoryView.test.js index ddbb0885..f1288da1 100644 --- a/frontend/test/views/applications/ApplicationsHistoryView.test.js +++ b/frontend/test/views/applications/ApplicationsHistoryView.test.js @@ -1,6 +1,5 @@ -import axios from 'axios' -import { beforeEach, describe, expect, test, vi } from 'vitest' -import { useRouter } from 'vue-router' +import moment from 'moment' +import { describe, expect, test } from 'vitest' import { createVuetify } from 'vuetify' import * as components from 'vuetify/components' import * as directives from 'vuetify/directives' @@ -8,62 +7,52 @@ import * as directives from 'vuetify/directives' import { useAuthStore } from '@/stores/auth' import ApplicationsHistoryView from '@/views/applications/ApplicationsHistoryView.vue' import { createTestingPinia } from '@pinia/testing' -import { mount } from '@vue/test-utils' +import { flushPromises, mount } from '@vue/test-utils' + +import { getApplicationsResponse } from '../../utils/mockResponses/applications' +import { getUserInfoResponse } from '../../utils/mockResponses/auth' const vuetify = createVuetify({ components, directives }) -vi.mock('axios') -describe('ApplicationsHistoryView', () => { - const global = { global: { plugins: [createTestingPinia(), vuetify] } } +describe('Applications History View', () => { + const global = { global: { plugins: [createTestingPinia(), vuetify], stubs: ['router-link'] } } const authStore = useAuthStore() - - // useRouter.mockReturnValue({ - // push: vi.fn(), - // }) - - // beforeEach(() => { - // useRouter().push.mockReset() - // }) - - /* - =============================================== - Data Setup - =============================================== - */ - authStore.userInfo = { - facilities: [ - { - facilityId: 'c9ecef6c-437d-ee11-8179-000d3a09d132', - facilityAccountNumber: 'Test-Facility-1', - facilityName: 'Test OFM Facility #1', - facilityType: 0, - facilityStateCode: 0, - facilityStatusCode: 1, - }, - { - facilityId: '6df8623a-447d-ee11-8179-000d3a09d499', - facilityAccountNumber: 'Test-Facility-2', - facilityName: 'Test OFM Facility #2', - facilityType: 0, - facilityStateCode: 0, - facilityStatusCode: 1, - }, - ], - } + authStore.userInfo = getUserInfoResponse /* =============================================== TESTS =============================================== */ - test('getApplications() requests are called', async () => { + test('Verify page labels', async () => { const wrapper = mount(ApplicationsHistoryView, global) - console.log(wrapper.text()) - axios.get.mockResolvedValue({ - data: mockApplications, - }) + await flushPromises() + expect(wrapper.text()).toContain('Application ID') + expect(wrapper.text()).toContain('Facility') + expect(wrapper.text()).toContain('Status') + expect(wrapper.text()).toContain('Actions') + expect(wrapper.text()).toContain('Date submitted') + expect(wrapper.text()).toContain('Latest activity') + expect(wrapper.text()).toContain('Back to Home') + }) - // expect(axios.get).toHaveBeenCalledTimes(2) - // expect(axios.get).toHaveBeenCalledWith('/api/get') + test('Verify applications history table after receiving GET applications response', async () => { + const wrapper = mount(ApplicationsHistoryView, global) + await flushPromises() + getApplicationsResponse?.forEach((application) => { + // const action = application?.status === 'Draft' ? 'Continue application' : 'View submission' + const dateSubmitted = !application?.dateSubmitted ? '- - - -' : moment(application?.dateSubmitted).format('YYYY-MMM-DD') + const latestActivity = !application?.latestActivity ? '- - - -' : moment(application?.latestActivity).format('YYYY-MMM-DD') + expect(wrapper.text()).toContain(application.referenceNumber) + expect(wrapper.text()).toContain(application.facilityName) + expect(wrapper.text()).toContain(application.status) + // expect(wrapper.text()).toContain(action) + expect(wrapper.text()).toContain(dateSubmitted) + expect(wrapper.text()).toContain(latestActivity) + }) }) + + // TO-DO + // Cancel Application button + // Vue Router (Continue Application/View Submission/Back to Home): https://test-utils.vuejs.org/guide/advanced/vue-router.html }) diff --git a/frontend/test/views/applications/FacilityDetailsView.test.js b/frontend/test/views/applications/FacilityDetailsView.test.js new file mode 100644 index 00000000..34036915 --- /dev/null +++ b/frontend/test/views/applications/FacilityDetailsView.test.js @@ -0,0 +1,114 @@ +import { describe, expect, test } from 'vitest' +import { createVuetify } from 'vuetify' +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' + +import { useAppStore } from '@/stores/app' +import { useApplicationsStore } from '@/stores/applications' +import FacilityDetailsView from '@/views/applications/FacilityDetailsView.vue' +import { createTestingPinia } from '@pinia/testing' +import { flushPromises, mount } from '@vue/test-utils' + +import { getLookupInfoResponse } from '../../utils/mockResponses/app' +import { getApplicationResponse } from '../../utils/mockResponses/applications' +import { getContactsResponse, getFacilityResponse } from '../../utils/mockResponses/facilities' + +const vuetify = createVuetify({ components, directives }) + +describe('Application - Facility Details View', () => { + const global = { + global: { + plugins: [createTestingPinia(), vuetify], + mocks: { + $route: { + params: { + path: '/applications/b2b7f374-2995-ee11-be37-000d3a09d4d4/facility-details', + }, + }, + }, + }, + } + + const appStore = useAppStore() + appStore.userRoles = getLookupInfoResponse.userRoles + + const applicationsStore = useApplicationsStore() + applicationsStore.currentApplication = getApplicationResponse + + /* + =============================================== + TESTS + =============================================== + */ + test('Verify page labels', async () => { + const wrapper = mount(FacilityDetailsView, global) + await flushPromises() + expect(wrapper.text()).toContain('Your facility') + expect(wrapper.text()).toContain('Facility Information') + expect(wrapper.text()).toContain('Primary Contact') + expect(wrapper.text()).toContain('Secondary Contact (Recommended)') + expect(wrapper.text()).toContain('Select contact who to contact about your application') + expect(wrapper.text()).toContain('Select contact') + }) + + test('Verify Facility Information details', async () => { + const wrapper = mount(FacilityDetailsView, global) + await flushPromises() + expect(wrapper.text()).toContain(getFacilityResponse.name) + expect(wrapper.text()).toContain(getFacilityResponse.phoneLandline) + expect(wrapper.text()).toContain(getFacilityResponse.phoneCell) + expect(wrapper.text()).toContain(getFacilityResponse.email) + expect(wrapper.text()).toContain(getFacilityResponse.streetAddress1) + expect(wrapper.text()).toContain(getFacilityResponse.streetAddress2) + expect(wrapper.text()).toContain(getFacilityResponse.city) + expect(wrapper.text()).toContain(getFacilityResponse.postalCode) + expect(wrapper.text()).toContain(getFacilityResponse.province) + expect(wrapper.text()).toContain(getFacilityResponse.mailingStreetAddress1) + expect(wrapper.text()).toContain(getFacilityResponse.mailingStreetAddress2) + expect(wrapper.text()).toContain(getFacilityResponse.mailingCity) + expect(wrapper.text()).toContain(getFacilityResponse.mailingPostalCode) + expect(wrapper.text()).toContain(getFacilityResponse.mailingProvince) + }) + + test('Verify selected Primary Contact in dropdown list', async () => { + const wrapper = mount(FacilityDetailsView, global) + await flushPromises() + const primaryContact = getContactsResponse.find((contact) => getApplicationResponse.primaryContactId === contact.contactId) + const primaryContactFullName = `${primaryContact.firstName} ${primaryContact.lastName}` + expect(wrapper.get('#primary-contact').wrapperElement._value).toEqual(primaryContactFullName) + }) + + test('Verify Primary Contact Information details', async () => { + const wrapper = mount(FacilityDetailsView, global) + await flushPromises() + const primaryContact = getContactsResponse.find((contact) => getApplicationResponse.primaryContactId === contact.contactId) + const roleName = appStore.getRoleNameById(primaryContact.role) + expect(wrapper.text()).toContain(primaryContact?.firstName) + expect(wrapper.text()).toContain(primaryContact?.lastName) + expect(wrapper.text()).toContain(primaryContact?.email) + expect(wrapper.text()).toContain(primaryContact?.phone) + expect(wrapper.text()).toContain(primaryContact?.userName) + expect(wrapper.text()).toContain(roleName) + }) + + test('Verify selected Secondary Contact in dropdown list', async () => { + const wrapper = mount(FacilityDetailsView, global) + await flushPromises() + const secondaryContact = getContactsResponse.find((contact) => getApplicationResponse.secondaryContactId === contact.contactId) + const secondaryContactFullName = `${secondaryContact.firstName} ${secondaryContact.lastName}` + expect(wrapper.get('#secondary-contact').wrapperElement._value).toEqual(secondaryContactFullName) + }) + + test('Verify Secondary Contact Information details', async () => { + const wrapper = mount(FacilityDetailsView, global) + await flushPromises() + const secondaryContact = getContactsResponse.find((contact) => getApplicationResponse.secondaryContactId === contact.contactId) + const roleName = appStore.getRoleNameById(secondaryContact.role) + expect(wrapper.text()).toContain(secondaryContact?.firstName) + expect(wrapper.text()).toContain(secondaryContact?.lastName) + expect(wrapper.text()).toContain(secondaryContact?.email) + expect(wrapper.text()).toContain(secondaryContact?.phone) + expect(wrapper.text()).toContain(secondaryContact?.userName) + expect(wrapper.text()).toContain(roleName) + }) +}) diff --git a/frontend/test/views/applications/OperatingCostsView.test.js b/frontend/test/views/applications/OperatingCostsView.test.js new file mode 100644 index 00000000..eb456121 --- /dev/null +++ b/frontend/test/views/applications/OperatingCostsView.test.js @@ -0,0 +1,63 @@ +import { describe, expect, test } from 'vitest' +import { createVuetify } from 'vuetify' +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' + +import { useAppStore } from '@/stores/app' +import { useApplicationsStore } from '@/stores/applications' +import OperatingCostsView from '@/views/applications/OperatingCostsView.vue' +import { createTestingPinia } from '@pinia/testing' +import { flushPromises, mount } from '@vue/test-utils' + +import { getLookupInfoResponse } from '../../utils/mockResponses/app' +import { getApplicationResponse } from '../../utils/mockResponses/applications' + +const vuetify = createVuetify({ components, directives }) + +describe('Application - Operating Costs View', () => { + const global = { + global: { + plugins: [createTestingPinia(), vuetify], + mocks: { + $route: { + params: { + path: '/applications/b2b7f374-2995-ee11-be37-000d3a09d4d4/operating-costs', + }, + }, + }, + }, + } + + const appStore = useAppStore() + appStore.facilityTypes = getLookupInfoResponse.facilityTypes + + const applicationsStore = useApplicationsStore() + applicationsStore.currentApplication = getApplicationResponse + + /* + =============================================== + TESTS + =============================================== + */ + test('Verify page labels', async () => { + const wrapper = mount(OperatingCostsView, global) + await flushPromises() + expect(wrapper.text()).toContain('Please provide operating costs for the selected facility') + expect(wrapper.text()).toContain('Facility Type') + expect(wrapper.text()).toContain('Yearly Operating Cost') + expect(wrapper.text()).toContain('Yearly Facility Cost') + }) + + test('Verify uploaded documents when facility type is Rent/Lease', async () => { + const wrapper = mount(OperatingCostsView, global) + await flushPromises() + console.log(wrapper.text()) + expect(wrapper.text()).toContain('Supporting Documents') + }) + + // TO-DO + // Check Operating costs + // Check page label when Facility Type is Rent/Lease or others + // Check Uploaded Documents when Facility Type is Rent/Lease or others + // Check if form is readonly when status != DRAFT +}) diff --git a/frontend/test/views/applications/SelectFacilityView.test.js b/frontend/test/views/applications/SelectFacilityView.test.js new file mode 100644 index 00000000..03f0412e --- /dev/null +++ b/frontend/test/views/applications/SelectFacilityView.test.js @@ -0,0 +1,67 @@ +import { describe, expect, test } from 'vitest' +import { createVuetify } from 'vuetify' +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' + +import { useAuthStore } from '@/stores/auth' +import SelectFacilityView from '@/views/applications/SelectFacilityView.vue' +import { createTestingPinia } from '@pinia/testing' +import { flushPromises, mount } from '@vue/test-utils' + +import { getUserInfoResponse } from '../../utils/mockResponses/auth' +import { getOrganizationResponse } from '../../utils/mockResponses/organizations' + +const vuetify = createVuetify({ components, directives }) + +describe('Application - Select Facility View', () => { + const global = { + global: { + plugins: [createTestingPinia(), vuetify], + }, + } + + const authStore = useAuthStore() + authStore.userInfo = getUserInfoResponse + + /* + =============================================== + TESTS + =============================================== + */ + test('Verify page labels', async () => { + const wrapper = mount(SelectFacilityView, global) + await flushPromises() + expect(wrapper.text()).toContain('Begin an Operating Funding Model application') + expect(wrapper.text()).toContain('Organization information') + expect(wrapper.text()).toContain("Please review the following pre-populated information for correctness and contact your organization's account manager to make updates if required.") + expect(wrapper.text()).toContain('I confirm that Organization information is correct.') + expect(wrapper.text()).toContain('To start your application, select a facility') + expect(wrapper.text()).toContain('If your facility is not listed, contact your Account Manager.') + expect(wrapper.text()).toContain('Select your facility:') + }) + + test('Verify Organization Information details', async () => { + const wrapper = mount(SelectFacilityView, global) + await flushPromises() + expect(wrapper.text()).toContain(getOrganizationResponse.name) + expect(wrapper.text()).toContain(getOrganizationResponse.businessType) + expect(wrapper.text()).toContain(getOrganizationResponse.email) + expect(wrapper.text()).toContain(getOrganizationResponse.phoneCell) + expect(wrapper.text()).toContain(getOrganizationResponse.phoneLandline) + expect(wrapper.text()).toContain(getOrganizationResponse.streetAddress1) + expect(wrapper.text()).toContain(getOrganizationResponse.streetAddress2) + expect(wrapper.text()).toContain(getOrganizationResponse.city) + expect(wrapper.text()).toContain(getOrganizationResponse.postalCode) + expect(wrapper.text()).toContain(getOrganizationResponse.province) + expect(wrapper.text()).toContain(getOrganizationResponse.mailingStreetAddress1) + expect(wrapper.text()).toContain(getOrganizationResponse.mailingStreetAddress2) + expect(wrapper.text()).toContain(getOrganizationResponse.mailingCity) + expect(wrapper.text()).toContain(getOrganizationResponse.mailingPostalCode) + expect(wrapper.text()).toContain(getOrganizationResponse.mailingProvince) + expect(wrapper.text()).toContain(getOrganizationResponse.mailingStreetAddress2) + }) + + // TO-DO + // Select facility from dropdown list + // Check if form is readonly when status != DRAFT +}) diff --git a/frontend/test/views/applications/StaffingView.test.js b/frontend/test/views/applications/StaffingView.test.js new file mode 100644 index 00000000..5eef8bab --- /dev/null +++ b/frontend/test/views/applications/StaffingView.test.js @@ -0,0 +1,56 @@ +import { describe, expect, test } from 'vitest' +import { createVuetify } from 'vuetify' +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' + +import { useApplicationsStore } from '@/stores/applications' +import StaffingView from '@/views/applications/StaffingView.vue' +import { createTestingPinia } from '@pinia/testing' +import { mount } from '@vue/test-utils' + +import { getApplicationResponse } from '../../utils/mockResponses/applications' + +const vuetify = createVuetify({ components, directives }) + +describe('Application - Staffing View', () => { + const global = { + global: { + plugins: [createTestingPinia(), vuetify], + }, + } + const applicationsStore = useApplicationsStore() + applicationsStore.currentApplication = getApplicationResponse + + /* + =============================================== + TESTS + =============================================== + */ + test('Verify page labels', async () => { + const wrapper = mount(StaffingView, global) + expect(wrapper.text()).toContain('Employee Category') + expect(wrapper.text()).toContain('Full-Time Position') + expect(wrapper.text()).toContain('Part-Time Position') + expect(wrapper.text()).toContain('Infant/Toddler Early Childhood Educator') + expect(wrapper.text()).toContain('Early Childhood Educator') + expect(wrapper.text()).toContain('Early Childhood Educator Assistant') + expect(wrapper.text()).toContain('Responsible Adult') + expect(wrapper.text()).toContain('Total') + }) + + test('Verify total staff calculation', async () => { + const wrapper = mount(StaffingView, global) + const totalFullTimePosition = + getApplicationResponse?.staffingInfantECEducatorFullTime + + getApplicationResponse?.staffingECEducatorFullTime + + getApplicationResponse?.staffingECEducatorAssistantFullTime + + getApplicationResponse?.staffingResponsibleAdultFullTime + const totalPartTimePosition = + getApplicationResponse?.staffingInfantECEducatorPartTime + + getApplicationResponse?.staffingECEducatorPartTime + + getApplicationResponse?.staffingECEducatorAssistantPartTime + + getApplicationResponse?.staffingResponsibleAdultPartTime + expect(wrapper.text()).toContain(totalFullTimePosition) + expect(wrapper.text()).toContain(totalPartTimePosition) + }) +}) From 44ebe4153c1f3f09f609ae5eaa7938d742691188 Mon Sep 17 00:00:00 2001 From: Le Date: Tue, 6 Feb 2024 10:08:22 -0800 Subject: [PATCH 7/7] clean up --- .../test/views/applications/ApplicationView.test.js | 12 ++++-------- .../views/applications/FacilityDetailsView.test.js | 6 +++--- .../views/applications/OperatingCostsView.test.js | 3 ++- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/frontend/test/views/applications/ApplicationView.test.js b/frontend/test/views/applications/ApplicationView.test.js index 1f8486da..7611525c 100644 --- a/frontend/test/views/applications/ApplicationView.test.js +++ b/frontend/test/views/applications/ApplicationView.test.js @@ -1,4 +1,4 @@ -import { describe, expect, test } from 'vitest' +import { describe, test } from 'vitest' import { createVuetify } from 'vuetify' import * as components from 'vuetify/components' import * as directives from 'vuetify/directives' @@ -26,12 +26,6 @@ describe('Application View', () => { }, } const authStore = useAuthStore() - - /* - =============================================== - Data Setup - =============================================== - */ authStore.userInfo = getUserInfoResponse /* @@ -39,9 +33,11 @@ describe('Application View', () => { TESTS =============================================== */ - test('Verify Applications History table after getApplications() requests is called', async () => { + test('TO-DO', async () => { const wrapper = mount(ApplicationView, global) await flushPromises() console.log(wrapper.text()) }) + // TO-DO + // Vue Router (Navigation Bar): https://test-utils.vuejs.org/guide/advanced/vue-router.html }) diff --git a/frontend/test/views/applications/FacilityDetailsView.test.js b/frontend/test/views/applications/FacilityDetailsView.test.js index 34036915..f64b6bb8 100644 --- a/frontend/test/views/applications/FacilityDetailsView.test.js +++ b/frontend/test/views/applications/FacilityDetailsView.test.js @@ -82,7 +82,7 @@ describe('Application - Facility Details View', () => { const wrapper = mount(FacilityDetailsView, global) await flushPromises() const primaryContact = getContactsResponse.find((contact) => getApplicationResponse.primaryContactId === contact.contactId) - const roleName = appStore.getRoleNameById(primaryContact.role) + const roleName = appStore.getRoleNameById(primaryContact?.role) expect(wrapper.text()).toContain(primaryContact?.firstName) expect(wrapper.text()).toContain(primaryContact?.lastName) expect(wrapper.text()).toContain(primaryContact?.email) @@ -95,7 +95,7 @@ describe('Application - Facility Details View', () => { const wrapper = mount(FacilityDetailsView, global) await flushPromises() const secondaryContact = getContactsResponse.find((contact) => getApplicationResponse.secondaryContactId === contact.contactId) - const secondaryContactFullName = `${secondaryContact.firstName} ${secondaryContact.lastName}` + const secondaryContactFullName = `${secondaryContact?.firstName} ${secondaryContact?.lastName}` expect(wrapper.get('#secondary-contact').wrapperElement._value).toEqual(secondaryContactFullName) }) @@ -103,7 +103,7 @@ describe('Application - Facility Details View', () => { const wrapper = mount(FacilityDetailsView, global) await flushPromises() const secondaryContact = getContactsResponse.find((contact) => getApplicationResponse.secondaryContactId === contact.contactId) - const roleName = appStore.getRoleNameById(secondaryContact.role) + const roleName = appStore.getRoleNameById(secondaryContact?.role) expect(wrapper.text()).toContain(secondaryContact?.firstName) expect(wrapper.text()).toContain(secondaryContact?.lastName) expect(wrapper.text()).toContain(secondaryContact?.email) diff --git a/frontend/test/views/applications/OperatingCostsView.test.js b/frontend/test/views/applications/OperatingCostsView.test.js index eb456121..1344c251 100644 --- a/frontend/test/views/applications/OperatingCostsView.test.js +++ b/frontend/test/views/applications/OperatingCostsView.test.js @@ -51,7 +51,8 @@ describe('Application - Operating Costs View', () => { test('Verify uploaded documents when facility type is Rent/Lease', async () => { const wrapper = mount(OperatingCostsView, global) await flushPromises() - console.log(wrapper.text()) + // console.log(wrapper.text()) + // TO-DO expect(wrapper.text()).toContain('Supporting Documents') })