import { Injectable } from '@angular/core'; import { CLIENT_SETTINGS_SERVICE_MOCK } from '@core/mocks/client-settings.service.mock'; import { GCMockModule } from '@core/mocks/gc-module.mock'; import { ReferenceFieldAPI } from '@core/typings/api/reference-fields.typing'; import { ApplicantFormFromApi, ApplicationForUi, ApplicationFromApi, ApplicationFromPaginated, BulkApplicationDetail, Nominee } from '@core/typings/application.typing'; import { UserTypes } from '@core/typings/client-user.typing'; import { BulkCollaboratorResponse, Collaborator } from '@core/typings/collaboration.typing'; import { NonprofitAdditionalDataApi } from '@core/typings/organization.typing'; import { ApplicantInfoForPDF, ApplicationInfoForPDF, FileUploadForPDF, TableCsvForPdf } from '@core/typings/pdf.typing'; import { ProgramApplicantType, ProgramDetailFromApi } from '@core/typings/program.typing'; import { ViewTranslationsBlank } from '@core/typings/translation.typing'; import { AdHocReportingUI } from '@core/typings/ui/ad-hoc-reporting.typing'; import { ReferenceFieldsUI } from '@core/typings/ui/reference-fields.typing'; import { WorkflowDetail, WorkflowLevel, WorkflowManagerActions } from '@core/typings/workflow.typing'; import { AwardFromApi } from '@features/awards/typings/award.typing'; import { AllFormsResponse, ApplicationFormSignature, ApplicationViewFormFromApi, AvailabilityOptions, CompletionRequirementType, FormAudience, FormDecisionTypes, FormDefinitionForUi, FormResponse, FormStatuses, FormTypes, ResponseVisibilityOptions, SubmissionMap, UserSignatureForBulk, WorkflowLevelFormApi, WorkflowLevelSubmissionForm } from '@features/configure-forms/form.typing'; import { EmployeeSSOFieldBulkFromApi, EmployeeSSOFieldsData } from '@features/employee-sso-fields/employee-sso-fields.typing'; import { Email, EmailByApplication, EmailNotificationType } from '@features/system-emails/email.typing'; import { AfterEach, BeforeEach, Spec, TestCase } from '@yourcause/test-decorators'; import { DescribeAngularService } from '@yourcause/test-decorators/angular'; import { expect, spy } from 'chai'; import { SimpleGrantsAddress } from 'frontend-common/src/typings/address.typing'; import { ApplicationDownloadService } from './application-download.service'; import { AppDownloadBulkModalResponse } from './bulk-download-application-modal/bulk-download-application-modal.component'; import { DownloadAppModalResponse } from './download-application-pdf-modal/download-application-pdf-modal.component'; @Injectable({ providedIn: 'root' }) @DescribeAngularService(ApplicationDownloadService, { imports: [ GCMockModule ], providers: [ CLIENT_SETTINGS_SERVICE_MOCK ] }) export class ApplicationDownloadServiceSpec implements Spec { defaultFormId = 7; reviewFormId = 12412; revisionId = 2; appId = 3; applicationFormId = 4; workflowId = 5; textFieldId = 6; textFieldKey = 'textFieldKey'; cdtFieldKey = 'cdtFieldKey'; cdtGuid = 'asdfasdf235'; level1 = 132; level2 = 346; textField: ReferenceFieldAPI.ReferenceFieldDisplayModel = { isEncrypted: false, isMasked: false, aggregateType: null, referenceFieldId: this.textFieldId, parentReferenceFieldId: null, formCount: 1, usedOnReports: false, createdBy: '', createDate: '', updateDate: '', updatedBy: '', customDataTableGuid: '', name: 'Text Field', description: '', type: ReferenceFieldsUI.ReferenceFieldTypes.TextField, key: this.textFieldKey, supportsMultiple: false, categoryId: 2, formAudience: FormAudience.APPLICANT, isSingleResponse: true, tableAllowsImport: false, isTableField: false, aggregateTableReferenceFieldId: null, referenceFieldTableId: null, standardComponentIsPublished: true, isStandardProductField: false, subsetCollectionType: null }; cdtField: ReferenceFieldAPI.ReferenceFieldDisplayModel = { isEncrypted: false, isMasked: false, aggregateType: null, referenceFieldId: 54, parentReferenceFieldId: null, formCount: 0, usedOnReports: false, createdBy: '', createDate: '', updatedBy: '', updateDate: '', customDataTableGuid: this.cdtGuid, name: 'Custom data table', description: '', type: ReferenceFieldsUI.ReferenceFieldTypes.CustomDataTable, key: this.cdtFieldKey, supportsMultiple: true, categoryId: null, formAudience: FormAudience.APPLICANT, isSingleResponse: true, tableAllowsImport: false, isTableField: false, aggregateTableReferenceFieldId: null, referenceFieldTableId: null, standardComponentIsPublished: true, isStandardProductField: false, subsetCollectionType: null }; formDef: FormDefinitionForUi[] = [{ logic: null, index: 0, tabName: '', components: [{ key: this.textFieldKey, type: `referenceFields-${this.textFieldKey}` }, { key: this.cdtFieldKey, type: `referenceFields-${this.cdtFieldKey}` }] }]; formResponse: FormResponse = { applicationFormId: this.applicationFormId, isDraft: true, revisionNotes: '', formComments: '', applicationFormStatusId: FormStatuses.DraftSaved, formData: {}, formDefinition: this.formDef, formRevisionId: this.revisionId, workflowLevelName: '', revisionLastSentDate: '', decision: FormDecisionTypes.Decline, dueDate: null, reviewerRecommendedFundingAmount: null }; appViewFormsFromApi: ApplicationViewFormFromApi[] = [{ audience: FormAudience.APPLICANT, formId: this.defaultFormId, formRevisionId: this.revisionId, grantManagerActionType: ResponseVisibilityOptions.VIEW_AT_ALL_WORKFLOW, responses: [this.formResponse], otherLevelResponses: [], nominationResponses: [], name: '', formType: FormTypes.REQUEST, comments: [], actionType: ResponseVisibilityOptions.VIEW_AT_ALL_WORKFLOW, completionRequirementType: CompletionRequirementType.ALL_USERS, specificNumberForCompletion: null, managersCount: 4, portalAvailabilityDetails: { portalFormAvailabilityType: AvailabilityOptions.AUTO, portalFormAvailabilityDateOption: null, portalFormAvailabilityDateOffset: '', portalFormAvailabilityDate: '', portalFormAvailabilityDynamicDateApplicationApproval: '', portalFormAvailabilityDynamicDateAwardCreation: '', portalFormAvailabilityDynamicDateApplicationSubmission: '', portalFormAvailabilityDynamicDateWorkflowLevelEntry: '' }, dueDate: '', sortOrder: 1, requireSignature: false, signatureDescription: '' }, { audience: FormAudience.MANAGER, formId: this.reviewFormId, formRevisionId: this.revisionId, grantManagerActionType: ResponseVisibilityOptions.VIEW_AT_ALL_WORKFLOW, responses: [{ ...this.formResponse, isDraft: false, applicationFormId: this.applicationFormId, applicationFormStatusId: FormStatuses.Submitted, workflowLevelId: this.level1 }], otherLevelResponses: [], nominationResponses: [], name: '', formType: FormTypes.REVIEW, comments: [], actionType: ResponseVisibilityOptions.VIEW_AT_ALL_WORKFLOW, completionRequirementType: CompletionRequirementType.ALL_USERS, specificNumberForCompletion: null, managersCount: 4, portalAvailabilityDetails: { portalFormAvailabilityType: AvailabilityOptions.AUTO, portalFormAvailabilityDateOption: null, portalFormAvailabilityDateOffset: '', portalFormAvailabilityDate: '', portalFormAvailabilityDynamicDateApplicationApproval: '', portalFormAvailabilityDynamicDateAwardCreation: '', portalFormAvailabilityDynamicDateApplicationSubmission: '', portalFormAvailabilityDynamicDateWorkflowLevelEntry: '' }, dueDate: '', sortOrder: 1, requireSignature: false, signatureDescription: '' }]; applicationForms: ApplicantFormFromApi[] = [{ updatedBy: '', updatedDate: '', createdBy: '', impersonatedBy: '', createImpersonatedBy: '', formTypeId: FormTypes.REQUEST, applicationFormId: this.applicationFormId, formId: this.defaultFormId, formRevisionId: this.revisionId, formName: 'Form name', formDescription: '', formStatus: FormStatuses.DraftSaved, statusUpdatedDate: '', statusUpdatedBy: '', formSubmittedOn: '', totalCommentsInCurrentWorkflow: 0, canRequestRevision: false, canApproveApplicaitonForm: false, canDeclineApplicationForm: false, formData: {}, statusUpdatedByClientUser: null, formComments: [], myCommentInCurrentLevel: '', programApplicantType: ProgramApplicantType.ORGS, isDefault: true, portalFormAvailabilityInfo: null, dueDate: '', submittedBy: '', isDraft: false, formDefinition: [], requireSignature: false, signatureDescription: '' }]; workflowDetail: WorkflowDetail = { levels: [{ id: this.level1, name: 'Review', subLevels: [{ id: 644, name: 'Sub Level Review' } as WorkflowLevel] } as WorkflowLevel, { id: this.level2, name: 'Complete', subLevels: [] } as WorkflowLevel], id: 80001, name: 'Simple Workflow', workflowLevelManagers: [] } as WorkflowDetail; workflowForms: WorkflowLevelFormApi[] = [{ formId: this.defaultFormId, workflowLevelId: this.level1, completionRequirementType: CompletionRequirementType.MAJORITY, specificNumberForCompletion: null, managerActionType: ResponseVisibilityOptions.VIEW_AT_ALL_WORKFLOW, portalAvailability: AvailabilityOptions.AUTO, notifyApplicantOfFormAvailability: false, grantProgramId: 264397, clientEmailTemplateId: null, portalAvailabilityDetails: { dateOption: null, dateOffset: null, date: null }, dueDateDetails: null, sortOrder: 1 }, { formId: this.reviewFormId, workflowLevelId: this.level1, completionRequirementType: CompletionRequirementType.MAJORITY, specificNumberForCompletion: null, managerActionType: ResponseVisibilityOptions.VIEW_AT_ALL_WORKFLOW, portalAvailability: AvailabilityOptions.AUTO, notifyApplicantOfFormAvailability: true, grantProgramId: 264397, clientEmailTemplateId: null, portalAvailabilityDetails: { dateOption: null, dateOffset: null, date: null }, dueDateDetails: null, sortOrder: 2 }, { formId: this.reviewFormId, workflowLevelId: this.level1, completionRequirementType: CompletionRequirementType.MAJORITY, specificNumberForCompletion: null, managerActionType: 1, portalAvailability: AvailabilityOptions.AUTO, notifyApplicantOfFormAvailability: true, grantProgramId: 264397, clientEmailTemplateId: null, portalAvailabilityDetails: { dateOption: null, dateOffset: null, date: null }, dueDateDetails: null, sortOrder: 2 }]; program = { id: 3465, name: 'program', logoUrl: 'program logo', defaultFormId: this.defaultFormId } as ProgramDetailFromApi; submissions: SubmissionMap[] = [{ workflowLevelId: null, workflowLevelName: 'Default form', forms: [{ formAudience: FormAudience.APPLICANT, formId: this.defaultFormId, formName: 'Default form', selected: true, submissions: [{ ...this.formResponse }], submittedOn: '' }] }, { workflowLevelId: null, workflowLevelName: 'Review', forms: [{ formAudience: FormAudience.MANAGER, formId: this.reviewFormId, formName: 'Review form', selected: true, submissions: [{ ...this.formResponse }], submittedOn: '' }] }]; application = { applicationId: this.appId, grantProgramCycle: { id: 235 }, organizationIdentification: '1245', organizationName: 'Org', workflowId: this.workflowId, orgPhoneNumber: '1353' } as ApplicationFromPaginated; applicants = [{ firstName: 'Tina', lastName: 'Conway' } as Collaborator ]; employeeData = { region: 'region', employeeTypeCode: 'employeeTypeCode', reportGroupName: 'reportGroupName', division: 'division', departmentName: 'departmentName' } as EmployeeSSOFieldsData; signature: ApplicationFormSignature = { userSignatureUserId: 346, applicationFormId: this.applicationFormId, userSignatureBypassed: false, userSignatureId: 1, signedDate: '', userSignatureUrl: '', signedByName: '', signedByEmail: '', ipAddress: '', signedInWorkflowLevelId: '', signedInWorkflowLevelName: '' }; applicationFromApi = { applicationId: this.appId, nonprofitGuid: this.cdtGuid, inKindItems: [] } as ApplicationFromApi; reportFieldResponse = { application: { id: this.appId } as any, form: { applicationFormId: this.applicationFormId } as any, referenceFields: [] } as AdHocReportingUI.ReportResponseRow; formIds = [ this.defaultFormId, this.reviewFormId ]; emails: Email[] = [{ subject: 'Your Application is Approved - ID: {{APPLICATION_ID}}', name: 'ApplicationApproved', description: 'Grant manager approves application', title: 'Application Approved', emailNotificationType: EmailNotificationType.ApplicationApproved, canBeDisabledByClient: true, isDisabled: false, audienceType: 1, heroImage: 'https://grantsconnectui.azureedge.net/static/okCheck.png', customizable: true, maxCopies: -1, emailUsageType: 2, nomination: false, numberOfClientCopies: 6, mergeModelType: 1, supportsCarbonCopy: true, useClientDefaultCopy: true, allowDocumentTemplates: true }, { subject: 'Your Application is Declined - ID: {{APPLICATION_ID}}', name: 'ApplicationDeclined', description: 'Grant manager declines an application', title: 'Application Declined', emailNotificationType: EmailNotificationType.ApplicationDeclined, canBeDisabledByClient: true, isDisabled: false, audienceType: 1, heroImage: 'https://grantsconnectui.azureedge.net/static/IconBell.png', customizable: true, maxCopies: -1, emailUsageType: 2, nomination: false, numberOfClientCopies: 1, mergeModelType: 1, supportsCarbonCopy: true, useClientDefaultCopy: false, allowDocumentTemplates: true }, { subject: 'Invitation to GrantsConnect', name: 'ApplicantAddedToApplication', description: 'Sent when an applicant or collaborator is added to an application', title: 'Invitation to GrantsConnect', emailNotificationType: EmailNotificationType.ApplicantAddedToApplication, canBeDisabledByClient: false, isDisabled: false, audienceType: 1, heroImage: 'https://grantsconnectui.azureedge.net/static/okCheck.png', customizable: false, maxCopies: -1, emailUsageType: 2, nomination: false, numberOfClientCopies: 0, mergeModelType: 5, supportsCarbonCopy: false, useClientDefaultCopy: false, allowDocumentTemplates: false }]; applicationEmail: EmailByApplication = { emailNotificationTypeId: EmailNotificationType.ApplicantAddedToApplication, subject: 'Invitation to GrantsConnect', body: 'body', toAddress: 'kc54861+new@gmail.com', toName: 'Tina Conway', sentTime: '2022-02-10T20:50:26.058991Z', multipleToAddresses: [], carbonCopyRecipients: [] }; downloadAppModalResponse: DownloadAppModalResponse = { submissions: this.submissions, isMasked: false, showActivityTrail: true, showEmails: true, showAwards: true }; bulkDownloadModalResponse: AppDownloadBulkModalResponse = { isMasked: true, groups: [], program: this.program, formIds: this.formIds }; nominee: Nominee = { email: 'email', firstName: 'firstName', lastName: 'lastName' }; allFormsResponse: AllFormsResponse; awards: AwardFromApi[] = [{ id: 196805, amount: 200.0000, description: '', createdDate: '2022-07-19T14:58:16.9675024Z', totalCash: 200.0000, totalUnits: 0, sendEmail: false, payments: [{ paymentId: 178692, awardId: 196805, budgetId: 253178, budgetName: '2022 In Kind', fundingSourceId: 350730, fundingSourceName: 'In Kind 2022', fundingSourceType: 2, scheduledDate: '2022-07-19T04:00:00Z', totalAmount: 200.0000, totalUnits: null, canAdjustPayment: true, notes: 'notes', status: 1, statusDate: '2022-07-19T14:58:17.0612652Z', payeeOverrideInfo: null, paymentTags: [], paymentDesignation: 'designation', paymentNumber: null, isACH: false, currencyRequested: 'USD', currencyRequestedAmountEquivalent: 200.0000, differentThanConversion: false, exchangeRate: null, exchangeRateDateTime: null, exchangeRateId: null, clearedDate: null, issuedDate: null, inKindItems: [ { itemIdentification: 'desktop123', count: 2, value: 100.0000 } ], createdDate: '2022-07-19T14:58:17.1393832Z', substatus: null, reissuedForPaymentId: null, reissuedInPaymentId: null, batchName: null, paymentType: null }], awardDate: '2022-07-19T00:00:00Z', clientLogoUrl: 'https://grantsconnectqa-cdn.azureedge.net/static-content/management/160/images/deeb36cc-9087-42c5-9a1d-a2c88b6c3e8b.png', currencyRequested: 'USD', currencyRequestedAmountEquivalent: 200.0000, exchangeRate: null, exchangeRateDateTime: null, exchangeRateId: null, awardType: 2, inKindItems: [{ itemIdentification: 'desktop123', count: 2, value: 100.0000 }], organizationEligibleForGivingStatus: null }, { id: 196804, amount: 48204.2500, description: '', createdDate: '2022-07-19T14:58:16.7174972Z', totalCash: 48204.2500, totalUnits: 0, sendEmail: false, payments: [{ paymentId: 178691, awardId: 196804, budgetId: 66763, budgetName: 'Community Grants 2018', fundingSourceId: 106379, fundingSourceName: '2018 Grants Funding', fundingSourceType: 1, scheduledDate: '2022-07-19T00:00:00Z', totalAmount: 48204.2500, totalUnits: null, canAdjustPayment: false, notes: '', status: 5, statusDate: '2022-07-19T18:46:14.634Z', payeeOverrideInfo: null, paymentTags: [], paymentDesignation: null, paymentNumber: '657857', isACH: false, currencyRequested: 'EUR', currencyRequestedAmountEquivalent: 45745.2200, differentThanConversion: false, exchangeRate: 1.053755, exchangeRateDateTime: '2022-05-08T23:54:44.17Z', exchangeRateId: 2505645, clearedDate: '2022-07-05T18:44:33Z', issuedDate: '2022-07-12T18:44:33Z', inKindItems: [], createdDate: '2022-07-19T14:58:16.8268742Z', substatus: null, reissuedForPaymentId: null, reissuedInPaymentId: null, batchName: 'Tina\'s 7/19/22 Batch', paymentType: 2 }], awardDate: '2022-07-19T00:00:00Z', clientLogoUrl: 'https://grantsconnectqa-cdn.azureedge.net/static-content/management/160/images/deeb36cc-9087-42c5-9a1d-a2c88b6c3e8b.png', currencyRequested: 'EUR', currencyRequestedAmountEquivalent: 45745.2200, exchangeRate: 1.053755, exchangeRateDateTime: '2022-05-08T23:54:44.17Z', exchangeRateId: 2505645, awardType: 1, inKindItems: [], organizationEligibleForGivingStatus: null }]; @BeforeEach() prepare (service: ApplicationDownloadService) { this.allFormsResponse = { formDetails: this.appViewFormsFromApi, applicationReferenceFieldResponses: [{ value: '2', referenceFieldKey: this.textField.key, referenceFieldId: this.textField.referenceFieldId, numericValue: 2, dateValue: '', currencyValue: null, file: null, files: [], applicationFormId: null, // This is null when it's a shared ref response across app (not single response) applicationId: this.appId }, { value: '24', referenceFieldKey: this.cdtField.key, referenceFieldId: this.cdtField.referenceFieldId, numericValue: null, dateValue: '', currencyValue: null, file: null, files: [], applicationFormId: this.applicationFormId, applicationId: this.appId }, { value: '25', referenceFieldKey: this.cdtField.key, referenceFieldId: this.cdtField.referenceFieldId, numericValue: null, dateValue: '', currencyValue: null, file: null, files: [], applicationFormId: this.applicationFormId, applicationId: this.appId }] }; service['referenceFieldsService'].setAllReferenceFields([ this.textField, this.cdtField ]); service['applicationDownloadResources'].getAllFormResponsesForCurrentWorkflowLevel = async () => { return this.allFormsResponse; }; service['applicationDownloadResources'].getAllFormResponsesForApplication = async () => { return this.allFormsResponse; }; service['policyService'].grantApplication.canManageAllApplications = () => { return false; }; service['policyService'].grantApplication.canTakeActionsOnAllApps = () => { return false; }; service['workflowService']['workflowResources'].getWorkflow = async () => { return this.workflowDetail; }; service['workflowService']['workflowResources'].getWorkflows = async () => { return []; }; service['workflowService']['workflowResources'].getWorkflowForms = async () => { return this.workflowForms; }; service['workflowService']['workflowResources'].getMyWorkflowManagerRoles = async () => { return [{ workflowId: this.workflowId, workflowActions: [ WorkflowManagerActions.Approve, WorkflowManagerActions.NotifyOfStatus ] }, { workflowId: this.workflowId, workflowActions: [ WorkflowManagerActions.Approve, WorkflowManagerActions.NotifyOfStatus ] }]; }; service['workflowService'].setMyWorkflowManagerRolesMap(); service['emailService']['emailResources'].getEmailTemplates = async () => { return { records: this.emails, recordCount: this.emails.length }; }; service['exportEmailService']['exportEmailResources'].getApplicationEmails = async () => { return [this.applicationEmail]; }; service['translationService'].setViewTranslationsOnState(ViewTranslationsBlank); service['translationService'].getFormTranslationsByLanguage = async () => { return { richTextMap: {}, standardMap: {} }; }; service['applicationFormService']['applicationFormResources'].getApplicationForms = async () => { return this.applicationForms; }; service['applicationManagerService']['applicationManagerResources'].getNomineeInfo = async () => { return this.nominee; }; service['programService'].getProgram = async () => { return this.program; }; service['collaborationService']['collaborationResources'].getCollaborators = async () => { return this.applicants; }; service['collaborationService']['collaborationResources'].getCollaboratorsBulk = async () => { return [{ ...this.applicants[0], address: {} as SimpleGrantsAddress, applicationId: this.appId }]; }; service['pdfService']['getEmailPdfBlobForApplication'] = async () => { return new Blob(); }; service['systemTagsService']['systemTagsResources'].getTags = async () => { return []; }; service['systemTagsService']['systemTagsResources'].getTagsBulk = async () => { return []; }; service['employeeSsoFieldsService']['employeeSSOFieldsResources'].getEmployeeSSOFieldsBulk = async () => { return [{ applicationId: this.appId } as EmployeeSSOFieldBulkFromApi]; }; service['employeeSsoFieldsService']['employeeSSOFieldsResources'].getEmployeeSSOFieldsForApp = async () => { return this.employeeData; }; service['formHelperService']['customDataTableService']['customDataTableResources'].getBulkCustomDataTables = async () => { return []; }; service['signatureService']['signatureResources'].getSignatureForApplicationFormResponse = async () => { return [this.signature]; }; service['signatureService']['signatureResources'].getSignaturesBulk = async () => { return [{ applicationId: this.appId, applicationFormId: this.applicationFormId } as UserSignatureForBulk]; }; service['applicationViewService']['applicationViewResources'].getApplication = async () => { return this.applicationFromApi; }; service['reportFieldService']['reportFieldResources'].getReportFieldResponse = async () => { return this.reportFieldResponse; }; service['applicationManagerService']['applicationManagerResources'].getBulkApplicationDetails = async () => { return { applicationBulkActionIndicators: [{ applicationId: this.appId, inKindItems: [] } as BulkApplicationDetail] }; }; service['applicationActivityService']['applicationActivityResources']['getApplicationActivity'] = async () => { return { records: [], recordCount: 0 }; }; service['reportFieldService']['reportFieldResources'].getReportFieldResponsesBulk = async () => { return [this.reportFieldResponse]; }; service['nonprofitService']['nonprofitResources'].getNonprofitAdditionalDataByGuid = async () => { return { nonprofitDetail: {} } as NonprofitAdditionalDataApi; }; service['awardService']['getAwards'] = async () => { return { totalAmount: null, awards: this.awards }; }; service['statusService'].preparePaymentStatuses(); } @AfterEach() cleanup () { spy.restore(); } @TestCase('should be able to open download app modal') async downloadApplicationModal (service: ApplicationDownloadService) { spy.on(service['modalFactory'], 'open', async () => { return this.downloadAppModalResponse; }); spy.on(service, 'handleDownloadApplicationResponse'); spy.on(service, 'prepareDownloadApplicationModal'); await service.downloadApplicationModal( this.application, false, true, false, true, null ); expect(service['modalFactory']['open']).to.have.been.called.once; expect(service['prepareDownloadApplicationModal']).to.have.been.called.once; expect(service['handleDownloadApplicationResponse']).to.have.been.called.once; } @TestCase('should be able to handle download app modal response') async handleDownloadApplicationResponse (service: ApplicationDownloadService) { spy.on(service, 'handleDownloadApplication'); const { refResponseMapByAppFormId } = await service.getFormResponsesForDownload( this.appId, false, this.defaultFormId ); await service.handleDownloadApplicationResponse( this.downloadAppModalResponse, this.application, false, 'Workflow level name', 'Workflow name', this.defaultFormId, false, refResponseMapByAppFormId, null ); expect(service['handleDownloadApplication']).to.have.been.called.once; } @TestCase('should be able to get workflow attrs - Application') getWorkflowAttrsApplication (service: ApplicationDownloadService) { const { workflowId, workflowLevelName, workflowName } = service.getWorkflowAttrs(this.application); expect(workflowId).to.be.equal(this.application.workflowId); expect(workflowName).to.be.equal(this.application.workflowName); expect(workflowLevelName).to.be.equal(this.application.currentWorkflowLevelName); } @TestCase('should be able to get workflow attrs - ApplicationFromApi') getWorkflowAttrsApplicationFromApi (service: ApplicationDownloadService) { const application = { currentWorkFlowId: this.workflowId, currentWorkFlowLevelName: 'Workflow level name', currentWorkflowName: 'Workflow name' } as ApplicationForUi; const { workflowId, workflowLevelName, workflowName } = service.getWorkflowAttrs(application); expect(workflowId).to.be.equal(application.currentWorkFlowId); expect(workflowName).to.be.equal(application.currentWorkflowName); expect(workflowLevelName).to.be.equal(application.currentWorkFlowLevelName); } @TestCase('should be able to open bulk download application modal') async bulkDownloadApplicationModal (service: ApplicationDownloadService) { spy.on(service['modalFactory'], 'open', async () => { return this.bulkDownloadModalResponse; }); spy.on(service, 'handleBulkDownloadApplications'); await service.bulkDownloadApplicationModal( [this.application], false, false ); expect(service['modalFactory']['open']).to.have.been.called.once; expect(service['handleBulkDownloadApplications']).to.have.been.called.once; } @TestCase('should be able to handle bulk download application - pass') async handleBulkDownloadApplicationsPass (service: ApplicationDownloadService) { spy.on(service, 'downloadMultipleApplicationsAsPdf'); await service.handleBulkDownloadApplications( [this.application], this.bulkDownloadModalResponse, false, false ); expect(service['downloadMultipleApplicationsAsPdf']).to.have.been.called.once; } @TestCase('should be able to handle bulk download application - fail') async handleBulkDownloadApplicationsFail (service: ApplicationDownloadService) { spy.on(service['logger'], 'error'); spy.on(service['notifier'], 'error'); service['downloadMultipleApplicationsAsPdf'] = async () => { /* eslint-disable no-throw-literal */ throw { error: { message: 'Error' } }; }; await service.handleBulkDownloadApplications( [this.application], this.bulkDownloadModalResponse, false, false ); expect(service['logger']['error']).to.have.been.called.once; expect(service['notifier']['error']).to.have.been.called.once; } @TestCase('should be able to handle download application - pass') async handleDownloadApplicationPass (service: ApplicationDownloadService) { spy.on(service, 'prepSingleApplicationForDownload'); spy.on(service, 'prepApplicationForDownload'); spy.on(service, 'getEmailPdfBlob'); spy.on(service['applicationActivityService'], 'convertActivitiesToCsv'); spy.on(service, 'buildApplicationPDF'); const { refResponseMapByAppFormId } = await service.getFormResponsesForDownload( this.appId, false, this.defaultFormId ); await service.handleDownloadApplication( this.application, this.submissions, false, 'workflow level name', 'workflow name', this.defaultFormId, true, true, refResponseMapByAppFormId, true, true, true, this.awards ); expect(service['prepSingleApplicationForDownload']).to.have.been.called.once; expect(service['prepApplicationForDownload']).to.have.been.called.once; expect(service['getEmailPdfBlob']).to.have.been.called.once; expect(service['applicationActivityService']['convertActivitiesToCsv']).to.have.been.called.once; expect(service['buildApplicationPDF']).to.have.been.called.once; } @TestCase('should be able to handle download application - fail') async handleDownloadApplicationFail (service: ApplicationDownloadService) { spy.on(service['logger'], 'error'); spy.on(service['notifier'], 'error'); service['prepSingleApplicationForDownload'] = async () => { /* eslint-disable no-throw-literal */ throw { error: { message: 'Error' } }; }; await service.handleDownloadApplication( this.application, this.submissions, false, 'workflow level name', 'workflow name', this.defaultFormId, true, true, {}, true, true, true, this.awards ); expect(service['logger']['error']).to.have.been.called.once; expect(service['notifier']['error']).to.have.been.called.once; } @TestCase('should be able to get email pdf blob - show true') async getEmailPdfBlobShowTrue (service: ApplicationDownloadService) { spy.on(service['pdfService'], 'getEmailPdfBlobForApplication'); const showEmails = true; const { emails } = await service.prepSingleApplicationForDownload( this.application, this.submissions, true, true, showEmails, false ); await service.getEmailPdfBlob( this.appId, showEmails, emails ); expect(service['pdfService']['getEmailPdfBlobForApplication']).to.have.been.called.once; } @TestCase('should be able to get email pdf blob - show false') async getEmailPdfBlobShowFalse (service: ApplicationDownloadService) { spy.on(service['pdfService'], 'getEmailPdfBlobForApplication'); const showEmails = false; const { emails } = await service.prepSingleApplicationForDownload( this.application, this.submissions, true, true, showEmails, false ); await service.getEmailPdfBlob( this.appId, showEmails, emails ); expect(service['pdfService']['getEmailPdfBlobForApplication']).to.not.have.been.called; } @TestCase('should be able to build application pdf - with url') async buildApplicationPDF (service: ApplicationDownloadService) { spy.on(service['pdfService'], 'generateApplicationPdf', async () => { return 'url'; }); spy.on(service, 'getApplicantFooterText'); spy.on(service, 'handleAttachmentsAndDownload', () => {}); const applicant: ApplicantInfoForPDF = { name: 'Josie', addressString: '', email: '', phone: '' }; const appForPdf = { appId: this.appId } as ApplicationInfoForPDF; const nominee: Nominee = { email: 'email', firstName: 'first', lastName: 'last' }; await service.buildApplicationPDF( [applicant], appForPdf, nominee, null, true, [], [], [], 'csv', new Blob(), false, '', '', this.defaultFormId, null, service['awardService'].constructAwards(this.awards), false, false ); expect(service['pdfService']['generateApplicationPdf']).to.have.been.called.once; expect(service['getApplicantFooterText']).to.have.been.called.once; expect(service['handleAttachmentsAndDownload']).to.have.been.called.once; } @TestCase('should be able to build application pdf - without url') async buildApplicationPDFNoUrl (service: ApplicationDownloadService) { spy.on(service['pdfService'], 'generateApplicationPdf', async () => { return ''; }); spy.on(service, 'getApplicantFooterText'); spy.on(service, 'handleAttachmentsAndDownload', () => {}); const applicant: ApplicantInfoForPDF = { name: 'Josie', addressString: '', email: '', phone: '' }; const appForPdf = { appId: this.appId } as ApplicationInfoForPDF; const nominee: Nominee = { email: 'email', firstName: 'first', lastName: 'last' }; await service.buildApplicationPDF( [applicant], appForPdf, nominee, null, true, [], [], [], 'csv', new Blob(), false, '', '', this.defaultFormId, null, service['awardService'].constructAwards(this.awards), false, true ); expect(service['pdfService']['generateApplicationPdf']).to.have.been.called.once; expect(service['getApplicantFooterText']).to.have.been.called.once; expect(service['handleAttachmentsAndDownload']).to.not.have.been.called; } @TestCase('should be able to get applicant footer text') getApplicantFooterText (service: ApplicationDownloadService) { const applicant1 = { name: 'Grady Rogers', addressString: '', email: 'grady.rogers@gmail.com', phone: '' }; const applicant2 = { name: 'Tina Rogers', addressString: '', email: 'tina.rogers@gmail.com', phone: '' }; const applicants: ApplicantInfoForPDF[] = [ applicant1, applicant2 ]; const text = service.getApplicantFooterText(applicants, false); const expected = `Applicant(s): ${applicant1.name} (${applicant1.email}) | ${applicant2.name} (${applicant2.email})`; expect(text).to.be.equal(expected); } @TestCase('should be able to handle attachments and download - non bulk') async handleAttachmentsAndDownload (service: ApplicationDownloadService) { spy.on(service['pdfService'], 'getPdfBlob', () => { return new Blob(); }); spy.on(service['pdfService'], 'handleFileUploads', () => {}); spy.on(service, 'handleTableCsvs'); spy.on(service, 'handleActivities'); spy.on(service, 'handleEmails'); spy.on(service['pdfService'], 'handleZipDownload', () => {}); const fileUploads: FileUploadForPDF[] = [{ applicationId: '' + this.appId, applicationFormId: '' + this.applicationFormId, fileId: '1345', fileName: 'File name' }]; const tableCsvs: TableCsvForPdf[] = [{ csv: 'csv', referenceFieldId: 2, fileName: 'table csv', rows: [] }]; await service.handleAttachmentsAndDownload( this.appId, 'url', fileUploads, tableCsvs, 'activitiesCsv', new Blob(), null ); expect(service['pdfService']['getPdfBlob']).to.have.been.called.once; expect(service['pdfService']['handleZipDownload']).to.have.been.called.once; expect(service['pdfService']['handleFileUploads']).to.have.been.called.once; expect(service['handleTableCsvs']).to.have.been.called.once; expect(service['handleActivities']).to.have.been.called.once; expect(service['handleEmails']).to.have.been.called.once; } @TestCase('should be able to handle attachments and download - bulk') async handleAttachmentsAndDownloadBulk (service: ApplicationDownloadService) { spy.on(service['pdfService'], 'getPdfBlob', () => { return new Blob(); }); spy.on(service['pdfService'], 'handleFileUploads', () => {}); spy.on(service, 'handleTableCsvs'); spy.on(service, 'handleActivities'); spy.on(service, 'handleEmails'); spy.on(service['pdfService'], 'handleZipDownload', () => {}); const fileUploads: FileUploadForPDF[] = [{ applicationId: '' + this.appId, applicationFormId: '' + this.applicationFormId, fileId: '1345', fileName: 'File name' }]; const tableCsvs: TableCsvForPdf[] = [{ csv: 'csv', referenceFieldId: 2, fileName: 'table csv', rows: [] }]; await service.handleAttachmentsAndDownload( this.appId, 'url', fileUploads, tableCsvs, 'activitiesCsv', new Blob(), service['jsZipService'].createZip() ); expect(service['pdfService']['getPdfBlob']).to.have.been.called.once; expect(service['pdfService']['handleZipDownload']).to.not.have.been.called; expect(service['pdfService']['handleFileUploads']).to.have.been.called.once; expect(service['handleTableCsvs']).to.have.been.called.once; expect(service['handleActivities']).to.have.been.called.once; expect(service['handleEmails']).to.have.been.called.once; } @TestCase('should be able to handle attachments and download - no bulk or files') async handleAttachmentsAndDownloadNoBulkOrFiles (service: ApplicationDownloadService) { spy.on(service['pdfService'], 'getPdfBlob', () => { return new Blob(); }); spy.on(service['pdfService'], 'handleFileUploads', () => {}); spy.on(service, 'handleTableCsvs'); spy.on(service, 'handleActivities'); spy.on(service, 'handleEmails'); spy.on(service['pdfService'], 'handleZipDownload', () => {}); spy.on(service['fileService'], 'downloadUrlAs', () => {}); await service.handleAttachmentsAndDownload( this.appId, 'url', [], [], '', null, null ); expect(service['pdfService']['getPdfBlob']).to.not.have.been.called; expect(service['pdfService']['handleZipDownload']).to.not.have.been.called; expect(service['pdfService']['handleFileUploads']).to.not.have.been.called; expect(service['handleTableCsvs']).to.not.have.been.called; expect(service['handleActivities']).to.not.have.been.called; expect(service['handleEmails']).to.not.have.been.called; expect(service['fileService']['downloadUrlAs']).to.have.been.called.once; } @TestCase('should be able to handle activites') handleActivities (service: ApplicationDownloadService) { let addedFile = false; service.handleActivities( 'csv', { file: () => { addedFile = true; } } as any ); expect(addedFile).to.be.true; } @TestCase('should be able to handle emails') handleEmails (service: ApplicationDownloadService) { let addedFile = false; service.handleEmails( new Blob(), { file: () => { addedFile = true; } } as any ); expect(addedFile).to.be.true; } @TestCase('should be able to handle table csvs') handleTableCsvs (service: ApplicationDownloadService) { let addedFileCount = 0; const csv1: TableCsvForPdf = { csv: 'csv1', referenceFieldId: 2, fileName: 'table csv1', rows: [] }; const csv2: TableCsvForPdf = { csv: 'csv2', referenceFieldId: 3, fileName: 'table csv2', rows: [] }; service.handleTableCsvs( [ csv1, csv2 ], { file: () => { addedFileCount = addedFileCount + 1; } } as any ); expect(addedFileCount).to.be.equal(2); } @TestCase('should be able to download multiple apps as pdf') async downloadMultipleApplicationsAsPdf (service: ApplicationDownloadService) { spy.on(service, 'prepMultipleApplicationsForDownload'); spy.on(service, 'adaptToSubmissionsForBulk'); spy.on(service, 'prepApplicationForDownload'); spy.on(service, 'getApplicantsForDownload'); spy.on(service, 'buildApplicationPDF', () => { return service['jsZipService'].createZip(); }); spy.on(service['pdfService'], 'handleZipDownload', () => {}); await service.downloadMultipleApplicationsAsPdf( [ this.application ], this.bulkDownloadModalResponse, false, false ); expect(service['prepMultipleApplicationsForDownload']).to.have.been.called.once; expect(service['adaptToSubmissionsForBulk']).to.have.been.called.once; expect(service['prepApplicationForDownload']).to.have.been.called.once; expect(service['getApplicantsForDownload']).to.have.been.called.once; expect(service['buildApplicationPDF']).to.have.been.called.once; expect(service['pdfService']['handleZipDownload']).to.have.been.called.once; } @TestCase('should be able to get applicants for download - masked') getApplicantsForDownloadMasked (service: ApplicationDownloadService) { const isMasked = true; const collabs: BulkCollaboratorResponse[] = [{ firstName: 'Josie', lastName: 'Rogers', email: 'josie.rogers@mailinator.com' } as BulkCollaboratorResponse]; const applicants = service.getApplicantsForDownload(collabs, isMasked); const isEmptyArray = applicants.length === 0; expect(isEmptyArray).to.be.true; } @TestCase('should be able to get applicants for download - non masked') getApplicantsForDownloadNonMasked (service: ApplicationDownloadService) { const isMasked = false; const collabs: BulkCollaboratorResponse[] = [{ firstName: 'Josie', lastName: 'Rogers', email: 'josie.rogers@mailinator.com', address: { address: '', address2: '', city: '', state: '', country: '', postalCode: '' } } as BulkCollaboratorResponse]; const applicants = service.getApplicantsForDownload(collabs, isMasked); const hasApplicant = applicants.some((applicant) => { return applicant.name === 'Josie Rogers'; }); expect(hasApplicant).to.be.true; } @TestCase('should be able to prepare download app modal') async prepareDownloadApplicationModal (service: ApplicationDownloadService) { const result = await service.prepareDownloadApplicationModal( this.application, true, null ); expect(result.forCurrentWfl).to.be.false; const workflowsAreSet = !!service['workflowService'].workflows; expect(workflowsAreSet).to.be.true; expect(result.defaultForm.formId).to.be.equal(this.defaultFormId); } @TestCase('should be able to fetch form responses for app download') async fetchFormResponsesForApplicationDownload (service: ApplicationDownloadService) { let response = await service.fetchFormResponsesForApplicationDownload( this.appId, this.workflowId, this.defaultFormId ); expect(response.forCurrentWfl).to.be.false; // All submissions map should be set when not for current WFL const hasSetAllSubmissionMap = !!response.submissions; expect(hasSetAllSubmissionMap).to.be.true; response = await service.fetchFormResponsesForApplicationDownload( this.appId, 324, this.defaultFormId ); expect(response.forCurrentWfl).to.be.true; // All wlf submissions map should be set when for current WFL const hasSetAllWflSubmissionMap = !!response.submissions; expect(hasSetAllWflSubmissionMap).to.be.true; } @TestCase('should be able to get ref response map') getRefResponseMap (service: ApplicationDownloadService) { const map = service.getRefResponseMap( this.allFormsResponse.applicationReferenceFieldResponses, [this.applicationFormId] ); const refResponses = map[this.applicationFormId]; const hasMyResponse = refResponses.some((res) => { return res.referenceFieldKey === this.cdtFieldKey; }); const hasSharedResponses = refResponses.some((res) => { return res.referenceFieldKey === this.textFieldKey; }); expect(hasMyResponse).to.be.true; expect(hasSharedResponses).to.be.true; } @TestCase('should be able to adapt form repsonse for UI') adaptFormResponseForUi (service: ApplicationDownloadService) { const adapted = service.adaptFormResponseForUi( [{ ...this.formResponse, dueDate: '', isOverdue: true }], '02/05/2021', 1, 2 ); const adaptedResponse = adapted[0]; expect(adaptedResponse.isOverdue).to.be.true; } @TestCase('should be able to filter to submitted responses') filterToSubmittedResponses (service: ApplicationDownloadService) { let isDefaultForm = false; const responses = [{ ...this.formResponse, applicationFormStatusId: FormStatuses.Submitted }, { ...this.formResponse, applicationFormStatusId: FormStatuses.DraftSaved }, { ...this.formResponse, applicationFormStatusId: FormStatuses.RevisionRequested }]; let result = service.filterToSubmittedResponses( responses, isDefaultForm ); // Should only return submitted bc it's not the default form expect(result.length).to.be.equal(1); const hasCorrectResults = result.every((res) => { return res.applicationFormStatusId === FormStatuses.Submitted; }); expect(hasCorrectResults).to.be.true; isDefaultForm = true; // Should return anything bc it's the default form result = service.filterToSubmittedResponses( responses, isDefaultForm ); expect(result.length).to.be.equal(responses.length); } @TestCase('should be able to prepare bulk download modal - program') async prepareBulkDownloadModalProgram (service: ApplicationDownloadService) { const res = await service.prepareBulkDownloadModal( this.program.id, this.workflowId ); expect(res.program.id).to.be.equal(this.program.id); } @TestCase('should be able to prepare bulk download modal - workflow forms map') async prepareBulkDownloadModalWorkflowMap (service: ApplicationDownloadService) { const res = await service.prepareBulkDownloadModal( this.program.id, this.workflowId ); const level1Forms = this.workflowForms.filter((form) => { return form.workflowLevelId === this.level1; }).map((form) => { return form.formId; }); const formsInMap = res.workflowFormsMap[this.level1].map((form) => { return form.formId; }); expect(level1Forms).to.deep.equal(formsInMap); } @TestCase('should be able to prepare bulk download modal - default group') async prepareBulkDownloadModalDefaultGroup (service: ApplicationDownloadService) { const res = await service.prepareBulkDownloadModal( this.program.id, this.workflowId ); const defaultGroups = res.bulkDownloadGroups.filter((group) => { return group.isDefaultFormGroup; }); const defaultGroup = defaultGroups[0]; expect(defaultGroups.length).to.be.equal(1); expect(defaultGroup.forms.length).to.be.equal(1); const defaultForm = defaultGroup.forms[0]; expect(defaultForm.formId).to.be.equal(this.defaultFormId); expect(defaultForm.selected).to.be.true; } @TestCase('should be able to prepare bulk download modal - groups') async prepareBulkDownloadModalGroups (service: ApplicationDownloadService) { const res = await service.prepareBulkDownloadModal( this.program.id, this.workflowId ); const hasLevel1Group = res.bulkDownloadGroups.some((group) => { return group.workflowLevelId === this.level1; }); expect(hasLevel1Group).to.be.true; } @TestCase('should be able to prep single app for download - from api') async prepSingleApplicationForDownload (service: ApplicationDownloadService) { const result = await service.prepSingleApplicationForDownload( { ...this.applicationFromApi, amountRequestedForEdit: 500, designation: '' }, this.submissions, false, true, true, false ); const hasApplicant = result.applicants[0].name === 'Tina Conway'; expect(hasApplicant).to.be.true; expect(result.employeeInfo).to.deep.equal(this.employeeData); expect(result.programLogo).to.equal(this.program.logoUrl); } @TestCase('should be able to prep single app for download - application') async prepSingleApplicationForDownloadApp (service: ApplicationDownloadService) { const result = await service.prepSingleApplicationForDownload( this.application, this.submissions, false, true, true, false ); const hasApplicant = result.applicants[0].name === 'Tina Conway'; expect(hasApplicant).to.be.true; expect(result.employeeInfo).to.deep.equal(this.employeeData); expect(result.programLogo).to.equal(this.program.logoUrl); } @TestCase('should be able to prep application for download') async prepApplicationForDownload (service: ApplicationDownloadService) { const { refResponseMapByAppFormId } = await service.getFormResponsesForDownload( this.appId, false, this.defaultFormId ); const response = await service.prepApplicationForDownload( this.application, this.submissions, '', '', [], this.employeeData, this.reportFieldResponse, [{ count: 12, itemIdentification: 'test' }], refResponseMapByAppFormId, null, null, false ); expect(response.appForPdf.appId).to.be.equal(this.appId); expect(response.appForPdf.employeeInfo).to.deep.equal(this.employeeData); expect(response.formInfos[0].applicationFormId).to.equal(this.applicationFormId); expect(response.orgForPdf.name).to.be.equal(this.application.organizationName); } @TestCase('should be able to get form submitted by - first if') getFormSubmittedByFirstIf (service: ApplicationDownloadService) { const submittedBy = service.getFormSubmittedBy( { ...this.formResponse, submittedBy: { firstName: 'Josie', lastName: 'Rogers', email: 'josie.rogers@gmail.com', userType: UserTypes.APPLICANT, impersonatedBy: '' } }, false ); expect(submittedBy).to.be.equal('Josie Rogers'); } @TestCase('should be able to get form submitted by - second if') getFormSubmittedBySecondIf (service: ApplicationDownloadService) { const submittedBy = service.getFormSubmittedBy( { ...this.formResponse, createdBy: { firstName: 'Josie', lastName: 'Rogers', email: 'josie.rogers@gmail.com', userType: UserTypes.APPLICANT, impersonatedBy: '' } }, false ); expect(submittedBy).to.be.equal('Josie Rogers'); } @TestCase('should be able to get form submitted by - masked') getFormSubmittedByMasked (service: ApplicationDownloadService) { const submittedBy = service.getFormSubmittedBy( { ...this.formResponse, createdBy: { firstName: 'Josie', lastName: 'Rogers', email: 'josie.rogers@gmail.com', userType: UserTypes.APPLICANT, impersonatedBy: '' } }, true ); expect(submittedBy).to.be.equal(''); } @TestCase('should be able to prep cdts for bulk download') async prepCdtsForBulkDownload (service: ApplicationDownloadService) { const appDetailMap = await service.getAppDetailMap( [this.application], this.formIds, this.defaultFormId ); await service.prepCdtsForBulkDownload( appDetailMap, this.formIds ); const optionsAreSet = !!service['formHelperService']['customDataTableService'].customDataTableOptionsMap[ this.cdtGuid ]; expect(optionsAreSet).to.be.true; } @TestCase('should be able to get external fields from app') getExternalFieldsFromApp (service: ApplicationDownloadService) { const form: WorkflowLevelSubmissionForm = { formId: 16, formName: 'Form name', formAudience: FormAudience.APPLICANT, submittedOn: '', submissions: [], selected: false }; const referenceFields: ReferenceFieldsUI.RefResponseMap = { textKey1: 'text answer', picklistKey2: 'picklist answer' }; const externalFields = service.getExternalFieldsFromApp( this.application, form, this.formResponse, referenceFields, this.reportFieldResponse, this.employeeData, [], null ); expect(externalFields.decision).to.be.equal(this.formResponse.decision); expect(externalFields.amountRequested).to.be.equal(this.application.amountRequested); expect(externalFields.reviewerRecommendedFundingAmount).to.be.equal( this.formResponse.reviewerRecommendedFundingAmount ); expect(externalFields.designation).to.be.equal(this.application.designation); expect(externalFields.reportFieldResponse).to.deep.equal(this.reportFieldResponse); expect(externalFields.referenceFields).to.deep.equal(referenceFields); } @TestCase('should be able to get report field response') async getReportFieldResponseForMultipleForms (service: ApplicationDownloadService) { const formDef: FormDefinitionForUi[] = [{ logic: null, index: 0, tabName: '', components: [{ key: 'reportFieldKey', type: 'reportField' }] }]; const result = await service.getReportFieldResponseForMultipleForms( [formDef], this.appId ); expect(result.application.id).to.be.equal(this.appId); } @TestCase('should be able to get app detail map') async getAppDetailMap (service: ApplicationDownloadService) { const map = await service.getAppDetailMap( [this.application], this.formIds, this.defaultFormId ); const hasDetails = !!map[this.appId].appDetail; const hasCollabs = !!map[this.appId].collaborators; const hasAppDetail = !!map[this.appId].appDetail; const reportFieldResponse = !!map[this.appId].reportFieldResponse; expect(hasDetails).to.be.true; expect(hasCollabs).to.be.true; expect(hasAppDetail).to.be.true; expect(reportFieldResponse).to.be.true; } @TestCase('should be able to adapt to submissions for bulk') async adaptToSubmissionsForBulk (service: ApplicationDownloadService) { const res = await service.prepareBulkDownloadModal( this.program.id, this.workflowId ); const appDetail = await service.getAppDetailMap( [this.application], this.formIds, this.defaultFormId ); const submissions = service.adaptToSubmissionsForBulk( res.bulkDownloadGroups, appDetail[this.appId] ); const hasDefaultFormSubmission = submissions.some((sub) => { return sub.workflowLevelName === 'Default form'; }); expect(hasDefaultFormSubmission).to.be.true; } @TestCase('should be able to prep single app for download - nomination') async prepSingleApplicationForDownloadNomination (service: ApplicationDownloadService) { const result = await service.prepSingleApplicationForDownload( this.application, this.submissions, false, true, true, true ); expect(result.nominee).to.equal(this.nominee); } }