From 563394ba746fc22525d8140f7bbd4a9b408ded0f Mon Sep 17 00:00:00 2001 From: Georgi Parlakov Date: Sun, 24 Nov 2024 15:22:32 +0200 Subject: [PATCH] fix: update the text for the campaign application - create - show text that does not confirm campaign creation rather speaks about application for a campaign and further details required - following up on discussion https://discord.com/channels/778984868146577458/1136685006908035092/1307348393521057792 - and texts from https://docs.google.com/document/d/1uZXrVxPKHo9PkMrEE9oIBixO8IGWxbYGBkxlqIJJwck/edit?tab=t.0 --- .eslintrc.json | 13 + ...create-campaign-application-organizer.json | 2 +- ...create-campaign-application-organizer.mjml | 21 +- apps/api/src/email/readme.email.md | 27 ++ .../email/template.service.spec-adapter.ts | 46 ++++ apps/api/src/email/template.service.spec.ts | 247 ++++++++++++++++++ apps/api/src/email/template.service.ts | 4 +- .../notifications.sendgrid.provider.ts | 1 - 8 files changed, 351 insertions(+), 10 deletions(-) create mode 100644 apps/api/src/email/readme.email.md create mode 100644 apps/api/src/email/template.service.spec-adapter.ts create mode 100644 apps/api/src/email/template.service.spec.ts diff --git a/.eslintrc.json b/.eslintrc.json index 06cc47d9a..453c5bff7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,6 +26,19 @@ "extends": ["plugin:@nrwl/nx/typescript"], "rules": {} }, + { + "files": ["*.spec.ts"], + "extends": ["plugin:@nrwl/nx/typescript"], + "rules": { + "no-restricted-syntax": [ + "error", + { + "message": "Do you really need to write file to disk in a test?", + "selector": "[name=writeFileSync], [name=writeFile]" + } + ] + } + }, { "files": ["*.js", "*.jsx"], "extends": ["plugin:@nrwl/nx/javascript"], diff --git a/apps/api/src/assets/templates/create-campaign-application-organizer.json b/apps/api/src/assets/templates/create-campaign-application-organizer.json index bdccf1639..d0f8a40ba 100644 --- a/apps/api/src/assets/templates/create-campaign-application-organizer.json +++ b/apps/api/src/assets/templates/create-campaign-application-organizer.json @@ -1,3 +1,3 @@ { - "subject": "Създадена нова кампания" + "subject": "Потвърждение за получаване на заявка за дарителска кампания " } diff --git a/apps/api/src/assets/templates/create-campaign-application-organizer.mjml b/apps/api/src/assets/templates/create-campaign-application-organizer.mjml index 0c07ffb2b..a2b99589a 100644 --- a/apps/api/src/assets/templates/create-campaign-application-organizer.mjml +++ b/apps/api/src/assets/templates/create-campaign-application-organizer.mjml @@ -12,7 +12,7 @@ padding-right="25px" padding-bottom="30px" padding-top="50px"> - Успешно създадохте кампания в Подкрепи.бг + Потвърждение за получаване на заявка за дарителска кампания @@ -25,7 +25,7 @@ font-family="open Sans Helvetica, Arial, sans-serif" padding-left="25px" padding-right="25px"> - Здравейте {{firstName}}, + Здравейте, {{firstName}},

- Вашата кампания е създадена успешно! Вижте я + Благодарим Ви, че подадохте заявка за кампания на платформата Подкрепи.бг!
Можете да + я прегледате ТУК!

+ >.

- Пожелаваме успешно набиране на средствата! + Искаме да Ви уверим, че заявката Ви е успешно получена и ще бъде разгледана от екипа ни в + най-кратък срок. Ако има нужда от допълнителна информация или уточнения, член на екип + „Кампании“ ще се свърже с Вас.

+ + Междувременно, ако имате въпроси или желаете да предоставите допълнителни детайли за + кампанията, можете да се свържете с нас на следния имейл: + campaign_coordinators@podkrepi.bg. Благодарим Ви, че заедно правим добро!

