"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
require("mocha");
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");
function checkVideosServer1(server, idHttp, idMagnet, idTorrent) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const videoHttp = yield server.videos.get({ id: idHttp });
        (0, chai_1.expect)(videoHttp.name).to.equal('small video - youtube');
        (0, chai_1.expect)(videoHttp.language.label).to.equal('Unknown');
        (0, chai_1.expect)(videoHttp.nsfw).to.be.false;
        (0, chai_1.expect)(videoHttp.description).to.equal('this is a super description');
        (0, chai_1.expect)(videoHttp.tags).to.deep.equal(['tag1', 'tag2']);
        (0, chai_1.expect)(videoHttp.files).to.have.lengthOf(1);
        const originallyPublishedAt = new Date(videoHttp.originallyPublishedAt);
        (0, chai_1.expect)(originallyPublishedAt.getDate()).to.equal(14);
        (0, chai_1.expect)(originallyPublishedAt.getMonth()).to.equal(0);
        (0, chai_1.expect)(originallyPublishedAt.getFullYear()).to.equal(2019);
        const videoMagnet = yield server.videos.get({ id: idMagnet });
        const videoTorrent = yield server.videos.get({ id: idTorrent });
        for (const video of [videoMagnet, videoTorrent]) {
            (0, chai_1.expect)(video.category.label).to.equal('Misc');
            (0, chai_1.expect)(video.licence.label).to.equal('Unknown');
            (0, chai_1.expect)(video.language.label).to.equal('Unknown');
            (0, chai_1.expect)(video.nsfw).to.be.false;
            (0, chai_1.expect)(video.description).to.equal('this is a super torrent description');
            (0, chai_1.expect)(video.tags).to.deep.equal(['tag_torrent1', 'tag_torrent2']);
            (0, chai_1.expect)(video.files).to.have.lengthOf(1);
        }
        (0, chai_1.expect)(videoTorrent.name).to.contain('你好 世界 720p.mp4');
        (0, chai_1.expect)(videoMagnet.name).to.contain('super peertube2 video');
        const bodyCaptions = yield server.captions.list({ videoId: idHttp });
        (0, chai_1.expect)(bodyCaptions.total).to.equal(2);
    });
}
function checkVideoServer2(server, id) {
    return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
        const video = yield server.videos.get({ id });
        (0, chai_1.expect)(video.name).to.equal('my super name');
        (0, chai_1.expect)(video.category.label).to.equal('Entertainment');
        (0, chai_1.expect)(video.licence.label).to.equal('Public Domain Dedication');
        (0, chai_1.expect)(video.language.label).to.equal('English');
        (0, chai_1.expect)(video.nsfw).to.be.false;
        (0, chai_1.expect)(video.description).to.equal('my super description');
        (0, chai_1.expect)(video.tags).to.deep.equal(['supertag1', 'supertag2']);
        (0, chai_1.expect)(video.files).to.have.lengthOf(1);
        const bodyCaptions = yield server.captions.list({ videoId: id });
        (0, chai_1.expect)(bodyCaptions.total).to.equal(2);
    });
}
describe('Test video imports', function () {
    if ((0, core_utils_1.areHttpImportTestsDisabled)())
        return;
    function runSuite(mode) {
        describe('Import ' + mode, function () {
            let servers = [];
            before(function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(30000);
                    servers = yield (0, server_commands_1.createMultipleServers)(2, {
                        import: {
                            videos: {
                                http: {
                                    youtube_dl_release: {
                                        url: mode === 'youtube-dl'
                                            ? 'https://yt-dl.org/downloads/latest/youtube-dl'
                                            : 'https://api.github.com/repos/yt-dlp/yt-dlp/releases',
                                        name: mode
                                    }
                                }
                            }
                        }
                    });
                    yield (0, server_commands_1.setAccessTokensToServers)(servers);
                    yield (0, server_commands_1.setDefaultVideoChannel)(servers);
                    yield (0, server_commands_1.doubleFollow)(servers[0], servers[1]);
                });
            });
            it('Should import videos on server 1', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(60000);
                    const baseAttributes = {
                        channelId: servers[0].store.channel.id,
                        privacy: 1
                    };
                    {
                        const attributes = Object.assign(Object.assign({}, baseAttributes), { targetUrl: shared_1.FIXTURE_URLS.youtube });
                        const { video } = yield servers[0].imports.importVideo({ attributes });
                        (0, chai_1.expect)(video.name).to.equal('small video - youtube');
                        {
                            (0, chai_1.expect)(video.thumbnailPath).to.match(new RegExp(`^/static/thumbnails/.+.jpg$`));
                            (0, chai_1.expect)(video.previewPath).to.match(new RegExp(`^/lazy-static/previews/.+.jpg$`));
                            const suffix = mode === 'yt-dlp'
                                ? '_yt_dlp'
                                : '';
                            yield (0, shared_1.testImage)(servers[0].url, 'video_import_thumbnail' + suffix, video.thumbnailPath);
                            yield (0, shared_1.testImage)(servers[0].url, 'video_import_preview' + suffix, video.previewPath);
                        }
                        const bodyCaptions = yield servers[0].captions.list({ videoId: video.id });
                        const videoCaptions = bodyCaptions.data;
                        (0, chai_1.expect)(videoCaptions).to.have.lengthOf(2);
                        {
                            const enCaption = videoCaptions.find(caption => caption.language.id === 'en');
                            (0, chai_1.expect)(enCaption).to.exist;
                            (0, chai_1.expect)(enCaption.language.label).to.equal('English');
                            (0, chai_1.expect)(enCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-en.vtt$`));
                            const regex = `WEBVTT[ \n]+Kind: captions[ \n]+Language: en[ \n]+00:00:01.600 --> 00:00:04.200[ \n]+English \\(US\\)[ \n]+` +
                                `00:00:05.900 --> 00:00:07.999[ \n]+This is a subtitle in American English[ \n]+` +
                                `00:00:10.000 --> 00:00:14.000[ \n]+Adding subtitles is very easy to do`;
                            yield (0, shared_1.testCaptionFile)(servers[0].url, enCaption.captionPath, new RegExp(regex));
                        }
                        {
                            const frCaption = videoCaptions.find(caption => caption.language.id === 'fr');
                            (0, chai_1.expect)(frCaption).to.exist;
                            (0, chai_1.expect)(frCaption.language.label).to.equal('French');
                            (0, chai_1.expect)(frCaption.captionPath).to.match(new RegExp(`^/lazy-static/video-captions/.+-fr.vtt`));
                            const regex = `WEBVTT[ \n]+Kind: captions[ \n]+Language: fr[ \n]+00:00:01.600 --> 00:00:04.200[ \n]+` +
                                `Français \\(FR\\)[ \n]+00:00:05.900 --> 00:00:07.999[ \n]+C'est un sous-titre français[ \n]+` +
                                `00:00:10.000 --> 00:00:14.000[ \n]+Ajouter un sous-titre est vraiment facile`;
                            yield (0, shared_1.testCaptionFile)(servers[0].url, frCaption.captionPath, new RegExp(regex));
                        }
                    }
                    {
                        const attributes = Object.assign(Object.assign({}, baseAttributes), { magnetUri: shared_1.FIXTURE_URLS.magnet, description: 'this is a super torrent description', tags: ['tag_torrent1', 'tag_torrent2'] });
                        const { video } = yield servers[0].imports.importVideo({ attributes });
                        (0, chai_1.expect)(video.name).to.equal('super peertube2 video');
                    }
                    {
                        const attributes = Object.assign(Object.assign({}, baseAttributes), { torrentfile: 'video-720p.torrent', description: 'this is a super torrent description', tags: ['tag_torrent1', 'tag_torrent2'] });
                        const { video } = yield servers[0].imports.importVideo({ attributes });
                        (0, chai_1.expect)(video.name).to.equal('你好 世界 720p.mp4');
                    }
                });
            });
            it('Should list the videos to import in my videos on server 1', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    const { total, data } = yield servers[0].videos.listMyVideos({ sort: 'createdAt' });
                    (0, chai_1.expect)(total).to.equal(3);
                    (0, chai_1.expect)(data).to.have.lengthOf(3);
                    (0, chai_1.expect)(data[0].name).to.equal('small video - youtube');
                    (0, chai_1.expect)(data[1].name).to.equal('super peertube2 video');
                    (0, chai_1.expect)(data[2].name).to.equal('你好 世界 720p.mp4');
                });
            });
            it('Should list the videos to import in my imports on server 1', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    const { total, data: videoImports } = yield servers[0].imports.getMyVideoImports({ sort: '-createdAt' });
                    (0, chai_1.expect)(total).to.equal(3);
                    (0, chai_1.expect)(videoImports).to.have.lengthOf(3);
                    (0, chai_1.expect)(videoImports[2].targetUrl).to.equal(shared_1.FIXTURE_URLS.youtube);
                    (0, chai_1.expect)(videoImports[2].magnetUri).to.be.null;
                    (0, chai_1.expect)(videoImports[2].torrentName).to.be.null;
                    (0, chai_1.expect)(videoImports[2].video.name).to.equal('small video - youtube');
                    (0, chai_1.expect)(videoImports[1].targetUrl).to.be.null;
                    (0, chai_1.expect)(videoImports[1].magnetUri).to.equal(shared_1.FIXTURE_URLS.magnet);
                    (0, chai_1.expect)(videoImports[1].torrentName).to.be.null;
                    (0, chai_1.expect)(videoImports[1].video.name).to.equal('super peertube2 video');
                    (0, chai_1.expect)(videoImports[0].targetUrl).to.be.null;
                    (0, chai_1.expect)(videoImports[0].magnetUri).to.be.null;
                    (0, chai_1.expect)(videoImports[0].torrentName).to.equal('video-720p.torrent');
                    (0, chai_1.expect)(videoImports[0].video.name).to.equal('你好 世界 720p.mp4');
                });
            });
            it('Should filter my imports on target URL', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    const { total, data: videoImports } = yield servers[0].imports.getMyVideoImports({ targetUrl: shared_1.FIXTURE_URLS.youtube });
                    (0, chai_1.expect)(total).to.equal(1);
                    (0, chai_1.expect)(videoImports).to.have.lengthOf(1);
                    (0, chai_1.expect)(videoImports[0].targetUrl).to.equal(shared_1.FIXTURE_URLS.youtube);
                });
            });
            it('Should have the video listed on the two instances', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(120000);
                    yield (0, server_commands_1.waitJobs)(servers);
                    for (const server of servers) {
                        const { total, data } = yield server.videos.list();
                        (0, chai_1.expect)(total).to.equal(3);
                        (0, chai_1.expect)(data).to.have.lengthOf(3);
                        const [videoHttp, videoMagnet, videoTorrent] = data;
                        yield checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid);
                    }
                });
            });
            it('Should import a video on server 2 with some fields', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(60000);
                    const attributes = {
                        targetUrl: shared_1.FIXTURE_URLS.youtube,
                        channelId: servers[1].store.channel.id,
                        privacy: 1,
                        category: 10,
                        licence: 7,
                        language: 'en',
                        name: 'my super name',
                        description: 'my super description',
                        tags: ['supertag1', 'supertag2']
                    };
                    const { video } = yield servers[1].imports.importVideo({ attributes });
                    (0, chai_1.expect)(video.name).to.equal('my super name');
                });
            });
            it('Should have the videos listed on the two instances', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(120000);
                    yield (0, server_commands_1.waitJobs)(servers);
                    for (const server of servers) {
                        const { total, data } = yield server.videos.list();
                        (0, chai_1.expect)(total).to.equal(4);
                        (0, chai_1.expect)(data).to.have.lengthOf(4);
                        yield checkVideoServer2(server, data[0].uuid);
                        const [, videoHttp, videoMagnet, videoTorrent] = data;
                        yield checkVideosServer1(server, videoHttp.uuid, videoMagnet.uuid, videoTorrent.uuid);
                    }
                });
            });
            it('Should import a video that will be transcoded', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(240000);
                    const attributes = {
                        name: 'transcoded video',
                        magnetUri: shared_1.FIXTURE_URLS.magnet,
                        channelId: servers[1].store.channel.id,
                        privacy: 1
                    };
                    const { video } = yield servers[1].imports.importVideo({ attributes });
                    const videoUUID = video.uuid;
                    yield (0, server_commands_1.waitJobs)(servers);
                    for (const server of servers) {
                        const video = yield server.videos.get({ id: videoUUID });
                        (0, chai_1.expect)(video.name).to.equal('transcoded video');
                        (0, chai_1.expect)(video.files).to.have.lengthOf(4);
                    }
                });
            });
            it('Should import no HDR version on a HDR video', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(300000);
                    const config = {
                        transcoding: {
                            enabled: true,
                            resolutions: {
                                '144p': true,
                                '240p': true,
                                '360p': false,
                                '480p': false,
                                '720p': false,
                                '1080p': false,
                                '1440p': false,
                                '2160p': false
                            },
                            webtorrent: { enabled: true },
                            hls: { enabled: false }
                        },
                        import: {
                            videos: {
                                http: {
                                    enabled: true
                                },
                                torrent: {
                                    enabled: true
                                }
                            }
                        }
                    };
                    yield servers[0].config.updateCustomSubConfig({ newConfig: config });
                    const attributes = {
                        name: 'hdr video',
                        targetUrl: shared_1.FIXTURE_URLS.youtubeHDR,
                        channelId: servers[0].store.channel.id,
                        privacy: 1
                    };
                    const { video: videoImported } = yield servers[0].imports.importVideo({ attributes });
                    const videoUUID = videoImported.uuid;
                    yield (0, server_commands_1.waitJobs)(servers);
                    const video = yield servers[0].videos.get({ id: videoUUID });
                    (0, chai_1.expect)(video.name).to.equal('hdr video');
                    const maxResolution = Math.max.apply(Math, video.files.map(function (o) { return o.resolution.id; }));
                    (0, chai_1.expect)(maxResolution, 'expected max resolution not met').to.equals(240);
                });
            });
            it('Should import a peertube video', function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    this.timeout(120000);
                    const toTest = [shared_1.FIXTURE_URLS.peertube_long];
                    if (mode === 'yt-dlp') {
                        toTest.push(shared_1.FIXTURE_URLS.peertube_short);
                    }
                    for (const targetUrl of toTest) {
                        yield servers[0].config.disableTranscoding();
                        const attributes = {
                            targetUrl,
                            channelId: servers[0].store.channel.id,
                            privacy: 1
                        };
                        const { video } = yield servers[0].imports.importVideo({ attributes });
                        const videoUUID = video.uuid;
                        yield (0, server_commands_1.waitJobs)(servers);
                        for (const server of servers) {
                            const video = yield server.videos.get({ id: videoUUID });
                            (0, chai_1.expect)(video.name).to.equal('E2E tests');
                        }
                    }
                });
            });
            after(function () {
                return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                    yield (0, server_commands_1.cleanupTests)(servers);
                });
            });
        });
    }
    runSuite('youtube-dl');
    runSuite('yt-dlp');
    describe('Delete/cancel an import', function () {
        let server;
        let finishedImportId;
        let finishedVideo;
        let pendingImportId;
        function importVideo(name) {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                const attributes = { name, channelId: server.store.channel.id, targetUrl: shared_1.FIXTURE_URLS.goodVideo };
                const res = yield server.imports.importVideo({ attributes });
                return res.id;
            });
        }
        before(function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                this.timeout(120000);
                server = yield (0, server_commands_1.createSingleServer)(1);
                yield (0, server_commands_1.setAccessTokensToServers)([server]);
                yield (0, server_commands_1.setDefaultVideoChannel)([server]);
                finishedImportId = yield importVideo('finished');
                yield (0, server_commands_1.waitJobs)([server]);
                yield server.jobs.pauseJobQueue();
                pendingImportId = yield importVideo('pending');
                const { data } = yield server.imports.getMyVideoImports();
                (0, chai_1.expect)(data).to.have.lengthOf(2);
                finishedVideo = data.find(i => i.id === finishedImportId).video;
            });
        });
        it('Should delete a video import', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                yield server.imports.delete({ importId: finishedImportId });
                const { data } = yield server.imports.getMyVideoImports();
                (0, chai_1.expect)(data).to.have.lengthOf(1);
                (0, chai_1.expect)(data[0].id).to.equal(pendingImportId);
                (0, chai_1.expect)(data[0].state.id).to.equal(1);
            });
        });
        it('Should not have deleted the associated video', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                const video = yield server.videos.get({ id: finishedVideo.id, token: server.accessToken, expectedStatus: 200 });
                (0, chai_1.expect)(video.name).to.equal('finished');
                (0, chai_1.expect)(video.state.id).to.equal(1);
            });
        });
        it('Should cancel a video import', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                yield server.imports.cancel({ importId: pendingImportId });
                const { data } = yield server.imports.getMyVideoImports();
                (0, chai_1.expect)(data).to.have.lengthOf(1);
                (0, chai_1.expect)(data[0].id).to.equal(pendingImportId);
                (0, chai_1.expect)(data[0].state.id).to.equal(5);
            });
        });
        it('Should not have processed the cancelled video import', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                this.timeout(60000);
                yield server.jobs.resumeJobQueue();
                yield (0, server_commands_1.waitJobs)([server]);
                const { data } = yield server.imports.getMyVideoImports();
                (0, chai_1.expect)(data).to.have.lengthOf(1);
                (0, chai_1.expect)(data[0].id).to.equal(pendingImportId);
                (0, chai_1.expect)(data[0].state.id).to.equal(5);
                (0, chai_1.expect)(data[0].video.state.id).to.equal(3);
            });
        });
        it('Should delete the cancelled video import', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                yield server.imports.delete({ importId: pendingImportId });
                const { data } = yield server.imports.getMyVideoImports();
                (0, chai_1.expect)(data).to.have.lengthOf(0);
            });
        });
        after(function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                yield (0, server_commands_1.cleanupTests)([server]);
            });
        });
    });
    describe('Auto update', function () {
        let server;
        function quickPeerTubeImport() {
            const attributes = {
                targetUrl: shared_1.FIXTURE_URLS.peertube_long,
                channelId: server.store.channel.id,
                privacy: 1
            };
            return server.imports.importVideo({ attributes });
        }
        function testBinaryUpdate(releaseUrl, releaseName) {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                yield (0, fs_extra_1.remove)((0, path_1.join)(server.servers.buildDirectory('bin'), releaseName));
                yield server.kill();
                yield server.run({
                    import: {
                        videos: {
                            http: {
                                youtube_dl_release: {
                                    url: releaseUrl,
                                    name: releaseName
                                }
                            }
                        }
                    }
                });
                yield quickPeerTubeImport();
                const base = server.servers.buildDirectory('bin');
                const content = yield (0, fs_extra_1.readdir)(base);
                const binaryPath = (0, path_1.join)(base, releaseName);
                (0, chai_1.expect)(yield (0, fs_extra_1.pathExists)(binaryPath), `${binaryPath} does not exist in ${base} (${content.join(', ')})`).to.be.true;
            });
        }
        before(function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                this.timeout(30000);
                server = yield (0, server_commands_1.createSingleServer)(1);
                yield (0, server_commands_1.setAccessTokensToServers)([server]);
                yield (0, server_commands_1.setDefaultVideoChannel)([server]);
            });
        });
        it('Should update youtube-dl from github URL', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                this.timeout(120000);
                yield testBinaryUpdate('https://api.github.com/repos/ytdl-org/youtube-dl/releases', 'youtube-dl');
            });
        });
        it('Should update youtube-dl from raw URL', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                this.timeout(120000);
                yield testBinaryUpdate('https://yt-dl.org/downloads/latest/youtube-dl', 'youtube-dl');
            });
        });
        it('Should update youtube-dl from youtube-dl fork', function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                this.timeout(120000);
                yield testBinaryUpdate('https://api.github.com/repos/yt-dlp/yt-dlp/releases', 'yt-dlp');
            });
        });
        after(function () {
            return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
                yield (0, server_commands_1.cleanupTests)([server]);
            });
        });
    });
});
//# sourceMappingURL=video-imports.js.map