unit testing
MODIFY
file.txt
file.txt
</mj-head>
<mj-body><mj-section>
<mj-column>
- <mj-image width="100px" href="http://utsmartcharging.localhost:45000" src="null"></mj-image>
+ <mj-image width="100px" href="some_url" src="undefined"></mj-image>
</mj-column>
</mj-section>
,<mj-section padding-top="20px">
<mj-column>
<mj-text>
- <p>Hello ! Admin,</p>
+ <p>Hello ! User,</p>
<p>You have registered to SAP. Welcome abroad!</p>
</mj-text>
</mj-column>
</mj-section>
,<mj-section>
<mj-column>
- <mj-button font-size="16px" href="http://utsmartcharging.localhost:45000/auth/verify-email?VerificationToken=34800542563bb959484fbf76a629ce047e7bb226dbd6a3194a75ace8fa5c5e94&Email=stone_huels90@gmail.com&ResetToken=4f389595-3783-468b-b837-1d75cf64339d">
+ <mj-button font-size="16px" href="some_url">
E-Mobility
</mj-button>
</mj-column>
</mj-section>
<mj-section>
- <mj-column width="65%">
- <mj-image align="left" width="50px" href="undefined" src="http://utsmartcharging.localhost:45000/assets/img/info.png"></mj-image>
- </mj-column>
- <mj-column width="35%">
- <mj-table>
- <tr style="list-style: none;line-height:1">
- <td> <a href="https://twitter.com/RecastAI">
- <img width="25" src="https://cdn.recast.ai/newsletter/twitter.png" />
- </a> </td>
- <td> <a href="https://www.facebook.com/recastAI">
- <img width="25" src="https://cdn.recast.ai/newsletter/facebook.png" />
- </a> </td>
- <td> <a href="https://medium.com/@RecastAI">
- <img width="25" src="https://cdn.recast.ai/newsletter/medium.png" />
- </a> </td>
- <td> <a href="https://www.youtube.com/channel/UCA0UZlR8crpgwFiVaSTbVWw">
- <img width="25" src="https://cdn.recast.ai/newsletter/youtube.png" />
- </a> </td>
- <td> <a href="https://plus.google.com/u/0/+RecastAi">
- <img width="25" src="https://cdn.recast.ai/newsletter/google%2B.png" />
- </a> </td>
- </tr>
- </mj-table>
+ <mj-column>
+ <mj-image width="50px" href="https://open-e-mobility.io/" src="https://imgur.com/VU2plEe.png"></mj-image>
</mj-column>
</mj-section>
</mj-body></mjml>
\ No newline at end of file

