1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { getLiveNotificationSocket } from '@shared/extra-utils/socket/socket-io'
6 import { VideoPrivacy, VideoState } from '@shared/models'
11 flushAndRunMultipleServers,
13 sendRTMPStreamInVideo,
15 setAccessTokensToServers,
16 setDefaultVideoChannel,
18 updateCustomSubConfig,
23 waitUntilLivePublishedOnAllServers
24 } from '../../../../shared/extra-utils'
26 const expect = chai.expect
28 describe('Test live', function () {
29 let servers: ServerInfo[] = []
31 before(async function () {
34 servers = await flushAndRunMultipleServers(2)
36 // Get the access tokens
37 await setAccessTokensToServers(servers)
38 await setDefaultVideoChannel(servers)
40 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
50 // Server 1 and server 2 follow each other
51 await doubleFollow(servers[0], servers[1])
54 describe('Live socket messages', function () {
56 async function createLiveWrapper () {
57 const liveAttributes = {
59 channelId: servers[0].videoChannel.id,
60 privacy: VideoPrivacy.PUBLIC
63 const res = await createLive(servers[0].url, servers[0].accessToken, liveAttributes)
64 return res.body.video.uuid
67 it('Should correctly send a message when the live starts and ends', async function () {
70 const localStateChanges: VideoState[] = []
71 const remoteStateChanges: VideoState[] = []
73 const liveVideoUUID = await createLiveWrapper()
74 await waitJobs(servers)
77 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
79 const localSocket = getLiveNotificationSocket(servers[0].url)
80 localSocket.on('state-change', data => localStateChanges.push(data.state))
81 localSocket.emit('subscribe', { videoId })
85 const videoId = await getVideoIdFromUUID(servers[1].url, liveVideoUUID)
87 const remoteSocket = getLiveNotificationSocket(servers[1].url)
88 remoteSocket.on('state-change', data => remoteStateChanges.push(data.state))
89 remoteSocket.emit('subscribe', { videoId })
92 const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
94 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
95 await waitJobs(servers)
97 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
98 expect(stateChanges).to.have.length.at.least(1)
99 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.PUBLISHED)
102 await stopFfmpeg(command)
104 for (const server of servers) {
105 await waitUntilLiveEnded(server.url, server.accessToken, liveVideoUUID)
107 await waitJobs(servers)
109 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
110 expect(stateChanges).to.have.length.at.least(2)
111 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.LIVE_ENDED)
115 it('Should correctly send views change notification', async function () {
118 let localLastVideoViews = 0
119 let remoteLastVideoViews = 0
121 const liveVideoUUID = await createLiveWrapper()
122 await waitJobs(servers)
125 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
127 const localSocket = getLiveNotificationSocket(servers[0].url)
128 localSocket.on('views-change', data => { localLastVideoViews = data.views })
129 localSocket.emit('subscribe', { videoId })
133 const videoId = await getVideoIdFromUUID(servers[1].url, liveVideoUUID)
135 const remoteSocket = getLiveNotificationSocket(servers[1].url)
136 remoteSocket.on('views-change', data => { remoteLastVideoViews = data.views })
137 remoteSocket.emit('subscribe', { videoId })
140 const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
142 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
143 await waitJobs(servers)
145 expect(localLastVideoViews).to.equal(0)
146 expect(remoteLastVideoViews).to.equal(0)
148 await viewVideo(servers[0].url, liveVideoUUID)
149 await viewVideo(servers[1].url, liveVideoUUID)
151 await waitJobs(servers)
153 await waitJobs(servers)
155 expect(localLastVideoViews).to.equal(2)
156 expect(remoteLastVideoViews).to.equal(2)
158 await stopFfmpeg(command)
161 it('Should not receive a notification after unsubscribe', async function () {
164 const stateChanges: VideoState[] = []
166 const liveVideoUUID = await createLiveWrapper()
167 await waitJobs(servers)
169 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
171 const socket = getLiveNotificationSocket(servers[0].url)
172 socket.on('state-change', data => stateChanges.push(data.state))
173 socket.emit('subscribe', { videoId })
175 const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
177 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
178 await waitJobs(servers)
180 // Notifier waits before sending a notification
183 expect(stateChanges).to.have.lengthOf(1)
184 socket.emit('unsubscribe', { videoId })
186 await stopFfmpeg(command)
187 await waitJobs(servers)
189 expect(stateChanges).to.have.lengthOf(1)
193 after(async function () {
194 await cleanupTests(servers)