import { Injectable } from '@angular/core'; import { GCMockModule } from '@core/mocks/gc-module.mock'; import { UserInfo, UserTypes } from '@core/typings/client-user.typing'; import { EmailNotificationType, EmailStatus } from '@features/system-emails/email.typing'; import { BeforeEach, Spec, TestCase } from '@yourcause/test-decorators'; import { DescribeAngularService } from '@yourcause/test-decorators/angular'; import { expect } from 'chai'; import { CommunicationsResources } from './communications.resources'; import { CommunicationsService } from './communications.service'; import { APIOrganizationCommunicationList, Communication, CommunicationsByDate, CommunicationTypes, CommunicationVisibility, SimpleCommunication, SimpleEmail } from './communications.typing'; @Injectable({ providedIn: 'root' }) @DescribeAngularService(CommunicationsService, { imports: [ GCMockModule ] }) export class CommunicationsServiceSpec implements Spec< CommunicationsServiceSpec, CommunicationsService > { communicationId = 1; jobCommunicationId = 2; id = 3; sampleUser: UserInfo = { firstName: 'Tina', lastName: 'Conway', email: 'asdf@mailinator.com', userType: UserTypes.MANAGER, impersonatedBy: 'test impersonator' }; communication: Communication = { files: [{ fileName: 'abc', fileUploadId: 123 }], createdBy: this.sampleUser, updatedBy: this.sampleUser, description: 'description', isRich: false, communicationId: this.communicationId, joinCommunicationId: this.jobCommunicationId, visibility: CommunicationVisibility.ALL_GRANT_MANAGERS, publishToNonprofit: true, type: CommunicationTypes.DOCUMENTATION, subject: 'Subject', date: new Date().toString(), updatedDate: new Date().toString(), content: 'content', emailStatusType: EmailStatus.Sent, emailNotificationType: EmailNotificationType.ApplicantAddedToApplication }; communications: Communication[] = [ this.communication, { ...this.communication, communicationId: 2, date: new Date('05/27/2019').toString() } ]; simpleCommunication: SimpleCommunication = { communicationId: this.communicationId, subject: 'Subject', date: new Date().toString(), updatedDate: new Date().toString(), fileUploadIds: [1], fileName: 'File name', fileAccessURL: '', visibility: CommunicationVisibility.MANAGERS_IN_LEVEL, type: CommunicationTypes.DOCUMENTATION, createdBy: this.sampleUser, updatedBy: this.sampleUser, applicationCommunicationId: this.id, emailNotificationType: EmailNotificationType.ApplicantAddedToApplication, files: [{ fileName: 'a', fileUploadId: 1 }] }; textToStrip = ''; organizationCommunicationListFromApi: APIOrganizationCommunicationList = { manualCommunicationRecords: [ this.simpleCommunication ] }; firstDate = '05/27/2021'; secondDate = '05/27/2020'; thirdDate = '04/30/2018'; firstComm: Communication[] = [{ createdBy: this.sampleUser, updatedBy: this.sampleUser, description: 'description2', isRich: true, communicationId: this.communicationId, joinCommunicationId: this.jobCommunicationId, visibility: CommunicationVisibility.ALL_GRANT_MANAGERS, publishToNonprofit: true, type: CommunicationTypes.SYSTEM_EMAIL, subject: 'Subject 1', date: '06/14/2021', updatedDate: new Date().toString(), content: 'content 1', emailStatusType: EmailStatus.Sent, emailNotificationType: EmailNotificationType.ApplicantAddedToApplication, files: [{ fileName: 'string', fileUploadId: 123 }] }]; secondComm: Communication[] = [{ createdBy: this.sampleUser, updatedBy: this.sampleUser, description: 'description2', isRich: true, communicationId: this.communicationId, joinCommunicationId: this.jobCommunicationId, visibility: CommunicationVisibility.ALL_GRANT_MANAGERS, publishToNonprofit: true, type: CommunicationTypes.DOCUMENTATION, subject: 'Subject 2', date: '06/14/2021', updatedDate: new Date().toString(), content: 'content 2', emailStatusType: EmailStatus.Sent, emailNotificationType: EmailNotificationType.ApplicantAddedToApplication, files: [{ fileName: 'string', fileUploadId: 123 }] }]; thirdComm: Communication[] = [{ createdBy: this.sampleUser, updatedBy: this.sampleUser, description: 'description2', isRich: true, communicationId: this.communicationId, joinCommunicationId: this.jobCommunicationId, visibility: CommunicationVisibility.ALL_GRANT_MANAGERS, publishToNonprofit: true, type: CommunicationTypes.DOCUMENTATION, subject: 'Subject 3', date: '06/14/2021', updatedDate: new Date().toString(), content: 'content 3', emailStatusType: EmailStatus.Sent, emailNotificationType: EmailNotificationType.ApplicantAddedToApplication, files: [{ fileName: 'string', fileUploadId: 123 }] }]; commsByDate: CommunicationsByDate[] = [{ date: this.secondDate, communications: this.secondComm }, { date: this.firstDate, communications: this.firstComm }, { date: this.thirdDate, communications: this.thirdComm }]; constructor ( private communicationsResources: CommunicationsResources ) { } @BeforeEach() mock (service: CommunicationsService) { service['communicationResources'] = this.communicationsResources; this.communicationsResources.getCommunicationsForOrganization = async () => { return this.organizationCommunicationListFromApi; }; service['emailService'].isEmailActive = () => { return true; }; } @TestCase('should be able to adapt communication to applicant communication') async adaptCommunicationToApplicantCommunication ( service: CommunicationsService ) { const adapted = await service.adaptCommunicationToApplicantCommunication( this.communication, this.id ); expect(adapted.applicationId).to.be.equal(this.id); expect(adapted.content).to.be.equal(this.communication.content); } @TestCase('should be able to adapt communication to nonprofit communication') async adaptCommunicationToNonprofitCommunication (service: CommunicationsService) { const adapted = await service.adaptCommunicationToNonprofitCommunication( this.communication, this.id ); expect(adapted.organizationId).to.be.equal(this.id); expect(adapted.content).to.be.equal(this.communication.content); } @TestCase('should be able to adapt simple communication') adaptSimpleCommunication (service: CommunicationsService) { const adapted = service.adaptSimpleCommunication( this.simpleCommunication ); expect(adapted.type).to.be.equal(this.simpleCommunication.type); } @TestCase('should be able to strip extra text') stripExtraText (service: CommunicationsService) { const stripped = service.stripExtraText(this.textToStrip); expect(stripped).to.be.equal(''); } @TestCase('should be able to sort communications by date') sortCommunications (service: CommunicationsService) { const sorted = service.sortCommunications(this.commsByDate); // newest to top expect(sorted[0]).to.deep.equal(this.firstComm); expect(sorted[1]).to.deep.equal(this.secondComm); expect(sorted[2]).to.deep.equal(this.thirdComm); } @TestCase('should be able to get communications for organization') async getCommunicationsForOrganization ( service: CommunicationsService ) { await service.getCommunicationsForOrganization(this.id); const map = service.nonprofitCommunicationsMap[this.id]; expect(map.length).to.be.equal(1); expect(map[0][0].type).to.be.equal(this.simpleCommunication.type); } @TestCase('should be able to adapt email to communication') adaptEmailToCommunication (service: CommunicationsService) { const email: SimpleEmail = { id: 1, fromAddress: '', fromFriendlyName: '', toAddress: '', toFriendlyName: '', subject: '', sentDate: '', createdDate: '', updatedDate: '', emailNumber: 'GC-71', emailNotificationType: EmailNotificationType.AddressRequestReadyForReview, emailStatusType: EmailStatus.Failed, body: '', emailAttachments: [] }; const adapted = service.adaptEmailToCommunication(email); const correctType = adapted.type === CommunicationTypes.SYSTEM_EMAIL; const correctJoin = adapted.joinCommunicationId === email.id; expect(adapted.isRich).to.be.true; expect(correctType).to.be.true; expect(correctJoin).to.be.true; } @TestCase('should be able to get description for email') getDescriptionEmail (service: CommunicationsService) { const description = service.getDescription(this.firstComm[0]); const hasExptectedDescription = description.includes('System email: Jun 14, 2021'); expect(hasExptectedDescription).to.be.true; } @TestCase('should be able to get description for non email') getDescriptionNonEmail (service: CommunicationsService) { const description = service.getDescription(this.secondComm[0]); const hasExptectedDescription = description.includes('Created by Tina Conway on Jun 14, 2021'); expect(hasExptectedDescription).to.be.true; } }