- Поздрави,
+ С уважение,
Екипът на Подкрепи.бг
diff --git a/apps/api/src/email/readme.email.md b/apps/api/src/email/readme.email.md new file mode 100644 index 000000000..8854de71f --- /dev/null +++ b/apps/api/src/email/readme.email.md @@ -0,0 +1,27 @@ +# Email Template Service + +It gets the templates based on the name and the templates in the src/assets/templates. + +## Testing with adapter + +Why do we need the `template.service.spec-adapter.ts` when we have the `template.service.ts`? +It's looking in a hardcoded path which is correct when the app is built and deployed but incorrect when running the tests. Hence we extend the base class with this for the tests. + +## Visualize the template before you ship the code + +- temporarily add a line like `writeFileSync('./rendered-template.html', rendered.html)` to your test (careful to not ) +- then open that with the browser i.e. `file:///C:/Users/gparl/Downloads/projects/podkrepi-bg-api/rendered-template.html` or on ubuntu under wsl `file://wsl.localhost/Ubuntu/home/gparlakov/projects/podkrepi-bg-api/rendered-template.html` +- remember to delete that `writeFileSync` line and the `rendered-template.html` before you ship + +```ts +const t = new CreateCampaignApplicationOrganizerEmailDto({ + firstName: 'test', + email: 'test@email', + campaignApplicationLink: 'link', + campaignApplicationName: 'campaignApplicationName', +}) + +const rendered = await s.getTemplate(t) + +writeFileSync('./rendered-template.html', rendered.html) +``` diff --git a/apps/api/src/email/template.service.spec-adapter.ts b/apps/api/src/email/template.service.spec-adapter.ts new file mode 100644 index 000000000..335c66037 --- /dev/null +++ b/apps/api/src/email/template.service.spec-adapter.ts @@ -0,0 +1,46 @@ +import { Logger } from '@nestjs/common' +import { readFile } from 'fs/promises' +import mjml from 'mjml' +import path from 'path' + +import { EmailMetadata, TemplateType } from './template.interface' +import { TemplateService } from './template.service' + +export class TemplateServiceSpecAdapter extends TemplateService { + /** + * Why do we need this when we have the template.service.ts? + * It's looking in a hardcoded path which is correct when the app is built and deployed but incorrect when running the tests. + * Hence we extend the base class with this for the tests. + * + * @param basePath where to look for the assets/templates/*.mjml files + */ + constructor(private basePath: string) { + super() + } + + protected async getEmailTemplate(templateName: TemplateType): Promise> { + try { + const file = await readFile( + path.resolve(this.basePath, `./assets/templates/${templateName}.mjml`), + { encoding: 'utf-8' }, + ) + return mjml(file) + } catch (error) { + Logger.error(`getEmailTemplate`, error) + throw error + } + } + + protected async getEmailData(templateName: string): Promise { + try { + const contents = await readFile( + path.resolve(this.basePath, `./assets/templates/${templateName}.json`), + { encoding: 'utf-8' }, + ) + return JSON.parse(contents) + } catch (error) { + Logger.error(`getEmailData`, error) + throw error + } + } +} diff --git a/apps/api/src/email/template.service.spec.ts b/apps/api/src/email/template.service.spec.ts new file mode 100644 index 000000000..aa7a93e91 --- /dev/null +++ b/apps/api/src/email/template.service.spec.ts @@ -0,0 +1,247 @@ +import { CreateCampaignApplicationOrganizerEmailDto } from './template.interface' +import { TemplateServiceSpecAdapter } from './template.service.spec-adapter' + +describe('Template service', () => { + let s: TemplateServiceSpecAdapter + + beforeEach(() => { + s = new TemplateServiceSpecAdapter('./apps/api/src') + }) + + it('should render the campaign application email template', async () => { + const t = new CreateCampaignApplicationOrganizerEmailDto({ + firstName: 'test', + email: 'test@email', + campaignApplicationLink: 'link', + campaignApplicationName: 'campaignApplicationName', + }) + + const rendered = await s.getTemplate(t) + // prettier-ignore-start + /* eslint-disable */ + expect(rendered).toMatchInlineSnapshot(` + { + "html": " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + +
+ + +
+ + + + + + + + + +
+ +
Потвърждение за получаване на заявка за дарителска кампания
+ +
+ +
+ + +
+ +
+ + + + + +
+ + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + +
+ +
Здравейте, test, +

+ +
+ +
Благодарим Ви, че подадохте заявка за кампания на платформата Подкрепи.бг!
Можете да + я прегледате + ТУК.

+ + Искаме да Ви уверим, че заявката Ви е успешно получена и ще бъде разгледана от екипа ни в + най-кратък срок. Ако има нужда от допълнителна информация или уточнения, член на екип + „Кампании“ ще се свърже с Вас.

+ + Междувременно, ако имате въпроси или желаете да предоставите допълнителни детайли за + кампанията, можете да се свържете с нас на следния имейл: + campaign_coordinators@podkrepi.bg. Благодарим Ви, че заедно правим добро!

+ +
+ +
С уважение,
+ Екипът на Подкрепи.бг
+ +
+ +
+ + +
+ +
+ + + + + +
+ + + + ", + "metadata": { + "subject": "Потвърждение за получаване на заявка за дарителска кампания ", + }, + } + `) + /* eslint-enable */ + // prettier-ignore-start + }) +}) diff --git a/apps/api/src/email/template.service.ts b/apps/api/src/email/template.service.ts index efc1f8764..16cfcb007 100644 --- a/apps/api/src/email/template.service.ts +++ b/apps/api/src/email/template.service.ts @@ -26,7 +26,7 @@ export class TemplateService { } } - private async getEmailTemplate(templateName: TemplateType): Promise> { + protected async getEmailTemplate(templateName: TemplateType): Promise> { try { const file = await readFile( path.resolve(__dirname, `./assets/templates/${templateName}.mjml`), @@ -39,7 +39,7 @@ export class TemplateService { } } - private async getEmailData(templateName: string): Promise { + protected async getEmailData(templateName: string): Promise { try { const contents = await readFile( path.resolve(__dirname, `./assets/templates/${templateName}.json`), diff --git a/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts b/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts index bdfa78a4d..b06909992 100644 --- a/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts +++ b/apps/api/src/notifications/providers/notifications.sendgrid.provider.ts @@ -27,7 +27,6 @@ import { ContactsMap } from '../notifications.service' import { MailDataRequired } from '@sendgrid/mail' import { PersonalizationData } from '@sendgrid/helpers/classes/personalization' - @Injectable() export class SendGridNotificationsProvider implements NotificationsProviderInterface