1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { FfmpegCommand } from 'fluent-ffmpeg'
6 import { prepareViewsServers, prepareViewsVideos, processViewsBuffer } from '@server/tests/shared'
7 import { wait } from '@shared/core-utils'
8 import { cleanupTests, PeerTubeServer, stopFfmpeg, waitJobs } from '@shared/server-commands'
10 const expect = chai.expect
12 describe('Test video views/viewers counters', function () {
13 let servers: PeerTubeServer[]
15 async function checkCounter (field: 'views' | 'viewers', id: string, expected: number) {
16 for (const server of servers) {
17 const video = await server.videos.get({ id })
19 const messageSuffix = video.isLive
23 expect(video[field]).to.equal(expected, `${field} not valid on server ${server.serverNumber} for ${messageSuffix} ${video.uuid}`)
27 before(async function () {
30 servers = await prepareViewsServers()
33 describe('Test views counter on VOD', function () {
36 before(async function () {
39 const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
42 await waitJobs(servers)
45 it('Should not view a video if watch time is below the threshold', async function () {
46 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 2 ] })
47 await processViewsBuffer(servers)
49 await checkCounter('views', videoUUID, 0)
52 it('Should view a video if watch time is above the threshold', async function () {
53 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 4 ] })
54 await processViewsBuffer(servers)
56 await checkCounter('views', videoUUID, 1)
59 it('Should not view again this video with the same IP', async function () {
60 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 4 ] })
61 await processViewsBuffer(servers)
63 await checkCounter('views', videoUUID, 1)
66 it('Should view the video from server 2 and send the event', async function () {
67 await servers[1].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 4 ] })
68 await waitJobs(servers)
69 await processViewsBuffer(servers)
71 await checkCounter('views', videoUUID, 2)
75 describe('Test views and viewers counters on live and VOD', function () {
76 let liveVideoId: string
77 let vodVideoId: string
78 let command: FfmpegCommand
80 before(async function () {
83 ({ vodVideoId, liveVideoId, ffmpegCommand: command } = await prepareViewsVideos({ servers, live: true, vod: true }))
86 it('Should display no views and viewers', async function () {
87 await checkCounter('views', liveVideoId, 0)
88 await checkCounter('viewers', liveVideoId, 0)
90 await checkCounter('views', vodVideoId, 0)
91 await checkCounter('viewers', vodVideoId, 0)
94 it('Should view twice and display 1 view/viewer', async function () {
97 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
98 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
99 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
100 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
102 await waitJobs(servers)
103 await checkCounter('viewers', liveVideoId, 1)
104 await checkCounter('viewers', vodVideoId, 1)
106 await processViewsBuffer(servers)
108 await checkCounter('views', liveVideoId, 1)
109 await checkCounter('views', vodVideoId, 1)
112 it('Should wait and display 0 viewers but still have 1 view', async function () {
116 await waitJobs(servers)
118 await checkCounter('views', liveVideoId, 1)
119 await checkCounter('viewers', liveVideoId, 0)
121 await checkCounter('views', vodVideoId, 1)
122 await checkCounter('viewers', vodVideoId, 0)
125 it('Should view on a remote and on local and display 2 viewers and 3 views', async function () {
128 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
129 await servers[1].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
130 await servers[1].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
132 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
133 await servers[1].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
134 await servers[1].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
136 await waitJobs(servers)
138 await checkCounter('viewers', liveVideoId, 2)
139 await checkCounter('viewers', vodVideoId, 2)
141 await processViewsBuffer(servers)
143 await checkCounter('views', liveVideoId, 3)
144 await checkCounter('views', vodVideoId, 3)
147 after(async function () {
148 await stopFfmpeg(command)
152 after(async function () {
153 await cleanupTests(servers)