"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const chai_1 = require("chai");
const fs_extra_1 = require("fs-extra");
const path_1 = require("path");
const shared_1 = require("../../shared");
const core_utils_1 = require("../../../../shared/core-utils");
const server_commands_1 = require("../../../../shared/server-commands");
describe('Test plugins', function () {
    let server = null;
    let command;
    before(function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(30000);
            const configOverride = {
                plugins: {
                    index: { check_latest_versions_interval: '5 seconds' }
                }
            };
            server = yield (0, server_commands_1.createSingleServer)(1, configOverride);
            yield (0, server_commands_1.setAccessTokensToServers)([server]);
            command = server.plugins;
        });
    });
    it('Should list and search available plugins and themes', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(30000);
            {
                const body = yield command.listAvailable({
                    count: 1,
                    start: 0,
                    pluginType: 2,
                    search: 'background-red'
                });
                (0, chai_1.expect)(body.total).to.be.at.least(1);
                (0, chai_1.expect)(body.data).to.have.lengthOf(1);
            }
            {
                const body1 = yield command.listAvailable({
                    count: 2,
                    start: 0,
                    sort: 'npmName'
                });
                (0, chai_1.expect)(body1.total).to.be.at.least(2);
                const data1 = body1.data;
                (0, chai_1.expect)(data1).to.have.lengthOf(2);
                const body2 = yield command.listAvailable({
                    count: 2,
                    start: 0,
                    sort: '-npmName'
                });
                (0, chai_1.expect)(body2.total).to.be.at.least(2);
                const data2 = body2.data;
                (0, chai_1.expect)(data2).to.have.lengthOf(2);
                (0, chai_1.expect)(data1[0].npmName).to.not.equal(data2[0].npmName);
            }
            {
                const body = yield command.listAvailable({
                    count: 10,
                    start: 0,
                    pluginType: 2,
                    search: 'background-red',
                    currentPeerTubeEngine: '1.0.0'
                });
                const p = body.data.find(p => p.npmName === 'peertube-theme-background-red');
                (0, chai_1.expect)(p).to.be.undefined;
            }
        });
    });
    it('Should install a plugin and a theme', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(30000);
            yield command.install({ npmName: 'peertube-plugin-hello-world' });
            yield command.install({ npmName: 'peertube-theme-background-red' });
        });
    });
    it('Should have the plugin loaded in the configuration', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            for (const config of [yield server.config.getConfig(), yield server.config.getIndexHTMLConfig()]) {
                const theme = config.theme.registered.find(r => r.name === 'background-red');
                (0, chai_1.expect)(theme).to.not.be.undefined;
                (0, chai_1.expect)(theme.npmName).to.equal('peertube-theme-background-red');
                const plugin = config.plugin.registered.find(r => r.name === 'hello-world');
                (0, chai_1.expect)(plugin).to.not.be.undefined;
                (0, chai_1.expect)(plugin.npmName).to.equal('peertube-plugin-hello-world');
            }
        });
    });
    it('Should update the default theme in the configuration', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield server.config.updateCustomSubConfig({
                newConfig: {
                    theme: { default: 'background-red' }
                }
            });
            for (const config of [yield server.config.getConfig(), yield server.config.getIndexHTMLConfig()]) {
                (0, chai_1.expect)(config.theme.default).to.equal('background-red');
            }
        });
    });
    it('Should update my default theme', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield server.users.updateMe({ theme: 'background-red' });
            const user = yield server.users.getMyInfo();
            (0, chai_1.expect)(user.theme).to.equal('background-red');
        });
    });
    it('Should list plugins and themes', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            {
                const body = yield command.list({
                    count: 1,
                    start: 0,
                    pluginType: 2
                });
                (0, chai_1.expect)(body.total).to.be.at.least(1);
                const data = body.data;
                (0, chai_1.expect)(data).to.have.lengthOf(1);
                (0, chai_1.expect)(data[0].name).to.equal('background-red');
            }
            {
                const { data } = yield command.list({
                    count: 2,
                    start: 0,
                    sort: 'name'
                });
                (0, chai_1.expect)(data[0].name).to.equal('background-red');
                (0, chai_1.expect)(data[1].name).to.equal('hello-world');
            }
            {
                const body = yield command.list({
                    count: 2,
                    start: 1,
                    sort: 'name'
                });
                (0, chai_1.expect)(body.data[0].name).to.equal('hello-world');
            }
        });
    });
    it('Should get registered settings', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield (0, shared_1.testHelloWorldRegisteredSettings)(server);
        });
    });
    it('Should get public settings', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const body = yield command.getPublicSettings({ npmName: 'peertube-plugin-hello-world' });
            const publicSettings = body.publicSettings;
            (0, chai_1.expect)(Object.keys(publicSettings)).to.have.lengthOf(1);
            (0, chai_1.expect)(Object.keys(publicSettings)).to.deep.equal(['user-name']);
            (0, chai_1.expect)(publicSettings['user-name']).to.be.null;
        });
    });
    it('Should update the settings', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const settings = {
                'admin-name': 'Cid'
            };
            yield command.updateSettings({
                npmName: 'peertube-plugin-hello-world',
                settings
            });
        });
    });
    it('Should have watched settings changes', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(10000);
            yield server.servers.waitUntilLog('Settings changed!');
        });
    });
    it('Should get a plugin and a theme', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            {
                const plugin = yield command.get({ npmName: 'peertube-plugin-hello-world' });
                (0, chai_1.expect)(plugin.type).to.equal(1);
                (0, chai_1.expect)(plugin.name).to.equal('hello-world');
                (0, chai_1.expect)(plugin.description).to.exist;
                (0, chai_1.expect)(plugin.homepage).to.exist;
                (0, chai_1.expect)(plugin.uninstalled).to.be.false;
                (0, chai_1.expect)(plugin.enabled).to.be.true;
                (0, chai_1.expect)(plugin.description).to.exist;
                (0, chai_1.expect)(plugin.version).to.exist;
                (0, chai_1.expect)(plugin.peertubeEngine).to.exist;
                (0, chai_1.expect)(plugin.createdAt).to.exist;
                (0, chai_1.expect)(plugin.settings).to.not.be.undefined;
                (0, chai_1.expect)(plugin.settings['admin-name']).to.equal('Cid');
            }
            {
                const plugin = yield command.get({ npmName: 'peertube-theme-background-red' });
                (0, chai_1.expect)(plugin.type).to.equal(2);
                (0, chai_1.expect)(plugin.name).to.equal('background-red');
                (0, chai_1.expect)(plugin.description).to.exist;
                (0, chai_1.expect)(plugin.homepage).to.exist;
                (0, chai_1.expect)(plugin.uninstalled).to.be.false;
                (0, chai_1.expect)(plugin.enabled).to.be.true;
                (0, chai_1.expect)(plugin.description).to.exist;
                (0, chai_1.expect)(plugin.version).to.exist;
                (0, chai_1.expect)(plugin.peertubeEngine).to.exist;
                (0, chai_1.expect)(plugin.createdAt).to.exist;
                (0, chai_1.expect)(plugin.settings).to.be.null;
            }
        });
    });
    it('Should update the plugin and the theme', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(180000);
            yield (0, core_utils_1.wait)(6000);
            function testUpdate(type, name) {
                return tslib_1.__awaiter(this, void 0, void 0, function* () {
                    yield server.sql.setPluginVersion(name, '0.0.1');
                    const packageJSON = yield command.getPackageJSON(`peertube-${type}-${name}`);
                    const oldVersion = packageJSON.version;
                    packageJSON.version = '0.0.1';
                    yield command.updatePackageJSON(`peertube-${type}-${name}`, packageJSON);
                    yield (0, server_commands_1.killallServers)([server]);
                    yield server.run();
                    const checkConfig = (version) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                        for (const config of [yield server.config.getConfig(), yield server.config.getIndexHTMLConfig()]) {
                            (0, chai_1.expect)(config[type].registered.find(r => r.name === name).version).to.equal(version);
                        }
                    });
                    const getPluginFromAPI = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
                        const body = yield command.list({ pluginType: type === 'plugin' ? 1 : 2 });
                        return body.data.find(p => p.name === name);
                    });
                    {
                        const plugin = yield getPluginFromAPI();
                        (0, chai_1.expect)(plugin.version).to.equal('0.0.1');
                        (0, chai_1.expect)(plugin.latestVersion).to.exist;
                        (0, chai_1.expect)(plugin.latestVersion).to.not.equal('0.0.1');
                        yield checkConfig('0.0.1');
                    }
                    {
                        yield command.update({ npmName: `peertube-${type}-${name}` });
                        const plugin = yield getPluginFromAPI();
                        (0, chai_1.expect)(plugin.version).to.equal(oldVersion);
                        const updatedPackageJSON = yield command.getPackageJSON(`peertube-${type}-${name}`);
                        (0, chai_1.expect)(updatedPackageJSON.version).to.equal(oldVersion);
                        yield checkConfig(oldVersion);
                    }
                });
            }
            yield testUpdate('theme', 'background-red');
            yield testUpdate('plugin', 'hello-world');
        });
    });
    it('Should uninstall the plugin', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield command.uninstall({ npmName: 'peertube-plugin-hello-world' });
            const body = yield command.list({ pluginType: 1 });
            (0, chai_1.expect)(body.total).to.equal(0);
            (0, chai_1.expect)(body.data).to.have.lengthOf(0);
        });
    });
    it('Should list uninstalled plugins', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const body = yield command.list({ pluginType: 1, uninstalled: true });
            (0, chai_1.expect)(body.total).to.equal(1);
            (0, chai_1.expect)(body.data).to.have.lengthOf(1);
            const plugin = body.data[0];
            (0, chai_1.expect)(plugin.name).to.equal('hello-world');
            (0, chai_1.expect)(plugin.enabled).to.be.false;
            (0, chai_1.expect)(plugin.uninstalled).to.be.true;
        });
    });
    it('Should uninstall the theme', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield command.uninstall({ npmName: 'peertube-theme-background-red' });
        });
    });
    it('Should have updated the configuration', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            for (const config of [yield server.config.getConfig(), yield server.config.getIndexHTMLConfig()]) {
                (0, chai_1.expect)(config.theme.default).to.equal('default');
                const theme = config.theme.registered.find(r => r.name === 'background-red');
                (0, chai_1.expect)(theme).to.be.undefined;
                const plugin = config.plugin.registered.find(r => r.name === 'hello-world');
                (0, chai_1.expect)(plugin).to.be.undefined;
            }
        });
    });
    it('Should have updated the user theme', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const user = yield server.users.getMyInfo();
            (0, chai_1.expect)(user.theme).to.equal('instance-default');
        });
    });
    it('Should not install a broken plugin', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(60000);
            function check() {
                return tslib_1.__awaiter(this, void 0, void 0, function* () {
                    const body = yield command.list({ pluginType: 1 });
                    const plugins = body.data;
                    (0, chai_1.expect)(plugins.find(p => p.name === 'test-broken')).to.not.exist;
                });
            }
            yield command.install({
                path: server_commands_1.PluginsCommand.getPluginTestPath('-broken'),
                expectedStatus: 400
            });
            yield check();
            yield (0, server_commands_1.killallServers)([server]);
            yield server.run();
            yield check();
        });
    });
    it('Should rebuild native modules on Node ABI change', function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.timeout(60000);
            const removeNativeModule = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
                yield (0, fs_extra_1.remove)((0, path_1.join)(baseNativeModule, 'build'));
                yield (0, fs_extra_1.remove)((0, path_1.join)(baseNativeModule, 'prebuilds'));
            });
            yield command.install({ path: server_commands_1.PluginsCommand.getPluginTestPath('-native') });
            yield (0, server_commands_1.makeGetRequest)({
                url: server.url,
                path: '/plugins/test-native/router',
                expectedStatus: 204
            });
            const query = `UPDATE "application" SET "nodeABIVersion" = 1`;
            yield server.sql.updateQuery(query);
            const baseNativeModule = server.servers.buildDirectory((0, path_1.join)('plugins', 'node_modules', 'a-native-example'));
            yield removeNativeModule();
            yield server.kill();
            yield server.run();
            yield (0, core_utils_1.wait)(3000);
            (0, chai_1.expect)(yield (0, fs_extra_1.pathExists)((0, path_1.join)(baseNativeModule, 'build'))).to.be.true;
            (0, chai_1.expect)(yield (0, fs_extra_1.pathExists)((0, path_1.join)(baseNativeModule, 'prebuilds'))).to.be.true;
            yield (0, server_commands_1.makeGetRequest)({
                url: server.url,
                path: '/plugins/test-native/router',
                expectedStatus: 204
            });
            yield removeNativeModule();
            yield server.kill();
            yield server.run();
            (0, chai_1.expect)(yield (0, fs_extra_1.pathExists)((0, path_1.join)(baseNativeModule, 'build'))).to.be.false;
            (0, chai_1.expect)(yield (0, fs_extra_1.pathExists)((0, path_1.join)(baseNativeModule, 'prebuilds'))).to.be.false;
            yield (0, server_commands_1.makeGetRequest)({
                url: server.url,
                path: '/plugins/test-native/router',
                expectedStatus: 404
            });
        });
    });
    after(function () {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield (0, server_commands_1.cleanupTests)([server]);
        });
    });
});
//# sourceMappingURL=plugins.js.map