Skip to content

Commit

Permalink
feat(email-plugin): Generate test emails from dev mailbox
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Apr 15, 2019
1 parent e38075f commit 35105ec
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 251 deletions.
1 change: 0 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@
"gulp": "^4.0.0",
"mysql": "^2.16.0",
"node-libcurl": "^1.3.3",
"opn": "^5.4.0",
"pg": "^7.8.0",
"rimraf": "^2.6.3",
"sql.js": "^0.5.0",
Expand Down
40 changes: 39 additions & 1 deletion packages/email-plugin/dev-mailbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
}
button#refresh {
margin-left: 12px;
border: 1px solid #15a9df;
border-radius: 3px;
padding: 3px 6px;
display: flex;
Expand All @@ -33,6 +32,20 @@
margin-left: 6px;
font-size: 16px;
}
.generate-controls {
flex: 1;
display: flex;
justify-content: flex-end;
}
input, select, button {
padding: 6px;
border-radius: 3px;
border: 1px solid #15a9df;
margin-left: 3px;
}
#language-code {
width: 32px;
}
.content {
display: flex;
flex: 1;
Expand Down Expand Up @@ -83,6 +96,11 @@ <h1 class="heading">Vendure Dev Mailbox</h1>
<span class="label">Refresh</span>
</button>
</div>
<div class="generate-controls">
<select id="type-selector"></select>
<input id="language-code" value="en" type="text">
<button id="generate-test">Generate test</button>
</div>
</div>
<div class="content">
<div class="list">
Expand All @@ -95,6 +113,26 @@ <h1 class="heading">Vendure Dev Mailbox</h1>
const refreshButton = document.querySelector('button#refresh');
refreshButton.addEventListener('click', refreshInbox);

const typeSelect = document.querySelector('#type-selector');
fetch('./types')
.then(res => res.json())
.then(res => {
res.forEach(type => {
const option = document.createElement('option');
option.value = type;
option.text = type;
typeSelect.appendChild(option);
});
});

const languageCodeInput = document.querySelector('#language-code');
const generateTestButton = document.querySelector('#generate-test');
generateTestButton.addEventListener('click', e => {
fetch(`./generate/${typeSelect.value}/${languageCodeInput.value}`)
.then(() => new Promise(resolve => setTimeout(resolve, 500)))
.then(() => refreshInbox());
});

const list = document.querySelector('.list');
refreshInbox();

Expand Down
143 changes: 0 additions & 143 deletions packages/email-plugin/preview/email-contexts.ts

This file was deleted.

63 changes: 0 additions & 63 deletions packages/email-plugin/preview/generate-email-preview.ts

This file was deleted.

10 changes: 7 additions & 3 deletions packages/email-plugin/src/default-email-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import { AccountRegistrationEvent, OrderStateTransitionEvent, PasswordResetEvent } from '@vendure/core';

import { EmailEventListener } from './event-listener';
import { mockAccountRegistrationEvent, mockOrderStateTransitionEvent, mockPasswordResetEvent } from './mock-events';

export const orderConfirmationHandler = new EmailEventListener('order-confirmation')
.on(OrderStateTransitionEvent)
.filter(event => event.toState === 'PaymentSettled' && !!event.order.customer)
.setRecipient(event => event.order.customer!.emailAddress)
.setSubject(`Order confirmation for #{{ order.code }}`)
.setTemplateVars(event => ({ order: event.order }));
.setTemplateVars(event => ({ order: event.order }))
.setMockEvent(mockOrderStateTransitionEvent);

export const emailVerificationHandler = new EmailEventListener('email-verification')
.on(AccountRegistrationEvent)
Expand All @@ -17,7 +19,8 @@ export const emailVerificationHandler = new EmailEventListener('email-verificati
.setTemplateVars(event => ({
user: event.user,
verifyUrl: 'verify',
}));
}))
.setMockEvent(mockAccountRegistrationEvent);

export const passwordResetHandler = new EmailEventListener('password-reset')
.on(PasswordResetEvent)
Expand All @@ -26,7 +29,8 @@ export const passwordResetHandler = new EmailEventListener('password-reset')
.setTemplateVars(event => ({
user: event.user,
passwordResetUrl: 'reset-password',
}));
}))
.setMockEvent(mockPasswordResetEvent);

export const defaultEmailHandlers = [
orderConfirmationHandler,
Expand Down
43 changes: 41 additions & 2 deletions packages/email-plugin/src/dev-mailbox.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { Channel, RequestContext } from '@vendure/core';
import express from 'express';
import fs from 'fs-extra';
import http from 'http';
import path from 'path';

import { LanguageCode } from '../../common/lib/generated-types';

import { EmailEventHandler } from './event-listener';
import { EmailPluginDevModeOptions, EventWithContext } from './types';

/**
* An email inbox application that serves the contents of the dev mode `outputPath` directory.
*/
export class DevMailbox {
server: http.Server;
private handleMockEventFn: (handler: EmailEventHandler<string, any>, event: EventWithContext) => void | undefined;

serve(port: number, outputPath: string) {
serve(options: EmailPluginDevModeOptions) {
const { outputPath, handlers, mailboxPort } = options;
const server = express();
server.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '../../dev-mailbox.html'));
Expand All @@ -19,12 +27,33 @@ export class DevMailbox {
const contents = await this.getEmailList(outputPath);
res.send(contents);
});
server.get('/types', async (req, res) => {
res.send(handlers.map(h => h.type));
});
server.get('/generate/:type/:languageCode', async (req, res) => {
const { type, languageCode } = req.params;
if (this.handleMockEventFn) {
const handler = handlers.find(h => h.type === type);
if (!handler || !handler.mockEvent) {
res.statusCode = 404;
res.send({ success: false, error: `No mock event registered for type "${type}"`});
return;
}
this.handleMockEventFn(handler, { ...handler.mockEvent, ctx: this.createRequestContext(languageCode) });
res.send({ success: true });
}
res.send({ success: false, error: `Mock email generation not set up.` });
});
server.get('/item/:id', async (req, res) => {
const fileName = req.params.id;
const content = await this.getEmail(outputPath, fileName);
res.send(content);
});
this.server = server.listen(port);
this.server = server.listen(mailboxPort);
}

handleMockEvent(handler: (handler: EmailEventHandler<string, any>, event: EventWithContext) => void) {
this.handleMockEventFn = handler;
}

destroy() {
Expand Down Expand Up @@ -57,4 +86,14 @@ export class DevMailbox {
const content = JSON.parse(json);
return content;
}

private createRequestContext(languageCode: LanguageCode): RequestContext {
return new RequestContext({
languageCode,
session: {} as any,
isAuthorized: false,
authorizedAsOwnerOnly: true,
channel: new Channel(),
});
}
}

0 comments on commit 35105ec

Please sign in to comment.