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 { expect } from 'chai';
import { Message } from '../../src/core/message.js';
import { MessagesGetHandler } from '../../src/handlers/messages-get.js';
import { stubInterface } from 'ts-sinon';
import { TestDataGenerator } from '../utils/test-data-generator.js';
import { TestStoreInitializer } from '../test-store-initializer.js';
import { DidKeyResolver, DidResolver, Dwn } from '../../src/index.js';
import sinon from 'sinon';
describe('MessagesGetHandler.handle()', () => {
    if (process.env.TESTSOFF === 'true') {
        return;
    }
    let dwn;
    let didResolver;
    let messageStore;
    let dataStore;
    let eventLog;
    // 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(void 0, void 0, void 0, function* () {
        didResolver = new DidResolver([new DidKeyResolver()]);
        const stores = TestStoreInitializer.initializeStores();
        messageStore = stores.messageStore;
        dataStore = stores.dataStore;
        eventLog = stores.eventLog;
        dwn = yield Dwn.create({ didResolver, messageStore, dataStore, eventLog });
    }));
    beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
        // 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();
        sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
    }));
    after(() => __awaiter(void 0, void 0, void 0, function* () {
        yield dwn.close();
    }));
    it('returns a 401 if tenant is not author', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const bob = yield DidKeyResolver.generate();
        const { recordsWrite } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
        const { message } = yield TestDataGenerator.generateMessagesGet({
            author: alice,
            messageCids: [yield Message.getCid(recordsWrite.message)]
        });
        const reply = yield dwn.processMessage(bob.did, message);
        expect(reply.status.code).to.equal(401);
        expect(reply.entries).to.not.exist;
        expect(reply.data).to.not.exist;
    }));
    it('returns a 400 if message is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const { recordsWrite } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
        const { message } = yield TestDataGenerator.generateMessagesGet({
            author: alice,
            messageCids: [yield Message.getCid(recordsWrite.message)]
        });
        message['descriptor']['troll'] = 'hehe';
        const reply = yield dwn.processMessage(alice.did, message);
        expect(reply.status.code).to.equal(400);
        expect(reply.entries).to.not.exist;
        expect(reply.data).to.not.exist;
    }));
    it('returns a 400 if message contains an invalid message cid', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const { recordsWrite } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
        const { message } = yield TestDataGenerator.generateMessagesGet({
            author: alice,
            messageCids: [yield Message.getCid(recordsWrite.message)]
        });
        message.descriptor.messageCids = ['hehetroll'];
        const reply = yield dwn.processMessage(alice.did, message);
        expect(reply.status.code).to.equal(400);
        expect(reply.status.detail).to.include('is not a valid CID');
        expect(reply.messages).to.be.undefined;
    }));
    it('returns all requested messages', () => __awaiter(void 0, void 0, void 0, function* () {
        const did = yield DidKeyResolver.generate();
        const alice = yield TestDataGenerator.generatePersona(did);
        const messageCids = [];
        const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
            author: alice
        });
        let messageCid = yield Message.getCid(recordsWrite.message);
        messageCids.push(messageCid);
        let reply = yield dwn.processMessage(alice.did, recordsWrite.toJSON(), dataStream);
        expect(reply.status.code).to.equal(202);
        const { recordsDelete } = yield TestDataGenerator.generateRecordsDelete({
            author: alice,
            recordId: recordsWrite.message.recordId
        });
        messageCid = yield Message.getCid(recordsDelete.message);
        messageCids.push(messageCid);
        reply = yield dwn.processMessage(alice.did, recordsDelete.toJSON());
        expect(reply.status.code).to.equal(202);
        const { protocolsConfigure } = yield TestDataGenerator.generateProtocolsConfigure({
            author: alice
        });
        messageCid = yield Message.getCid(protocolsConfigure.message);
        messageCids.push(messageCid);
        reply = yield dwn.processMessage(alice.did, protocolsConfigure.toJSON());
        expect(reply.status.code).to.equal(202);
        const { messagesGet } = yield TestDataGenerator.generateMessagesGet({
            author: alice,
            messageCids
        });
        const messagesGetReply = yield dwn.processMessage(alice.did, messagesGet.toJSON());
        expect(messagesGetReply.status.code).to.equal(200);
        expect(messagesGetReply.messages.length).to.equal(messageCids.length);
        for (const messageReply of messagesGetReply.messages) {
            expect(messageReply.messageCid).to.not.be.undefined;
            expect(messageReply.message).to.not.be.undefined;
            expect(messageCids).to.include(messageReply.messageCid);
            const cid = yield Message.getCid(messageReply.message);
            expect(messageReply.messageCid).to.equal(cid);
        }
    }));
    it('returns message as undefined in reply entry when a messageCid is not found', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const { recordsWrite } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
        const recordsWriteMessageCid = yield Message.getCid(recordsWrite.message);
        const { message } = yield TestDataGenerator.generateMessagesGet({
            author: alice,
            messageCids: [recordsWriteMessageCid]
        });
        // 0 messages expected because the RecordsWrite created above was never stored
        const reply = yield dwn.processMessage(alice.did, message);
        expect(reply.status.code).to.equal(200);
        expect(reply.messages.length).to.equal(1);
        for (const messageReply of reply.messages) {
            expect(messageReply.messageCid).to.equal(recordsWriteMessageCid);
            expect(messageReply.message).to.be.undefined;
        }
    }));
    it('returns an error message for a specific cid if getting that message from the MessageStore fails', () => __awaiter(void 0, void 0, void 0, function* () {
        // stub the messageStore.get call to throw an error
        const messageStore = stubInterface();
        messageStore.get.rejects('internal db error');
        const dataStore = stubInterface();
        const messagesGetHandler = new MessagesGetHandler(didResolver, messageStore, dataStore);
        const alice = yield DidKeyResolver.generate();
        const { recordsWrite } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
        const recordsWriteMessageCid = yield Message.getCid(recordsWrite.message);
        const { message } = yield TestDataGenerator.generateMessagesGet({
            author: alice,
            messageCids: [recordsWriteMessageCid]
        });
        const reply = yield messagesGetHandler.handle({ tenant: alice.did, message });
        expect(messageStore.get.called).to.be.true;
        expect(reply.status.code).to.equal(200);
        expect(reply.messages.length).to.equal(1);
        expect(reply.messages[0].error).to.exist;
        expect(reply.messages[0].error).to.include(`Failed to get message ${recordsWriteMessageCid}`);
        expect(reply.messages[0].message).to.be.undefined;
    }));
    it('includes encodedData in reply entry if the data is available and dataSize < threshold', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
            author: alice
        });
        const reply = yield dwn.processMessage(alice.did, recordsWrite.toJSON(), dataStream);
        expect(reply.status.code).to.equal(202);
        const recordsWriteMessageCid = yield Message.getCid(recordsWrite.message);
        const { message } = yield TestDataGenerator.generateMessagesGet({
            author: alice,
            messageCids: [recordsWriteMessageCid]
        });
        const messagesGetReply = yield dwn.processMessage(alice.did, message);
        expect(messagesGetReply.status.code).to.equal(200);
        expect(messagesGetReply.messages.length).to.equal(1);
        for (const messageReply of messagesGetReply.messages) {
            expect(messageReply.messageCid).to.exist;
            expect(messageReply.messageCid).to.equal(recordsWriteMessageCid);
            expect(messageReply.message).to.exist.and.not.be.undefined;
            expect(messageReply.encodedData).to.exist.and.not.be.undefined;
        }
    }));
    it('does not return messages that belong to other tenants', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const bob = yield DidKeyResolver.generate();
        const { recordsWrite, dataStream } = yield TestDataGenerator.generateRecordsWrite({
            author: alice
        });
        const reply = yield dwn.processMessage(alice.did, recordsWrite.toJSON(), dataStream);
        expect(reply.status.code).to.equal(202);
        const recordsWriteMessageCid = yield Message.getCid(recordsWrite.message);
        const { message } = yield TestDataGenerator.generateMessagesGet({
            author: bob,
            messageCids: [yield Message.getCid(recordsWrite.message)]
        });
        // 0 messages expected because the RecordsWrite created above is not bob's
        const messagesGetReply = yield dwn.processMessage(bob.did, message);
        expect(messagesGetReply.status.code).to.equal(200);
        expect(messagesGetReply.messages.length).to.equal(1);
        for (const messageReply of messagesGetReply.messages) {
            expect(messageReply.messageCid).to.equal(recordsWriteMessageCid);
            expect(messageReply.message).to.be.undefined;
        }
    }));
});
//# sourceMappingURL=messages-get.spec.js.map