import { Injectable } from '@angular/core'; import { GCMockModule } from '@core/mocks/gc-module.mock'; import { BeforeEach, Spec, TestCase } from '@yourcause/test-decorators'; import { DescribeAngularService } from '@yourcause/test-decorators/angular'; import { expect } from 'chai'; import { Email, EmailByApplication, EmailByProgramResponse, EmailNotificationType } from '../email.typing'; import { ExportEmailModalResponse } from './export-emails-modal/export-emails-modal.component'; import { ExportEmailService } from './export-emails.service'; @Injectable({ providedIn: 'root' }) @DescribeAngularService(ExportEmailService, { imports: [ GCMockModule ] }) export class ExportEmailServiceSpec implements Spec { appApprovedCopy = { id: 2883476, active: true, default: false, clientEmailTemplate: { id: 57173, name: 'Your Application is Approved - ID: {{APPLICATION_ID}}', body: '\r\n

 

\n\n


\nDear {{APPLICANT_FIRST_NAME}} {{APPLICANT_LAST_NAME}},
\n
\nYour grant application to {{CLIENT_NAME}}/{{PROGRAM_NAME}} on behalf of {{ON_BEHALF_OF}} has been approved.
\n
\n(Application ID# {{APPLICATION_ID}})
\n
\n{{#if Custom.CustomMessage}} {{CUSTOM_MESSAGE}} {{#else GrantProgram.SenderDisplayName}} {{SENDER_DISPLAY_NAME}} {{/else}}
\n
\n{{/if}}

\n\n

Annual Operating Budget: {{ReferenceField.annualOperatingBudget2}}

\n\n

 

\n\n

Sincerely,
\nGrantsConnect Support

\n\n

 

\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n       Go to GrantsConnect      \r\n \r\n
\r\n \r\n \r\n', subject: 'Your Application is Approved - ID: {{APPLICATION_ID}}', copy: true, description: 'Grant manager approves application', title: 'Application Approved' }, emailNotificationTypeId: EmailNotificationType.ApplicationApproved }; programEmails: EmailByProgramResponse[] = [{ emailInfo: [{ id: 2883465, active: true, default: false, clientEmailTemplate: { id: 51913, name: 'Your Application is Approved - ID: {{APPLICATION_ID}}  Copy', body: `\r\n

Copy

\n\n


\nDear {{APPLICANT_FIRST_NAME}} {{APPLICANT_LAST_NAME}},
\n
\nYour grant application to {{CLIENT_NAME}}/{{PROGRAM_NAME}} on behalf of {{ON_BEHALF_OF}} has been approved.
\n
\n(Application ID# {{APPLICATION_ID}})
\n
\n{{#if Custom.CustomMessage}} {{CUSTOM_MESSAGE}}
\n
\n{{/if}} Sincerely,
\nGrantsConnect Support

\n\n

\"\"

\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n\r\n
\r\n \r\nGo to GrantsConnect\r\n\r\n
\r\n\r\n \r\n`, subject: 'Your Application is Approved - ID: {{APPLICATION_ID}}  Copy', copy: true, description: 'Grant manager approves application - has image', title: 'Application Approved' }, emailNotificationTypeId: EmailNotificationType.ApplicationApproved }, this.appApprovedCopy, { id: 0, active: false, default: true, clientEmailTemplate: { id: 0, name: 'Standard Email', body: '\r\n \r\n
\r\n
\r\n Dear {{APPLICANT_FIRST_NAME}} {{APPLICANT_LAST_NAME}},\r\n
\r\n
\r\n Your grant application to {{CLIENT_NAME}}/{{PROGRAM_NAME}} on behalf of {{ON_BEHALF_OF}} has been approved.\r\n
\r\n
\r\n (Application ID# {{APPLICATION_ID}})\r\n
\r\n
\r\n {{#if Custom.CustomMessage}}\r\n {{CUSTOM_MESSAGE}}\r\n {{#else GrantProgram.SenderDisplayName}}\r\n {{SENDER_DISPLAY_NAME}}\r\n {{/else}}\r\n
\r\n
\r\n {{/if}}\r\n Sincerely,
\r\n GrantsConnect Support\r\n \r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n       Go to GrantsConnect      \r\n \r\n
\r\n \r\n \r\n', subject: 'Your Application is Approved - ID: {{APPLICATION_ID}}', copy: false, description: 'Standard Email', title: 'Application Approved' }, emailNotificationTypeId: EmailNotificationType.ApplicationApproved }] }, { emailInfo: [{ id: 0, active: true, default: true, clientEmailTemplate: { id: 0, name: 'Standard Email', body: '\r\n \r\n
\r\n
\r\n Dear {{APPLICANT_FIRST_NAME}} {{APPLICANT_LAST_NAME}},\r\n
\r\n
\r\n Your grant application to {{CLIENT_NAME}}/{{PROGRAM_NAME}} on behalf of {{ON_BEHALF_OF}} has been declined.\r\n
\r\n
\r\n (Application ID# {{APPLICATION_ID}})\r\n
\r\n
\r\n {{#if Custom.CustomMessage}}\r\n {{CUSTOM_MESSAGE}}\r\n
\r\n
\r\n {{/if}}\r\n Sincerely,
\r\n GrantsConnect Support\r\n \r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n       Go to GrantsConnect      \r\n \r\n
\r\n \r\n \r\n', subject: 'Your Application is Declined - ID: {{APPLICATION_ID}}', copy: false, description: 'Standard Email', title: 'Application Declined' }, emailNotificationTypeId: EmailNotificationType.ApplicationDeclined }] }]; 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 }]; buttonHtml = '\r\n \r\n \r\n \r\n \r\n
\r\n \r\n       Go to GrantsConnect      \r\n \r\n
\r\n '; bodyWithButton = `\r\n

 

\n\n


\nDear {{APPLICANT_FIRST_NAME}} {{APPLICANT_LAST_NAME}},
\n
\nYou have successfully submitted your application for the following program:
\n
\n{{CLIENT_NAME}} / {{PROGRAM_NAME}}
\n
\nApplication ID: {{APPLICATION_ID}}
\nForm Submitted: {{FORM_NAME}}
\n
\nSincerely,
\nGrantsConnect Support

\n\n

{{CLIENT_NAME}}

\n\n

 

\n\r\n\r\n\r\n \r\n ${this.buttonHtml}\r\n \r\n`; applicationEmail: EmailByApplication = { emailNotificationTypeId: EmailNotificationType.ApplicantAddedToApplication, subject: 'Invitation to GrantsConnect', body: this.bodyWithButton, toAddress: 'kc54861+new@gmail.com', toName: 'Tina Conway', sentTime: '2022-02-10T20:50:26.058991Z', multipleToAddresses: [], carbonCopyRecipients: [] }; @BeforeEach() mock (service: ExportEmailService) { service['exportEmailResources'].getEmailsByProgramAndLang = async () => { return this.programEmails; }; } @TestCase('should be able to handle export emails by program and lang') async handleExportEmailsByProgramAndLang (service: ExportEmailService) { let didDownload = false; let generatedPdf = false; service['pdfService'].generateEmailPdf = async () => { generatedPdf = true; return 'url'; }; service['fileService']['downloadUrlAs'] = async () => { didDownload = true; }; const modalResponse: ExportEmailModalResponse = { programId: 123, emailLanguage: 'en-US' }; await service.handleExportEmailsByProgramAndLang(modalResponse, this.emails); expect(didDownload).to.be.true; expect(generatedPdf).to.be.true; } @TestCase('should be able to handle export emails by program and lang - fail') async handleExportEmailsByProgramAndLangFail (service: ExportEmailService) { let errorNotified = false; let loggedError = false; service['notifier'].error = () => { errorNotified = true; }; service['logger'].error = () => { loggedError = true; }; service['exportEmailResources'].getEmailsByProgramAndLang= async () => { /* eslint-disable no-throw-literal */ throw { error: { message: 'Error' } }; }; const modalResponse: ExportEmailModalResponse = { programId: 123, emailLanguage: 'en-US' }; await service.handleExportEmailsByProgramAndLang(modalResponse, this.emails); expect(errorNotified).to.be.true; expect(loggedError).to.be.true; } @TestCase('should be able to adapt program email for UI') adaptProgramEmailForUi (service: ExportEmailService) { const foundEmail = this.emails.find((email) => { return email.emailNotificationType === this.appApprovedCopy.emailNotificationTypeId; }); const adapted = service.adaptProgramEmailForUi(this.appApprovedCopy, foundEmail, 0); expect(adapted.emailNotificationTypeId).to.be.equal(this.appApprovedCopy.emailNotificationTypeId); expect(adapted.emailNotificationName).to.be.equal('GC-13.1'); expect(adapted.description).to.be.equal(this.appApprovedCopy.clientEmailTemplate.description); } @TestCase('should be able to adapt program emails for UI') adaptProgramEmailsForUi (service: ExportEmailService) { const adapted = service.adaptProgramEmailsForUi( this.programEmails, this.emails ); const numberOfActiveEmails = this.programEmails.reduce((acc, info) => { const activeEmails = info.emailInfo.filter((item) => { return item.active; }); return acc + activeEmails.length; }, 0); expect(adapted.length).to.be.equal(numberOfActiveEmails); const hasAdaptedApprovedCopy = adapted.some((item) => { return item.emailNotificationTypeId === this.appApprovedCopy.emailNotificationTypeId; }); expect(hasAdaptedApprovedCopy).to.be.true; } @TestCase('should be able to get application emails - fetch') async getApplicationEmails (service: ExportEmailService) { let fetchedData = false; service['exportEmailResources'].getApplicationEmails = async () => { fetchedData = true; return []; }; await service.getApplicationEmails( 232, this.emails ); expect(fetchedData).to.be.true; } @TestCase('should be able to get application emails - adapt') async getApplicationEmailsAdapt (service: ExportEmailService) { service['exportEmailResources'].getApplicationEmails = async () => { return [this.applicationEmail]; }; const result = await service.getApplicationEmails( 232, this.emails ); const foundEmail = this.emails.find((email) => { return email.emailNotificationType === this.applicationEmail.emailNotificationTypeId; }); const adaptedEmail = result[0]; expect(adaptedEmail.emailNotificationName).to.be.equal('GC-16'); expect(adaptedEmail.audienceText).to.be.equal('Applicant'); expect(adaptedEmail.description).to.be.equal(foundEmail.description); expect(adaptedEmail.name).to.be.equal(foundEmail.name); } @TestCase('should be able to adapt application email for UI') adaptApplicationEmailForUi (service: ExportEmailService) { const foundEmail = this.emails.find((email) => { return email.emailNotificationType === this.applicationEmail.emailNotificationTypeId; }); const adapted = service.adaptApplicationEmailForUi(this.applicationEmail, foundEmail); expect(adapted.audienceText).to.be.equal('Applicant'); expect(adapted.name).to.be.equal(foundEmail.name); expect(adapted.title).to.be.equal(foundEmail.title); } @TestCase('should be able to get body without button') getBodyWithoutButton (service: ExportEmailService) { const { body, buttonHTML } = service.getBodyWithoutButton(this.bodyWithButton); expect(buttonHTML).to.be.equal(this.buttonHtml); const noButtonInBody = !body.includes(this.buttonHtml); expect(noButtonInBody).to.be.true; } @TestCase('should be able to get email notification name') getEmailNotificationName (service: ExportEmailService) { let name = service.getEmailNotificationName( EmailNotificationType.ApplicationApproved, 2 ); let expectedName = 'GC-13.3'; expect(name).to.be.equal(expectedName); name = service.getEmailNotificationName( EmailNotificationType.AddressRequestReadyForReview ); expectedName = 'GC-71'; expect(name).to.be.equal(expectedName); } @TestCase('should be able to get audience text') getAudienceText (service: ExportEmailService) { let text = service.getAudienceText(true); expect(text).to.be.equal('Applicant'); text = service.getAudienceText(false); expect(text).to.be.equal('Grant manager'); } }