Add HTTP integration tests

This commit is contained in:
Tankred Hase 2016-06-01 15:20:49 +02:00
parent a27e833a8d
commit 45b7b95a5f
3 changed files with 413 additions and 23 deletions

View File

@ -61,6 +61,7 @@ class REST {
ctx.throw(400, 'Invalid request!'); ctx.throw(400, 'Invalid request!');
} }
yield this._userId.verify(q); yield this._userId.verify(q);
ctx.body = 'Key successfully verified!';
} }
/** /**
@ -97,6 +98,7 @@ class REST {
ctx.throw(400, 'Invalid request!'); ctx.throw(400, 'Invalid request!');
} }
yield this._publicKey.requestRemove(q); yield this._publicKey.requestRemove(q);
ctx.status = 202;
} }
/** /**
@ -109,6 +111,7 @@ class REST {
ctx.throw(400, 'Invalid request!'); ctx.throw(400, 'Invalid request!');
} }
yield this._publicKey.verifyRemove(q); yield this._publicKey.verifyRemove(q);
ctx.body = 'Key successfully removed!';
} }
} }

View File

@ -3,49 +3,335 @@
require('co-mocha')(require('mocha')); // monkey patch mocha for generators require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const request = require('supertest'); const request = require('supertest');
const Mongo = require('../../src/dao/mongo');
const nodemailer = require('nodemailer');
const log = require('npmlog');
const config = require('config');
const fs = require('fs'); const fs = require('fs');
const expect = require('chai').expect;
const sinon = require('sinon');
describe.skip('Koa App (HTTP Server) Integration Tests', function() { log.level = config.log.level;
describe('Koa App (HTTP Server) Integration Tests', function() {
this.timeout(20000); this.timeout(20000);
let app, pgpKey1; let app, mongo,
sendEmailStub, publicKeyArmored, emailParams;
const DB_TYPE_PUB_KEY = 'publickey';
const DB_TYPE_USER_ID = 'userid';
const primaryEmail = 'safewithme.testuser@gmail.com';
before(function *() { before(function *() {
pgpKey1 = fs.readFileSync(__dirname + '/../key1.asc', 'utf8'); publicKeyArmored = fs.readFileSync(__dirname + '/../key1.asc', 'utf8');
let credentials;
try {
credentials = require('../../credentials.json');
} catch(e) {
log.info('mongo-test', 'No credentials.json found ... using environment vars.');
}
mongo = new Mongo({
uri: process.env.MONGO_URI || credentials.mongo.uri,
user: process.env.MONGO_USER || credentials.mongo.user,
password: process.env.MONGO_PASS || credentials.mongo.pass
});
yield mongo.connect();
sendEmailStub = sinon.stub().returns(Promise.resolve({ response:'250' }));
sendEmailStub.withArgs(sinon.match(recipient => {
return recipient.to.address === primaryEmail;
}), sinon.match(params => {
emailParams = params;
return !!params.nonce;
}));
sinon.stub(nodemailer, 'createTransport').returns({
templateSender: () => { return sendEmailStub; }
});
global.testing = true; global.testing = true;
let init = require('../../src/app'); let init = require('../../src/app');
app = yield init(); app = yield init();
}); });
beforeEach(function *() {
yield mongo.clear(DB_TYPE_PUB_KEY);
yield mongo.clear(DB_TYPE_USER_ID);
emailParams = null;
});
after(function *() {
nodemailer.createTransport.restore();
yield mongo.clear(DB_TYPE_PUB_KEY);
yield mongo.clear(DB_TYPE_USER_ID);
yield mongo.disconnect();
});
describe('REST api', () => { describe('REST api', () => {
describe('POST /api/v1/key', () => { describe('POST /api/v1/key', () => {
it('should return 400 for an invalid body', done => { it('should return 400 for an invalid pgp key', done => {
request(app.listen()) request(app.listen())
.post('/api/v1/key') .post('/api/v1/key')
.send({ foo: 'bar' }) .send({ publicKeyArmored:'foo' })
.expect(400) .expect(400)
.end(done); .end(done);
}); });
it('should return 400 for an invalid primaryEmail', done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored, primaryEmail:'foo' })
.expect(400)
.end(done);
});
it('should return 201 with primaryEmail', done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored, primaryEmail })
.expect(201)
.end(() => {
expect(emailParams).to.exist;
done();
});
});
it('should return 201 without primaryEmail', done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored })
.expect(201)
.end(() => {
expect(emailParams).to.exist;
done();
});
});
});
describe('GET /api/v1/verify', () => {
beforeEach(done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored, primaryEmail })
.expect(201)
.end(done);
});
it('should return 200 for valid params', done => {
request(app.listen())
.get('/api/v1/verify?keyid=' + emailParams.keyid + '&nonce=' + emailParams.nonce)
.expect(200)
.end(done);
});
it('should return 400 for missing keyid and', done => {
request(app.listen())
.get('/api/v1/verify?nonce=' + emailParams.nonce)
.expect(400)
.end(done);
});
it('should return 400 for missing nonce', done => {
request(app.listen())
.get('/api/v1/verify?keyid=' + emailParams.keyid)
.expect(400)
.end(done);
});
});
describe('GET /api/key', () => {
beforeEach(done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored, primaryEmail })
.expect(201)
.end(done);
});
describe('Not yet verified', () => {
it('should return 404', done => {
request(app.listen())
.get('/api/v1/key?keyid=' + emailParams.keyid)
.expect(404).end(done);
});
});
describe('Verified', () => {
beforeEach(done => {
request(app.listen())
.get('/api/v1/verify?keyid=' + emailParams.keyid + '&nonce=' + emailParams.nonce)
.expect(200)
.end(done);
});
it('should return 200 and get key by id', done => {
request(app.listen())
.get('/api/v1/key?keyid=' + emailParams.keyid)
.expect(200, {
_id: emailParams.keyid,
publicKeyArmored
})
.end(done);
});
it('should return 200 and get key email address', done => {
request(app.listen())
.get('/api/v1/key?email=' + primaryEmail)
.expect(200, {
_id: emailParams.keyid,
publicKeyArmored
})
.end(done);
});
it('should return 400 for missing params', done => {
request(app.listen())
.get('/api/v1/key')
.expect(400)
.end(done);
});
it('should return 404 for wrong key id', done => {
request(app.listen())
.get('/api/v1/key?keyid=0123456789ABCDF')
.expect(404)
.end(done);
});
});
});
describe('GET /:email (sharing link)', () => {
beforeEach(done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored, primaryEmail })
.expect(201)
.end(done);
});
describe('Not yet verified', () => {
it('should return 404', done => {
request(app.listen())
.get('/' + primaryEmail)
.expect(404)
.end(done);
});
});
describe('Verified', () => {
beforeEach(done => {
request(app.listen())
.get('/api/v1/verify?keyid=' + emailParams.keyid + '&nonce=' + emailParams.nonce)
.expect(200)
.end(done);
});
it('should return 200 for correct email address', done => {
request(app.listen())
.get('/' + primaryEmail)
.expect(200, publicKeyArmored)
.end(done);
});
it('should return 400 for invalid email', done => {
request(app.listen())
.get('/a@bco')
.expect(400)
.end(done);
});
it('should return 404 for unkown email', done => {
request(app.listen())
.get('/a@b.co')
.expect(404)
.end(done);
});
it('should return 404 for missing email', done => {
request(app.listen())
.get('/')
.expect(404)
.end(done);
});
});
});
describe('DELETE /api/v1/key', () => {
beforeEach(done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored, primaryEmail })
.expect(201)
.end(done);
});
it('should return 202 for key id', done => {
request(app.listen())
.del('/api/v1/key?keyid=' + emailParams.keyid)
.expect(202)
.end(done);
});
it('should return 202 for email address', done => {
request(app.listen())
.del('/api/v1/key?email=' + primaryEmail)
.expect(202)
.end(done);
});
it('should return 400 for invalid params', done => {
request(app.listen())
.del('/api/v1/key')
.expect(400)
.end(done);
});
it('should return 404 for unknown email address', done => {
request(app.listen())
.del('/api/v1/key?email=a@foo.com')
.expect(404)
.end(done);
});
});
describe('GET /api/v1/verifyRemove', () => {
beforeEach(done => {
request(app.listen())
.post('/api/v1/key')
.send({ publicKeyArmored, primaryEmail })
.expect(201)
.end(function() {
request(app.listen())
.del('/api/v1/key?keyid=' + emailParams.keyid)
.expect(202)
.end(done);
});
});
it('should return 200 for key id', done => {
request(app.listen())
.get('/api/v1/verifyRemove?keyid=' + emailParams.keyid + '&nonce=' + emailParams.nonce)
.expect(200)
.end(done);
});
it('should return 400 for invalid params', done => {
request(app.listen())
.get('/api/v1/verifyRemove')
.expect(400)
.end(done);
});
it('should return 404 for unknown email address', done => {
request(app.listen())
.get('/api/v1/verifyRemove?keyid=0123456789ABCDF&nonce=' + emailParams.nonce)
.expect(404)
.end(done);
});
}); });
}); });
describe('HKP api', () => { describe('HKP api', () => {
describe('GET /pks/add', () => {
it.skip('should return 200 for a valid request', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=0xDBC0B3D92B1B86E9')
.expect(200)
.end(done);
});
it('should return 404 if not found', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=0xDBC0B3D92A1B86E9')
.expect(404)
.end(done);
});
});
describe('POST /pks/add', () => { describe('POST /pks/add', () => {
it('should return 400 for an invalid body', done => { it('should return 400 for an invalid body', done => {
request(app.listen()) request(app.listen())
@ -60,11 +346,105 @@ describe.skip('Koa App (HTTP Server) Integration Tests', function() {
request(app.listen()) request(app.listen())
.post('/pks/add') .post('/pks/add')
.type('form') .type('form')
.send('keytext=' + encodeURIComponent(pgpKey1)) .send('keytext=' + encodeURIComponent(publicKeyArmored))
.expect(201) .expect(201)
.end(done); .end(done);
}); });
}); });
describe('GET /pks/lookup', () => {
beforeEach(done => {
request(app.listen())
.post('/pks/add')
.type('form')
.send('keytext=' + encodeURIComponent(publicKeyArmored))
.expect(201)
.end(done);
});
describe('Not yet verified', () => {
it('should return 404', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=0x' + emailParams.keyid)
.expect(404)
.end(done);
});
});
describe('Verified', () => {
beforeEach(done => {
request(app.listen())
.get('/api/v1/verify?keyid=' + emailParams.keyid + '&nonce=' + emailParams.nonce)
.expect(200)
.end(done);
});
it('should return 200 for a valid request', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=0x' + emailParams.keyid)
.expect(200, publicKeyArmored)
.end(done);
});
it('should return 200 for correct email address', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=' + primaryEmail)
.expect(200, publicKeyArmored)
.end(done);
});
it('should return 200 for "mr" (machine readable) option', done => {
request(app.listen())
.get('/pks/lookup?op=get&options=mr&search=' + primaryEmail)
.expect('Content-Type', 'application/pgp-keys; charset=UTF-8')
.expect('Content-Disposition', 'attachment; filename=openpgpkey.asc')
.expect(200, publicKeyArmored)
.end(done);
});
it('should return 400 for invalid email', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=a@bco')
.expect(400)
.end(done);
});
it('should return 404 for unkown email', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=a@b.co')
.expect(404)
.end(done);
});
it('should return 400 for missing params', done => {
request(app.listen())
.get('/pks/lookup?op=get')
.expect(400)
.end(done);
});
it('should return 400 for a invalid key id format', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=' + emailParams.keyid)
.expect(400)
.end(done);
});
it('should return 404 for unkown key id', done => {
request(app.listen())
.get('/pks/lookup?op=get&search=0xDBC0B3D92A1B86E9')
.expect(404)
.end(done);
});
it('should return 501 (Not implemented) for "index" op', done => {
request(app.listen())
.get('/pks/lookup?op=index&search=0x' + emailParams.keyid)
.expect(501)
.end(done);
});
});
});
}); });
}); });

View File

@ -3,6 +3,7 @@
require('co-mocha')(require('mocha')); // monkey patch mocha for generators require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const log = require('npmlog'); const log = require('npmlog');
const config = require('config');
const openpgp = require('openpgp'); const openpgp = require('openpgp');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const Email = require('../../src/email/email'); const Email = require('../../src/email/email');
@ -12,6 +13,8 @@ const PublicKey = require('../../src/service/public-key');
const expect = require('chai').expect; const expect = require('chai').expect;
const sinon = require('sinon'); const sinon = require('sinon');
log.level = config.log.level;
describe('Public Key Integration Tests', function() { describe('Public Key Integration Tests', function() {
this.timeout(20000); this.timeout(20000);
@ -74,10 +77,14 @@ describe('Public Key Integration Tests', function() {
}); });
describe('put', () => { describe('put', () => {
it('should persist key and send verification email', function *() { it('should persist key and send verification email with primaryEmail', function *() {
yield publicKey.put({ publicKeyArmored, primaryEmail, origin }); yield publicKey.put({ publicKeyArmored, primaryEmail, origin });
expect(emailParams.nonce).to.exist; expect(emailParams.nonce).to.exist;
}); });
it('should persist key and send verification email without primaryEmail', function *() {
yield publicKey.put({ publicKeyArmored, origin });
expect(emailParams.nonce).to.exist;
});
it('should work twice if not yet verified', function *() { it('should work twice if not yet verified', function *() {
yield publicKey.put({ publicKeyArmored, primaryEmail, origin }); yield publicKey.put({ publicKeyArmored, primaryEmail, origin });