Skip to content

Commit

Permalink
Add test mode. Fixes #160
Browse files Browse the repository at this point in the history
  • Loading branch information
bojand committed Oct 25, 2018
1 parent 6948911 commit f538ae5
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 8 deletions.
80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ list.members('bob@gmail.com').delete(function (err, data) {
That is, we will try an operation only once with no retries on error. You can also use a config
object compatible with the `async` library for more control as to how the retries take place.
See docs [here](https://caolan.github.io/async/docs.html#retry)
* `testMode` - turn test mode on. If test mode is on, no requests are made, rather the request options and data is logged
* `testModeLogger` - custom test mode logging function


#### Attachments
Expand Down Expand Up @@ -423,6 +425,84 @@ mailgun.parse([ 'test@mail.com', 'test2@mail.com' ], function (err, body) {
});
```

## Debug logging

[debug](https://npmjs.com/package/debug) package is used for debug logging.

```sh
DEBUG=mailgun-js node app.js
```

## Test mode

Test mode can be turned on using `testMode` option. When on, no requests are actually sent to Mailgun, rather we log the request options and applicable payload and form data. By default we log to `console.log`, unless `DEBUG` is turned on, in which case we use debug logging.

```js
mailgun = require('../')({ apiKey: api_key, domain: domain, testMode: true })

const data = {
from: 'mailgunjs+test1@gmail.com',
to: 'mailgunjstest+recv1@gmail.com',
subject: 'Test email subject',
text: 'Test email text'
};

mailgun.messages().send(data, function (error, body) {
console.log(body);
});
```

```
options: { hostname: 'api.mailgun.net',
port: 443,
protocol: 'https:',
path: '/v3/sandbox12345.mailgun.org/messages',
method: 'POST',
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 127 },
auth: 'api:key-0e8pwgtt5ylx0m94xwuzqys2-o0x4-77',
agent: false,
timeout: undefined }
payload: 'to=mailgunjs%2Btest1%40gmail.com&from=mailgunjstest%2Brecv1%40gmail.com&subject=Test%20email%20subject&text=Test%20email%20text'
form: undefined
undefined
```

Note that in test mode no error or body are returned as a result.

The logging can be customized using `testModeLogger` option which is a function to perform custom logging.

```js
const logger = (httpOptions, payload, form) => {
const { method, path } = httpOptions
const hasPayload = !!payload
const hasForm = !!form

console.log(`%s %s payload: %s form: %s`, method, path, hasPayload, hasForm)
}

mailgun = require('../')({ apiKey: api_key, domain: domain, testMode: true, testModeLogger: logger })

const data = {
from: 'mailgunjs+test1@gmail.com',
to: 'mailgunjstest+recv1@gmail.com',
subject: 'Test email subject',
text: 'Test email text'
};

mailgun.messages().send(data, function (error, body) {
console.log(body);
});
```

Sample output:

```
POST /v3/sandbox12345.mailgun.org/messages payload: true form: false
undefined
```

## Tests

To run the test suite you must first have a Mailgun account with a domain setup. Then create a file named _./test/data/auth.json_, which contains your credentials as JSON, for example:
Expand Down
2 changes: 2 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- [Promises](/promises)
- [Webhook Validation](/webhook)
- [Email Validation](/email_validation)
- [Debug Logging](/debug)
- [Test Mode](/testmode)
- [Tests](/tests)
- API Reference
- [Message](/api/message)
Expand Down
7 changes: 7 additions & 0 deletions docs/debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Debug logging

[debug](https://npmjs.com/package/debug) package is used for debug logging.

```sh
DEBUG=mailgun-js node app.js
```
69 changes: 69 additions & 0 deletions docs/testmode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## Test mode

Test mode can be turned on using `testMode` option. When on, no requests are actually sent to Mailgun, rather we log the request options and applicable payload and form data. By default we log to `console.log`, unless `DEBUG` is turned on, in which case we use debug logging.

```js
mailgun = require('../')({ apiKey: api_key, domain: domain, testMode: true })

const data = {
from: 'mailgunjs+test1@gmail.com',
to: 'mailgunjstest+recv1@gmail.com',
subject: 'Test email subject',
text: 'Test email text'
};

mailgun.messages().send(data, function (error, body) {
console.log(body);
});
```

```
options: { hostname: 'api.mailgun.net',
port: 443,
protocol: 'https:',
path: '/v3/sandbox12345.mailgun.org/messages',
method: 'POST',
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 127 },
auth: 'api:key-0e8pwgtt5ylx0m94xwuzqys2-o0x4-77',
agent: false,
timeout: undefined }
payload: 'to=mailgunjs%2Btest1%40gmail.com&from=mailgunjstest%2Brecv1%40gmail.com&subject=Test%20email%20subject&text=Test%20email%20text'
form: undefined
undefined
```

Note that in test mode no error or body are returned as a result.

The logging can be customized using `testModeLogger` option which is a function to perform custom logging.

```js
const logger = (httpOptions, payload, form) => {
const { method, path } = httpOptions
const hasPayload = !!payload
const hasForm = !!form

console.log(`%s %s payload: %s form: %s`, method, path, hasPayload, hasForm)
}

mailgun = require('../')({ apiKey: api_key, domain: domain, testMode: true, testModeLogger: logger })

const data = {
from: 'mailgunjs+test1@gmail.com',
to: 'mailgunjstest+recv1@gmail.com',
subject: 'Test email subject',
text: 'Test email text'
};

mailgun.messages().send(data, function (error, body) {
console.log(body);
});
```

Sample output:

```
POST /v3/sandbox12345.mailgun.org/messages payload: true form: false
undefined
```
21 changes: 13 additions & 8 deletions lib/mailgun.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,24 @@ class Mailgun {
this.port = options.port || 443
this.retry = options.retry || 1

this.testMode = options.testMode
this.testModeLogger = options.testModeLogger

if (options.proxy) {
this.proxy = options.proxy
}

this.options = {
'host': this.host,
'endpoint': this.endpoint,
'protocol': this.protocol,
'port': this.port,
'auth': this.auth,
'proxy': this.proxy,
'timeout': this.timeout,
'retry': this.retry
host: this.host,
endpoint: this.endpoint,
protocol: this.protocol,
port: this.port,
auth: this.auth,
proxy: this.proxy,
timeout: this.timeout,
retry: this.retry,
testMode: this.testMode,
testModeLogger: this.testModeLogger
}

this.mailgunTokens = {}
Expand Down
15 changes: 15 additions & 0 deletions lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class Request {
this.proxy = options.proxy
this.timeout = options.timeout
this.retry = options.retry || 1
this.testMode = options.testMode
this.testModeLogger = typeof options.testModeLogger === 'function'
? options.testModeLogger : this.defaultTestModeLogger
}

_request (method, resource, data, fn) {
Expand Down Expand Up @@ -129,6 +132,11 @@ class Request {
opts.agent = new ProxyAgent(this.proxy)
}

if (this.testMode) {
this.testModeLogger(opts, this.payload, this.form)
return fn()
}

if (typeof this.retry === 'object' || this.retry > 1) {
retry(this.retry, (retryCb) => {
this.callback = retryCb
Expand Down Expand Up @@ -372,6 +380,13 @@ class Request {
req.end()
}
}

defaultTestModeLogger (httpOptions, payload, formData) {
const testlog = debug.enabled ? debug : console.log
testlog('options: %o', httpOptions)
testlog('payload: %o', payload)
testlog('form: %o', formData)
}
}

module.exports = Request
117 changes: 117 additions & 0 deletions test/testmode.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const auth = require('./data/auth.json')
const fixture = require('./data/fixture.json')
const clone = require('clone')
const assert = require('assert')
const path = require('path')
const debug = require('debug')

let mailgun
describe('test mode', () => {
describe('default operation', () => {
before(() => {
mailgun = require('../')({
apiKey: auth.api_key,
domain: auth.domain,
testMode: true
})
})

beforeEach(done => {
setTimeout(done, 100)
})

it('test messages().send()', done => {
const msg = clone(fixture.message)

mailgun.messages().send(msg, (err, body) => {
assert.ifError(err)
done()
})
})

it('test messages().send() with attachment using filename', done => {
const msg = clone(fixture.message)
const filename = path.join(__dirname, '/data/mailgun_logo.png')

msg.attachment = filename

mailgun.messages().send(msg, (err, body) => {
assert.ifError(err)

done()
})
})
})

describe('default operation with DEBUG', () => {
before(() => {
mailgun = require('../')({
apiKey: auth.api_key,
domain: auth.domain,
testMode: true
})

debug.enable('mailgun-js')
})

after(() => {
debug.disable()
})

beforeEach(done => {
setTimeout(done, 100)
})

it('test messages().send()', done => {
const msg = clone(fixture.message)

mailgun.messages().send(msg, (err, body) => {
assert.ifError(err)
done()
})
})
})

describe('custom logger', () => {
before(() => {
mailgun = require('../')({
apiKey: auth.api_key,
domain: auth.domain,
testMode: true,
testModeLogger: (httpOptions, payload, form) => {
const { method, path } = httpOptions
const hasPayload = !!payload
const hasForm = !!form

console.log(`%s %s payload: %s form: %s`, method, path, hasPayload, hasForm)
}
})
})

beforeEach(done => {
setTimeout(done, 100)
})

it('test messages().send()', done => {
const msg = clone(fixture.message)

mailgun.messages().send(msg, (err, body) => {
assert.ifError(err)
done()
})
})

it('test messages().send() with attachment using filename', done => {
const msg = clone(fixture.message)
const filename = path.join(__dirname, '/data/mailgun_logo.png')

msg.attachment = filename

mailgun.messages().send(msg, (err, body) => {
assert.ifError(err)

done()
})
})
})
})

0 comments on commit f538ae5

Please sign in to comment.