X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Ftests%2Fapi%2Flive%2Flive-save-replay.ts;h=05ffe8af9e59ff974cc7f3dfff845c098e66638c;hb=6a9b3151822461a85bbc72b7a50e12ffb69bec3a;hp=3d4736c8fb65e635de22779547b5f3b2bea44b7b;hpb=8f608a4cb22ab232cfab20665050764b38bac9c7;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/tests/api/live/live-save-replay.ts b/server/tests/api/live/live-save-replay.ts index 3d4736c8f..05ffe8af9 100644 --- a/server/tests/api/live/live-save-replay.ts +++ b/server/tests/api/live/live-save-replay.ts @@ -1,99 +1,129 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' -import * as chai from 'chai' +import { expect } from 'chai' import { FfmpegCommand } from 'fluent-ffmpeg' -import { LiveVideoCreate, VideoDetails, VideoPrivacy, VideoState } from '@shared/models' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' +import { checkLiveCleanup } from '@server/tests/shared' +import { wait } from '@shared/core-utils' +import { HttpStatusCode, LiveVideoCreate, LiveVideoError, VideoPrivacy, VideoState } from '@shared/models' import { - addVideoToBlacklist, - checkLiveCleanup, cleanupTests, - createLive, + ConfigCommand, + createMultipleServers, doubleFollow, - flushAndRunMultipleServers, - getCustomConfigResolutions, - getVideo, - getVideosList, - removeVideo, - sendRTMPStreamInVideo, - ServerInfo, + findExternalSavedVideo, + PeerTubeServer, setAccessTokensToServers, setDefaultVideoChannel, stopFfmpeg, testFfmpegStreamError, - updateCustomSubConfig, - updateVideo, - wait, waitJobs, - waitUntilLiveEnded, - waitUntilLivePublished, - waitUntilLiveSaved -} from '../../../../shared/extra-utils' - -const expect = chai.expect + waitUntilLivePublishedOnAllServers, + waitUntilLiveReplacedByReplayOnAllServers, + waitUntilLiveWaitingOnAllServers +} from '@shared/server-commands' describe('Save replay setting', function () { - let servers: ServerInfo[] = [] + let servers: PeerTubeServer[] = [] let liveVideoUUID: string let ffmpegCommand: FfmpegCommand - async function createLiveWrapper (saveReplay: boolean) { + async function createLiveWrapper (options: { permanent: boolean, replay: boolean, replaySettings?: { privacy: VideoPrivacy } }) { if (liveVideoUUID) { try { - await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + await servers[0].videos.remove({ id: liveVideoUUID }) await waitJobs(servers) } catch {} } const attributes: LiveVideoCreate = { - channelId: servers[0].videoChannel.id, + channelId: servers[0].store.channel.id, privacy: VideoPrivacy.PUBLIC, name: 'my super live', - saveReplay + saveReplay: options.replay, + replaySettings: options.replaySettings, + permanentLive: options.permanent } - const res = await createLive(servers[0].url, servers[0].accessToken, attributes) - return res.body.video.uuid + const { uuid } = await servers[0].live.create({ fields: attributes }) + return uuid + } + + async function publishLive (options: { permanent: boolean, replay: boolean, replaySettings?: { privacy: VideoPrivacy } }) { + liveVideoUUID = await createLiveWrapper(options) + + const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) + + const liveDetails = await servers[0].videos.get({ id: liveVideoUUID }) + + await waitJobs(servers) + await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + + return { ffmpegCommand, liveDetails } + } + + async function publishLiveAndDelete (options: { permanent: boolean, replay: boolean, replaySettings?: { privacy: VideoPrivacy } }) { + const { ffmpegCommand, liveDetails } = await publishLive(options) + + await Promise.all([ + servers[0].videos.remove({ id: liveVideoUUID }), + testFfmpegStreamError(ffmpegCommand, true) + ]) + + await waitJobs(servers) + await wait(5000) + await waitJobs(servers) + + return { liveDetails } + } + + async function publishLiveAndBlacklist (options: { permanent: boolean, replay: boolean, replaySettings?: { privacy: VideoPrivacy } }) { + const { ffmpegCommand, liveDetails } = await publishLive(options) + + await Promise.all([ + servers[0].blacklist.add({ videoId: liveVideoUUID, reason: 'bad live', unfederate: true }), + testFfmpegStreamError(ffmpegCommand, true) + ]) + + await waitJobs(servers) + await wait(5000) + await waitJobs(servers) + + return { liveDetails } } - async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) { + async function checkVideosExist (videoId: string, existsInList: boolean, expectedStatus?: number) { for (const server of servers) { const length = existsInList ? 1 : 0 - const resVideos = await getVideosList(server.url) - expect(resVideos.body.data).to.have.lengthOf(length) - expect(resVideos.body.total).to.equal(length) + const { data, total } = await server.videos.list() + expect(data).to.have.lengthOf(length) + expect(total).to.equal(length) - if (getStatus) { - await getVideo(server.url, videoId, getStatus) + if (expectedStatus) { + await server.videos.get({ id: videoId, expectedStatus }) } } } async function checkVideoState (videoId: string, state: VideoState) { for (const server of servers) { - const res = await getVideo(server.url, videoId) - expect((res.body as VideoDetails).state.id).to.equal(state) + const video = await server.videos.get({ id: videoId }) + expect(video.state.id).to.equal(state) } } - async function waitUntilLivePublishedOnAllServers (videoId: string) { + async function checkVideoPrivacy (videoId: string, privacy: VideoPrivacy) { for (const server of servers) { - await waitUntilLivePublished(server.url, server.accessToken, videoId) - } - } - - async function waitUntilLiveSavedOnAllServers (videoId: string) { - for (const server of servers) { - await waitUntilLiveSaved(server.url, server.accessToken, videoId) + const video = await server.videos.get({ id: videoId }) + expect(video.privacy.id).to.equal(privacy) } } before(async function () { this.timeout(120000) - servers = await flushAndRunMultipleServers(2) + servers = await createMultipleServers(2) // Get the access tokens await setAccessTokensToServers(servers) @@ -102,29 +132,30 @@ describe('Save replay setting', function () { // Server 1 and server 2 follow each other await doubleFollow(servers[0], servers[1]) - await updateCustomSubConfig(servers[0].url, servers[0].accessToken, { - live: { - enabled: true, - allowReplay: true, - maxDuration: -1, - transcoding: { - enabled: false, - resolutions: getCustomConfigResolutions(true) + await servers[0].config.updateCustomSubConfig({ + newConfig: { + live: { + enabled: true, + allowReplay: true, + maxDuration: -1, + transcoding: { + enabled: false, + resolutions: ConfigCommand.getCustomConfigResolutions(true) + } } } }) }) describe('With save replay disabled', function () { - - before(async function () { - this.timeout(10000) - }) + let sessionStartDateMin: Date + let sessionStartDateMax: Date + let sessionEndDateMin: Date it('Should correctly create and federate the "waiting for stream" live', async function () { - this.timeout(20000) + this.timeout(40000) - liveVideoUUID = await createLiveWrapper(false) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: false }) await waitJobs(servers) @@ -133,11 +164,13 @@ describe('Save replay setting', function () { }) it('Should correctly have updated the live and federated it when streaming in the live', async function () { - this.timeout(30000) + this.timeout(60000) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) - await waitUntilLivePublishedOnAllServers(liveVideoUUID) + sessionStartDateMin = new Date() + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) + sessionStartDateMax = new Date() await waitJobs(servers) @@ -146,12 +179,13 @@ describe('Save replay setting', function () { }) it('Should correctly delete the video files after the stream ended', async function () { - this.timeout(40000) + this.timeout(60000) + sessionEndDateMin = new Date() await stopFfmpeg(ffmpegCommand) for (const server of servers) { - await waitUntilLiveEnded(server.url, server.accessToken, liveVideoUUID) + await server.live.waitUntilEnded({ videoId: liveVideoUUID }) } await waitJobs(servers) @@ -160,167 +194,373 @@ describe('Save replay setting', function () { await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED) // No resolutions saved since we did not save replay - await checkLiveCleanup(servers[0], liveVideoUUID, []) + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false }) }) - it('Should correctly terminate the stream on blacklist and delete the live', async function () { - this.timeout(40000) + it('Should have appropriate ended session', async function () { + const { data, total } = await servers[0].live.listSessions({ videoId: liveVideoUUID }) + expect(total).to.equal(1) + expect(data).to.have.lengthOf(1) - liveVideoUUID = await createLiveWrapper(false) + const session = data[0] - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + const startDate = new Date(session.startDate) + expect(startDate).to.be.above(sessionStartDateMin) + expect(startDate).to.be.below(sessionStartDateMax) - await waitUntilLivePublishedOnAllServers(liveVideoUUID) + expect(session.endDate).to.exist + expect(new Date(session.endDate)).to.be.above(sessionEndDateMin) - await waitJobs(servers) - await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + expect(session.saveReplay).to.be.false + expect(session.error).to.not.exist + expect(session.replayVideo).to.not.exist + }) - await Promise.all([ - addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true), - testFfmpegStreamError(ffmpegCommand, true) - ]) + it('Should correctly terminate the stream on blacklist and delete the live', async function () { + this.timeout(60000) - await waitJobs(servers) + await publishLiveAndBlacklist({ permanent: false, replay: false }) await checkVideosExist(liveVideoUUID, false) - await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401) - await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) + await servers[0].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) + await servers[1].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) await wait(5000) await waitJobs(servers) - await checkLiveCleanup(servers[0], liveVideoUUID, []) + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false }) }) - it('Should correctly terminate the stream on delete and delete the video', async function () { - this.timeout(40000) + it('Should have blacklisted session error', async function () { + const session = await servers[0].live.findLatestSession({ videoId: liveVideoUUID }) + expect(session.startDate).to.exist + expect(session.endDate).to.exist - liveVideoUUID = await createLiveWrapper(false) - - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) - - await waitUntilLivePublishedOnAllServers(liveVideoUUID) - - await waitJobs(servers) - await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + expect(session.error).to.equal(LiveVideoError.BLACKLISTED) + expect(session.replayVideo).to.not.exist + }) - await Promise.all([ - testFfmpegStreamError(ffmpegCommand, true), - removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) - ]) + it('Should correctly terminate the stream on delete and delete the video', async function () { + this.timeout(60000) - await wait(5000) - await waitJobs(servers) + await publishLiveAndDelete({ permanent: false, replay: false }) await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) - await checkLiveCleanup(servers[0], liveVideoUUID, []) + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false }) }) }) - describe('With save replay enabled', function () { + describe('With save replay enabled on non permanent live', function () { it('Should correctly create and federate the "waiting for stream" live', async function () { - this.timeout(20000) + this.timeout(60000) - liveVideoUUID = await createLiveWrapper(true) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: true, replaySettings: { privacy: VideoPrivacy.UNLISTED } }) await waitJobs(servers) await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200) await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE) + await checkVideoPrivacy(liveVideoUUID, VideoPrivacy.PUBLIC) }) it('Should correctly have updated the live and federated it when streaming in the live', async function () { - this.timeout(20000) + this.timeout(60000) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) - await waitUntilLivePublishedOnAllServers(liveVideoUUID) + ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) await waitJobs(servers) await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) + await checkVideoPrivacy(liveVideoUUID, VideoPrivacy.PUBLIC) }) it('Should correctly have saved the live and federated it after the streaming', async function () { - this.timeout(30000) + this.timeout(60000) + + const session = await servers[0].live.findLatestSession({ videoId: liveVideoUUID }) + expect(session.endDate).to.not.exist + expect(session.endingProcessed).to.be.false + expect(session.saveReplay).to.be.true + expect(session.replaySettings).to.exist + expect(session.replaySettings.privacy).to.equal(VideoPrivacy.UNLISTED) await stopFfmpeg(ffmpegCommand) - await waitUntilLiveSavedOnAllServers(liveVideoUUID) + await waitUntilLiveReplacedByReplayOnAllServers(servers, liveVideoUUID) await waitJobs(servers) // Live has been transcoded - await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200) await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) + await checkVideoPrivacy(liveVideoUUID, VideoPrivacy.UNLISTED) + }) + + it('Should find the replay live session', async function () { + const session = await servers[0].live.getReplaySession({ videoId: liveVideoUUID }) + + expect(session).to.exist + + expect(session.startDate).to.exist + expect(session.endDate).to.exist + + expect(session.error).to.not.exist + expect(session.saveReplay).to.be.true + expect(session.endingProcessed).to.be.true + expect(session.replaySettings).to.exist + expect(session.replaySettings.privacy).to.equal(VideoPrivacy.UNLISTED) + + expect(session.replayVideo).to.exist + expect(session.replayVideo.id).to.exist + expect(session.replayVideo.shortUUID).to.exist + expect(session.replayVideo.uuid).to.equal(liveVideoUUID) }) it('Should update the saved live and correctly federate the updated attributes', async function () { - this.timeout(30000) + this.timeout(60000) - await updateVideo(servers[0].url, servers[0].accessToken, liveVideoUUID, { name: 'video updated' }) + await servers[0].videos.update({ id: liveVideoUUID, attributes: { name: 'video updated', privacy: VideoPrivacy.PUBLIC } }) await waitJobs(servers) for (const server of servers) { - const res = await getVideo(server.url, liveVideoUUID) - expect(res.body.name).to.equal('video updated') - expect(res.body.isLive).to.be.false + const video = await server.videos.get({ id: liveVideoUUID }) + expect(video.name).to.equal('video updated') + expect(video.isLive).to.be.false + expect(video.privacy.id).to.equal(VideoPrivacy.PUBLIC) } }) it('Should have cleaned up the live files', async function () { - await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ]) + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false, savedResolutions: [ 720 ] }) }) it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () { - this.timeout(40000) + this.timeout(120000) - liveVideoUUID = await createLiveWrapper(true) + await publishLiveAndBlacklist({ permanent: false, replay: true, replaySettings: { privacy: VideoPrivacy.PUBLIC } }) + + await checkVideosExist(liveVideoUUID, false) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) - await waitUntilLivePublishedOnAllServers(liveVideoUUID) + await servers[0].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) + await servers[1].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) + await wait(5000) await waitJobs(servers) - await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false, savedResolutions: [ 720 ] }) + }) + + it('Should correctly terminate the stream on delete and delete the video', async function () { + this.timeout(60000) - await Promise.all([ - addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true), - testFfmpegStreamError(ffmpegCommand, true) - ]) + await publishLiveAndDelete({ permanent: false, replay: true, replaySettings: { privacy: VideoPrivacy.PUBLIC } }) - await waitJobs(servers) + await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false }) + }) + }) - await checkVideosExist(liveVideoUUID, false) + describe('With save replay enabled on permanent live', function () { + let lastReplayUUID: string - await getVideo(servers[0].url, liveVideoUUID, HttpStatusCode.UNAUTHORIZED_401) - await getVideo(servers[1].url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) + describe('With a first live and its replay', function () { - await wait(5000) - await waitJobs(servers) - await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ]) + it('Should correctly create and federate the "waiting for stream" live', async function () { + this.timeout(60000) + + liveVideoUUID = await createLiveWrapper({ permanent: true, replay: true, replaySettings: { privacy: VideoPrivacy.UNLISTED } }) + + await waitJobs(servers) + + await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200) + await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE) + await checkVideoPrivacy(liveVideoUUID, VideoPrivacy.PUBLIC) + }) + + it('Should correctly have updated the live and federated it when streaming in the live', async function () { + this.timeout(60000) + + ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) + + await waitJobs(servers) + + await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) + await checkVideoPrivacy(liveVideoUUID, VideoPrivacy.PUBLIC) + }) + + it('Should correctly have saved the live and federated it after the streaming', async function () { + this.timeout(60000) + + const liveDetails = await servers[0].videos.get({ id: liveVideoUUID }) + + await stopFfmpeg(ffmpegCommand) + + await waitUntilLiveWaitingOnAllServers(servers, liveVideoUUID) + await waitJobs(servers) + + const video = await findExternalSavedVideo(servers[0], liveDetails) + expect(video).to.exist + + for (const server of servers) { + await server.videos.get({ id: video.uuid }) + } + + lastReplayUUID = video.uuid + }) + + it('Should have appropriate ended session and replay live session', async function () { + const { data, total } = await servers[0].live.listSessions({ videoId: liveVideoUUID }) + expect(total).to.equal(1) + expect(data).to.have.lengthOf(1) + + const sessionFromLive = data[0] + const sessionFromReplay = await servers[0].live.getReplaySession({ videoId: lastReplayUUID }) + + for (const session of [ sessionFromLive, sessionFromReplay ]) { + expect(session.startDate).to.exist + expect(session.endDate).to.exist + + expect(session.replaySettings).to.exist + expect(session.replaySettings.privacy).to.equal(VideoPrivacy.UNLISTED) + + expect(session.error).to.not.exist + + expect(session.replayVideo).to.exist + expect(session.replayVideo.id).to.exist + expect(session.replayVideo.shortUUID).to.exist + expect(session.replayVideo.uuid).to.equal(lastReplayUUID) + } + }) + + it('Should have the first live replay with correct settings', async function () { + await checkVideosExist(lastReplayUUID, false, HttpStatusCode.OK_200) + await checkVideoState(lastReplayUUID, VideoState.PUBLISHED) + await checkVideoPrivacy(lastReplayUUID, VideoPrivacy.UNLISTED) + }) }) - it('Should correctly terminate the stream on delete and delete the video', async function () { - this.timeout(40000) + describe('With a second live and its replay', function () { - liveVideoUUID = await createLiveWrapper(true) + it('Should update the replay settings', async function () { + await servers[0].live.update({ videoId: liveVideoUUID, fields: { replaySettings: { privacy: VideoPrivacy.PUBLIC } } }) + await waitJobs(servers) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) - await waitUntilLivePublishedOnAllServers(liveVideoUUID) + const live = await servers[0].live.get({ videoId: liveVideoUUID }) - await waitJobs(servers) - await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + expect(live.saveReplay).to.be.true + expect(live.replaySettings).to.exist + expect(live.replaySettings.privacy).to.equal(VideoPrivacy.PUBLIC) - await Promise.all([ - removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID), - testFfmpegStreamError(ffmpegCommand, true) - ]) + }) - await wait(5000) - await waitJobs(servers) + it('Should correctly have updated the live and federated it when streaming in the live', async function () { + this.timeout(60000) - await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) - await checkLiveCleanup(servers[0], liveVideoUUID, []) + ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) + + await waitJobs(servers) + + await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) + await checkVideoPrivacy(liveVideoUUID, VideoPrivacy.PUBLIC) + }) + + it('Should correctly have saved the live and federated it after the streaming', async function () { + this.timeout(60000) + + const liveDetails = await servers[0].videos.get({ id: liveVideoUUID }) + + await stopFfmpeg(ffmpegCommand) + + await waitUntilLiveWaitingOnAllServers(servers, liveVideoUUID) + await waitJobs(servers) + + const video = await findExternalSavedVideo(servers[0], liveDetails) + expect(video).to.exist + + for (const server of servers) { + await server.videos.get({ id: video.uuid }) + } + + lastReplayUUID = video.uuid + }) + + it('Should have appropriate ended session and replay live session', async function () { + const { data, total } = await servers[0].live.listSessions({ videoId: liveVideoUUID }) + expect(total).to.equal(2) + expect(data).to.have.lengthOf(2) + + const sessionFromLive = data[1] + const sessionFromReplay = await servers[0].live.getReplaySession({ videoId: lastReplayUUID }) + + for (const session of [ sessionFromLive, sessionFromReplay ]) { + expect(session.startDate).to.exist + expect(session.endDate).to.exist + + expect(session.replaySettings).to.exist + expect(session.replaySettings.privacy).to.equal(VideoPrivacy.PUBLIC) + + expect(session.error).to.not.exist + + expect(session.replayVideo).to.exist + expect(session.replayVideo.id).to.exist + expect(session.replayVideo.shortUUID).to.exist + expect(session.replayVideo.uuid).to.equal(lastReplayUUID) + } + }) + + it('Should have the first live replay with correct settings', async function () { + await checkVideosExist(lastReplayUUID, true, HttpStatusCode.OK_200) + await checkVideoState(lastReplayUUID, VideoState.PUBLISHED) + await checkVideoPrivacy(lastReplayUUID, VideoPrivacy.PUBLIC) + }) + + it('Should have cleaned up the live files', async function () { + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false }) + }) + + it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () { + this.timeout(120000) + + await servers[0].videos.remove({ id: lastReplayUUID }) + const { liveDetails } = await publishLiveAndBlacklist({ + permanent: true, + replay: true, + replaySettings: { privacy: VideoPrivacy.PUBLIC } + }) + + const replay = await findExternalSavedVideo(servers[0], liveDetails) + expect(replay).to.exist + + for (const videoId of [ liveVideoUUID, replay.uuid ]) { + await checkVideosExist(videoId, false) + + await servers[0].videos.get({ id: videoId, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) + await servers[1].videos.get({ id: videoId, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) + } + + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false }) + }) + + it('Should correctly terminate the stream on delete and not save the video', async function () { + this.timeout(60000) + + const { liveDetails } = await publishLiveAndDelete({ + permanent: true, + replay: true, + replaySettings: { privacy: VideoPrivacy.PUBLIC } + }) + + const replay = await findExternalSavedVideo(servers[0], liveDetails) + expect(replay).to.not.exist + + await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) + await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false }) + }) }) })