var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import sinon from 'sinon';
import { DidKeyResolver } from '../../src/did/did-key-resolver.js';
import { DidResolver } from '../../src/did/did-resolver.js';
import { Dwn } from '../../src/dwn.js';
import { DwnErrorCode } from '../../src/core/dwn-error.js';
import { expect } from 'chai';
import { Message } from '../../src/core/message.js';
import { PermissionsGrant } from '../../src/interfaces/permissions-grant.js';
import { PermissionsGrantHandler } from '../../src/handlers/permissions-grant.js';
import { TestDataGenerator } from '../utils/test-data-generator.js';
import { TestStores } from '../test-stores.js';
export function testPermissionsGrantHandler() {
    describe('PermissionsGrantHandler.handle()', () => {
        if (process.env.TESTSOFF === 'true') {
            return;
        }
        let didResolver;
        let messageStore;
        let dataStore;
        let eventLog;
        let dwn;
        describe('functional tests', () => {
            // important to follow the `before` and `after` pattern to initialize and clean the stores in tests
            // so that different test suites can reuse the same backend store for testing
            before(() => __awaiter(this, void 0, void 0, function* () {
                didResolver = new DidResolver([new DidKeyResolver()]);
                const stores = TestStores.get();
                messageStore = stores.messageStore;
                dataStore = stores.dataStore;
                eventLog = stores.eventLog;
                dwn = yield Dwn.create({ didResolver, messageStore, dataStore, eventLog });
            }));
            beforeEach(() => __awaiter(this, void 0, void 0, function* () {
                sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
                // clean up before each test rather than after so that a test does not depend on other tests to do the clean up
                yield messageStore.clear();
                yield dataStore.clear();
                yield eventLog.clear();
            }));
            after(() => __awaiter(this, void 0, void 0, function* () {
                yield dwn.close();
            }));
            it('should accept a PermissionsGrant with permissionsRequestId omitted', () => __awaiter(this, void 0, void 0, function* () {
                const alice = yield DidKeyResolver.generate();
                const { message } = yield TestDataGenerator.generatePermissionsGrant({
                    author: alice,
                    grantedBy: alice.did,
                    grantedFor: alice.did,
                });
                const reply = yield dwn.processMessage(alice.did, message);
                expect(reply.status.code).to.equal(202);
            }));
            it('should accept a PermissionsGrant with associated PermissionsRequest', () => __awaiter(this, void 0, void 0, function* () {
                const alice = yield DidKeyResolver.generate();
                const { permissionsRequest } = yield TestDataGenerator.generatePermissionsRequest({
                    author: alice,
                });
                const permissionsRequestReply = yield dwn.processMessage(alice.did, permissionsRequest.message);
                expect(permissionsRequestReply.status.code).to.equal(202);
                const { permissionsGrant } = yield TestDataGenerator.generatePermissionsGrant({
                    author: alice,
                    grantedBy: alice.did,
                    grantedFor: alice.did,
                    permissionsRequestId: yield Message.getCid(permissionsRequest.message),
                });
                const permissionsGrantReply = yield dwn.processMessage(alice.did, permissionsGrant.message);
                expect(permissionsGrantReply.status.code).to.equal(202);
            }));
            it('should return 401 if authentication fails', () => __awaiter(this, void 0, void 0, function* () {
                const alice = yield DidKeyResolver.generate();
                alice.keyId = 'wrongValue'; // to fail authentication
                const { message } = yield TestDataGenerator.generatePermissionsGrant({
                    author: alice,
                });
                const reply = yield dwn.processMessage(alice.did, message);
                expect(reply.status.code).to.equal(401);
                expect(reply.status.detail).to.contain('not a valid DID');
            }));
            it('should reject if author does not match grantedBy', () => __awaiter(this, void 0, void 0, function* () {
                const alice = yield DidKeyResolver.generate();
                const bob = yield DidKeyResolver.generate();
                const { message } = yield TestDataGenerator.generatePermissionsGrant({
                    author: alice,
                    grantedBy: bob.did,
                });
                const reply = yield dwn.processMessage(alice.did, message);
                expect(reply.status.code).to.equal(401);
                expect(reply.status.detail).to.contain(DwnErrorCode.PermissionsGrantGrantedByMismatch);
            }));
            it('should reject if grantedBy is not a delegate and does not match grantedFor', () => __awaiter(this, void 0, void 0, function* () {
                const alice = yield DidKeyResolver.generate();
                const bob = yield DidKeyResolver.generate();
                const { message } = yield TestDataGenerator.generatePermissionsGrant({
                    author: alice,
                    grantedBy: alice.did,
                    grantedFor: bob.did,
                });
                const reply = yield dwn.processMessage(alice.did, message);
                expect(reply.status.code).to.equal(401);
                expect(reply.status.detail).to.contain(DwnErrorCode.PermissionsGrantUnauthorizedGrant);
            }));
            it('should return 400 if failure parsing the message', () => __awaiter(this, void 0, void 0, function* () {
                const alice = yield DidKeyResolver.generate();
                const { message } = yield TestDataGenerator.generatePermissionsGrant();
                const permissionsRequestHandler = new PermissionsGrantHandler(didResolver, messageStore, eventLog);
                // stub the `parse()` function to throw an error
                sinon.stub(PermissionsGrant, 'parse').throws('anyError');
                const reply = yield permissionsRequestHandler.handle({ tenant: alice.did, message });
                expect(reply.status.code).to.equal(400);
            }));
            describe('event log', () => {
                it('should add event for PermissionsGrant', () => __awaiter(this, void 0, void 0, function* () {
                    const alice = yield DidKeyResolver.generate();
                    const { message } = yield TestDataGenerator.generatePermissionsGrant({
                        author: alice,
                        grantedBy: alice.did,
                    });
                    const reply = yield dwn.processMessage(alice.did, message);
                    expect(reply.status.code).to.equal(202);
                    const events = yield eventLog.getEvents(alice.did);
                    expect(events.length).to.equal(1);
                    const messageCid = yield Message.getCid(message);
                    expect(events[0].messageCid).to.equal(messageCid);
                }));
                it('should not add a new event if we have already stored this PermissionsRequest', () => __awaiter(this, void 0, void 0, function* () {
                    const alice = yield DidKeyResolver.generate();
                    const { message } = yield TestDataGenerator.generatePermissionsGrant({
                        author: alice,
                        grantedBy: alice.did,
                    });
                    let reply = yield dwn.processMessage(alice.did, message);
                    expect(reply.status.code).to.equal(202);
                    reply = yield dwn.processMessage(alice.did, message);
                    expect(reply.status.code).to.equal(202);
                    const events = yield eventLog.getEvents(alice.did);
                    expect(events.length).to.equal(1);
                    const messageCid = yield Message.getCid(message);
                    expect(events[0].messageCid).to.equal(messageCid);
                }));
            });
        });
    });
}
//# sourceMappingURL=permissions-grant.spec.js.map