-/* 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');
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 () {
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 () {
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']);
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'));
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' });
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);
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';
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);
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 () {
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);
});
}); // getAdminMaintenance
-}); // Manager
\ No newline at end of file
+}); // Manager