MODIFY
package.json
package.json
"test:transaction": "npm run test:jest -- test/**/TransactionTest.ts",
"test:template": "npm run test:jest -- test/**/UnitTestTemplate.ts",
"test:user": "npm run test:jest -- test/**/UserTest.ts",
+ "test:email": "cross-env NODE_ENV=development jest --config='test/jest.config.ts' --runInBand --logHeapUsage --verbose --colors --silent --forceExit -- test/**/EmailTest.ts",
"test:jest": "npm version && cross-env TS_NODE_FILES=true jest --config='./test/jest.config.ts' --runInBand --logHeapUsage --verbose --colors --silent --forceExit"
},
"dependencies": {

MODIFY
src/notification/email/EMailNotificationTask.ts
src/notification/email/EMailNotificationTask.ts
@@ -316,16 +316,20 @@ export default class EMailNotificationTask implements NotificationTask {
message: 'User is mandatory'
});
}
- context.appUrl = context.appUrl && 'https://open-e-mobility.io/';
+ context.appUrl = context.appUrl || 'https://open-e-mobility.io/';
+ context.userFirstName = context.user.firstName || context.user.name;
+ context.tenantLogoURL = tenant.logo;
const i18nInstance = I18nManager.getInstanceForLocale(user.locale);
const template = (await mjmlBuilder.initialize())
.addToBody(await EmailComponentManager.getComponent(EmailComponent.TITLE))
.addToBody(await EmailComponentManager.getComponent(EmailComponent.TEXT1))
.addToBody(await EmailComponentManager.getComponent(EmailComponent.BUTTON))
.buildTemplate();
+ console.log(context);
template.resolve(i18nInstance, context,prefix);
- console.log(template.getTemplate());
+ if (Utils.isDevelopmentEnv()) {
fs.writeFileSync('./file.txt',template.getTemplate(),'utf-8');
+ }
const html = template.getHtml();
emailContent = {
to: user.email,

MODIFY
src/notification/email/mjml-components/footer.mjml
src/notification/email/mjml-components/footer.mjml
</mj-section>
<mj-section>
- <mj-column width="65%">
- <mj-image align="left" width="50px" href="{{appUrl}}" src="{{evseDashboardURL}}/assets/img/info.png"></mj-image>
- </mj-column>
- <mj-column width="35%">
- <mj-table>
- <tr style="list-style: none;line-height:1">
- <td> <a href="https://twitter.com/RecastAI">
- <img width="25" src="https://cdn.recast.ai/newsletter/twitter.png" />
- </a> </td>
- <td> <a href="https://www.facebook.com/recastAI">
- <img width="25" src="https://cdn.recast.ai/newsletter/facebook.png" />
- </a> </td>
- <td> <a href="https://medium.com/@RecastAI">
- <img width="25" src="https://cdn.recast.ai/newsletter/medium.png" />
- </a> </td>
- <td> <a href="https://www.youtube.com/channel/UCA0UZlR8crpgwFiVaSTbVWw">
- <img width="25" src="https://cdn.recast.ai/newsletter/youtube.png" />
- </a> </td>
- <td> <a href="https://plus.google.com/u/0/+RecastAi">
- <img width="25" src="https://cdn.recast.ai/newsletter/google%2B.png" />
- </a> </td>
- </tr>
- </mj-table>
+ <mj-column>
+ <mj-image width="50px" href="{{appUrl}}" src="https://imgur.com/VU2plEe.png"></mj-image>
</mj-column>
</mj-section>

MODIFY
src/notification/email/mjml-template/MjmlTemplate.ts
src/notification/email/mjml-template/MjmlTemplate.ts
@@ -18,15 +18,10 @@ export default class MjmlTemplate {
}
public resolve(i18nManager: I18nManager, context: any, prefix: string): void {
- const data = {};
- Utils.flatten(context,data);
- console.log(data);
-
this.preparei18nSelectors(prefix);
-
const i18nSelectors = this.geti18nSelectors();
for (const selector of i18nSelectors) {
- let value = i18nManager.translate(selector,data);
+ let value = i18nManager.translate(selector,context);
if (Array.isArray(value)) {
value = value.join('</br>');
}
@@ -37,7 +32,6 @@ export default class MjmlTemplate {
for (const selector of contextSelectors) {
const keys = this.splitSelector(selector);
const value = this.getValue(keys, context);
- console.log(selector, value);
this.replace(selector,value);
}
}

MODIFY
src/types/UserNotifications.ts
src/types/UserNotifications.ts
@@ -100,6 +100,7 @@ export interface BaseNotification {
tenantLogoURL?: string;
buttonUrl?:string;
appUrl?:string;
+ userFirstName?:string;
}
export interface EndOfChargeNotification extends BaseNotification {

MODIFY
src/utils/Utils.ts
src/utils/Utils.ts
@@ -52,18 +52,6 @@ export default class Utils {
}
}
- public static flatten(context,data, tag = null): any {
- return Object.keys(context).forEach((key) => {
- const tagT = !tag ? key : tag + '.' + key;
- if (typeof context[key] === 'object' && context[key] !== null) {
- this.flatten(context[key],data, tagT);
- } else {
- data[tagT] = context[key];
- }
- });
- }
-
-
public static convertBufferArrayToString(data: ArrayBuffer): string {
if (!data) {
return null;

ADD
test/api/EmailTest.ts
+import { NewRegisteredUserNotification, NotificationSeverity, RequestPasswordNotification } from '../../src/types/UserNotifications';
+
+import ContextDefinition from './context/ContextDefinition';
+import ContextProvider from './context/ContextProvider';
+import EMailNotificationTask from '../../src/notification/email/EMailNotificationTask';
+import I18nManager from '../../src/utils/I18nManager';
+import MongoDBStorage from '../../src/storage/mongodb/MongoDBStorage';
+import Tenant from '../../src/types/Tenant';
+import User from '../../src/types/User';
+import chai from 'chai';
+import chaiSubset from 'chai-subset';
+import config from '../config';
+import global from '../../src/types/GlobalType';
+import responseHelper from '../helpers/responseHelper';
+
+chai.use(chaiSubset);
+chai.use(responseHelper);
+
+describe('Initialization', () => {
+ jest.setTimeout(9990000);
+
+ beforeAll(async () => {
+ global.database = new MongoDBStorage(config.get('storage'));
+ await global.database.start();
+ I18nManager.initialize();
+ });
+
+ afterAll(async () => {
+ // Close DB connection
+ await global.database.stop();
+ });
+
+ describe('Email', () => {
+ const emailNotificationTask = new EMailNotificationTask();
+ let user : User;
+ let tenant : Tenant;
+ const severity = 'INFO' as NotificationSeverity;
+
+ let data: any;
+ beforeAll(async () => {
+ const tenantContext = await ContextProvider.defaultInstance.getTenantContext(ContextDefinition.TENANT_CONTEXTS.TENANT_WITH_ALL_COMPONENTS);
+ user = tenantContext.getUserContext(ContextDefinition.USER_CONTEXTS.DEFAULT_ADMIN);
+ tenant = tenantContext.getTenant();
+ });
+
+ it('request-password', async () => {
+ data = {
+ user,
+ evseDashboardResetPassURL:'some_url',
+ evseDashboardURL:'some_url2'
+ } as RequestPasswordNotification;
+ await emailNotificationTask.sendRequestPassword(data,user,tenant,severity);
+ });
+
+ it('new-registered-user', async () => {
+ data = {
+ tenant: tenant.subdomain,
+ user,
+ evseDashboardURL: 'some_url',
+ evseDashboardVerifyEmailURL: 'some_url',
+ } as NewRegisteredUserNotification;
+ await emailNotificationTask.sendNewRegisteredUser(data,user,tenant,severity);
+ });
+ });
+});
+

unit testing