X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=test%2Fsrc%2Fmanager.js;h=f2d708b93947c3f1c3730140eac96277e5313f70;hb=f0bf29c75b0fd405ff92fa76f058e61162b87e43;hp=f3c38b4586c115088912039ab4be3efb151f9592;hpb=11160730c4e424bbb6f90b62a674cab522620192;p=squeep-indie-auther diff --git a/test/src/manager.js b/test/src/manager.js index f3c38b4..f2d708b 100644 --- a/test/src/manager.js +++ b/test/src/manager.js @@ -1,10 +1,9 @@ -/* eslint-env mocha */ -/* eslint-disable capitalized-comments, sonarjs/no-duplicate-string, sonarjs/no-identical-functions */ +/* eslint-disable sonarjs/no-duplicate-string */ 'use strict'; const assert = require('assert'); -const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require +const sinon = require('sinon'); const Manager = require('../../src/manager'); const Config = require('../../config'); @@ -49,10 +48,14 @@ describe('Manager', function () { sinon.stub(manager.communication, 'fetchProfile'); sinon.stub(manager.communication, 'fetchClientIdentifier'); sinon.stub(manager.communication, 'deliverTicket'); + sinon.stub(manager.communication, 'redeemTicket'); sinon.stub(dns.promises, 'lookup').resolves([{ family: 4, address: '10.11.12.13' }]); sinon.stub(manager.queuePublisher, 'connect'); sinon.stub(manager.queuePublisher, 'establishAMQPPlumbing'); sinon.stub(manager.queuePublisher, 'publish'); + sinon.stub(manager.queueConsumer, 'connect'); + sinon.stub(manager.queueConsumer, 'establishAMQPPlumbing'); + sinon.stub(manager.queueConsumer, 'consume'); }); afterEach(function () { @@ -425,7 +428,8 @@ describe('Manager', function () { assert.strictEqual(res.statusCode, 302); assert.strictEqual(ctx.session.error, 'invalid_request'); assert.strictEqual(ctx.session.errorDescriptions.length, 1); - }); }); // getAuthorization + }); + }); // getAuthorization describe('_setError', function () { it('covers', function () { @@ -899,7 +903,7 @@ describe('Manager', function () { assert.deepStrictEqual(result, []); }); it('filters invalid scopes', function () { - ctx.parsedBody['accepted_scopes'] = ['read', 'email']; + ctx.parsedBody['accepted_scopes[]'] = ['read', 'email']; ctx.parsedBody['ad_hoc_scopes'] = 'bad"scope create '; const result = manager._parseConsentScopes(ctx); assert.deepStrictEqual(result, ['read', 'create']); @@ -1008,12 +1012,12 @@ describe('Manager', function () { assert(ctx.session.error); }); it('removes email scope without profile', async function () { - ctx.parsedBody['accepted_scopes'] = ['email', 'create']; + ctx.parsedBody['accepted_scopes[]'] = ['email', 'create']; await manager.postConsent(res, ctx); assert(!ctx.session.acceptedScopes.includes('email')); }); it('merges valid ad-hoc scopes', async function () { - ctx.parsedBody['accepted_scopes'] = ['email', 'create']; + ctx.parsedBody['accepted_scopes[]'] = ['email', 'create']; ctx.parsedBody['ad_hoc_scopes'] = ' my:scope "badScope'; await manager.postConsent(res, ctx); assert(ctx.session.acceptedScopes.includes('my:scope')); @@ -1553,13 +1557,13 @@ describe('Manager', function () { manager.mysteryBox.unpack.resolves({}); req.getHeader.returns('Bearer XXX'); await manager._checkTokenValidationRequest(dbCtx, req, ctx); - assert(ctx.session.error) + assert(ctx.session.error); }); it('covers no token', async function () { manager.mysteryBox.unpack.resolves({ c: 'xxx' }); req.getHeader.returns('Bearer XXX'); await manager._checkTokenValidationRequest(dbCtx, req, ctx); - assert(ctx.session.error) + assert(ctx.session.error); }); it('covers db error', async function () { manager.mysteryBox.unpack.resolves({ c: 'xxx' }); @@ -2047,7 +2051,7 @@ describe('Manager', function () { describe('save-scopes action', function () { beforeEach(function () { ctx.parsedBody['action'] = 'save-scopes'; - ctx.parsedBody['scopes-https://profile/example.com/'] = ['scope1', 'scope2']; + ctx.parsedBody['scopes-https://profile/example.com/[]'] = ['scope1', 'scope2']; }); it('covers saving scopes', async function () { await manager.postAdmin(res, ctx); @@ -2205,7 +2209,7 @@ describe('Manager', function () { describe('postAdminTicket', function () { beforeEach(function () { ctx.parsedBody['action'] = 'proffer-ticket'; - ctx.parsedBody['scopes'] = ['read', 'role:private']; + ctx.parsedBody['scopes[]'] = ['read', 'role:private']; ctx.parsedBody['adhoc'] = 'adhoc_scope'; ctx.parsedBody['profile'] = 'https://profile.example.com/'; ctx.parsedBody['resource'] = 'https://profile.example.com/feed'; @@ -2229,7 +2233,7 @@ describe('Manager', function () { ctx.parsedBody['profile'] = 'bad url'; ctx.parsedBody['resource'] = 'bad url'; ctx.parsedBody['subject'] = 'bad url'; - ctx.parsedBody['scopes'] = ['fl"hrgl', 'email']; + ctx.parsedBody['scopes[]'] = ['fl"hrgl', 'email']; await manager.postAdminTicket(res, ctx); assert(res.end.called); assert.strictEqual(ctx.errors.length, 5); @@ -2276,6 +2280,7 @@ describe('Manager', function () { ticket: 'ticket123', resource: 'https://blog.example.com/', subject: 'https://otheruser.example.com/', + iss: 'https://ia.example.com/', }; }); it('accepts a ticket for a known profile', async function () { @@ -2300,12 +2305,81 @@ describe('Manager', function () { it('covers no ticket queue', async function () { delete options.queues.amqp.url; manager = new Manager(logger, stubDb, options); - await assert.rejects(() => manager.postTicket(req, res, ctx), ResponseError); }); + it('covers no issuer', async function () { + delete ctx.parsedBody.iss; + manager.db.profileIsValid.resolves(true); + await manager.postTicket(req, res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 202); + }); + it('covers bad issuer', async function () { + ctx.parsedBody.iss = 'not a url'; + manager.db.profileIsValid.resolves(true); + await manager.postTicket(req, res, ctx); + assert(res.end.called); + assert.strictEqual(res.statusCode, 202); + }); }); // postTicket + describe('queuedTicketProcessor', function () { + let channel, content; + const message = () => ({ + content: Buffer.from(JSON.stringify(content)), + }); + beforeEach(function () { + channel = { + ack: sinon.stub(), + }; + content = { + ticket: 'XXXticketXXX', + resource: 'https://blog.example.com/', + subject: 'https://otheruser.exmaple.com/', + iss: 'https://ia.example.com/', + epochMs: Date.now(), + }; + }); + it('redeems a ticket', async function () { + await manager.queuedTicketProcessor(channel, message()); + assert(manager.queuePublisher.publish.called); + assert(channel.ack.called); + }); + it('redeems a ticket, missing issuer', async function () { + delete content.iss; + await manager.queuedTicketProcessor(channel, message()); + assert(manager.queuePublisher.publish.called); + assert(channel.ack.called); + }); + it('covers bad message', async function () { + await manager.queuedTicketProcessor(channel, { content: 'diddly' }); + assert(channel.ack.called); + }); + it('covers bad issuer', async function () { + content.iss = 'not a url'; + await manager.queuedTicketProcessor(channel, message()); + assert(manager.queuePublisher.publish.called); + }); + it('covers bad resource', async function () { + content.resource = 'not a url'; + await manager.queuedTicketProcessor(channel, message()); + assert(manager.communication.redeemTicket.notCalled); + assert(manager.queuePublisher.publish.notCalled); + assert(channel.ack.called); + }); + it('covers failed redemption', async function () { + const expectedException = new Error('oh no'); + manager.communication.redeemTicket.rejects(expectedException); + assert.rejects(() => manager.queuedTicketProcessor(channel, message()), expectedException); + }); + it('covers failed publish', async function () { + const expectedException = new Error('oh no'); + manager.queuePublisher.publish.rejects(expectedException); + assert.rejects(() => manager.queuedTicketProcessor(channel, message()), expectedException); + }); + }); // queuedTicketProcessor + describe('getAdminMaintenance', function () { it('covers information', async function () { await manager.getAdminMaintenance(res, ctx); @@ -2320,4 +2394,4 @@ describe('Manager', function () { }); }); // getAdminMaintenance -}); // Manager \ No newline at end of file +}); // Manager