diff --git a/test/baker-controller-test.js b/test/baker-controller-test.js deleted file mode 100644 index 6d33d647..00000000 --- a/test/baker-controller-test.js +++ /dev/null @@ -1,154 +0,0 @@ -var fs = require('fs'); -var nock = require('nock'); -var vows = require('vows'); -var assert = require('assert'); -var should = require('should'); -var request = require('request'); -var mysql = require('../lib/mysql'); -var conmock = require('./conmock.js'); -var fixture = require('../lib/utils.js').fixture; -var controller = require('../controllers/baker.js'); - -var imagedata = fs.readFileSync(__dirname + '/utils/images/no-badge-data.png') -var scope = nock('http://example.com') - .intercept('/missing.json', 'HEAD').reply(404, '') - .get('/missing.json').reply(404, '') - - .intercept('/invalid.json', 'HEAD').reply(200, '') - .get('/invalid.json').reply(200, 'eeeeyyyyy', { 'Content-Type': 'application/json' }) - - .intercept('/invalid-content-type.json', 'HEAD').reply(200, '') - .get('/invalid-content-type.json').reply(200, fixture()) - - .intercept('/missing-image.json', 'HEAD').reply(200, '') - .get('/missing-image.json') - .reply(200, fixture({'badge.image': 'http://example.com/image-not-found.png'}), { 'Content-Type': 'application/json' }) - - .intercept('/image-not-found.png', 'HEAD').reply(404, '') - .get('/image-not-found.png').reply(404, '') - - .intercept('/legit.json', 'HEAD').reply(200, '') - .get('/legit.json') - .reply(200, fixture({ - 'badge.image': 'http://example.com/image.png', - 'recipient': 'brian@example.com' - }), { 'Content-Type': 'application/json' }) - - .intercept('/image.png', 'HEAD').reply(200, '', { 'Content-Type': 'image/png' }) - .get('/image.png').reply(200, imagedata, { 'Content-Type': 'image/png' }) - - .intercept('/legit-award.json', 'HEAD').reply(200, '') - .get('/legit-award.json') - .reply(200, fixture({ - 'badge.image': 'http://example.com/image-award.png', - 'recipient': 'brian@example.com' - }), { 'Content-Type': 'application/json' }) - - .intercept('/image-award.png', 'HEAD').reply(200, '', { 'Content-Type': 'image/png' }) - .get('/image-award.png').reply(200, imagedata, { 'Content-Type': 'image/png' }) - - .intercept('/invalidAssertion', 'HEAD').reply(200, '') - .get('/invalidAssertion') - .reply(200, fixture({ - 'badge.image': 'http://example.com/image.png', - // invalid content for email - 'recipient': 'example.com' - }), { 'Content-Type': 'application/json' }) -; - -mysql.prepareTesting(); -vows.describe('baker controller testing').addBatch({ - '#baker called with a' : { - 'missing assertion url': { - topic : function () { - conmock(controller.baker, {}, this.callback); - }, - 'renders the creator' : function (error, mock) { - mock.fntype.should.equal('render'); - mock.path.should.equal('baker'); - } - }, - 'bogus assertion url': { - topic : function () { - var req = { query: { assertion: 'wuuuuut' } }; - conmock(controller.baker, req, this.callback); - }, - 'returns 400, unreachable' : function (error, mock) { - mock.headers.should.have.property('Content-Type', 'application/json'); - mock.body.should.match(/unreachable/i); - } - }, - 'correct, but missing assertion url': { - topic : function () { - var req = { query: { assertion: 'http://example.com/missing.json' } }; - conmock(controller.baker, req, this.callback); - }, - 'returns 400, unreachable assertion' : function (error, mock) { - mock.body.should.match(/unreachable/i); - mock.body.should.match(/assertion/i); - } - }, - 'valid url, but the endpoint is not the right content type': { - topic : function () { - var req = { query: { assertion: 'http://example.com/invalid-content-type.json' } }; - conmock(controller.baker, req, this.callback); - }, - 'returns 400, content type error' : function (error, mock) { - mock.status.should.equal(400); - mock.body.should.match(/ContentType/); - } - }, - 'valid url, valid content-type, but the content is unparseable ': { - topic : function () { - var req = { query: { assertion: 'http://example.com/invalid.json' } }; - conmock(controller.baker, req, this.callback); - }, - 'returns 400, parse error' : function (error, mock) { - mock.status.should.equal(400); - mock.body.should.match(/ParseError/); - } - }, - 'valid assertion, but the image url 404s ': { - topic : function () { - var req = { query: { assertion: 'http://example.com/missing-image.json' } }; - conmock(controller.baker, req, this.callback); - }, - 'returns 400, unreachable image' : function (error, mock) { - mock.status.should.equal(400); - mock.body.match(/unreachable/); - mock.body.match(/image/); - } - }, - 'valid assertion, valid image url ': { - topic : function () { - var req = { query: { assertion: 'http://example.com/legit.json' } }; - conmock(controller.baker, req, this.callback); - }, - 'returns 200, baked image data' : function (error, mock) { - mock.headers.should.have.property('Content-Type', 'image/png'); - mock.status.should.equal(200); - } - }, - 'valid assertion, valid image url, trying to award': { - topic : function () { - var req = { query: { assertion: 'http://example.com/legit-award.json', award: 'brian@example.com' } }; - conmock(controller.baker, req, this.callback); - }, - 'returns 200, baked image data' : function (error, mock) { - mock.headers.should.have.property('Content-Type', 'image/png'); - mock.headers.should.have.property('x-badge-awarded', 'brian@example.com'); - mock.status.should.equal(200); - } - }, - 'Valid assertion url, but invalid assertion content':{ - topic: function(){ - var req = { query: { assertion: 'http://example.com/invalidAssertion'}}; - conmock(controller.baker, req, this.callback); - }, - 'returns 400, Invalid Assertion': function(error, mock){ - mock.status.should.equal(400); - mock.body.should.match(/invalid/); - } - } - } -}).export(module); diff --git a/test/baker-controller.test.js b/test/baker-controller.test.js new file mode 100644 index 00000000..539053c8 --- /dev/null +++ b/test/baker-controller.test.js @@ -0,0 +1,210 @@ +const test = require('tap').test; +const testUtils = require('./'); +const nock = require('nock'); +const fs = require('fs'); +const baker = require('../controllers/baker'); +const conmock = require('./conmock'); + +const makeAssertion = testUtils.makeAssertion; +const IMAGEDATA = fs.readFileSync(__dirname + '/utils/images/no-badge-data.png') + +// Mock a bunch of http responses +// ------------------------------ + +const BASE = 'http://example.org'; +const MISSING_JSON = '/missing.json'; +const INVALID_JSON = '/invalid.json'; +const INVALID_CONTENT_TYPE = '/invalid-content-type.json'; +const MISSING_IMAGE = '/missing-image.json'; +const LEGIT_REQUEST = '/legit.json'; +const LEGIT_AND_AWARD = '/legit-and-award.json'; +const INVALID_ASSERTION = '/invalid-assertion.json'; +const EXAMPLE_EMAIL = 'brian@example.org'; + +function makeRequest(path) { + return {query: {assertion: makeUrl(path)}}; +} +function makeUrl(path) { + return BASE + path; +} + +nock(BASE) + .intercept(MISSING_JSON, 'HEAD') + .reply(404, '') + .get(MISSING_JSON) + .reply(404, '') + + .intercept(INVALID_JSON, 'HEAD') + .reply(200, '') + .get(INVALID_JSON) + .reply(200, 'eeeeyyyyy', {'Content-Type': 'application/json'}) + + .intercept(INVALID_CONTENT_TYPE, 'HEAD') + .reply(200, '') + .get(INVALID_CONTENT_TYPE) + .reply(200, makeAssertion(), {'Content-Type': 'cheese/brie'}) + + .intercept(MISSING_IMAGE, 'HEAD') + .reply(200, '') + .get(MISSING_IMAGE) + .reply(200, makeAssertion({ + 'badge.image': makeUrl('/image-not-found.png') + }), { 'Content-Type': 'application/json' }) + + .intercept('/image-not-found.png', 'HEAD') + .reply(404, '') + .get('/image-not-found.png') + .reply(404, '') + + .intercept(LEGIT_REQUEST, 'HEAD') + .reply(200, '') + .get(LEGIT_REQUEST) + .reply(200, makeAssertion({ + 'badge.image': makeUrl('/image.png'), + 'recipient': EXAMPLE_EMAIL + }), { 'Content-Type': 'application/json' }) + + .intercept('/image.png', 'HEAD') + .reply(200, '', { 'Content-Type': 'image/png' }) + .get('/image.png') + .reply(200, IMAGEDATA, { 'Content-Type': 'image/png' }) + + .intercept(LEGIT_AND_AWARD, 'HEAD').reply(200, '') + .get(LEGIT_AND_AWARD) + .reply(200, makeAssertion({ + 'badge.image': makeUrl('/image-award.png'), + 'recipient': EXAMPLE_EMAIL + }), { 'Content-Type': 'application/json' }) + + .intercept('/image-award.png', 'HEAD') + .reply(200, '', { 'Content-Type': 'image/png' }) + .get('/image-award.png') + .reply(200, IMAGEDATA, { 'Content-Type': 'image/png' }) + + .intercept(INVALID_ASSERTION, 'HEAD') + .reply(200, '') + .get(INVALID_ASSERTION) + .reply(200, makeAssertion({ + 'badge.image': makeUrl('/image.png'), + // invalid content for email + 'recipient': 'example.com' + }), { 'Content-Type': 'application/json' }) + + +testUtils.prepareDatabase(function () { + const handler = baker.baker; + test('without an assertion', function (t) { + conmock(handler, function (err, mock) { + t.same(mock.fntype, 'render', 'should try to render'); + t.same(mock.status, 200, 'should be 200'); + t.end(); + }); + }); + + test('bogus assertion url', function (t) { + const request = {query: {assertion: 'lol'}}; + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'application/json'); + t.same(mock.status, 400); + t.ok(mock.body.match(/unreachable/i), 'should be unreachable'); + t.end(); + }); + }); + + test('well formed, but missing assertion', function (t) { + const request = makeRequest(MISSING_JSON); + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'application/json'); + t.same(mock.status, 400); + t.ok(mock.body.match(/unreachable/i), 'should be unreachable'); + t.end(); + }); + }); + + test('valid url, invalid content type', function (t) { + const request = makeRequest(INVALID_CONTENT_TYPE); + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'application/json'); + t.ok(mock.body.match(/content-type/i), 'should be content type error'); + t.same(mock.status, 400); + t.end(); + }); + }); + + test('valid url, valid content type, unparseable json', function (t) { + const request = makeRequest(INVALID_JSON); + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'application/json'); + t.ok(mock.body.match(/ParseError/i), 'should be parse error'); + t.same(mock.status, 400); + t.end(); + }); + }); + + test('invalid assertion', function (t) { + const request = makeRequest(INVALID_ASSERTION); + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'application/json'); + t.ok(mock.body.match(/recipient/i), 'should have error with recipient'); + t.same(mock.status, 400); + t.end(); + }); + }); + + test('valid assertion, but the image 404s', function (t) { + const request = makeRequest(MISSING_IMAGE); + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'application/json'); + t.ok(mock.body.match(/unreachable/i), 'should be unreachable'); + t.same(mock.status, 400); + t.end(); + }); + }); + + test('valid assertion, valid image', function (t) { + const request = makeRequest(LEGIT_REQUEST); + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'image/png'); + t.same(mock.status, 200); + t.end(); + }); + }); + + test('valid assertion, valid image, trying to award', function (t) { + const request = makeRequest(LEGIT_AND_AWARD); + request.query.award = EXAMPLE_EMAIL; + conmock({ + handler: handler, + request: request + }, function (err, mock) { + t.same(mock.headers['Content-Type'], 'image/png'); + t.same(mock.headers['x-badge-awarded'], EXAMPLE_EMAIL); + t.same(mock.status, 200); + t.end(); + }); + }); + + testUtils.finish(test); +}); +