Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ build/Release
node_modules
config.json
npmrc

# Email template files
templates/*
84 changes: 84 additions & 0 deletions apiary.apib
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,90 @@ __optionals__ | String | Optional | Object containing all send options (onlyGcm
}


# Group Templates

## Create email template [/api/notification/template]

### Create an HTML email template [POST]
Generates a new HTML email template from a non-HTML input.

**Currently supported formats are .mjml files, using the format specified by [MJML](https://mjml.io/)**

#### Attributes for the json body parameter

Name | Type | Required | Description
--- | --- | --- | ---
__filename__ | String | Required | Name of the email template to be generated
__content__ | String | Required | Input text that will be transformed into HTML
__type__ | String | Required | The input type. Currently can be ´mjml´ **only**

+ Request (application/json; charset=utf-8)

+ Body

{
"filename": "custom-template",
"content": "<mj-body><mj-section><mj-column><mj-text font-size="20px" color="#F45E43" font-family="helvetica">Hello World!</mj-text></mj-column></mj-section></mj-body>",
"type": "mjml"
}

+ Response 200

{
"output": "done"
}

+ Response 400 (application/json; charset=utf-8)

{
"code": "BadRequestError",
"message": "Missing or invalid parameters: content, filename, type"
}

## Email template listing [/api/notification/template/list]

### Fetch list of email templates [GET]
Returns a list of the email template filenames currently available

+ Request (application/json; charset=utf-8)

+ Body

{}

+ Response 200

[
{
"name": "my-template-1",
"type": "html",
},
{
"name": "my-template-2",
"type": "html"
}
]

## Email template details [/api/notification/template/details/:templateName.:type]

### Fetch email template details [GET]
Returns a the content of an email template (either HTML or other) and the placeholders it has in its content.

+ Request (application/json; charset=utf-8)

+ Response 200

{
"html": "<mj-body><mj-section><mj-column><mj-text font-size="20px" color="#F45E43" font-family="helvetica">Hello World!</mj-text></mj-column></mj-section></mj-body>",
"placeholders": ["USER"]
}

+ Response 404

{
"code": "NotFoundError",
"message": "Template not found"
}

# Data Structures

Expand Down
26 changes: 22 additions & 4 deletions cucumber/features/email_features/email_send.feature
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
Feature: the server receives a request to send an email

Scenario Outline: send batch Email to an identity objects
Scenario Outline: send in-body HTML batch Email to identity objects
Given an authenticated identity in the app with <identity_id>
Then a request is sent to <endpoint> to send an email <email> and returns <response>

Examples:
| identity_id | endpoint | email | response |
| identity_id | endpoint | email | response |
| 01f0000000000000003f0001 | /api/notification/email | email/batch/valid_email_over_batch_limit.json | email/valid_email_response.json |
| 01f0000000000000003f0001 | /api/notification/email | email/batch/valid_email_under_batch_limit.json | email/valid_email_response.json |
| 01f0000000000000003f0002 | /api/notification/email | email/batch/invalid_to_email.json | email/invalid_to_email_response.json |
| 01f0000000000000003f0003 | /api/notification/email | email/batch/invalid_from_email.json | email/invalid_from_email_response.json |
| 01f0000000000000003f0001 | /api/notification/email | email/batch/empty_email.json | email/empty_email_response.json |
| 01f0000000000000003f0002 | /api/notification/email | email/batch/missing_email_message.json | email/missing_email_message_response.json |

Scenario Outline: send email to a single email address
Scenario Outline: send custom HTML template batch Email to identity objects
Given an authenticated identity in the app with <identity_id>
Then a request is sent to <endpoint> to send a custom email template <template> for <email> and returns <response>

Examples:
| identity_id | endpoint | template | email | response |
| 01f0000000000000003f0001 | /api/notification/email | email/successful_template_read.json | email/batch/valid_custom_template_email.json | email/valid_email_response.json |
| 01f0000000000000003f0002 | /api/notification/email | email/errored_template_read.json | email/batch/invalid_custom_template_email.json | email/invalid_template_email_response.json |

Scenario Outline: send in-body HTML email to a single email address
Given an authenticated identity in the app with <identity_id>
Then a request is sent to <endpoint> to send an email <email> and returns <response>

Expand All @@ -23,4 +32,13 @@ Feature: the server receives a request to send an email
| 01f0000000000000003f0002 | /api/notification/singleEmail | email/single/invalid_to_single_email.json | email/invalid_to_email_response.json |
| 01f0000000000000003f0003 | /api/notification/singleEmail | email/single/missing_from_single_email.json | email/valid_email_response.json |
| 01f0000000000000003f0001 | /api/notification/singleEmail | email/single/empty_single_email.json | email/empty_email_response.json |
| 01f0000000000000003f0002 | /api/notification/singleEmail | email/single/missing_single_email_message.json | email/missing_email_message_response.json |
| 01f0000000000000003f0002 | /api/notification/singleEmail | email/single/missing_single_email_message.json | email/missing_email_message_response.json |

Scenario Outline: send custom HTML template email to a single email address
Given an authenticated identity in the app with <identity_id>
Then a request is sent to <endpoint> to send a custom email template <template> for <email> and returns <response>

Examples:
| identity_id | endpoint | template | email | response |
| 01f0000000000000003f0001 | /api/notification/singleEmail | email/successful_template_read.json | email/single/valid_custom_template_email.json | email/valid_email_response.json |
| 01f0000000000000003f0002 | /api/notification/singleEmail | email/errored_template_read.json | email/single/invalid_custom_template_email.json | email/invalid_template_email_response.json |
47 changes: 44 additions & 3 deletions cucumber/features/step_definitions/email_steps.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
'use strict';
const config = require('config');
const nock = require('nock');
const sinon = require('sinon');
const fileHandler = require('../../../lib/util/file_handler');
const errors = require('../../../lib/util/errors');

let fileHandlerStub;
nock.disableNetConnect();


const MAILGUN_MESSAGES_BASE_URL = 'https://api.mailgun.net';
const MAILGUN_MESSAGES_ENDPOINT_URL = '/v3/' + config.get('transport.mailgun.domain') + '/messages';

module.exports = function() {

this.World = require('../support/world').World;
Expand All @@ -14,9 +22,6 @@ module.exports = function() {
let emailObj = _this.readJSONResource(email);
let res = _this.readJSONResource(response);

const MAILGUN_MESSAGES_BASE_URL = 'https://api.mailgun.net';
const MAILGUN_MESSAGES_ENDPOINT_URL = '/v3/' + config.get('transport.mailgun.domain') + '/messages';

nock(MAILGUN_MESSAGES_BASE_URL)
.persist() // Required since multiple requests can be made in parallel from the platform
.post(MAILGUN_MESSAGES_ENDPOINT_URL)
Expand All @@ -31,4 +36,40 @@ module.exports = function() {
.expect(res.status)
.end(callback);
});

this.Then(/^a request is sent to (.*) to send a custom email template (.*) for (.*) and returns (.*)$/, function(endpoint, templateFile, email, response, callback) {
let _this = this;

let template = _this.readJSONResource(templateFile);
let emailObj = _this.readJSONResource(email);
let res = _this.readJSONResource(response);
fileHandlerStub = sinon.stub(fileHandler, 'readFile');

if (template.success) {
fileHandlerStub.returns(template.success);
} else {
fileHandlerStub.returns({error: new errors.NotFoundError(template.error.message)});
}

nock(MAILGUN_MESSAGES_BASE_URL)
.persist() // Required since multiple requests can be made in parallel from the platform
.post(MAILGUN_MESSAGES_ENDPOINT_URL)
.reply(200, res.data);

let request = this.buildRequest('POST', endpoint, {
'x-user-id': this.get('identity')
});

request
.send(emailObj)
.expect(res.status)
.end(function(err) {
fileHandlerStub.restore();
if (err) {
return callback(err);
}

return callback();
});
});
};
90 changes: 90 additions & 0 deletions cucumber/features/step_definitions/template_steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'use strict';
const expect = require('chai').expect;
const sinon = require('sinon');
const templatePlatform = require('../../../lib/platforms/template');

let templatePlatformStub = {};

module.exports = function() {

this.World = require('../support/world').World;

this.Then(/^a template object (.*) is sent to (.*) yielding (.*)/, function(requestBody, endpoint, response, callback) {
let _this = this;

let requestBodyObj = _this.readJSONResource(requestBody);
let res = _this.readJSONResource(response);

templatePlatformStub.generateHtmlTemplate = sinon.stub(templatePlatform, 'generateHtmlTemplate');
templatePlatformStub.generateHtmlTemplate.yields(res.stubbed.error, res.stubbed.output);

let request = this.buildRequest('POST', endpoint, {
'x-user-id': this.get('identity')
});

request
.send(requestBodyObj)
.expect(res.result.status)
.end(function(err, output) {
templatePlatformStub.generateHtmlTemplate.restore();
if (err) {
return callback(err);
}

expect(output.body).to.deep.equal(res.result.body);
return callback();
});
});

this.Then(/^a request for template listing is sent to (.*) yielding (.*)$/, function(endpoint, response, callback) {
let _this = this;

let res = _this.readJSONResource(response);

templatePlatformStub.getListOfHtmlTemplates = sinon.stub(templatePlatform, 'getListOfHtmlTemplates');
templatePlatformStub.getListOfHtmlTemplates.yields(res.stubbed.error, res.stubbed.output);

let request = this.buildRequest('GET', endpoint, {
'x-user-id': this.get('identity')
});

request
.send()
.expect(res.result.status)
.end(function(err, output) {
templatePlatformStub.getListOfHtmlTemplates.restore();
if (err) {
return callback(err);
}

expect(output.body).to.deep.equal(res.result.body);
return callback();
});
});

this.Then(/^a request for template details is sent to (.*) yielding (.*)$/, function(endpoint, response, callback) {
let _this = this;

let res = _this.readJSONResource(response);

templatePlatformStub.getTemplateDetails = sinon.stub(templatePlatform, 'getTemplateDetails');
templatePlatformStub.getTemplateDetails.yields(res.stubbed.error, res.stubbed.output);

let request = this.buildRequest('GET', endpoint, {
'x-user-id': this.get('identity')
});

request
.send()
.expect(res.result.status)
.end(function(err, output) {
templatePlatformStub.getTemplateDetails.restore();
if (err) {
return callback(err);
}

expect(output.body).to.deep.equal(res.result.body);
return callback();
});
});
};
10 changes: 10 additions & 0 deletions cucumber/features/template_features/template_create.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Feature: the server receives a request to create a new email template

Scenario Outline: generate an HTML email template based on the request item
Given an authenticated identity in the app with <identity_id>
Then a template object <body> is sent to <endpoint> yielding <response>

Examples:
| identity_id | endpoint | body | response |
| 01f0000000000000003f0001 | /api/notification/template | template/valid_template_creation_body.json | template/valid_template_creation_response.js |
| 01f0000000000000003f0001 | /api/notification/template | template/invalid_template_creation_body.json | template/invalid_template_creation_response.js |
11 changes: 11 additions & 0 deletions cucumber/features/template_features/template_details.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Feature: the server receives a request to send a the details of a given email template

Scenario Outline: return successfully the details associated to a given email template
Given an authenticated identity in the app with <identity_id>
Then a request for template details is sent to <endpoint> yielding <response>

Examples:
| identity_id | endpoint | response |
| 01f0000000000000003f0001 | /api/notification/template/details/some-template.html | template/valid_template_details_response.js |
| 01f0000000000000003f0001 | /api/notification/template/details/no-file.html | template/invalid_template_details_response.js |
| 01f0000000000000003f0001 | /api/notification/template/details/invalid-format | template/missing_type_template_details_response.js |
12 changes: 12 additions & 0 deletions cucumber/features/template_features/template_list.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

Feature: the server receives a request to send a list of the available email templates

Scenario Outline: list successfully the names of the generated email templates
Given an authenticated identity in the app with <identity_id>
Then a request for template listing is sent to <endpoint> yielding <response>

Examples:
| identity_id | endpoint | response |
| 01f0000000000000003f0001 | /api/notification/template/list | template/valid_template_list_response.js |
| 01f0000000000000003f0001 | /api/notification/template/list | template/invalid_template_list_response.js |

15 changes: 15 additions & 0 deletions cucumber/test_files/email/batch/invalid_custom_template_email.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"identities": ["01f0000000000000003f0002"],
"channels": ["buddies"],
"content": {
"to": "[email protected]",
"from": "[email protected]",
"template": {
"filename": "no-file",
"placeholders": {}
},
"subject": "Testing"
}
}


17 changes: 17 additions & 0 deletions cucumber/test_files/email/batch/valid_custom_template_email.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"identities": ["01f0000000000000003f0002"],
"channels": ["buddies"],
"content": {
"to": "[email protected]",
"from": "[email protected]",
"template": {
"filename": "template",
"placeholders": {
"USER": "Mr. Invent"
}
},
"subject": "Testing"
}
}


10 changes: 10 additions & 0 deletions cucumber/test_files/email/errored_template_read.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"error": {
"message": "Template not found",
"statusCode": 404,
"body": {
"code": "NotFoundError",
"message": "Template not found"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"status": 404
}
Loading