From 71fc15bc962dc60ba22d044f5f46952d0fbb3217 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Mon, 7 Oct 2024 11:58:21 +0600 Subject: [PATCH 01/13] update config package to get certificates config from country config --- .../application/applicationConfigHandler.ts | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/packages/config/src/handlers/application/applicationConfigHandler.ts b/packages/config/src/handlers/application/applicationConfigHandler.ts index 15a461d1b1..669644e5a2 100644 --- a/packages/config/src/handlers/application/applicationConfigHandler.ts +++ b/packages/config/src/handlers/application/applicationConfigHandler.ts @@ -35,7 +35,7 @@ export default async function configHandler( ) { try { const [certificates, config, systems] = await Promise.all([ - getCertificates(request, h), + getCertificatesConfig(request, h), getApplicationConfig(request, h), getSystems(request, h) ]) @@ -53,7 +53,10 @@ export default async function configHandler( } } -async function getCertificates(request: Hapi.Request, h: Hapi.ResponseToolkit) { +async function getCertificatesConfig( + request: Hapi.Request, + h: Hapi.ResponseToolkit +) { const authToken = getToken(request) const decodedOrError = pipe(authToken, verifyToken) if (decodedOrError._tag === 'Left') { @@ -67,12 +70,18 @@ async function getCertificates(request: Hapi.Request, h: Hapi.ResponseToolkit) { scope.includes(RouteScope.VALIDATE) || scope.includes(RouteScope.NATLSYSADMIN)) ) { - return Promise.all( - (['birth', 'death', 'marriage'] as const).map(async (event) => { - const response = await getEventCertificate(event, getToken(request)) - return response - }) - ) + const url = new URL(`/certificates`, COUNTRY_CONFIG_URL).toString() + + const res = await fetch(url, { + headers: { Authorization: `Bearer ${authToken}` } + }) + + if (!res.ok) { + throw new Error( + `Failed to fetch certificates configuration: ${res.statusText} ${url}` + ) + } + return res.json() } return [] } @@ -86,27 +95,6 @@ async function getConfigFromCountry(authToken?: string) { return res.json() } -async function getEventCertificate( - event: 'birth' | 'death' | 'marriage', - authToken: string -) { - const url = new URL( - `/certificates/${event}.svg`, - env.COUNTRY_CONFIG_URL - ).toString() - - const res = await fetch(url, { - headers: { Authorization: `Bearer ${authToken}` } - }) - - if (!res.ok) { - throw new Error(`Failed to fetch ${event} certificate: ${res.statusText}`) - } - const responseText = await res.text() - - return { svgCode: responseText, event } -} - async function getApplicationConfig( request?: Hapi.Request, h?: Hapi.ResponseToolkit From 3f2cd146470282841cd9268bc5f8a05269ab3f62 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Fri, 4 Oct 2024 10:00:47 +0600 Subject: [PATCH 02/13] getting certificates config data from config package in client instead of svgcode --- packages/client/src/utils/referenceApi.ts | 52 +++++++++-------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/packages/client/src/utils/referenceApi.ts b/packages/client/src/utils/referenceApi.ts index 341257463b..d29a2a471b 100644 --- a/packages/client/src/utils/referenceApi.ts +++ b/packages/client/src/utils/referenceApi.ts @@ -18,7 +18,7 @@ import { ILocation } from '@client/offline/reducer' import { getToken } from '@client/utils/authUtils' -import { Event, System } from '@client/utils/gateway' +import { System } from '@client/utils/gateway' import { Validator } from '@client/forms/validators' import { IntlShape } from 'react-intl' @@ -77,9 +77,23 @@ interface ILoginBackground { backgroundImage?: string imageFit?: string } -export interface ICertificateTemplateData { - event: Event - svgCode: string +export interface ICertificateConfigData { + id: string + event: string + label: { + id: string + defaultMessage: string + description: string + } + svgUrl: string + fonts: { + [fontName: string]: { + normal: string + bold: string + italics: string + bolditalics: string + } + } } export interface ICurrency { isoCode: string @@ -143,7 +157,7 @@ export interface IApplicationConfig { } export interface IApplicationConfigResponse { config: IApplicationConfig - certificates: ICertificateTemplateData[] + certificates: ICertificateConfigData[] systems: System[] } @@ -250,33 +264,6 @@ async function importHandlebarHelpers(): Promise { return {} } } -async function loadCertificateConfiguration(): Promise { - const url = `${window.config.COUNTRY_CONFIG_URL}/certificate-configuration` - - const res = await fetch(url, { - method: 'GET' - }) - - // for backward compatibility, if the endpoint is unimplemented - if (res.status === 404) { - return { - fonts: { - notosans: { - normal: 'NotoSans-Light.ttf', - bold: 'NotoSans-Regular.ttf', - italics: 'NotoSans-Light.ttf', - bolditalics: 'NotoSans-Regular.ttf' - } - } - } - } - - if (!res.ok) { - throw Error(res.statusText) - } - - return res.json() -} async function loadContent(): Promise { const url = `${window.config.COUNTRY_CONFIG_URL}/content/client` @@ -415,7 +402,6 @@ async function loadFacilities(): Promise { export const referenceApi = { loadLocations, loadFacilities, - loadCertificateConfiguration, loadContent, loadConfig, loadForms, From 96fd29e3e092b2c708828d91f123b99687729601 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Fri, 4 Oct 2024 10:03:43 +0600 Subject: [PATCH 03/13] changing actions and reducers to accomodate new certificate config changes --- packages/client/src/offline/actions.ts | 33 +-------- packages/client/src/offline/reducer.ts | 94 +++----------------------- 2 files changed, 11 insertions(+), 116 deletions(-) diff --git a/packages/client/src/offline/actions.ts b/packages/client/src/offline/actions.ts index a6d2398d83..456798d980 100644 --- a/packages/client/src/offline/actions.ts +++ b/packages/client/src/offline/actions.ts @@ -26,8 +26,7 @@ import { LoadFormsResponse, LoadValidatorsResponse, LoadConditionalsResponse, - LoadHandlebarHelpersResponse, - CertificateConfiguration + LoadHandlebarHelpersResponse } from '@client/utils/referenceApi' import { System } from '@client/utils/gateway' import { UserDetails } from '@client/utils/userUtils' @@ -116,20 +115,6 @@ type CertificateLoadFailedAction = { payload: Error } -export const CERTIFICATE_CONFIGURATION_LOADED = - 'OFFLINE/CERTIFICATE_CONFIGURATION_LOADED' -type CertificateConfigurationLoadedAction = { - type: typeof CERTIFICATE_CONFIGURATION_LOADED - payload: CertificateConfiguration -} - -export const CERTIFICATE_CONFIGURATION_LOAD_FAILED = - 'OFFLINE/CERTIFICATE_CONFIGURATION_LOAD_FAILED' -type CertificateConfigurationLoadFailedAction = { - type: typeof CERTIFICATE_CONFIGURATION_LOAD_FAILED - payload: Error -} - export const UPDATE_OFFLINE_CONFIG = 'OFFLINE/UPDATE_OFFLINE_CONFIG' as const type ApplicationConfigUpdatedAction = { type: typeof UPDATE_OFFLINE_CONFIG @@ -274,20 +259,6 @@ export const certificateLoadFailed = ( payload }) -export const certificateConfigurationLoaded = ( - payload: CertificateConfiguration -): CertificateConfigurationLoadedAction => ({ - type: CERTIFICATE_CONFIGURATION_LOADED, - payload -}) - -export const certificateConfigurationLoadFailed = ( - payload: CertificateConfigurationLoadFailedAction['payload'] -): CertificateConfigurationLoadFailedAction => ({ - type: CERTIFICATE_CONFIGURATION_LOAD_FAILED, - payload -}) - export const configFailed = (error: Error): ApplicationConfigFailedAction => ({ type: APPLICATION_CONFIG_FAILED, payload: error @@ -362,8 +333,6 @@ export type Action = | ApplicationConfigFailedAction | ApplicationConfigUpdatedAction | CertificateLoadFailedAction - | CertificateConfigurationLoadedAction - | CertificateConfigurationLoadFailedAction | UpdateOfflineSystemsAction | IFilterLocationsAction | ReturnType diff --git a/packages/client/src/offline/reducer.ts b/packages/client/src/offline/reducer.ts index 41adfb050c..e000dabd00 100644 --- a/packages/client/src/offline/reducer.ts +++ b/packages/client/src/offline/reducer.ts @@ -27,14 +27,14 @@ import { referenceApi, CertificateConfiguration, IFacilitiesDataResponse, - IOfficesDataResponse + IOfficesDataResponse, + ICertificateConfigData } from '@client/utils/referenceApi' import { ILanguage } from '@client/i18n/reducer' import { filterLocations } from '@client/utils/locationUtils' import { Event, System } from '@client/utils/gateway' import { UserDetails } from '@client/utils/userUtils' import { isOfflineDataLoaded } from './selectors' -import { ISVGTemplate } from '@client/pdfRenderer' import { merge } from 'lodash' import { isNavigatorOnline } from '@client/utils' import { ISerializedForm } from '@client/forms' @@ -105,11 +105,7 @@ export interface IOfflineData { fonts?: CertificateConfiguration['fonts'] // Certificates might not be defined in the case of // a field agent using the app. - certificates?: { - birth: ISVGTemplate - death: ISVGTemplate - marriage: ISVGTemplate - } + certificates?: ICertificateConfigData[] } assets: { logo: string @@ -205,14 +201,6 @@ const CONFIG_CMD = Cmd.run(() => referenceApi.loadConfig(), { failActionCreator: actions.configFailed }) -const CERTIFICATE_CONFIG_CMD = Cmd.run( - () => referenceApi.loadCertificateConfiguration(), - { - successActionCreator: actions.certificateConfigurationLoaded, - failActionCreator: actions.certificateConfigurationLoadFailed - } -) - const CONTENT_CMD = Cmd.run(() => referenceApi.loadContent(), { successActionCreator: actions.contentLoaded, failActionCreator: actions.contentFailed @@ -247,7 +235,6 @@ function getDataLoadingCommands() { FACILITIES_CMD, LOCATIONS_CMD, CONFIG_CMD, - CERTIFICATE_CONFIG_CMD, CONDITIONALS_CMD, VALIDATORS_CMD, HANDLEBARS_CMD, @@ -373,58 +360,14 @@ function reducer( case actions.APPLICATION_CONFIG_LOADED: { const { certificates, config, systems } = action.payload merge(window.config, config) - const birthCertificateTemplate = certificates.find( - ({ event }) => event === Event.Birth - ) - - const deathCertificateTemplate = certificates.find( - ({ event }) => event === Event.Death - ) - - const marriageCertificateTemplate = certificates.find( - ({ event }) => event === Event.Marriage - ) - - let newOfflineData: Partial - if ( - birthCertificateTemplate && - deathCertificateTemplate && - marriageCertificateTemplate - ) { - const certificatesTemplates = { - birth: { - definition: birthCertificateTemplate.svgCode - }, - death: { - definition: deathCertificateTemplate.svgCode - }, - marriage: { - definition: marriageCertificateTemplate.svgCode - } - } - - newOfflineData = { - ...state.offlineData, - config, - systems, - templates: { - ...state.offlineData.templates, - certificates: certificatesTemplates - } - } - } else { - newOfflineData = { - ...state.offlineData, - config, - systems, - - // Field agents do not get certificate templates from the config service. - // Our loading logic depends on certificates being present and the app would load infinitely - // without a value here. - // This is a quickfix for the issue. If done properly, we should amend the "is loading" check - // to not expect certificate templates when a field agent is logged in. - templates: {} + const newOfflineData = { + ...state.offlineData, + config, + systems, + templates: { + ...state.offlineData.templates, + certificates } } @@ -482,23 +425,6 @@ function reducer( ) } - case actions.CERTIFICATE_CONFIGURATION_LOADED: { - return { - ...state, - offlineData: { - ...state.offlineData, - templates: { - ...state.offlineData.templates, - fonts: action.payload.fonts - } - } - } - } - - case actions.CERTIFICATE_CONFIGURATION_LOAD_FAILED: { - return loop(state, delay(CERTIFICATE_CONFIG_CMD, RETRY_TIMEOUT)) - } - /* * Locations */ From df2e9763daa643aa6fb6eaeaf2c131d1fe27fe8a Mon Sep 17 00:00:00 2001 From: tareq89 Date: Fri, 4 Oct 2024 10:18:12 +0600 Subject: [PATCH 04/13] certificate template selection is required for collectors to proceed to ReviewCertificate before print in advance --- .../fieldDefinitions/collectorSection.ts | 21 +++++- packages/client/src/navigation/index.ts | 9 ++- packages/client/src/navigation/routes.ts | 2 +- .../src/views/PrintCertificate/PDFUtils.ts | 18 ++--- .../ReviewCertificateAction.tsx | 12 ++-- .../collectorForm/CollectorForm.tsx | 10 ++- .../usePrintableCertificate.ts | 70 ++++++++++++------- 7 files changed, 92 insertions(+), 50 deletions(-) diff --git a/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts b/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts index d306f3df5b..406e4c2331 100644 --- a/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts +++ b/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts @@ -36,6 +36,7 @@ import { identityHelperTextMapper, identityNameMapper } from './messages' import { Event } from '@client/utils/gateway' import { IDeclaration } from '@client/declarations' import { issueMessages } from '@client/i18n/messages/issueCertificate' +import { ICertificateConfigData } from '@client/utils/referenceApi' interface INameField { firstNamesField: string @@ -1012,7 +1013,8 @@ const marriageIssueCollectorFormOptions = [ ] function getCertCollectorGroupForEvent( - declaration: IDeclaration + declaration: IDeclaration, + certificates?: ICertificateConfigData[] ): IFormSectionGroup { const informant = (declaration.data.informant.otherInformantType || declaration.data.informant.informantType) as string @@ -1055,13 +1057,26 @@ function getCertCollectorGroupForEvent( initialValue: '', validator: [], options: finalOptions + }, + { + name: 'certTemplateId', + type: 'SELECT_WITH_OPTIONS', + label: certificateMessages.certificateConfirmationTxt, + required: true, + initialValue: '', + validator: [], + options: + certificates + ?.filter((x) => x.event === declaration.event) + .map((x) => ({ label: x.label, value: x.id })) || [] } ] } } export function getCertificateCollectorFormSection( - declaration: IDeclaration + declaration: IDeclaration, + certificates?: ICertificateConfigData[] ): IFormSection { return { id: CertificateSection.Collector, @@ -1069,7 +1084,7 @@ export function getCertificateCollectorFormSection( name: certificateMessages.printCertificate, title: certificateMessages.certificateCollectionTitle, groups: [ - getCertCollectorGroupForEvent(declaration), + getCertCollectorGroupForEvent(declaration, certificates), otherCertCollectorFormGroup(declaration.event), affidavitCertCollectorGroup ] diff --git a/packages/client/src/navigation/index.ts b/packages/client/src/navigation/index.ts index 886a57da81..96dbd2d504 100644 --- a/packages/client/src/navigation/index.ts +++ b/packages/client/src/navigation/index.ts @@ -360,11 +360,14 @@ export function goToVerifyCorrector(declarationId: string, corrector: string) { ) } -export function goToReviewCertificate(registrationId: string, event: Event) { +export function goToReviewCertificate( + registrationId: string, + certTemplateId: string +) { return push( formatUrl(REVIEW_CERTIFICATE, { - registrationId: registrationId.toString(), - eventType: event + registrationId, + certTemplateId }), { isNavigatedInsideApp: true } ) diff --git a/packages/client/src/navigation/routes.ts b/packages/client/src/navigation/routes.ts index 15fae4c974..df59763910 100644 --- a/packages/client/src/navigation/routes.ts +++ b/packages/client/src/navigation/routes.ts @@ -48,7 +48,7 @@ export const ISSUE_COLLECTOR = '/issue/:registrationId/:pageId' export const ISSUE_VERIFY_COLLECTOR = '/issue/check/:registrationId/:eventType/:collector' export const VERIFY_COLLECTOR = - '/print/check/:registrationId/:eventType/:collector' + '/print/check/:registrationId/:certTemplateId/:collector' export const REVIEW_CERTIFICATE = '/review/:registrationId/:eventType' export const PRINT_CERTIFICATE_PAYMENT = diff --git a/packages/client/src/views/PrintCertificate/PDFUtils.ts b/packages/client/src/views/PrintCertificate/PDFUtils.ts index 91fe857eec..4a79878c09 100644 --- a/packages/client/src/views/PrintCertificate/PDFUtils.ts +++ b/packages/client/src/views/PrintCertificate/PDFUtils.ts @@ -14,11 +14,7 @@ import { createIntl, createIntlCache } from 'react-intl' -import { - AdminStructure, - ILocation, - IOfflineData -} from '@client/offline/reducer' +import { AdminStructure, ILocation } from '@client/offline/reducer' import { IPDFTemplate } from '@client/pdfRenderer' import { certificateBaseTemplate } from '@client/templates/register' import * as Handlebars from 'handlebars' @@ -27,7 +23,10 @@ import { getOfflineData } from '@client/offline/selectors' import isValid from 'date-fns/isValid' import format from 'date-fns/format' import { getHandlebarHelpers } from '@client/forms/handlebarHelpers' -import { FontFamilyTypes } from '@client/utils/referenceApi' +import { + CertificateConfiguration, + FontFamilyTypes +} from '@client/utils/referenceApi' type TemplateDataType = string | MessageDescriptor | Array function isMessageDescriptor( @@ -223,12 +222,15 @@ src: url("${url}") format("truetype"); const serializer = new XMLSerializer() return serializer.serializeToString(svg) } -export function svgToPdfTemplate(svg: string, offlineResource: IOfflineData) { +export function svgToPdfTemplate( + svg: string, + certificateFonts: CertificateConfiguration +) { const pdfTemplate: IPDFTemplate = { ...certificateBaseTemplate, fonts: { ...certificateBaseTemplate.fonts, - ...offlineResource.templates.fonts + ...certificateFonts } } diff --git a/packages/client/src/views/PrintCertificate/ReviewCertificateAction.tsx b/packages/client/src/views/PrintCertificate/ReviewCertificateAction.tsx index ac5ee08d4b..7a36f05e12 100644 --- a/packages/client/src/views/PrintCertificate/ReviewCertificateAction.tsx +++ b/packages/client/src/views/PrintCertificate/ReviewCertificateAction.tsx @@ -21,7 +21,7 @@ import { } from '@opencrvs/components' import React from 'react' import { useDispatch } from 'react-redux' -import { useLocation, useParams } from 'react-router' +import { useLocation } from 'react-router' import { messages as certificateMessages } from '@client/i18n/messages/views/certificate' import { useIntl } from 'react-intl' import { buttonMessages } from '@client/i18n/messages/buttons' @@ -110,19 +110,17 @@ const ReviewCertificateFrame = ({ } export const ReviewCertificate = () => { - const { registrationId } = useParams<{ registrationId: string }>() - const { - svg, + svgCode, handleCertify, isPrintInAdvance, canUserEditRecord, handleEdit - } = usePrintableCertificate(registrationId) + } = usePrintableCertificate() const intl = useIntl() const [modal, openModal] = useModal() - if (!svg) { + if (!svgCode) { return ( @@ -183,7 +181,7 @@ export const ReviewCertificate = () => { { this.props.writeDeclaration(draft) if (isCertificateForPrintInAdvance(draft)) { - this.props.goToReviewCertificate(declarationId, event) + this.props.goToReviewCertificate( + declarationId, + collector.certTemplateId as string + ) } else { this.props.goToVerifyCollector( declarationId, @@ -507,7 +510,10 @@ const mapStateToProps = ( const userOfficeId = userDetails?.primaryOffice?.id const registeringOfficeId = getRegisteringOfficeId(declaration) - const certFormSection = getCertificateCollectorFormSection(declaration) + const certFormSection = getCertificateCollectorFormSection( + declaration, + state.offline.offlineData.templates?.certificates + ) const isAllowPrintInAdvance = event === Event.Birth diff --git a/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts b/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts index e69966f338..27787c0b35 100644 --- a/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts +++ b/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts @@ -44,6 +44,8 @@ import { formatLongDate } from '@client/utils/date-formatting' import { AdminStructure, IOfflineData } from '@client/offline/reducer' import { getLocationHierarchy } from '@client/utils/locationUtils' import { printPDF } from '@client/pdfRenderer' +import { useEffect, useState } from 'react' +import { useParams } from 'react-router' const withEnhancedTemplateVariables = ( declaration: IPrintableDeclaration | undefined, @@ -100,10 +102,14 @@ const withEnhancedTemplateVariables = ( } } -export const usePrintableCertificate = (declarationId: string) => { +export const usePrintableCertificate = () => { + const { registrationId, certTemplateId } = useParams<{ + registrationId: string + certTemplateId: string + }>() const declarationWithoutAllTemplateVariables = useDeclaration< IPrintableDeclaration | undefined - >(declarationId) + >(registrationId) const userDetails = useSelector(getUserDetails) const offlineData = useSelector(getOfflineData) const declaration = withEnhancedTemplateVariables( @@ -120,28 +126,37 @@ export const usePrintableCertificate = (declarationId: string) => { declaration?.event !== Event.Marriage && (hasRegisterScope(scope) || hasRegistrationClerkScope(scope)) - let svg = undefined - const certificateTemplate = - declaration && - offlineData.templates.certificates?.[declaration.event].definition - if (certificateTemplate) { - const svgWithoutFonts = compileSvg( - certificateTemplate, - { ...declaration.data.template, preview: true }, - state - ) - const svgWithFonts = addFontsToSvg( - svgWithoutFonts, - offlineData.templates.fonts ?? {} - ) - svg = svgWithFonts - } + const [svgCode, setSvgCode] = useState() + const certificateConfig = offlineData.templates.certificates?.find( + (x) => x.id === certTemplateId + ) + const certificateFonts = certificateConfig?.fonts ?? {} + + useEffect(() => { + const certificateUrl = + declaration && + offlineData.templates.certificates?.find((x) => x.id === certTemplateId) + ?.svgUrl + + if (certificateUrl) { + fetch(certificateUrl) + .then((res) => res.text()) + .then((certificateTemplate) => { + if (!certificateTemplate) return + const svgWithoutFonts = compileSvg( + certificateTemplate, + { ...declaration.data.template, preview: true }, + state + ) + const svgWithFonts = addFontsToSvg(svgWithoutFonts, certificateFonts) + setSvgCode(svgWithFonts) + }) + } + // eslint-disable-next-line + }, []) const handleCertify = async () => { - if ( - !declaration || - !offlineData.templates.certificates?.[declaration.event].definition - ) { + if (!declaration || !certificateConfig) { return } const draft = cloneDeep(declaration) @@ -169,8 +184,11 @@ export const usePrintableCertificate = (declarationId: string) => { } } + const svgTemplate = await fetch(certificateConfig.svgUrl).then((res) => + res.text() + ) const svg = await compileSvg( - offlineData.templates.certificates[draft.event].definition, + svgTemplate, { ...draft.data.template, preview: false }, state ) @@ -185,7 +203,7 @@ export const usePrintableCertificate = (declarationId: string) => { ] } - const pdfTemplate = svgToPdfTemplate(svg, offlineData) + const pdfTemplate = svgToPdfTemplate(svg, certificateFonts) printPDF(pdfTemplate, draft.id) @@ -214,12 +232,12 @@ export const usePrintableCertificate = (declarationId: string) => { } dispatch( - goToCertificateCorrection(declarationId, CorrectionSection.Corrector) + goToCertificateCorrection(registrationId, CorrectionSection.Corrector) ) } return { - svg, + svgCode, handleCertify, isPrintInAdvance, canUserEditRecord, From 5b66e4827ecadeefb6a102543d3010823ebc61af Mon Sep 17 00:00:00 2001 From: tareq89 Date: Fri, 4 Oct 2024 10:18:59 +0600 Subject: [PATCH 05/13] certificate collection removed via migration script --- ...002232752-remove-certificate-collection.ts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 packages/migration/src/migrations/application-config/20241002232752-remove-certificate-collection.ts diff --git a/packages/migration/src/migrations/application-config/20241002232752-remove-certificate-collection.ts b/packages/migration/src/migrations/application-config/20241002232752-remove-certificate-collection.ts new file mode 100644 index 0000000000..5bbe022ece --- /dev/null +++ b/packages/migration/src/migrations/application-config/20241002232752-remove-certificate-collection.ts @@ -0,0 +1,66 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * OpenCRVS is also distributed under the terms of the Civil Registration + * & Healthcare Disclaimer located at http://opencrvs.org/license. + * + * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. + */ + +import { Db, MongoClient } from 'mongodb' + +export const up = async (db: Db, client: MongoClient) => { + const session = client.startSession() + try { + await session.withTransaction(async () => { + const collectionExists = await db + .listCollections({ name: 'certificates' }) + .hasNext() + + if (collectionExists) { + await db.collection('certificates').drop() + console.log('Certificates collection removed successfully') + } else { + console.log('Certificates collection does not exist, skipping removal') + } + }) + } catch (error) { + console.error( + 'Error occurred while removing certificates collection:', + error + ) + throw error + } finally { + session.endSession() + } +} + +export const down = async (db: Db, client: MongoClient) => { + const session = client.startSession() + try { + await session.withTransaction(async () => { + const collectionExists = await db + .listCollections({ name: 'certificates' }) + .hasNext() + + if (!collectionExists) { + await db.createCollection('certificates') + console.log('Certificates collection recreated successfully') + } else { + console.log( + 'Certificates collection already exists, skipping recreation' + ) + } + }) + } catch (error) { + console.error( + 'Error occurred while recreating certificates collection:', + error + ) + throw error + } finally { + session.endSession() + } +} From 1076878590576241d6697ddb15bc050693e74900 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Fri, 4 Oct 2024 11:36:22 +0600 Subject: [PATCH 06/13] select certificate template label added --- .../forms/certificate/fieldDefinitions/collectorSection.ts | 2 +- packages/client/src/i18n/messages/views/certificate.ts | 6 ++++++ packages/client/src/tests/languages.json | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts b/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts index 406e4c2331..48bfe44104 100644 --- a/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts +++ b/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts @@ -1061,7 +1061,7 @@ function getCertCollectorGroupForEvent( { name: 'certTemplateId', type: 'SELECT_WITH_OPTIONS', - label: certificateMessages.certificateConfirmationTxt, + label: certificateMessages.certificateTemplateSelectLabel, required: true, initialValue: '', validator: [], diff --git a/packages/client/src/i18n/messages/views/certificate.ts b/packages/client/src/i18n/messages/views/certificate.ts index 3c3601da74..062d679af8 100644 --- a/packages/client/src/i18n/messages/views/certificate.ts +++ b/packages/client/src/i18n/messages/views/certificate.ts @@ -14,6 +14,7 @@ interface ICertificateMessages extends Record { certificateCollectionTitle: MessageDescriptor addAnotherSignature: MessageDescriptor + certificateTemplateSelectLabel: MessageDescriptor certificateConfirmationTxt: MessageDescriptor certificateIsCorrect: MessageDescriptor certificateReceiptHeader: MessageDescriptor @@ -95,6 +96,11 @@ const messagesToDefine: ICertificateMessages = { description: 'The title of print certificate action', id: 'print.certificate.section.title' }, + certificateTemplateSelectLabel: { + defaultMessage: 'Select certificate template', + description: 'The title of select certificate template action', + id: 'certificate.selectTemplate' + }, certificateConfirmationTxt: { defaultMessage: 'Edit', description: 'Edit', diff --git a/packages/client/src/tests/languages.json b/packages/client/src/tests/languages.json index e3329737a3..57c24fea6d 100644 --- a/packages/client/src/tests/languages.json +++ b/packages/client/src/tests/languages.json @@ -52,6 +52,7 @@ "buttons.upload": "Upload", "buttons.yes": "Yes", "certificate.confirmCorrect": "Please confirm that the informant has reviewed that the information on the certificate is correct and that you are ready to print.", + "certificate.selectTemplate": "Select certificate template", "certificate.isCertificateCorrect": "Is the {event} certificate correct?", "certificate.label.birth": "Birth", "certificate.label.death": "Death", @@ -1200,6 +1201,7 @@ "buttons.upload": "আপলোড", "buttons.yes": "হ্যাঁ", "certificate.confirmCorrect": "অনুগ্রহ করে নিশ্চিত করুন যে নিবন্ধনটি পর্যালোচনা হয়েছে তার তথ্য সঠিক এবং আপনি মুদ্রণ করতে প্রস্তুত", + "certificate.selectTemplate": "নিবন্ধন টেমপ্লেট নির্বাচন করুন", "certificate.isCertificateCorrect": "জন্ম নিবন্ধনটি কি সঠিক?", "certificate.label.birth": "জন্ম", "certificate.label.death": "মৃত্যু", From 33ddc735fec7fd7b504c2343099a43e8765acec6 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Mon, 7 Oct 2024 11:23:19 +0600 Subject: [PATCH 07/13] fixed different routes to accomodate certTemplateId --- .../fieldDefinitions/collectorSection.ts | 16 ++++++---- packages/client/src/navigation/index.ts | 22 +++++++------- packages/client/src/navigation/routes.ts | 8 ++--- .../src/views/PrintCertificate/Payment.tsx | 29 +++++++++---------- .../PrintCertificate/VerifyCollector.tsx | 10 +++---- .../collectorForm/CollectorForm.tsx | 23 +++++++++++---- 6 files changed, 61 insertions(+), 47 deletions(-) diff --git a/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts b/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts index 48bfe44104..f6940a3b0b 100644 --- a/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts +++ b/packages/client/src/forms/certificate/fieldDefinitions/collectorSection.ts @@ -1041,7 +1041,14 @@ function getCertCollectorGroupForEvent( birthCertCollectorOptions, marriageCertCollectorOptions ) - + const certificateTemplateOptions = + certificates + ?.filter((x) => x.event === declaration.event) + .map((x) => ({ label: x.label, value: x.id })) || [] + const certTemplateDefaultValue = + certificateTemplateOptions.length > 0 + ? certificateTemplateOptions[0].value + : '' return { id: 'certCollector', title: certificateMessages.whoToCollect, @@ -1063,12 +1070,9 @@ function getCertCollectorGroupForEvent( type: 'SELECT_WITH_OPTIONS', label: certificateMessages.certificateTemplateSelectLabel, required: true, - initialValue: '', + initialValue: certTemplateDefaultValue, validator: [], - options: - certificates - ?.filter((x) => x.event === declaration.event) - .map((x) => ({ label: x.label, value: x.id })) || [] + options: certificateTemplateOptions } ] } diff --git a/packages/client/src/navigation/index.ts b/packages/client/src/navigation/index.ts index 96dbd2d504..5ed4a61704 100644 --- a/packages/client/src/navigation/index.ts +++ b/packages/client/src/navigation/index.ts @@ -293,13 +293,13 @@ export function goToBirthRegistrationAsParent(declarationId: string) { export function goToPrintCertificate( registrationId: string, - event: string, + certTemplateId: string, groupId?: string ) { return push( formatUrl(CERTIFICATE_COLLECTOR, { - registrationId: registrationId.toString(), - eventType: event.toLowerCase().toString(), + registrationId, + certTemplateId, groupId: groupId || 'certCollector' }) ) @@ -375,13 +375,13 @@ export function goToReviewCertificate( export function goToVerifyCollector( registrationId: string, - event: string, + certTemplateId: string, collector: string ) { return push( formatUrl(VERIFY_COLLECTOR, { registrationId: registrationId.toString(), - eventType: event.toLowerCase().toString(), + certTemplateId: certTemplateId.toLowerCase().toString(), collector: collector.toLowerCase().toString() }) ) @@ -389,24 +389,24 @@ export function goToVerifyCollector( export function goToPrintCertificatePayment( registrationId: string, - event: Event + certTemplateId: string ) { return push( formatUrl(PRINT_CERTIFICATE_PAYMENT, { - registrationId: registrationId.toString(), - eventType: event + registrationId, + certTemplateId }) ) } export function goToIssueCertificatePayment( registrationId: string, - event: Event + certTemplateId: string ) { return push( formatUrl(ISSUE_CERTIFICATE_PAYMENT, { - registrationId: registrationId.toString(), - eventType: event + registrationId, + certTemplateId }) ) } diff --git a/packages/client/src/navigation/routes.ts b/packages/client/src/navigation/routes.ts index df59763910..3ab4466422 100644 --- a/packages/client/src/navigation/routes.ts +++ b/packages/client/src/navigation/routes.ts @@ -43,18 +43,18 @@ export const VERIFY_CORRECTOR = '/correction/:declarationId/verify/:corrector' export const SEARCH = '/search' export const SEARCH_RESULT = '/search-result' export const CERTIFICATE_COLLECTOR = - '/cert/collector/:registrationId/:eventType/:groupId' + '/cert/collector/:registrationId/:certTemplateId/:groupId' export const ISSUE_COLLECTOR = '/issue/:registrationId/:pageId' export const ISSUE_VERIFY_COLLECTOR = '/issue/check/:registrationId/:eventType/:collector' export const VERIFY_COLLECTOR = '/print/check/:registrationId/:certTemplateId/:collector' -export const REVIEW_CERTIFICATE = '/review/:registrationId/:eventType' +export const REVIEW_CERTIFICATE = '/review/:registrationId/:certTemplateId' export const PRINT_CERTIFICATE_PAYMENT = - '/print/payment/:registrationId/:eventType' + '/print/payment/:registrationId/:certTemplateId' export const ISSUE_CERTIFICATE_PAYMENT = - '/issue/payment/:registrationId/:eventType' + '/issue/payment/:registrationId/:certTemplateId' export const REGISTRAR_HOME = '/registration-home' export const REGISTRAR_HOME_TAB = '/registration-home/:tabId/:selectorId?' diff --git a/packages/client/src/views/PrintCertificate/Payment.tsx b/packages/client/src/views/PrintCertificate/Payment.tsx index 296af04acc..ba98cd727c 100644 --- a/packages/client/src/views/PrintCertificate/Payment.tsx +++ b/packages/client/src/views/PrintCertificate/Payment.tsx @@ -46,6 +46,7 @@ import { UserDetails } from '@client/utils/userUtils' interface IProps { event: Event registrationId: string + certTemplateId: string language: string declaration: IPrintableDeclaration theme: ITheme @@ -63,11 +64,12 @@ const PaymentComponent = ({ declaration, intl, event, + registrationId, + certTemplateId, goBack, offlineCountryConfig, modifyDeclaration, - goToReviewCertificate, - registrationId + goToReviewCertificate }: IFullProps) => { const handleContinue = (paymentAmount: string) => { const certificates = @@ -96,7 +98,7 @@ const PaymentComponent = ({ } }) - goToReviewCertificate(registrationId, event) + goToReviewCertificate(registrationId, certTemplateId) } if (!declaration) { @@ -180,30 +182,25 @@ const PaymentComponent = ({ ) } -const getEvent = (eventType: string | undefined) => { - switch (eventType && eventType.toLowerCase()) { - case 'birth': - default: - return Event.Birth - case 'death': - return Event.Death - case 'marriage': - return Event.Marriage - } +const getEvent = (state: IStoreState, certTemplateId: string | undefined) => { + return state.offline.offlineData.templates?.certificates?.find( + (x) => x.id === certTemplateId + )?.event } function mapStatetoProps( state: IStoreState, - props: RouteComponentProps<{ registrationId: string; eventType: string }> + props: RouteComponentProps<{ registrationId: string; certTemplateId: string }> ) { - const { registrationId, eventType } = props.match.params - const event = getEvent(eventType) + const { registrationId, certTemplateId } = props.match.params + const event = getEvent(state, certTemplateId) as Event const declaration = state.declarationsState.declarations.find( (app) => app.id === registrationId && app.event === event ) as IPrintableDeclaration return { event, + certTemplateId, registrationId, language: state.i18n.language, declaration, diff --git a/packages/client/src/views/PrintCertificate/VerifyCollector.tsx b/packages/client/src/views/PrintCertificate/VerifyCollector.tsx index 5ae1f8aff0..3af807adcb 100644 --- a/packages/client/src/views/PrintCertificate/VerifyCollector.tsx +++ b/packages/client/src/views/PrintCertificate/VerifyCollector.tsx @@ -51,7 +51,7 @@ import { getUserDetails } from '@client/profile/profileSelectors' interface IMatchParams { registrationId: string - eventType: Event + certTemplateId: Event collector: string } @@ -104,24 +104,24 @@ class VerifyCollectorComponent extends React.Component { if (!isIssueUrl) { this.props.goToReviewCertificate( this.props.match.params.registrationId, - event + this.props.match.params.certTemplateId ) } else { this.props.goToIssueCertificatePayment( this.props.match.params.registrationId, - event + this.props.match.params.certTemplateId ) } } else { if (!isIssueUrl) { this.props.goToPrintCertificatePayment( this.props.match.params.registrationId, - event + this.props.match.params.certTemplateId ) } else { this.props.goToIssueCertificatePayment( this.props.match.params.registrationId, - event + this.props.match.params.certTemplateId ) } } diff --git a/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx b/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx index ff873fd8a3..b680f0cba9 100644 --- a/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx +++ b/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx @@ -184,6 +184,7 @@ interface IState { showError: boolean showModalForNoSignedAffidavit: boolean isFileUploading: boolean + certTemplateId: string } class CollectorFormComponent extends React.Component { @@ -192,7 +193,8 @@ class CollectorFormComponent extends React.Component { this.state = { showError: false, showModalForNoSignedAffidavit: false, - isFileUploading: false + isFileUploading: false, + certTemplateId: '' } } @@ -257,6 +259,10 @@ class CollectorFormComponent extends React.Component { sectionId as keyof typeof certificate ] as IFormSectionData + this.setState({ + ...this.state, + certTemplateId: collector.certTemplateId as string + }) if (errLength > 0) { this.setState({ showError: true @@ -309,12 +315,16 @@ class CollectorFormComponent extends React.Component { } else { this.props.goToVerifyCollector( declarationId, - event, + collector.certTemplateId as string, collector.type as string ) } } else { - this.props.goToPrintCertificate(declarationId, event, nextGroup) + this.props.goToPrintCertificate( + declarationId, + collector.certTemplateId as string, + nextGroup + ) } } @@ -333,9 +343,12 @@ class CollectorFormComponent extends React.Component { offlineCountryConfiguration ) ) { - this.props.goToReviewCertificate(declarationId, event) + this.props.goToReviewCertificate(declarationId, this.state.certTemplateId) } else { - this.props.goToPrintCertificatePayment(declarationId, event) + this.props.goToPrintCertificatePayment( + declarationId, + this.state.certTemplateId + ) } } From 4821efe9d6c77d4a1f388c8b69087e11cdb78fec Mon Sep 17 00:00:00 2001 From: tareq89 Date: Mon, 7 Oct 2024 12:23:41 +0600 Subject: [PATCH 08/13] fixing test --- packages/client/src/setupTests.ts | 1 - packages/client/src/tests/util.tsx | 51 +++++++++++++++++++----------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/packages/client/src/setupTests.ts b/packages/client/src/setupTests.ts index 9e2c276cdc..6f03e243d3 100644 --- a/packages/client/src/setupTests.ts +++ b/packages/client/src/setupTests.ts @@ -201,7 +201,6 @@ vi.doMock( languages: mockOfflineData.languages }), loadConfig: () => Promise.resolve(mockConfigResponse), - loadCertificateConfiguration: () => Promise.resolve({}), loadConfigAnonymousUser: () => Promise.resolve(mockConfigResponse), loadForms: () => Promise.resolve(mockOfflineData.forms.forms), importConditionals: () => Promise.resolve({}), diff --git a/packages/client/src/tests/util.tsx b/packages/client/src/tests/util.tsx index b74eeb33b5..c4a81b9562 100644 --- a/packages/client/src/tests/util.tsx +++ b/packages/client/src/tests/util.tsx @@ -802,26 +802,41 @@ export const mockDeathRegistrationSectionData = { const mockFetchCertificatesTemplatesDefinition = [ { - id: '12313546', - event: Event.Birth, - status: 'ACTIVE', - svgCode: - '\n\n\n\n{registrarName}
({role}) \n \n \nThis event was registered at {registrationLocation} \n{eventDate} \nDied on \nPlace of death \n \n{placeOfDeath} \n{informantName} \nThis is to certify that \n{registrationNumber} \nDeath Registration No \nDate of issuance of certificate: {certificateDate}\n\n\n\n\n\n\n\n\n\n\n', - svgDateCreated: '1640696680593', - svgDateUpdated: '1644326332088', - svgFilename: 'oCRVS_DefaultZambia_Death_v1.svg', - user: '61d42359f1a2c25ea01beb4b' + id: 'birth.certificate', + event: 'birth', + label: { + id: 'certificates.birth.certificate', + defaultMessage: 'Birth Certificate', + description: 'The label for a birth certificate' + }, + svgUrl: '/api/countryconfig/certificates/birth-certificate.svg', + fonts: { + 'Noto Sans': { + normal: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bold: '/api/countryconfig/fonts/NotoSans-Bold.ttf', + italics: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bolditalics: '/api/countryconfig/fonts/NotoSans-Regular.ttf' + } + } }, { - id: '25313546', - event: Event.Death, - status: 'ACTIVE', - svgCode: - '\n\n\n\n{registrarName}
({role}) \n \n \nThis event was registered at {registrationLocation} \n{eventDate} \nWas born on \nPlace of birth \n \n{placeOfBirth} \n{informantName} \nThis is to certify that \n{registrationNumber} \nBirth Registration No \nDate of issuance of certificate: {certificateDate}\n\n\n\n\n\n\n\n\n\n\n', - svgDateCreated: '1640696804785', - svgDateUpdated: '1643885502999', - svgFilename: 'oCRVS_DefaultZambia_Birth_v1.svg', - user: '61d42359f1a2c25ea01beb4b' + id: 'birth.certificate.copy', + event: 'birth', + label: { + id: 'certificates.birth.certificate.copy', + defaultMessage: 'Birth Certificate certified copy', + description: 'The label for a birth certificate' + }, + svgUrl: + '/api/countryconfig/certificates/birth-certificate-certified-copy.svg', + fonts: { + 'Noto Sans': { + normal: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bold: '/api/countryconfig/fonts/NotoSans-Bold.ttf', + italics: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bolditalics: '/api/countryconfig/fonts/NotoSans-Regular.ttf' + } + } } ] From 9e52409955a686e2eb1ba9c194bea36258bf78cc Mon Sep 17 00:00:00 2001 From: tareq89 Date: Mon, 7 Oct 2024 15:35:20 +0600 Subject: [PATCH 09/13] added missing variable --- .../config/src/handlers/application/applicationConfigHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/config/src/handlers/application/applicationConfigHandler.ts b/packages/config/src/handlers/application/applicationConfigHandler.ts index 669644e5a2..ffa436415c 100644 --- a/packages/config/src/handlers/application/applicationConfigHandler.ts +++ b/packages/config/src/handlers/application/applicationConfigHandler.ts @@ -70,7 +70,7 @@ async function getCertificatesConfig( scope.includes(RouteScope.VALIDATE) || scope.includes(RouteScope.NATLSYSADMIN)) ) { - const url = new URL(`/certificates`, COUNTRY_CONFIG_URL).toString() + const url = new URL(`/certificates`, env.COUNTRY_CONFIG_URL).toString() const res = await fetch(url, { headers: { Authorization: `Bearer ${authToken}` } From bbca65e6e4a7bebdb21671945c645645f2c22f69 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Mon, 7 Oct 2024 18:48:18 +0600 Subject: [PATCH 10/13] payment and verify-collector test fixed --- packages/client/src/tests/templates.json | 65 +++++++++++++++---- packages/client/src/tests/util.tsx | 18 +++++ .../views/PrintCertificate/Payment.test.tsx | 36 ++-------- .../src/views/PrintCertificate/Payment.tsx | 8 ++- .../PrintCertificate/VerifyCollector.test.tsx | 10 +-- .../PrintCertificate/VerifyCollector.tsx | 2 +- 6 files changed, 86 insertions(+), 53 deletions(-) diff --git a/packages/client/src/tests/templates.json b/packages/client/src/tests/templates.json index bc7f832fae..32e4e6f23a 100644 --- a/packages/client/src/tests/templates.json +++ b/packages/client/src/tests/templates.json @@ -7,19 +7,60 @@ "bolditalics": "NotoSans-Regular.ttf" } }, - "certificates": { - "birth": { - "definition": " {eventDate} Was born on Place of birth {placeOfBirth} {informantName} This is to certify that {registrationNumber} Birth Registration No Date of issuance of certificate:{certificateDate} {registrarName} ({role}) This event was registered at{registrationLocation} ", - "fileName": "farajaland-birth-certificate-v3.svg" + "certificates": [ + { + "id": "birth.certificate", + "event": "birth", + "label": { + "id": "certificates.birth.certificate", + "defaultMessage": "Birth Certificate", + "description": "The label for a birth certificate" + }, + "svgUrl": "/api/countryconfig/certificates/birth-certificate.svg", + "fonts": { + "Noto Sans": { + "normal": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bold": "/api/countryconfig/fonts/NotoSans-Bold.ttf", + "italics": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bolditalics": "/api/countryconfig/fonts/NotoSans-Regular.ttf" + } + } }, - "death": { - "definition": " {eventDate} Died on Place of death {placeOfDeath} {informantName} This is to certify that {registrationNumber} Death Registration No Date of issuance of certificate:{certificateDate} {registrarName} ({role}) This event was registered at{registrationLocation} ", - "fileName": "farajaland-death-certificate-v3.svg" + { + "id": "birth.certificate.copy", + "event": "birth", + "label": { + "id": "certificates.birth.certificate.copy", + "defaultMessage": "Birth Certificate certified copy", + "description": "The label for a birth certificate" + }, + "svgUrl": "/api/countryconfig/certificates/birth-certificate-certified-copy.svg", + "fonts": { + "Noto Sans": { + "normal": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bold": "/api/countryconfig/fonts/NotoSans-Bold.ttf", + "italics": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bolditalics": "/api/countryconfig/fonts/NotoSans-Regular.ttf" + } + } }, - "marriage": { - "definition": " {eventDate} Died on Place of death {placeOfDeath} {informantName} This is to certify that {registrationNumber} Death Registration No Date of issuance of certificate:{certificateDate} {registrarName} ({role}) This event was registered at{registrationLocation} ", - "fileName": "farajaland-marriage-certificate-v1.svg", - "lastModifiedDate": "1678106545001" + { + "id": "death-certificate", + "event": "death", + "label": { + "id": "certificates.death.certificate", + "defaultMessage": "Death Certificate", + "description": "The label for a death certificate" + }, + "svgUrl": "/api/countryconfig/certificates/death-certificate.svg", + "fonts": { + "Noto Sans": { + "normal": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bold": "/api/countryconfig/fonts/NotoSans-Bold.ttf", + "italics": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bolditalics": "/api/countryconfig/fonts/NotoSans-Regular.ttf" + } + } } - } + ] } diff --git a/packages/client/src/tests/util.tsx b/packages/client/src/tests/util.tsx index c4a81b9562..7b9a08cd51 100644 --- a/packages/client/src/tests/util.tsx +++ b/packages/client/src/tests/util.tsx @@ -837,6 +837,24 @@ const mockFetchCertificatesTemplatesDefinition = [ bolditalics: '/api/countryconfig/fonts/NotoSans-Regular.ttf' } } + }, + { + id: 'death-certificate', + event: 'death', + label: { + id: 'certificates.death.certificate', + defaultMessage: 'Death Certificate', + description: 'The label for a death certificate' + }, + svgUrl: '/api/countryconfig/certificates/death-certificate.svg', + fonts: { + 'Noto Sans': { + normal: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bold: '/api/countryconfig/fonts/NotoSans-Bold.ttf', + italics: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bolditalics: '/api/countryconfig/fonts/NotoSans-Regular.ttf' + } + } } ] diff --git a/packages/client/src/views/PrintCertificate/Payment.test.tsx b/packages/client/src/views/PrintCertificate/Payment.test.tsx index 9896a006a7..6397056511 100644 --- a/packages/client/src/views/PrintCertificate/Payment.test.tsx +++ b/packages/client/src/views/PrintCertificate/Payment.test.tsx @@ -82,7 +82,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - eventType: Event.Birth + certTemplateId: 'birth.certificate.copy' }, isExact: true, path: '', @@ -103,43 +103,15 @@ describe('verify collector tests', () => { testComponent.find('#Continue').hostNodes().simulate('click') }) - /* - - // Commenting out this test because receipt templates are not currently configurable - - it('print payment receipt', async () => { - const printMoneyReceiptSpy = vi.spyOn(PDFUtils, 'printMoneyReceipt') - const testComponent = await createTestComponent( - , - { store, history } - ) - - testComponent.find('#print-receipt').hostNodes().simulate('click') - - expect(printMoneyReceiptSpy).toBeCalled() - })*/ - it('invalid declaration id', async () => { - await createTestComponent( + const payments = await createTestComponent( { match={{ params: { registrationId: 'mockDeath1234', - eventType: Event.Death + certTemplateId: 'death-certificate' }, isExact: true, path: '', diff --git a/packages/client/src/views/PrintCertificate/Payment.tsx b/packages/client/src/views/PrintCertificate/Payment.tsx index ba98cd727c..679d61f945 100644 --- a/packages/client/src/views/PrintCertificate/Payment.tsx +++ b/packages/client/src/views/PrintCertificate/Payment.tsx @@ -183,9 +183,11 @@ const PaymentComponent = ({ } const getEvent = (state: IStoreState, certTemplateId: string | undefined) => { - return state.offline.offlineData.templates?.certificates?.find( - (x) => x.id === certTemplateId - )?.event + return ( + state.offline.offlineData.templates?.certificates?.find( + (x) => x.id === certTemplateId + )?.event || '' + ) } function mapStatetoProps( diff --git a/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx b/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx index 30d7de84a8..255ba4ec4f 100644 --- a/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx +++ b/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx @@ -67,7 +67,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - eventType: Event.Birth, + certTemplateId: 'birth.certificate.copy', collector: 'mother' }, isExact: true, @@ -89,7 +89,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - eventType: Event.Birth, + certTemplateId: 'birth.certificate.copy', collector: 'mother' }, isExact: true, @@ -128,7 +128,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockDeath1234', - eventType: Event.Death, + certTemplateId: 'death.certificate', collector: 'informant' }, isExact: true, @@ -168,7 +168,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - eventType: Event.Death, + certTemplateId: 'birth.certificate.copy', collector: 'father' }, isExact: true, @@ -251,7 +251,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockDeath1234', - eventType: Event.Death, + certTemplateId: 'death.certificate', collector: 'informant' }, isExact: true, diff --git a/packages/client/src/views/PrintCertificate/VerifyCollector.tsx b/packages/client/src/views/PrintCertificate/VerifyCollector.tsx index 3af807adcb..60a87577da 100644 --- a/packages/client/src/views/PrintCertificate/VerifyCollector.tsx +++ b/packages/client/src/views/PrintCertificate/VerifyCollector.tsx @@ -51,7 +51,7 @@ import { getUserDetails } from '@client/profile/profileSelectors' interface IMatchParams { registrationId: string - certTemplateId: Event + certTemplateId: string collector: string } From f2835ac57d5c56c6315bfb245ae06d7c978405b1 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Tue, 8 Oct 2024 15:05:33 +0600 Subject: [PATCH 11/13] VerifyCollector, ReviewCertificate and Payment test cases adjusted for certified copies changes --- packages/client/src/declarations/selectors.ts | 16 +- packages/client/src/tests/templates.json | 22 ++- packages/client/src/tests/util.tsx | 24 ++- .../views/PrintCertificate/Payment.test.tsx | 4 +- .../ReviewCertificateAction.test.tsx | 154 +++++++++++------- .../PrintCertificate/VerifyCollector.test.tsx | 10 +- .../usePrintableCertificate.ts | 11 +- 7 files changed, 160 insertions(+), 81 deletions(-) diff --git a/packages/client/src/declarations/selectors.ts b/packages/client/src/declarations/selectors.ts index f8369701a7..77d77eeb36 100644 --- a/packages/client/src/declarations/selectors.ts +++ b/packages/client/src/declarations/selectors.ts @@ -12,8 +12,9 @@ import { IDeclaration, IDeclarationsState } from '@client/declarations/index' import { IStoreState } from '@client/store' import { useSelector } from 'react-redux' -export const getDraftsState = (store: IStoreState): IDeclarationsState => - store.declarationsState +export const getDraftsState = (store: IStoreState): IDeclarationsState => { + return store.declarationsState +} function getKey( store: IStoreState, @@ -29,11 +30,16 @@ export const getInitialDeclarationsLoaded = ( export const selectDeclaration = (declarationId: string) => - (store: IStoreState) => - getKey(store, 'declarations').find(({ id }) => declarationId === id) as T + (store: IStoreState) => { + const bar = getKey(store, 'declarations').find( + ({ id }) => declarationId === id + ) as T + return bar + } export const useDeclaration = ( declarationId: string ) => { - return useSelector(selectDeclaration(declarationId)) + const foo = useSelector(selectDeclaration(declarationId)) + return foo } diff --git a/packages/client/src/tests/templates.json b/packages/client/src/tests/templates.json index 32e4e6f23a..6f9b93b0e9 100644 --- a/packages/client/src/tests/templates.json +++ b/packages/client/src/tests/templates.json @@ -9,7 +9,7 @@ }, "certificates": [ { - "id": "birth.certificate", + "id": "birth-certificate", "event": "birth", "label": { "id": "certificates.birth.certificate", @@ -27,7 +27,7 @@ } }, { - "id": "birth.certificate.copy", + "id": "birth-certificate-copy", "event": "birth", "label": { "id": "certificates.birth.certificate.copy", @@ -61,6 +61,24 @@ "bolditalics": "/api/countryconfig/fonts/NotoSans-Regular.ttf" } } + }, + { + "id": "marriage-certificate", + "event": "marriage", + "label": { + "id": "certificates.marriage.certificate", + "defaultMessage": "Marriage Certificate", + "description": "The label for a marriage certificate" + }, + "svgUrl": "/api/countryconfig/certificates/marriage-certificate.svg", + "fonts": { + "Noto Sans": { + "normal": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bold": "/api/countryconfig/fonts/NotoSans-Bold.ttf", + "italics": "/api/countryconfig/fonts/NotoSans-Regular.ttf", + "bolditalics": "/api/countryconfig/fonts/NotoSans-Regular.ttf" + } + } } ] } diff --git a/packages/client/src/tests/util.tsx b/packages/client/src/tests/util.tsx index 7b9a08cd51..222ba3e9b5 100644 --- a/packages/client/src/tests/util.tsx +++ b/packages/client/src/tests/util.tsx @@ -802,7 +802,7 @@ export const mockDeathRegistrationSectionData = { const mockFetchCertificatesTemplatesDefinition = [ { - id: 'birth.certificate', + id: 'birth-certificate', event: 'birth', label: { id: 'certificates.birth.certificate', @@ -820,10 +820,10 @@ const mockFetchCertificatesTemplatesDefinition = [ } }, { - id: 'birth.certificate.copy', + id: 'birth-certificate-copy', event: 'birth', label: { - id: 'certificates.birth.certificate.copy', + id: 'certificates.birth-certificate-copy', defaultMessage: 'Birth Certificate certified copy', description: 'The label for a birth certificate' }, @@ -855,6 +855,24 @@ const mockFetchCertificatesTemplatesDefinition = [ bolditalics: '/api/countryconfig/fonts/NotoSans-Regular.ttf' } } + }, + { + id: 'marriage-certificate', + event: 'marriage', + label: { + id: 'certificates.marriage.certificate', + defaultMessage: 'Marriage Certificate', + description: 'The label for a marriage certificate' + }, + svgUrl: '/api/countryconfig/certificates/marriage-certificate.svg', + fonts: { + 'Noto Sans': { + normal: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bold: '/api/countryconfig/fonts/NotoSans-Bold.ttf', + italics: '/api/countryconfig/fonts/NotoSans-Regular.ttf', + bolditalics: '/api/countryconfig/fonts/NotoSans-Regular.ttf' + } + } } ] diff --git a/packages/client/src/views/PrintCertificate/Payment.test.tsx b/packages/client/src/views/PrintCertificate/Payment.test.tsx index 6397056511..a4d2818636 100644 --- a/packages/client/src/views/PrintCertificate/Payment.test.tsx +++ b/packages/client/src/views/PrintCertificate/Payment.test.tsx @@ -82,7 +82,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - certTemplateId: 'birth.certificate.copy' + certTemplateId: 'birth-certificate-copy' }, isExact: true, path: '', @@ -111,7 +111,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth', - certTemplateId: 'birth.certificate.copy' + certTemplateId: 'birth-certificate-copy' }, isExact: true, path: '', diff --git a/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx b/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx index dd723b7643..131e26f08d 100644 --- a/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx +++ b/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { Mock } from 'vitest' +import { vi, Mock } from 'vitest' import * as React from 'react' import { createStore } from '@client/store' import { storeDeclaration, IDeclaration } from '@client/declarations' @@ -45,35 +45,74 @@ const deathDeclaration = { event: Event.Death } +const mockBirthDeclaration = { + id: 'mockBirth1234', + data: { + ...mockDeclarationData, + history: [ + { + date: '2022-03-21T08:16:24.467+00:00', + regStatus: 'REGISTERED', + reinstated: false + } + ] as unknown as IFormSectionData + }, + event: Event.Birth +} +const mockMarriageDeclaration = { + id: 'mockMarriage1234', + data: { + ...mockMarriageDeclarationData, + history: [ + { + date: '2022-03-21T08:16:24.467+00:00', + regStatus: 'REGISTERED', + reinstated: false + } + ] + }, + event: Event.Marriage +} + describe('when user wants to review death certificate', () => { - it('displays the "Confirm & Print" button', async () => { + let component: ReactWrapper<{}, {}> + beforeEach(async () => { + const mockSvgTemplate = 'Sample Certificate' + global.fetch = vi.fn().mockImplementation((url) => { + return Promise.resolve({ + text: vi.fn().mockResolvedValue(mockSvgTemplate) + }) + }) const { history, match } = createRouterProps( '/', { isNavigatedInsideApp: false }, { matchParams: { registrationId: 'mockDeath1234', - eventType: Event.Death + certTemplateId: 'death-certificate' } } ) ;(useParams as Mock).mockImplementation(() => match.params) - - const { store } = createStore() - + const { store } = createStore(history) loginAsFieldAgent(store) + const clonedMockDeathDeclarationData = cloneDeep(deathDeclaration) + await flushPromises() + // @ts-ignore + store.dispatch(storeDeclaration(clonedMockDeathDeclarationData)) - const component = await createTestComponent(, { + component = await createTestComponent(, { store, history }) - - // @ts-ignore - store.dispatch(storeDeclaration(deathDeclaration)) + await flushPromises() component.update() + }) - const confirmBtn = component.find('#confirm-print') - const confirmBtnExist = !!confirmBtn.hostNodes().length + it('displays the "Confirm & Print" button', async () => { + const confirmBtnExist = !!( + await waitForElement(component, '#confirm-print') + ).hostNodes().length expect(confirmBtnExist).toBe(true) }) }) @@ -118,7 +157,7 @@ describe('back button behavior tests of review certificate action', () => { const birthDeclaration = { id: 'asdhdqe2472487jsdfsdf', data: mockBirthDeclarationData, - event: Event.Birth + certTemplateId: 'birth-certificate-copy' } store.dispatch( // @ts-ignore @@ -153,7 +192,7 @@ describe('back button behavior tests of review certificate action', () => { storeDeclaration({ id: 'asdhdqe2472487jsdfsdf', data: mockBirthDeclarationData, - event: Event.Birth + certTemplateId: 'birth-certificate-copy' } as IDeclaration) ) component = await createTestComponent(, { @@ -169,45 +208,31 @@ describe('back button behavior tests of review certificate action', () => { describe('when user wants to review birth certificate', () => { let component: ReactWrapper<{}, {}> - beforeEach(async () => { + const mockSvgTemplate = 'Sample Certificate' + global.fetch = vi.fn().mockImplementation((url) => { + return Promise.resolve({ + text: vi.fn().mockResolvedValue(mockSvgTemplate) + }) + }) const { history, match } = createRouterProps( '/', { isNavigatedInsideApp: false }, { matchParams: { - registrationId: 'asdhdqe2472487jsdfsdf', - eventType: Event.Birth + registrationId: 'mockBirth1234', + certTemplateId: 'birth-certificate' } } ) ;(useParams as Mock).mockImplementation(() => match.params) const { store } = createStore(history) - - const mockBirthDeclarationData = cloneDeep(mockDeclarationData) - mockBirthDeclarationData.registration.certificates[0] = { - collector: { - type: 'PRINT_IN_ADVANCE' - } - } loginAsFieldAgent(store) await flushPromises() - store.dispatch( - storeDeclaration({ - id: 'asdhdqe2472487jsdfsdf', - data: { - ...mockBirthDeclarationData, - history: [ - { - date: '2022-03-21T08:16:24.467+00:00', - regStatus: 'REGISTERED', - reinstated: false - } - ] as unknown as IFormSectionData - }, - event: Event.Birth - }) - ) + + const clonedMockBirthDeclaration = cloneDeep(mockBirthDeclaration) + // @ts-ignore + store.dispatch(storeDeclaration(clonedMockBirthDeclaration)) component = await createTestComponent(, { store, @@ -216,20 +241,18 @@ describe('when user wants to review birth certificate', () => { await flushPromises() component.update() }) - - it('displays have the Continue and print Button', () => { - const confirmBtnExist = !!component.find('#confirm-print').hostNodes() - .length + it('displays have the Continue and print Button', async () => { + const confirmBtn = await waitForElement(component, '#confirm-print') + const confirmBtnExist = !!confirmBtn.hostNodes().length expect(confirmBtnExist).toBe(true) }) - it('shows the Confirm Print Modal', () => { - const confirmBtn = component.find('#confirm-print').hostNodes() - confirmBtn.simulate('click') + it('shows the Confirm Print Modal', async () => { + const confirmBtn = await waitForElement(component, '#confirm-print') + confirmBtn.hostNodes().simulate('click') component.update() - const modalIsDisplayed = !!component - .find('#confirm-print-modal') - .hostNodes().length + const modal = await waitForElement(component, '#confirm-print-modal') + const modalIsDisplayed = !!modal.hostNodes().length expect(modalIsDisplayed).toBe(true) }) @@ -245,19 +268,29 @@ describe('when user wants to review birth certificate', () => { expect(modalIsClosed).toBe(false) }) + + afterAll(() => { + flushPromises() + }) }) describe('when user wants to review marriage certificate', () => { let component: ReactWrapper<{}, {}> beforeEach(async () => { + const mockSvgTemplate = 'Sample Certificate' + global.fetch = vi.fn().mockImplementation((url) => { + return Promise.resolve({ + text: vi.fn().mockResolvedValue(mockSvgTemplate) + }) + }) const { history, match } = createRouterProps( '/', { isNavigatedInsideApp: false }, { matchParams: { registrationId: '1234896128934719', - eventType: Event.Birth + certTemplateId: 'marriage-certificate' } } ) @@ -293,19 +326,22 @@ describe('when user wants to review marriage certificate', () => { component.update() }) - it('displays have the Continue and print Button', () => { - const confirmBtnExist = !!component.find('#confirm-print').hostNodes() - .length + it('displays have the Continue and print Button toot', async () => { + const confirmBtnExist = !!( + await waitForElement(component, '#confirm-print') + ).hostNodes().length expect(confirmBtnExist).toBe(true) }) - it('shows the Confirm Print Modal', () => { - const confirmBtn = component.find('#confirm-print').hostNodes() + it('shows the Confirm Print Modal', async () => { + const confirmBtn = ( + await waitForElement(component, '#confirm-print') + ).hostNodes() confirmBtn.simulate('click') component.update() - const modalIsDisplayed = !!component - .find('#confirm-print-modal') - .hostNodes().length + const modalIsDisplayed = !!( + await waitForElement(component, '#confirm-print-modal') + ).hostNodes().length expect(modalIsDisplayed).toBe(true) }) diff --git a/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx b/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx index 255ba4ec4f..e5ccd9b186 100644 --- a/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx +++ b/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx @@ -67,7 +67,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - certTemplateId: 'birth.certificate.copy', + certTemplateId: 'birth-certificate-copy', collector: 'mother' }, isExact: true, @@ -89,7 +89,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - certTemplateId: 'birth.certificate.copy', + certTemplateId: 'birth-certificate-copy', collector: 'mother' }, isExact: true, @@ -128,7 +128,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockDeath1234', - certTemplateId: 'death.certificate', + certTemplateId: 'death-certificate', collector: 'informant' }, isExact: true, @@ -168,7 +168,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockBirth1234', - certTemplateId: 'birth.certificate.copy', + certTemplateId: 'birth-certificate-copy', collector: 'father' }, isExact: true, @@ -251,7 +251,7 @@ describe('verify collector tests', () => { match={{ params: { registrationId: 'mockDeath1234', - certTemplateId: 'death.certificate', + certTemplateId: 'death-certificate', collector: 'informant' }, isExact: true, diff --git a/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts b/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts index 27787c0b35..1e238c0fa3 100644 --- a/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts +++ b/packages/client/src/views/PrintCertificate/usePrintableCertificate.ts @@ -134,11 +134,12 @@ export const usePrintableCertificate = () => { useEffect(() => { const certificateUrl = - declaration && - offlineData.templates.certificates?.find((x) => x.id === certTemplateId) - ?.svgUrl + (declaration && + offlineData.templates.certificates?.find((x) => x.id === certTemplateId) + ?.svgUrl) || + '' - if (certificateUrl) { + if (certificateUrl && declaration) { fetch(certificateUrl) .then((res) => res.text()) .then((certificateTemplate) => { @@ -153,7 +154,7 @@ export const usePrintableCertificate = () => { }) } // eslint-disable-next-line - }, []) + }, [declaration]) const handleCertify = async () => { if (!declaration || !certificateConfig) { From b0b234b50f965d1ad3249195e5a441ee9731c21a Mon Sep 17 00:00:00 2001 From: tareq89 Date: Wed, 9 Oct 2024 06:49:42 +0600 Subject: [PATCH 12/13] CollectorForm test fixed for certified copies --- .../collectorForm/CollectorForm.test.tsx | 14 +++++++------- .../collectorForm/CollectorForm.tsx | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.test.tsx b/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.test.tsx index 32b2dbf018..c2325c3583 100644 --- a/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.test.tsx +++ b/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.test.tsx @@ -229,7 +229,7 @@ describe('Certificate collector test for a birth registration without father det }) component.update() expect(history.location.pathname).toBe( - '/print/check/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth/father' + '/print/check/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth-certificate/father' ) }) @@ -270,7 +270,7 @@ describe('Certificate collector test for a birth registration without father det }) component.update() expect(history.location.pathname).toBe( - '/cert/collector/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth/otherCertCollector' + '/cert/collector/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth-certificate/otherCertCollector' ) }) }) @@ -387,7 +387,7 @@ describe('Certificate collector test for a birth registration without father det }) it('takes the user to affedavit view', async () => { expect(history.location.pathname).toBe( - '/cert/collector/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth/affidavit' + '/cert/collector/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth-certificate/affidavit' ) }) @@ -439,7 +439,7 @@ describe('Certificate collector test for a birth registration without father det component.find('#submit_confirm').hostNodes().simulate('click') expect(history.location.pathname).toBe( - '/print/payment/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth' + '/print/payment/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth-certificate' ) }) @@ -464,7 +464,7 @@ describe('Certificate collector test for a birth registration without father det ).toHaveLength(1) component.find('#submit_confirm').hostNodes().simulate('click') expect(history.location.pathname).toBe( - '/review/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth' + '/review/6a5fd35d-01ec-4c37-976e-e055107a74a1/birth-certificate' ) }) @@ -575,7 +575,7 @@ describe('Certificate collector test for a death registration', () => { $confirm.hostNodes().simulate('click') expect(history.location.pathname).toBe( - '/review/16ff35e1-3f92-4db3-b812-c402e609fb00/death' + '/review/16ff35e1-3f92-4db3-b812-c402e609fb00/death-certificate' ) }) }) @@ -632,7 +632,7 @@ describe('Certificate collector test for a marriage registration', () => { $confirm.hostNodes().simulate('click') expect(history.location.pathname).toBe( - '/review/18ff35e1-3d92-4db3-b815-c4d2e609fb23/marriage' + '/review/18ff35e1-3d92-4db3-b815-c4d2e609fb23/marriage-certificate' ) }) }) diff --git a/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx b/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx index b680f0cba9..3b09790061 100644 --- a/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx +++ b/packages/client/src/views/PrintCertificate/collectorForm/CollectorForm.tsx @@ -261,7 +261,7 @@ class CollectorFormComponent extends React.Component { this.setState({ ...this.state, - certTemplateId: collector.certTemplateId as string + certTemplateId: collector?.certTemplateId as string }) if (errLength > 0) { this.setState({ @@ -310,19 +310,19 @@ class CollectorFormComponent extends React.Component { if (isCertificateForPrintInAdvance(draft)) { this.props.goToReviewCertificate( declarationId, - collector.certTemplateId as string + collector?.certTemplateId as string ) } else { this.props.goToVerifyCollector( declarationId, - collector.certTemplateId as string, + collector?.certTemplateId as string, collector.type as string ) } } else { this.props.goToPrintCertificate( declarationId, - collector.certTemplateId as string, + collector?.certTemplateId as string, nextGroup ) } From ede9e9c9eaa235c50898d5e76b2f2fd0bbf47502 Mon Sep 17 00:00:00 2001 From: tareq89 Date: Wed, 9 Oct 2024 10:29:28 +0600 Subject: [PATCH 13/13] refactor test code and lint issues --- .../views/PrintCertificate/Payment.test.tsx | 164 ++++---- .../ReviewCertificateAction.test.tsx | 390 +++++++----------- .../PrintCertificate/VerifyCollector.test.tsx | 373 ++++++++--------- .../PrintCertificate/VerifyCollector.tsx | 1 - 4 files changed, 419 insertions(+), 509 deletions(-) diff --git a/packages/client/src/views/PrintCertificate/Payment.test.tsx b/packages/client/src/views/PrintCertificate/Payment.test.tsx index a4d2818636..e404ed275d 100644 --- a/packages/client/src/views/PrintCertificate/Payment.test.tsx +++ b/packages/client/src/views/PrintCertificate/Payment.test.tsx @@ -27,75 +27,107 @@ import { vi, Mock } from 'vitest' import { WORKQUEUE_TABS } from '@client/components/interface/Navigation' import { REGISTRAR_HOME_TAB } from '@client/navigation/routes' import { formatUrl } from '@client/navigation' +import { IFormSectionData } from '@client/forms' +// Mock setup const getItem = window.localStorage.getItem as Mock ;(queries.fetchUserDetails as Mock).mockReturnValue(mockUserResponse) +// Common mock data +const birthDeclaration = { + id: 'mockBirth1234', + data: { + ...mockDeclarationData, + history: [ + { + date: '2022-03-21T08:16:24.467+00:00', + regStatus: 'REGISTERED', + reinstated: false + } + ] as unknown as IFormSectionData + }, + event: Event.Birth +} + +const deathDeclaration = { + id: 'mockDeath1234', + data: { + ...mockDeathDeclarationData, + history: [ + { + date: '2022-03-21T08:16:24.467+00:00', + regStatus: 'REGISTERED', + reinstated: false + } + ] as unknown as IFormSectionData + }, + event: Event.Death +} + +// Helper function to set up test +async function setupPaymentTest({ + registrationId, + certTemplateId, + declaration, + store, + history, + mockLocation +}: { + registrationId: string + certTemplateId: string + declaration: any + store: any + history: any + mockLocation: any +}) { + store.dispatch(storeDeclaration(declaration)) + await flushPromises() + + const testComponent = await createTestComponent( + , + { store, history } + ) + + return testComponent +} + describe('verify collector tests', () => { const { store, history } = createStore() const mockLocation: any = vi.fn() - const birthDeclaration = { - id: 'mockBirth1234', - data: { - ...mockDeclarationData, - history: [ - { - date: '2022-03-21T08:16:24.467+00:00', - regStatus: 'REGISTERED', - reinstated: false - } - ] - }, - event: Event.Birth - } - - const deathDeclaration = { - id: 'mockDeath1234', - data: { - ...mockDeathDeclarationData, - history: [ - { - date: '2022-03-21T08:16:24.467+00:00', - regStatus: 'REGISTERED', - reinstated: false - } - ] - }, - event: Event.Death - } - describe('in case of birth declaration', () => { beforeAll(async () => { getItem.mockReturnValue(validToken) await store.dispatch(checkAuth()) await flushPromises() - // @ts-ignore store.dispatch(storeDeclaration(birthDeclaration)) }) - it('when mother is collector renders Payment component', async () => { - const testComponent = await createTestComponent( - , - { store, history } - ) + it('renders Payment component when mother is collector', async () => { + const testComponent = await setupPaymentTest({ + registrationId: 'mockBirth1234', + certTemplateId: 'birth-certificate-copy', + declaration: birthDeclaration, + store, + history, + mockLocation + }) expect(testComponent.find('#service').hostNodes().text()).toContain( 'Birth' ) - expect(testComponent.find('#amountDue').hostNodes().text()).toContain( '20' ) @@ -103,8 +135,8 @@ describe('verify collector tests', () => { testComponent.find('#Continue').hostNodes().simulate('click') }) - it('invalid declaration id', async () => { - const payments = await createTestComponent( + it('redirects to home on invalid declaration id', async () => { + await createTestComponent( { />, { store, history } ) + expect(history.location.pathname).toEqual( formatUrl(REGISTRAR_HOME_TAB, { tabId: WORKQUEUE_TABS.readyToPrint, @@ -129,29 +162,20 @@ describe('verify collector tests', () => { }) }) - describe('in case of death declaration renders payment component', () => { + describe('in case of death declaration renders Payment component', () => { beforeAll(() => { - // @ts-ignore store.dispatch(storeDeclaration(deathDeclaration)) }) - it('when informant is collector', async () => { - const testComponent = await createTestComponent( - , - { store, history } - ) + it('renders Payment component when informant is collector', async () => { + const testComponent = await setupPaymentTest({ + registrationId: 'mockDeath1234', + certTemplateId: 'death-certificate', + declaration: deathDeclaration, + store, + history, + mockLocation + }) expect(testComponent.find('#service').hostNodes().text()).toContain( 'Death' diff --git a/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx b/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx index 131e26f08d..9be3eb7852 100644 --- a/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx +++ b/packages/client/src/views/PrintCertificate/ReviewCertificateAction.test.tsx @@ -11,7 +11,7 @@ import { vi, Mock } from 'vitest' import * as React from 'react' import { createStore } from '@client/store' -import { storeDeclaration, IDeclaration } from '@client/declarations' +import { storeDeclaration } from '@client/declarations' import { createTestComponent, mockDeclarationData, @@ -30,25 +30,26 @@ import { waitForElement } from '@client/tests/wait-for-element' import { push } from 'connected-react-router' import { useParams } from 'react-router' -const deathDeclaration = { - id: 'mockDeath1234', +const mockSvgTemplate = 'Sample Certificate' +const birthDeclaration = { + id: 'mockBirth1234', data: { - ...mockDeathDeclarationData, + ...mockDeclarationData, history: [ { date: '2022-03-21T08:16:24.467+00:00', regStatus: 'REGISTERED', reinstated: false } - ] + ] as unknown as IFormSectionData }, - event: Event.Death + event: Event.Birth } -const mockBirthDeclaration = { - id: 'mockBirth1234', +const deathDeclaration = { + id: 'mockDeath1234', data: { - ...mockDeclarationData, + ...mockDeathDeclarationData, history: [ { date: '2022-03-21T08:16:24.467+00:00', @@ -57,9 +58,10 @@ const mockBirthDeclaration = { } ] as unknown as IFormSectionData }, - event: Event.Birth + event: Event.Death } -const mockMarriageDeclaration = { + +const marriageDeclaration = { id: 'mockMarriage1234', data: { ...mockMarriageDeclarationData, @@ -69,73 +71,158 @@ const mockMarriageDeclaration = { regStatus: 'REGISTERED', reinstated: false } - ] + ] as unknown as IFormSectionData }, event: Event.Marriage } -describe('when user wants to review death certificate', () => { +async function setupTest({ + declaration, + certTemplateId, + registrationId +}: { + declaration: any + certTemplateId: string + registrationId: string +}) { + global.fetch = vi.fn().mockImplementation(() => + Promise.resolve({ + text: vi.fn().mockResolvedValue(mockSvgTemplate) + }) + ) + + const { history, match } = createRouterProps( + '/', + { isNavigatedInsideApp: false }, + { + matchParams: { + registrationId, + certTemplateId + } + } + ) + + ;(useParams as Mock).mockImplementation(() => match.params) + + const { store } = createStore(history) + loginAsFieldAgent(store) + const clonedDeclaration = cloneDeep(declaration) + + await flushPromises() + store.dispatch(storeDeclaration(clonedDeclaration)) + + const component = await createTestComponent(, { + store, + history + }) + + await flushPromises() + component.update() + + return component +} + +describe('Review Certificate Tests', () => { let component: ReactWrapper<{}, {}> - beforeEach(async () => { - const mockSvgTemplate = 'Sample Certificate' - global.fetch = vi.fn().mockImplementation((url) => { - return Promise.resolve({ - text: vi.fn().mockResolvedValue(mockSvgTemplate) + + describe('when user wants to review death certificate', () => { + beforeEach(async () => { + component = await setupTest({ + declaration: deathDeclaration, + certTemplateId: 'death-certificate', + registrationId: 'mockDeath1234' }) }) - const { history, match } = createRouterProps( - '/', - { isNavigatedInsideApp: false }, - { - matchParams: { - registrationId: 'mockDeath1234', - certTemplateId: 'death-certificate' - } - } - ) - ;(useParams as Mock).mockImplementation(() => match.params) - const { store } = createStore(history) - loginAsFieldAgent(store) - const clonedMockDeathDeclarationData = cloneDeep(deathDeclaration) - await flushPromises() - // @ts-ignore - store.dispatch(storeDeclaration(clonedMockDeathDeclarationData)) - component = await createTestComponent(, { - store, - history + it('displays the "Confirm & Print" button', async () => { + const confirmBtnExist = !!( + await waitForElement(component, '#confirm-print') + ).hostNodes().length + expect(confirmBtnExist).toBe(true) + }) + }) + + describe('when user wants to review birth certificate', () => { + beforeEach(async () => { + component = await setupTest({ + declaration: birthDeclaration, + certTemplateId: 'birth-certificate', + registrationId: 'mockBirth1234' + }) + }) + + it('displays the "Confirm & Print" button', async () => { + const confirmBtnExist = !!( + await waitForElement(component, '#confirm-print') + ).hostNodes().length + expect(confirmBtnExist).toBe(true) + }) + + it('shows the Confirm Print Modal', async () => { + const confirmBtn = await waitForElement(component, '#confirm-print') + confirmBtn.hostNodes().simulate('click') + component.update() + const modal = await waitForElement(component, '#confirm-print-modal') + const modalIsDisplayed = !!modal.hostNodes().length + expect(modalIsDisplayed).toBe(true) + }) + + it('closes the modal on clicking the print the button', async () => { + const confirmBtn = await waitForElement(component, '#confirm-print') + confirmBtn.hostNodes().simulate('click') + component.update() + component.find('#print-certificate').hostNodes().simulate('click') + component.update() + + const modalIsClosed = !!component.find('#confirm-print-modal').hostNodes() + .length + expect(modalIsClosed).toBe(false) }) - await flushPromises() - component.update() }) - it('displays the "Confirm & Print" button', async () => { - const confirmBtnExist = !!( - await waitForElement(component, '#confirm-print') - ).hostNodes().length - expect(confirmBtnExist).toBe(true) + describe('when user wants to review marriage certificate', () => { + beforeEach(async () => { + component = await setupTest({ + declaration: marriageDeclaration, + certTemplateId: 'marriage-certificate', + registrationId: 'mockMarriage1234' + }) + }) + + it('displays the "Confirm & Print" button', async () => { + const confirmBtnExist = !!( + await waitForElement(component, '#confirm-print') + ).hostNodes().length + expect(confirmBtnExist).toBe(true) + }) + + it('shows the Confirm Print Modal', async () => { + const confirmBtn = await waitForElement(component, '#confirm-print') + confirmBtn.hostNodes().simulate('click') + component.update() + const modalIsDisplayed = !!( + await waitForElement(component, '#confirm-print-modal') + ).hostNodes().length + expect(modalIsDisplayed).toBe(true) + }) + + it('closes the modal on clicking the print the button', async () => { + const confirmBtn = await waitForElement(component, '#confirm-print') + confirmBtn.hostNodes().simulate('click') + component.update() + component.find('#print-certificate').hostNodes().simulate('click') + component.update() + + const modalIsClosed = !!component.find('#confirm-print-modal').hostNodes() + .length + expect(modalIsClosed).toBe(false) + }) }) }) -describe('back button behavior tests of review certificate action', () => { +describe('Back button behavior tests of review certificate action', () => { let component: ReactWrapper - const mockBirthDeclarationData = { - ...cloneDeep(mockDeclarationData), - history: [ - { - date: '2022-03-21T08:16:24.467+00:00', - regStatus: 'REGISTERED', - reinstated: false - } - ] - } - mockBirthDeclarationData.registration.certificates[0] = { - collector: { - type: 'PRINT_IN_ADVANCE' - } - } - it('takes user history back when navigated from inside app', async () => { const { history, match } = createRouterProps( '/previous-route', @@ -152,17 +239,10 @@ describe('back button behavior tests of review certificate action', () => { const { store } = createStore(history) store.dispatch(push('/new-route', { isNavigatedInsideApp: true })) - loginAsFieldAgent(store) - const birthDeclaration = { - id: 'asdhdqe2472487jsdfsdf', - data: mockBirthDeclarationData, - certTemplateId: 'birth-certificate-copy' - } - store.dispatch( - // @ts-ignore - storeDeclaration(birthDeclaration) - ) + + store.dispatch(storeDeclaration(birthDeclaration)) + component = await createTestComponent(, { store, history @@ -178,7 +258,7 @@ describe('back button behavior tests of review certificate action', () => { { isNavigatedInsideApp: false }, { matchParams: { - registrationId: 'asdhdqe2472487jsdfsdf', + registrationId: 'mockBirth1234', eventType: Event.Birth } } @@ -187,174 +267,16 @@ describe('back button behavior tests of review certificate action', () => { const { store } = createStore(history) loginAsFieldAgent(store) - store.dispatch( - // @ts-ignore - storeDeclaration({ - id: 'asdhdqe2472487jsdfsdf', - data: mockBirthDeclarationData, - certTemplateId: 'birth-certificate-copy' - } as IDeclaration) - ) - component = await createTestComponent(, { - store, - history - }) - component.find('#action_page_back_button').hostNodes().simulate('click') - await flushPromises() - expect(history.location.pathname).toContain('/registration-home/print/') - }) -}) - -describe('when user wants to review birth certificate', () => { - let component: ReactWrapper<{}, {}> - beforeEach(async () => { - const mockSvgTemplate = 'Sample Certificate' - global.fetch = vi.fn().mockImplementation((url) => { - return Promise.resolve({ - text: vi.fn().mockResolvedValue(mockSvgTemplate) - }) - }) - const { history, match } = createRouterProps( - '/', - { isNavigatedInsideApp: false }, - { - matchParams: { - registrationId: 'mockBirth1234', - certTemplateId: 'birth-certificate' - } - } - ) - ;(useParams as Mock).mockImplementation(() => match.params) - const { store } = createStore(history) - loginAsFieldAgent(store) - await flushPromises() - - const clonedMockBirthDeclaration = cloneDeep(mockBirthDeclaration) - // @ts-ignore - store.dispatch(storeDeclaration(clonedMockBirthDeclaration)) + store.dispatch(storeDeclaration(birthDeclaration)) component = await createTestComponent(, { store, history }) - await flushPromises() - component.update() - }) - it('displays have the Continue and print Button', async () => { - const confirmBtn = await waitForElement(component, '#confirm-print') - const confirmBtnExist = !!confirmBtn.hostNodes().length - expect(confirmBtnExist).toBe(true) - }) - it('shows the Confirm Print Modal', async () => { - const confirmBtn = await waitForElement(component, '#confirm-print') - confirmBtn.hostNodes().simulate('click') - component.update() - const modal = await waitForElement(component, '#confirm-print-modal') - const modalIsDisplayed = !!modal.hostNodes().length - expect(modalIsDisplayed).toBe(true) - }) - - it('closes the modal on clicking the print the button', async () => { - const confirmBtn = await waitForElement(component, '#confirm-print') - confirmBtn.hostNodes().simulate('click') - component.update() - component.find('#print-certificate').hostNodes().simulate('click') - component.update() - - const modalIsClosed = !!component.find('#confirm-print-modal').hostNodes() - .length - - expect(modalIsClosed).toBe(false) - }) - - afterAll(() => { - flushPromises() - }) -}) - -describe('when user wants to review marriage certificate', () => { - let component: ReactWrapper<{}, {}> - - beforeEach(async () => { - const mockSvgTemplate = 'Sample Certificate' - global.fetch = vi.fn().mockImplementation((url) => { - return Promise.resolve({ - text: vi.fn().mockResolvedValue(mockSvgTemplate) - }) - }) - const { history, match } = createRouterProps( - '/', - { isNavigatedInsideApp: false }, - { - matchParams: { - registrationId: '1234896128934719', - certTemplateId: 'marriage-certificate' - } - } - ) - ;(useParams as Mock).mockImplementation(() => match.params) - const { store } = createStore(history) - - const mockMarriageData = cloneDeep(mockMarriageDeclarationData) - - loginAsFieldAgent(store) - await flushPromises() - store.dispatch( - storeDeclaration({ - id: '1234896128934719', - data: { - ...mockMarriageData, - history: [ - { - date: '2022-03-21T08:16:24.467+00:00', - regStatus: 'REGISTERED', - reinstated: false - } - ] as unknown as IFormSectionData - }, - event: Event.Marriage - }) - ) - - component = await createTestComponent(, { - store, - history - }) - await flushPromises() - component.update() - }) - - it('displays have the Continue and print Button toot', async () => { - const confirmBtnExist = !!( - await waitForElement(component, '#confirm-print') - ).hostNodes().length - expect(confirmBtnExist).toBe(true) - }) - - it('shows the Confirm Print Modal', async () => { - const confirmBtn = ( - await waitForElement(component, '#confirm-print') - ).hostNodes() - confirmBtn.simulate('click') - component.update() - const modalIsDisplayed = !!( - await waitForElement(component, '#confirm-print-modal') - ).hostNodes().length - expect(modalIsDisplayed).toBe(true) - }) - - it('closes the modal on clicking the print the button', async () => { - const confirmBtn = await waitForElement(component, '#confirm-print') - confirmBtn.hostNodes().simulate('click') - component.update() - component.find('#print-certificate').hostNodes().simulate('click') - component.update() - - const modalIsClosed = !!component.find('#confirm-print-modal').hostNodes() - .length + component.find('#action_page_back_button').hostNodes().simulate('click') - expect(modalIsClosed).toBe(false) + expect(history.location.pathname).toContain('/registration-home/print/') }) }) diff --git a/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx b/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx index e5ccd9b186..1a5c134813 100644 --- a/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx +++ b/packages/client/src/views/PrintCertificate/VerifyCollector.test.tsx @@ -13,255 +13,220 @@ import { createStore } from '@client/store' import { createTestComponent, mockDeclarationData, - mockDeathDeclarationData + mockDeathDeclarationData, + flushPromises } from '@client/tests/util' import { VerifyCollector } from './VerifyCollector' import { storeDeclaration } from '@client/declarations' import { Event } from '@client/utils/gateway' import { ReactWrapper } from 'enzyme' +// Common mock data +const birthDeclaration = { + id: 'mockBirth1234', + data: { + ...mockDeclarationData, + history: [ + { + date: '2022-03-21T08:16:24.467+00:00', + regStatus: 'REGISTERED', + reinstated: false + } + ] + }, + event: Event.Birth +} + +const deathDeclaration = { + id: 'mockDeath1234', + data: { + ...mockDeathDeclarationData, + history: [ + { + date: '2022-03-21T08:16:24.467+00:00', + regStatus: 'REGISTERED', + reinstated: false + } + ] + }, + event: Event.Death +} + +// Helper function for setting up tests +async function setupTest({ + registrationId, + certTemplateId, + collector, + declaration, + store, + history +}: { + registrationId: string + certTemplateId: string + collector: string + declaration: any + store: any + history: any +}) { + store.dispatch(storeDeclaration(declaration)) + await flushPromises() + + const testComponent = await createTestComponent( + // @ts-ignore + , + { store, history } + ) + + return testComponent +} + describe('verify collector tests', () => { const { store, history } = createStore() - const birthDeclaration = { - id: 'mockBirth1234', - data: { - ...mockDeclarationData, - history: [ - { - date: '2022-03-21T08:16:24.467+00:00', - regStatus: 'REGISTERED', - reinstated: false - } - ] - }, - event: Event.Birth - } - - const deathDeclaration = { - id: 'mockDeath1234', - data: { - ...mockDeathDeclarationData, - history: [ - { - date: '2022-03-21T08:16:24.467+00:00', - regStatus: 'REGISTERED', - reinstated: false - } - ] - }, - event: Event.Death - } - describe('in case of birth declaration', () => { + let testComponent: ReactWrapper + beforeAll(async () => { - // @ts-ignore - store.dispatch(storeDeclaration(birthDeclaration)) + testComponent = await setupTest({ + registrationId: 'mockBirth1234', + certTemplateId: 'birth-certificate-copy', + collector: 'mother', + declaration: birthDeclaration, + store, + history + }) }) - it('when mother is collector renders idVerifier component', async () => { - const testComponent = await createTestComponent( - // @ts-ignore - , - { store, history } - ) - + it('renders idVerifier component when mother is collector', () => { expect(testComponent.find('#idVerifier').hostNodes()).toHaveLength(1) }) - it('should takes user go back', async () => { - const testComponent = await createTestComponent( - // @ts-ignore - , - { store, history } - ) - + it('takes user back on clicking back button', async () => { testComponent .find('#action_page_back_button') .hostNodes() .simulate('click') - await new Promise((resolve) => { - setTimeout(resolve, 500) - }) - + await flushPromises() testComponent.update() expect(history.location.pathname).toBe('/') }) + }) - describe('when informant is collector', () => { - let testComponent: ReactWrapper - beforeAll(() => { - // @ts-ignore - store.dispatch(storeDeclaration(deathDeclaration)) - }) - beforeEach(async () => { - testComponent = await createTestComponent( - // @ts-ignore - , - { store, history } - ) - }) - - it('renders idVerifier compomnent', () => { - expect(testComponent.find('#idVerifier').hostNodes()).toHaveLength(1) - }) - - it('clicking on yes button takes user to review certificate if there is no fee', () => { - testComponent - .find('#idVerifier') - .find('#verifyPositive') - .hostNodes() - .simulate('click') + describe('when informant is collector for death declaration', () => { + let testComponent: ReactWrapper - expect(history.location.pathname).toContain('review') + beforeAll(async () => { + testComponent = await setupTest({ + registrationId: 'mockDeath1234', + certTemplateId: 'death-certificate', + collector: 'informant', + declaration: deathDeclaration, + store, + history }) + }) - describe('when father is collector', () => { - let testComponent: ReactWrapper - beforeAll(() => { - // @ts-ignore - store.dispatch(storeDeclaration(birthDeclaration)) - }) - beforeEach(async () => { - testComponent = await createTestComponent( - // @ts-ignore - , - { store, history } - ) - }) + it('renders idVerifier component', () => { + expect(testComponent.find('#idVerifier').hostNodes()).toHaveLength(1) + }) - it('clicking on send button on modal takes user to payment if there is fee', () => { - testComponent - .find('#idVerifier') - .find('#verifyNegative') - .hostNodes() - .simulate('click') + it('redirects to review page on clicking yes button with no fee', () => { + testComponent + .find('#idVerifier #verifyPositive') + .hostNodes() + .simulate('click') - testComponent.update() + expect(history.location.pathname).toContain('review') + }) + it('clicking on cancel button hides the modal', () => { + testComponent + .find('#idVerifier #verifyNegative') + .hostNodes() + .simulate('click') - testComponent - .find('#withoutVerificationPrompt') - .find('#send') - .hostNodes() - .simulate('click') + testComponent.update() + testComponent + .find('#withoutVerificationPrompt #cancel') + .hostNodes() + .simulate('click') - expect(history.location.pathname).toContain('payment') - }) - }) + testComponent.update() + expect( + testComponent.find('#withoutVerificationPrompt').hostNodes() + ).toHaveLength(0) + }) + it('shows modal on clicking no button', () => { + testComponent + .find('#idVerifier #verifyNegative') + .hostNodes() + .simulate('click') - it('clicking on no button shows up modal', () => { - testComponent - .find('#idVerifier') - .find('#verifyNegative') - .hostNodes() - .simulate('click') + testComponent.update() + expect( + testComponent.find('#withoutVerificationPrompt').hostNodes() + ).toHaveLength(1) + }) + }) - testComponent.update() + describe('when father is collector for birth declaration', () => { + let testComponent: ReactWrapper - expect( - testComponent.find('#withoutVerificationPrompt').hostNodes() - ).toHaveLength(1) + beforeAll(async () => { + testComponent = await setupTest({ + registrationId: 'mockBirth1234', + certTemplateId: 'birth-certificate-copy', + collector: 'father', + declaration: birthDeclaration, + store, + history }) + }) - it('clicking on cancel button hides the modal', () => { - testComponent - .find('#idVerifier') - .find('#verifyNegative') - .hostNodes() - .simulate('click') - - testComponent.update() - - testComponent - .find('#withoutVerificationPrompt') - .find('#cancel') - .hostNodes() - .simulate('click') + it('takes user to payment page on clicking send button when there is fee', () => { + testComponent + .find('#idVerifier #verifyNegative') + .hostNodes() + .simulate('click') - testComponent.update() + testComponent.update() + testComponent + .find('#withoutVerificationPrompt #send') + .hostNodes() + .simulate('click') - expect( - testComponent.find('#withoutVerificationPrompt').hostNodes() - ).toHaveLength(0) - }) + expect(history.location.pathname).toContain('payment') }) }) - describe('in case of death declaration renders idVerifier component', () => { - beforeAll(() => { - // @ts-ignore - store.dispatch(storeDeclaration(deathDeclaration)) - }) + describe('in case of death declaration with informant as collector', () => { + let testComponent: ReactWrapper - it('when informant is collector', async () => { - const testComponent = await createTestComponent( - // @ts-ignore - , - { store, history } - ) + beforeAll(async () => { + testComponent = await setupTest({ + registrationId: 'mockDeath1234', + certTemplateId: 'death-certificate', + collector: 'informant', + declaration: deathDeclaration, + store, + history + }) + }) + it('renders idVerifier component', () => { expect(testComponent.find('#idVerifier').hostNodes()).toHaveLength(1) }) }) diff --git a/packages/client/src/views/PrintCertificate/VerifyCollector.tsx b/packages/client/src/views/PrintCertificate/VerifyCollector.tsx index 60a87577da..9b035174c6 100644 --- a/packages/client/src/views/PrintCertificate/VerifyCollector.tsx +++ b/packages/client/src/views/PrintCertificate/VerifyCollector.tsx @@ -14,7 +14,6 @@ import { modifyDeclaration, writeDeclaration } from '@client/declarations' -import { Event } from '@client/utils/gateway' import { messages } from '@client/i18n/messages/views/certificate' import { formatUrl,