"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const test_utils_1 = require("@joplin/lib/testing/test-utils");
const mockShareService_1 = require("@joplin/lib/testing/share/mockShareService");
const testUtils_1 = require("./utils/testUtils");
const Folder_1 = require("@joplin/lib/models/Folder");
const ShareService_1 = require("@joplin/lib/services/share/ShareService");
const BaseItem_1 = require("@joplin/lib/models/BaseItem");
const BaseModel_1 = require("@joplin/lib/BaseModel");
const reducer_1 = require("@joplin/lib/services/share/reducer");
const app_1 = require("./app");
const Command = require('./command-share');
const setUpCommand = () => {
    const output = [];
    const stdout = (content) => {
        output.push(...content.split('\n'));
    };
    const command = (0, testUtils_1.setupCommandForTesting)(Command, stdout);
    return { command, output };
};
const shareId = 'test-id';
const defaultFolderShare = {
    id: shareId,
    type: BaseModel_1.ModelType.Folder,
    folder_id: 'some-folder-id-here',
    note_id: undefined,
    master_key_id: undefined,
    user: {
        full_name: 'Test user',
        email: 'test@localhost',
        id: 'some-user-id',
    },
};
const mockShareServiceForFolderSharing = (eventHandlerOverrides) => {
    const invitations = [];
    (0, mockShareService_1.default)(Object.assign({ getShareInvitations: async () => ({
            items: invitations,
        }), getShares: async () => ({ items: [defaultFolderShare] }), getShareUsers: async (_id) => ({ items: [] }), postShareUsers: async (_id, _body) => { }, postShares: async () => ({ id: shareId }) }, eventHandlerOverrides), ShareService_1.default.instance(), (0, app_1.default)().store());
    return {
        addInvitation: (invitation) => {
            const defaultInvitation = {
                share: defaultFolderShare,
                id: 'some-invitation-id',
                master_key: undefined,
                status: reducer_1.ShareUserStatus.Waiting,
                can_read: 1,
                can_write: 1,
            };
            invitations.push(Object.assign(Object.assign({}, defaultInvitation), invitation));
        },
    };
};
describe('command-share', () => {
    beforeEach(async () => {
        await (0, test_utils_1.setupDatabaseAndSynchronizer)(1);
        await (0, test_utils_1.switchClient)(1);
        await (0, testUtils_1.setupApplication)();
        BaseItem_1.default.shareService_ = ShareService_1.default.instance();
    });
    test('should allow adding a user to a share', async () => {
        const folder = await Folder_1.default.save({ title: 'folder1' });
        let lastShareUserUpdate = null;
        mockShareServiceForFolderSharing({
            getShares: async () => {
                const isShared = !!lastShareUserUpdate;
                if (isShared) {
                    return {
                        items: [Object.assign(Object.assign({}, defaultFolderShare), { folder_id: folder.id })],
                    };
                }
                else {
                    return { items: [] };
                }
            },
            // Called when a new user is added to a share
            postShareUsers: async (_id, body) => {
                lastShareUserUpdate = body;
            },
        });
        const { command } = setUpCommand();
        // Should share read-write by default
        await command.action({
            'command': 'add',
            'notebook': 'folder1',
            'user': 'test@localhost',
            options: {},
        });
        expect(lastShareUserUpdate).toMatchObject({
            email: 'test@localhost',
            can_write: 1,
            can_read: 1,
        });
        // Should also support sharing as read only
        await command.action({
            'command': 'add',
            'notebook': 'folder1',
            'user': 'test2@localhost',
            options: {
                'read-only': true,
            },
        });
        expect(lastShareUserUpdate).toMatchObject({
            email: 'test2@localhost',
            can_write: 0,
            can_read: 1,
        });
    });
    test.each([
        {
            label: 'should list a single pending invitation',
            invitations: [{ id: 'test', status: reducer_1.ShareUserStatus.Waiting }],
            expectedOutput: [
                'Incoming shares:',
                '\tWaiting: Notebook some-folder-id-here from test@localhost',
                'All shared folders:',
                '\tNone',
            ].join('\n'),
        },
        {
            label: 'should list accepted invitations for non-existent folders with [None] as the folder title',
            invitations: [
                { id: 'test2', status: reducer_1.ShareUserStatus.Accepted },
            ],
            expectedOutput: [
                'Incoming shares:',
                '\tAccepted: Notebook [None] from test@localhost',
                'All shared folders:',
                '\tNone',
            ].join('\n'),
        },
        {
            label: 'should not list rejected shares',
            invitations: [
                { id: 'test3', status: reducer_1.ShareUserStatus.Rejected },
            ],
            expectedOutput: [
                'Incoming shares:',
                '\tNone',
                'All shared folders:',
                '\tNone',
            ].join('\n'),
        },
    ])('share invitations: $label', async ({ invitations, expectedOutput }) => {
        const mock = mockShareServiceForFolderSharing({});
        for (const invitation of invitations) {
            mock.addInvitation(invitation);
        }
        await ShareService_1.default.instance().refreshShareInvitations();
        const { command, output } = setUpCommand();
        await command.action({
            'command': 'list',
            options: {},
        });
        expect(output.join('\n')).toBe(expectedOutput);
    });
});
//# sourceMappingURL=command-share.test.js.map