Skip to content

Commit cf89f18

Browse files
authored
Merge pull request #6 from mtrezza/add-user-locale-to-placeholder-callback
- Add user locale to placeholder callback
2 parents 643564a + 5275be0 commit cf89f18

File tree

4 files changed

+87
-16
lines changed

4 files changed

+87
-16
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
# main
44
[Full Changelog](https://github.com/mtrezza/parse-server-api-mail-adapter/compare/1.0.1...master)
55

6+
### 🧬 Improvements
7+
- Added locale to placeholder callback. [#6](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/6). Thanks to [mtrezza](https://github.com/mtrezza).
8+
69
# 1.0.1
710
[Full Changelog](https://github.com/mtrezza/parse-server-api-mail-adapter/compare/1.0.0...1.0.1)
811
### 🐛 Fixes
9-
- Removed unused config parameter from docs. [#1](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/1). Thanks to [mtrezza](https://github.com/mtrezza)
12+
- Removed unused config parameter from docs. [#1](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/1). Thanks to [mtrezza](https://github.com/mtrezza).
1013

1114
### 🧬 Improvements
1215
- ⚠️ Added locale to API callback. This is a breaking change because the `apiCallback` now returns an object `{payload, locale}` instead of only the `payload`. [#2](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/2). Thanks to [mtrezza](https://github.com/mtrezza)

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,11 @@ const server = new ParseServer({
9898
},
9999
// A callback that makes the Parse User accessible and allows
100100
// to return user-customized placeholders that will override
101-
// the default template placeholders.
102-
placeholderCallback: async (user) => {
101+
// the default template placeholders. It also makes the user
102+
// locale accessible, if it was returned by the `localeCallback`.
103+
placeholderCallback: async ({ user, locale }) => {
103104
return {
104-
phone: user.get('phone')
105+
phone: user.get('phone');
105106
};
106107
},
107108
// A callback that makes the Parse User accessible and allows

spec/ApiMailAdapter.spec.js

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ const config = {
3838
subjectPath: path.join(__dirname, 'templates/custom_email_subject.txt'),
3939
textPath: path.join(__dirname, 'templates/custom_email.txt'),
4040
htmlPath: path.join(__dirname, 'templates/custom_email.html'),
41+
placeholders: {
42+
appName: "TemplatePlaceholder"
43+
},
4144
placeholderCallback: () => new Promise((resolve) => {
4245
resolve({
43-
appName: 'ExampleApp'
46+
appName: 'CallbackPlaceholder'
4447
});
4548
})
4649
},
@@ -49,7 +52,21 @@ const config = {
4952
textPath: path.join(__dirname, 'templates/custom_email.txt'),
5053
htmlPath: path.join(__dirname, 'templates/custom_email.html'),
5154
localeCallback: async () => { return 'de-AT'; }
52-
}
55+
},
56+
customEmailWithPlaceholderCallbackAndLocaleCallback: {
57+
subjectPath: path.join(__dirname, 'templates/custom_email_subject.txt'),
58+
textPath: path.join(__dirname, 'templates/custom_email.txt'),
59+
htmlPath: path.join(__dirname, 'templates/custom_email.html'),
60+
placeholders: {
61+
appName: "TemplatePlaceholder"
62+
},
63+
placeholderCallback: () => new Promise((resolve) => {
64+
resolve({
65+
appName: 'CallbackPlaceholder'
66+
});
67+
}),
68+
localeCallback: async () => { return 'de-AT'; }
69+
},
5370
}
5471
};
5572
const examplePayload = {
@@ -400,7 +417,7 @@ describe('ApiMailAdapter', () => {
400417
});
401418
});
402419

403-
describe('validate placeholders', function () {
420+
describe('placeholders', function () {
404421

405422
it('returns valid placeholders', async () => {
406423
const adapter = new ApiMailAdapter(config);
@@ -413,6 +430,56 @@ describe('ApiMailAdapter', () => {
413430
const placeholders = 'invalid';
414431
expect(adapter._validatePlaceholders(placeholders)).toEqual({});
415432
});
433+
434+
it('fills in the template placeholder without placeholder callback', async () => {
435+
const adapter = new ApiMailAdapter(config);
436+
const apiCallback = spyOn(adapter, 'apiCallback').and.callThrough();
437+
const email = {
438+
templateName: 'customEmailWithPlaceholderCallback',
439+
recipient: '[email protected]',
440+
direct: true
441+
}
442+
const template = config.templates[email.templateName];
443+
const templatePlaceholder = template.placeholders.appName;
444+
const callbackPlaceholder = (await config.templates[email.templateName].placeholderCallback()).appName;
445+
spyOn(template, 'placeholderCallback').and.callFake(() => {});
446+
447+
await adapter._sendMail(email);
448+
expect(apiCallback.calls.all()[0].args[0].payload.text).toContain(templatePlaceholder);
449+
expect(apiCallback.calls.all()[0].args[0].payload.text).not.toContain(callbackPlaceholder);
450+
});
451+
452+
it('overrides the template placeholder with the callback placeholder', async () => {
453+
const adapter = new ApiMailAdapter(config);
454+
const apiCallback = spyOn(adapter, 'apiCallback').and.callThrough();
455+
const email = {
456+
templateName: 'customEmailWithPlaceholderCallback',
457+
recipient: '[email protected]',
458+
direct: true
459+
}
460+
const template = config.templates[email.templateName];
461+
const templatePlaceholder = template.placeholders.appName;
462+
const callbackPlaceholder = (await template.placeholderCallback()).appName;
463+
464+
await adapter._sendMail(email);
465+
expect(apiCallback.calls.all()[0].args[0].payload.text).toContain(callbackPlaceholder);
466+
expect(apiCallback.calls.all()[0].args[0].payload.text).not.toContain(templatePlaceholder);
467+
});
468+
469+
it('makes user locale accessible in placeholder callback', async () => {
470+
const adapter = new ApiMailAdapter(config);
471+
const apiCallback = spyOn(adapter, 'apiCallback').and.callThrough();
472+
const email = {
473+
templateName: 'customEmailWithPlaceholderCallbackAndLocaleCallback',
474+
recipient: '[email protected]',
475+
direct: true
476+
}
477+
const template = config.templates[email.templateName];
478+
const locale = await template.localeCallback();
479+
480+
await adapter._sendMail(email);
481+
expect(apiCallback.calls.all()[0].args[0].locale).toBe(locale);
482+
});
416483
});
417484

418485
describe('localization', () => {

src/ApiMailAdapter.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,6 @@ class ApiMailAdapter extends MailAdapter {
218218
const { placeholderCallback, localeCallback } = template;
219219
let locale;
220220

221-
// If placeholder callback is set
222-
if (placeholderCallback) {
223-
224-
// Add placeholders from callback
225-
let callbackPlaceholders = await placeholderCallback(user);
226-
callbackPlaceholders = this._validatePlaceholders(callbackPlaceholders);
227-
Object.assign(placeholders, callbackPlaceholders);
228-
}
229-
230221
// If locale callback is set
231222
if (localeCallback) {
232223

@@ -235,6 +226,15 @@ class ApiMailAdapter extends MailAdapter {
235226
locale = this._validateUserLocale(locale);
236227
}
237228

229+
// If placeholder callback is set
230+
if (placeholderCallback) {
231+
232+
// Add placeholders from callback
233+
let callbackPlaceholders = await placeholderCallback({ user, locale });
234+
callbackPlaceholders = this._validatePlaceholders(callbackPlaceholders);
235+
Object.assign(placeholders, callbackPlaceholders);
236+
}
237+
238238
// Get subject content
239239
const subject = message.subject || await this._loadFile(template.subjectPath, locale);
240240

0 commit comments

Comments
 (0)