1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import { expect } from 'chai'
4 import { FfmpegCommand } from 'fluent-ffmpeg'
5 import { prepareViewsServers, prepareViewsVideos, processViewsBuffer } from '@server/tests/shared'
6 import { wait } from '@shared/core-utils'
7 import { cleanupTests, PeerTubeServer, stopFfmpeg, waitJobs } from '@shared/server-commands'
9 describe('Test video views/viewers counters', function () {
10 let servers: PeerTubeServer[]
12 async function checkCounter (field: 'views' | 'viewers', id: string, expected: number) {
13 for (const server of servers) {
14 const video = await server.videos.get({ id })
16 const messageSuffix = video.isLive
20 expect(video[field]).to.equal(expected, `${field} not valid on server ${server.serverNumber} for ${messageSuffix} ${video.uuid}`)
24 before(async function () {
27 servers = await prepareViewsServers()
30 describe('Test views counter on VOD', function () {
33 before(async function () {
36 const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
39 await waitJobs(servers)
42 it('Should not view a video if watch time is below the threshold', async function () {
43 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 2 ] })
44 await processViewsBuffer(servers)
46 await checkCounter('views', videoUUID, 0)
49 it('Should view a video if watch time is above the threshold', async function () {
50 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 4 ] })
51 await processViewsBuffer(servers)
53 await checkCounter('views', videoUUID, 1)
56 it('Should not view again this video with the same IP', async function () {
57 await servers[0].views.simulateViewer({ id: videoUUID, xForwardedFor: '0.0.0.1,127.0.0.1', currentTimes: [ 1, 4 ] })
58 await servers[0].views.simulateViewer({ id: videoUUID, xForwardedFor: '0.0.0.1,127.0.0.1', currentTimes: [ 1, 4 ] })
59 await processViewsBuffer(servers)
61 await checkCounter('views', videoUUID, 2)
64 it('Should view the video from server 2 and send the event', async function () {
65 await servers[1].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 4 ] })
66 await waitJobs(servers)
67 await processViewsBuffer(servers)
69 await checkCounter('views', videoUUID, 3)
73 describe('Test views and viewers counters on live and VOD', function () {
74 let liveVideoId: string
75 let vodVideoId: string
76 let command: FfmpegCommand
78 before(async function () {
81 ({ vodVideoId, liveVideoId, ffmpegCommand: command } = await prepareViewsVideos({ servers, live: true, vod: true }))
84 it('Should display no views and viewers', async function () {
85 await checkCounter('views', liveVideoId, 0)
86 await checkCounter('viewers', liveVideoId, 0)
88 await checkCounter('views', vodVideoId, 0)
89 await checkCounter('viewers', vodVideoId, 0)
92 it('Should view twice and display 1 view/viewer', async function () {
95 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
96 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
97 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
98 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
100 await waitJobs(servers)
101 await checkCounter('viewers', liveVideoId, 1)
102 await checkCounter('viewers', vodVideoId, 1)
104 await processViewsBuffer(servers)
106 await checkCounter('views', liveVideoId, 1)
107 await checkCounter('views', vodVideoId, 1)
110 it('Should wait and display 0 viewers but still have 1 view', async function () {
114 await waitJobs(servers)
116 await checkCounter('views', liveVideoId, 1)
117 await checkCounter('viewers', liveVideoId, 0)
119 await checkCounter('views', vodVideoId, 1)
120 await checkCounter('viewers', vodVideoId, 0)
123 it('Should view on a remote and on local and display 2 viewers and 3 views', async function () {
126 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
127 await servers[1].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
128 await servers[1].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
130 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
131 await servers[1].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
132 await servers[1].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
134 await waitJobs(servers)
136 await checkCounter('viewers', liveVideoId, 2)
137 await checkCounter('viewers', vodVideoId, 2)
139 await processViewsBuffer(servers)
141 await checkCounter('views', liveVideoId, 3)
142 await checkCounter('views', vodVideoId, 3)
145 after(async function () {
146 await stopFfmpeg(command)
150 after(async function () {
151 await cleanupTests(servers)