Skip to content

Instantly share code, notes, and snippets.

@superduper

superduper/spicy-chai.js

Last active Nov 26, 2017
Embed
What would you like to do?
// http client
const chai = require('chai');
const chaiHttp = require('chai-http');
chai.use(chaiHttp);
const should = chai.should();
/*
* chai enhanced request factory
*
* Allows to transform requests before sending. Add transformer functions by
* calling `addRequestTransformer` and passing a function that mutates request.
*
* You can add more than one request transformer.
*
* Requires: ES5
*
* Usage:
*
* const client = spicyChai('http://example.com');
* const credentials = {
* 'username': 'user@example.com',
* 'password': 'password1234'
* };
*
* client.post('/account/login')
* .send(credentials)
* .end((err, res) => {
* const authToken = res.body['access_token'];
* client.addRequestTransformer((req) => {
* req.set('Authorization', `Bearer ${authToken}`);
* });
* });
*
**/
function spicyChai(baseUrl) {
const __requestTransformers = [];
// kudos to Dr. Axel Rauschmayer
// http://exploringjs.com/es6/ch_proxies.html#_intercepting-method-calls
const handler = {
get(target, propKey, receiver) {
// intercept call to addRequestTransformer()
if (propKey === 'addRequestTransformer') {
return function(...args) {
__requestTransformers.push(...args);
};
}
// intercept other calls
const origMethod = target[propKey];
return function(...args) {
let result = origMethod.apply(this, args);
// chain through transformers
for (const runTransformerFn of __requestTransformers) {
const newResult = runTransformerFn(result);
// don't rewrite request with undefined if
// transformer didn't return anything
if (newResult) {
result = newResult;
}
}
return result;
};
}
};
return new Proxy(chai.request(baseUrl), handler);
}
/*
* Example usage with test assertions
*/
const apiUrl = 'http://api.example.com';
const client = spicyChai(apiUrl); // equivalent of chai.request(apiUrl)
describe('Test Login Operations', function() {
describe('Login', () => {
it('should login as dave', (done) => {
client.post('/account/login').send({
'username': 'user@example.com',
'password': 'password1234'
}).end((err, res) => {
should.not.exist(err);
const authToken = res.body['access_token'];
client.addRequestTransformer((req) => {
req.set('Authorization', `Bearer ${authToken}`);
});
done();
});
});
it('should get a profile', (done) => {
client.get('/account/profile').end((err, res) => {
should.not.exist(err);
done();
});
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.