зеркало из
1
0
Форкнуть 0
fxa-email-event-proxy/tests/sendgrid.js

668 строки
20 KiB
JavaScript

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
'use strict'
const chai = require('chai')
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const P = require('bluebird')
chai.use(require('chai-as-promised'))
const { assert } = chai
/* eslint-env mocha */
suite('sendgrid:', () => {
let sqs, proxy, deliveryQueueUrl, bounceQueueUrl, complaintQueueUrl, error
setup(() => {
process.env.AUTH = 'authentication string'
process.env.PROVIDER = 'sendgrid'
process.env.SQS_SUFFIX = 'wibble'
process.env.DELIVERY_QUEUE_URL = deliveryQueueUrl = 'fxa-email-delivery'
process.env.BOUNCE_QUEUE_URL = bounceQueueUrl = 'fxa-email-bounce'
process.env.COMPLAINT_QUEUE_URL = complaintQueueUrl = 'fxa-email-complaint'
sinon.spy(console, 'log')
sinon.spy(console, 'error')
function SQS () {}
SQS.prototype = sqs = { sendMessage: () => {} }
sinon.stub(sqs, 'sendMessage').callsFake(() => {
return {
promise: () => {
if (error) {
return P.reject(error)
}
return P.resolve()
}
}
})
proxy = proxyquire('../', {
'aws-sdk': {
SQS
}
})
})
teardown(() => {
console.log.restore()
console.error.restore()
})
test('interface is correct', () => {
assert.isObject(proxy)
assert.isFunction(proxy.main)
assert.lengthOf(proxy.main, 1)
})
suite('call with an event array:', () => {
setup(done => {
proxy.main([
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'processed',
sg_event_id: 'be8eYqItNxixRpMOG1eoGg==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'deferred',
sg_event_id: 'J4wu57qAC1ftwo0gu0eMEQ==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0'
},
{
email: 'bar@example.com',
timestamp: 1529507951,
event: 'delivered',
sg_event_id: 'XrVChmcNybFOoRSukqXL-Q==',
sg_message_id: 'deadbeef.baadf00d.filter0001.16648.5515E0B88.0',
response: '250 OK'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'open',
sg_event_id: '-VYMCtsyK2VMiUcizsfHRg==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'click',
sg_event_id: 'YXTht66W-BqXBMmSO5oYEA==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0'
},
{
email: 'baz@example.com',
timestamp: 1529507952,
event: 'bounce',
sg_event_id: 'ZFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: 'deadbeef.baadf00d',
status: '5.0.0'
},
{
email: 'qux@example.com',
timestamp: 1529507953,
event: 'bounce',
sg_event_id: 'AFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: 'deadbeef',
status: '4.0.0'
},
{
email: 'wibble@example.com',
timestamp: 1529507954,
event: 'bounce',
sg_event_id: 'BFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '1.filter0001.16648.5515E0B88.0',
status: '5.1.1'
},
{
email: 'blee@example.com',
timestamp: 1529507955,
event: 'bounce',
sg_event_id: 'CFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '2.filter0001.16648.5515E0B88.0',
status: '4.2.2'
},
{
email: 'glug@example.com',
timestamp: 1529507956,
event: 'bounce',
sg_event_id: 'DFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '3.filter0001.16648.5515E0B88.0',
status: '4.2.3'
},
{
email: 'zip@example.com',
timestamp: 1529507957,
event: 'bounce',
sg_event_id: 'EFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '4.filter0001.16648.5515E0B88.0',
status: '5.6.0'
},
{
email: 'foo@example.com',
timestamp: 0,
event: 'bounce',
sg_event_id: 'EFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '5.filter0001.16648.5515E0B88.0',
status: '5.6.0'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: '',
sg_event_id: 'EFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '5.filter0001.16648.5515E0B88.0',
status: '5.6.0'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'bounce',
sg_event_id: 'EFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '',
status: '5.6.0'
},
{},
{
email: 'pop@example.com',
timestamp: 1529507958,
event: 'dropped',
sg_event_id: 'df7Bf7jbphkC1SxCbaF_og==',
sg_message_id: '5.filter0001.16648.5515E0B88.0',
status: '5.0.0'
},
{
email: 'gom@example.com',
timestamp: 1529507959,
event: 'spamreport',
sg_event_id: '9E0fndeHZ8KvAVm6TGOQ2A==',
sg_message_id: '6.filter0001.16648.5515E0B88.0'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'unsubscribe',
sg_event_id: '-_DeZAhMEvyjsT3WgS0Cwg==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'group_unsubscribe',
sg_event_id: 'wpuMn9Ud2ADJqudDQGPMVw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0'
},
{
email: 'foo@example.com',
timestamp: 1529507950,
event: 'group_resubscribe',
sg_event_id: 'NjTlbHZDYoLQuqhcgyQtqw==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0'
}
])
setImmediate(done)
})
test('sqs.sendMessage was called nine times', () => {
assert.equal(sqs.sendMessage.callCount, 9)
})
test('sqs.sendMessage was called correctly first time', () => {
const args = sqs.sendMessage.args[0][0]
assert.equal(args.QueueUrl, deliveryQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Delivery',
mail: {
timestamp: '2018-06-20T15:19:11.000Z',
messageId: 'deadbeef.baadf00d'
},
delivery: {
timestamp: '2018-06-20T15:19:11.000Z',
recipients: [ 'bar@example.com' ],
smtpResponse: '250 OK'
}
})
})
test('sqs.sendMessage was called correctly second time', () => {
const args = sqs.sendMessage.args[1][0]
assert.equal(args.QueueUrl, bounceQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Bounce',
mail: {
timestamp: '2018-06-20T15:19:12.000Z',
messageId: 'deadbeef.baadf00d'
},
bounce: {
bounceType: 'Permanent',
bounceSubType: 'General',
bouncedRecipients: [ { emailAddress: 'baz@example.com' } ],
feedbackId: 'ZFhGF8ap7qNCE8sEnJr2nQ==',
timestamp: '2018-06-20T15:19:12.000Z'
}
})
})
test('sqs.sendMessage was called correctly third time', () => {
const args = sqs.sendMessage.args[2][0]
assert.equal(args.QueueUrl, bounceQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Bounce',
mail: {
timestamp: '2018-06-20T15:19:13.000Z',
messageId: 'deadbeef'
},
bounce: {
bounceType: 'Transient',
bounceSubType: 'General',
bouncedRecipients: [ { emailAddress: 'qux@example.com' } ],
feedbackId: 'AFhGF8ap7qNCE8sEnJr2nQ==',
timestamp: '2018-06-20T15:19:13.000Z'
}
})
})
test('sqs.sendMessage was called correctly fourth time', () => {
const args = sqs.sendMessage.args[3][0]
assert.equal(args.QueueUrl, bounceQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Bounce',
mail: {
timestamp: '2018-06-20T15:19:14.000Z',
messageId: '1'
},
bounce: {
bounceType: 'Permanent',
bounceSubType: 'NoEmail',
bouncedRecipients: [ { emailAddress: 'wibble@example.com' } ],
feedbackId: 'BFhGF8ap7qNCE8sEnJr2nQ==',
timestamp: '2018-06-20T15:19:14.000Z'
}
})
})
test('sqs.sendMessage was called correctly fifth time', () => {
const args = sqs.sendMessage.args[4][0]
assert.equal(args.QueueUrl, bounceQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Bounce',
mail: {
timestamp: '2018-06-20T15:19:15.000Z',
messageId: '2'
},
bounce: {
bounceType: 'Transient',
bounceSubType: 'MailboxFull',
bouncedRecipients: [ { emailAddress: 'blee@example.com' } ],
feedbackId: 'CFhGF8ap7qNCE8sEnJr2nQ==',
timestamp: '2018-06-20T15:19:15.000Z'
}
})
})
test('sqs.sendMessage was called correctly sixth time', () => {
const args = sqs.sendMessage.args[5][0]
assert.equal(args.QueueUrl, bounceQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Bounce',
mail: {
timestamp: '2018-06-20T15:19:16.000Z',
messageId: '3'
},
bounce: {
bounceType: 'Transient',
bounceSubType: 'MessageTooLarge',
bouncedRecipients: [ { emailAddress: 'glug@example.com' } ],
feedbackId: 'DFhGF8ap7qNCE8sEnJr2nQ==',
timestamp: '2018-06-20T15:19:16.000Z'
}
})
})
test('sqs.sendMessage was called correctly seventh time', () => {
const args = sqs.sendMessage.args[6][0]
assert.equal(args.QueueUrl, bounceQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Bounce',
mail: {
timestamp: '2018-06-20T15:19:17.000Z',
messageId: '4'
},
bounce: {
bounceType: 'Permanent',
bounceSubType: 'ContentRejected',
bouncedRecipients: [ { emailAddress: 'zip@example.com' } ],
feedbackId: 'EFhGF8ap7qNCE8sEnJr2nQ==',
timestamp: '2018-06-20T15:19:17.000Z'
}
})
})
test('sqs.sendMessage was called correctly eighth time', () => {
const args = sqs.sendMessage.args[7][0]
assert.equal(args.QueueUrl, bounceQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Bounce',
mail: {
timestamp: '2018-06-20T15:19:18.000Z',
messageId: '5'
},
bounce: {
bounceType: 'Permanent',
bounceSubType: 'Suppressed',
bouncedRecipients: [ { emailAddress: 'pop@example.com' } ],
feedbackId: 'df7Bf7jbphkC1SxCbaF_og==',
timestamp: '2018-06-20T15:19:18.000Z'
}
})
})
test('sqs.sendMessage was called correctly ninth time', () => {
const args = sqs.sendMessage.args[8][0]
assert.equal(args.QueueUrl, complaintQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.equal(args.QueueUrl, complaintQueueUrl)
assert.deepEqual(message, {
notificationType: 'Complaint',
mail: {
timestamp: '2018-06-20T15:19:19.000Z',
messageId: '6'
},
complaint: {
complainedRecipients: [ { emailAddress: 'gom@example.com' } ],
feedbackId: '9E0fndeHZ8KvAVm6TGOQ2A==',
timestamp: '2018-06-20T15:19:19.000Z'
}
})
})
})
suite('call delivery without error:', () => {
let promise
setup(done => {
promise = proxy.main([{
email: 'bar@example.com',
timestamp: 1529507951,
event: 'delivered',
sg_event_id: 'XrVChmcNybFOoRSukqXL-Q==',
sg_message_id: 'deadbeef.baadf00d.filter0001.16648.5515E0B88.0',
response: '250 OK'
}])
setImmediate(done)
})
test('console.log was called correctly', () => {
assert.equal(console.log.callCount, 1)
const args = console.log.args[0]
assert.lengthOf(args, 2)
assert.equal(args[0], 'Sent:')
assert.equal(args[1], 'Delivery')
})
test('console.error was not called', () => {
assert.equal(console.error.callCount, 0)
})
test('promise is resolved', () => {
assert.isFulfilled(promise)
})
test('result is correct', () => {
return promise.then(result => assert.deepEqual(result, {
statusCode: 200,
body: '{"result":"Processed 1 events"}',
isBase64Encoded: false
}))
})
})
suite('call delivery with error:', () => {
let thrownError
setup(() => {
error = new Error('foo')
return proxy.main([{
email: 'bar@example.com',
timestamp: 1529507951,
event: 'delivered',
sg_event_id: 'XrVChmcNybFOoRSukqXL-Q==',
sg_message_id: 'deadbeef.baadf00d.filter0001.16648.5515E0B88.0',
response: '250 OK'
}])
.catch(e => thrownError = e)
})
teardown(() => {
error = undefined
})
test('console.log was not called', () => {
assert.equal(console.log.callCount, 0)
})
test('console.error was called twice', () => {
assert.equal(console.error.callCount, 2)
})
test('console.error was called correctly first time', () => {
const args = console.error.args[0]
assert.lengthOf(args, 2)
assert.equal(args[0], 'Failed to send event:')
assert.deepEqual(args[1], {
notificationType: 'Delivery',
mail: {
timestamp: '2018-06-20T15:19:11.000Z',
messageId: 'deadbeef.baadf00d'
},
delivery: {
timestamp: '2018-06-20T15:19:11.000Z',
recipients: [ 'bar@example.com' ],
smtpResponse: '250 OK'
}
})
})
test('console.error was called correctly second time', () => {
const args = console.error.args[1]
assert.lengthOf(args, 1)
assert.equal(args[0], error.stack)
})
test('call failed', () => {
assert.instanceOf(thrownError, Error)
assert.equal(error.message, 'foo')
})
})
suite('call bounce without error:', () => {
setup(done => {
proxy.main([{
email: 'blee@example.com',
timestamp: 1529507955,
event: 'bounce',
sg_event_id: 'CFhGF8ap7qNCE8sEnJr2nQ==',
sg_message_id: '2.filter0001.16648.5515E0B88.0',
status: '4.2.2'
}])
setImmediate(done)
})
test('console.log was called correctly', () => {
assert.equal(console.log.callCount, 1)
const args = console.log.args[0]
assert.lengthOf(args, 2)
assert.equal(args[0], 'Sent:')
assert.equal(args[1], 'Bounce')
})
test('console.error was not called', () => {
assert.equal(console.error.callCount, 0)
})
})
suite('call complaint without error:', () => {
setup(done => {
proxy.main([{
email: 'gom@example.com',
timestamp: 1529507959,
event: 'spamreport',
sg_event_id: '9E0fndeHZ8KvAVm6TGOQ2A==',
sg_message_id: '6.filter0001.16648.5515E0B88.0'
}])
setImmediate(done)
})
test('console.log was called correctly', () => {
assert.equal(console.log.callCount, 1)
const args = console.log.args[0]
assert.lengthOf(args, 2)
assert.equal(args[0], 'Sent:')
assert.equal(args[1], 'Complaint')
})
test('console.error was not called', () => {
assert.equal(console.error.callCount, 0)
})
})
suite('call with an authorised request object:', () => {
setup(done => {
proxy.main({
body: JSON.stringify({
email: 'foo@example.com',
timestamp: 1529507950,
event: 'delivered',
sg_event_id: 'be8eYqItNxixRpMOG1eoGg==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
response: '200 OK'
}),
queryStringParameters: {
auth: 'authentication string'
}
})
setImmediate(done)
})
test('sqs.sendMessage was called once', () => {
assert.equal(sqs.sendMessage.callCount, 1)
})
test('sqs.sendMessage was called correctly', () => {
const args = sqs.sendMessage.args[0][0]
assert.equal(args.QueueUrl, deliveryQueueUrl)
const messageBody = JSON.parse(args.MessageBody)
const message = JSON.parse(messageBody.Message)
assert.deepEqual(message, {
notificationType: 'Delivery',
mail: {
timestamp: '2018-06-20T15:19:10.000Z',
messageId: '14c5d75ce93.dfd.64b469'
},
delivery: {
timestamp: '2018-06-20T15:19:10.000Z',
recipients: [ 'foo@example.com' ],
smtpResponse: '200 OK'
}
})
})
})
suite('call with an unauthorised request object:', () => {
let promise
setup(() => {
promise = proxy.main({
body: JSON.stringify({
email: 'foo@example.com',
timestamp: 1529507950,
event: 'delivered',
sg_event_id: 'be8eYqItNxixRpMOG1eoGg==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
response: '200 OK'
}),
queryStringParameters: {
auth: 'authentication stringx'
}
})
return promise
})
test('sqs.sendMessage was not called', () => {
assert.equal(sqs.sendMessage.callCount, 0)
})
test('promise is resolved', () => {
assert.isFulfilled(promise)
})
test('result is correct', () => {
return promise.then(result => assert.deepEqual(result, {
statusCode: 401,
body: '{"error":"Unauthorized","errno":999,"code":401,"message":"Request must provide a valid auth query param."}',
isBase64Encoded: false
}))
})
})
suite('call without query params:', () => {
let promise
setup(() => {
promise = proxy.main({
body: JSON.stringify({
email: 'foo@example.com',
timestamp: 1529507950,
event: 'delivered',
sg_event_id: 'be8eYqItNxixRpMOG1eoGg==',
sg_message_id: '14c5d75ce93.dfd.64b469.filter0001.16648.5515E0B88.0',
response: '200 OK'
})
})
return promise
})
test('sqs.sendMessage was not called', () => {
assert.equal(sqs.sendMessage.callCount, 0)
})
test('promise is resolved', () => {
assert.isFulfilled(promise)
})
test('result is correct', () => {
return promise.then(result => assert.deepEqual(result, {
statusCode: 401,
body: '{"error":"Unauthorized","errno":999,"code":401,"message":"Request must provide a valid auth query param."}',
isBase64Encoded: false
}))
})
})
})