]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/views/video-views-overall-stats.ts
Added "total views" in the my channels list (#5007)
[github/Chocobozzz/PeerTube.git] / server / tests / api / views / video-views-overall-stats.ts
CommitLineData
b2111066
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import 'mocha'
4import * as chai from 'chai'
5import { FfmpegCommand } from 'fluent-ffmpeg'
6import { prepareViewsServers, prepareViewsVideos, processViewersStats } from '@server/tests/shared'
7import { cleanupTests, PeerTubeServer, stopFfmpeg, waitJobs } from '@shared/server-commands'
8
9const expect = chai.expect
10
11describe('Test views overall stats', function () {
12 let servers: PeerTubeServer[]
13
14 before(async function () {
15 this.timeout(120000)
16
17 servers = await prepareViewsServers()
18 })
19
b2111066
C
20 describe('Test watch time stats of local videos on live and VOD', function () {
21 let vodVideoId: string
22 let liveVideoId: string
23 let command: FfmpegCommand
24
25 before(async function () {
ac907dc7 26 this.timeout(120000);
b2111066
C
27
28 ({ vodVideoId, liveVideoId, ffmpegCommand: command } = await prepareViewsVideos({ servers, live: true, vod: true }))
29 })
30
31 it('Should display overall stats of a video with no viewers', async function () {
32 for (const videoId of [ liveVideoId, vodVideoId ]) {
33 const stats = await servers[0].videoStats.getOverallStats({ videoId })
f18a060a 34 const video = await servers[0].videos.get({ id: videoId })
b2111066 35
f18a060a 36 expect(video.views).to.equal(0)
b2111066
C
37 expect(stats.averageWatchTime).to.equal(0)
38 expect(stats.totalWatchTime).to.equal(0)
305ec384 39 expect(stats.totalViewers).to.equal(0)
b2111066
C
40 }
41 })
42
43 it('Should display overall stats with 1 viewer below the watch time limit', async function () {
44 this.timeout(60000)
45
46 for (const videoId of [ liveVideoId, vodVideoId ]) {
47 await servers[0].views.simulateViewer({ id: videoId, currentTimes: [ 0, 1 ] })
48 }
49
50 await processViewersStats(servers)
51
52 for (const videoId of [ liveVideoId, vodVideoId ]) {
53 const stats = await servers[0].videoStats.getOverallStats({ videoId })
f18a060a 54 const video = await servers[0].videos.get({ id: videoId })
b2111066 55
f18a060a 56 expect(video.views).to.equal(0)
b2111066
C
57 expect(stats.averageWatchTime).to.equal(1)
58 expect(stats.totalWatchTime).to.equal(1)
305ec384 59 expect(stats.totalViewers).to.equal(1)
b2111066
C
60 }
61 })
62
63 it('Should display overall stats with 2 viewers', async function () {
64 this.timeout(60000)
65
66 {
67 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 3 ] })
68 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35, 40 ] })
69
70 await processViewersStats(servers)
71
72 {
73 const stats = await servers[0].videoStats.getOverallStats({ videoId: vodVideoId })
f18a060a
C
74 const video = await servers[0].videos.get({ id: vodVideoId })
75
76 expect(video.views).to.equal(1)
b2111066
C
77 expect(stats.averageWatchTime).to.equal(2)
78 expect(stats.totalWatchTime).to.equal(4)
305ec384 79 expect(stats.totalViewers).to.equal(2)
b2111066
C
80 }
81
82 {
83 const stats = await servers[0].videoStats.getOverallStats({ videoId: liveVideoId })
f18a060a
C
84 const video = await servers[0].videos.get({ id: liveVideoId })
85
86 expect(video.views).to.equal(1)
b2111066
C
87 expect(stats.averageWatchTime).to.equal(21)
88 expect(stats.totalWatchTime).to.equal(41)
305ec384 89 expect(stats.totalViewers).to.equal(2)
b2111066
C
90 }
91 }
92 })
93
94 it('Should display overall stats with a remote viewer below the watch time limit', async function () {
95 this.timeout(60000)
96
97 for (const videoId of [ liveVideoId, vodVideoId ]) {
98 await servers[1].views.simulateViewer({ id: videoId, currentTimes: [ 0, 2 ] })
99 }
100
101 await processViewersStats(servers)
102
103 {
104 const stats = await servers[0].videoStats.getOverallStats({ videoId: vodVideoId })
f18a060a 105 const video = await servers[0].videos.get({ id: vodVideoId })
b2111066 106
f18a060a 107 expect(video.views).to.equal(1)
b2111066
C
108 expect(stats.averageWatchTime).to.equal(2)
109 expect(stats.totalWatchTime).to.equal(6)
305ec384 110 expect(stats.totalViewers).to.equal(3)
b2111066
C
111 }
112
113 {
114 const stats = await servers[0].videoStats.getOverallStats({ videoId: liveVideoId })
f18a060a 115 const video = await servers[0].videos.get({ id: liveVideoId })
b2111066 116
f18a060a 117 expect(video.views).to.equal(1)
b2111066
C
118 expect(stats.averageWatchTime).to.equal(14)
119 expect(stats.totalWatchTime).to.equal(43)
305ec384 120 expect(stats.totalViewers).to.equal(3)
b2111066
C
121 }
122 })
123
124 it('Should display overall stats with a remote viewer above the watch time limit', async function () {
125 this.timeout(60000)
126
127 await servers[1].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
128 await servers[1].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 45 ] })
129 await processViewersStats(servers)
130
131 {
132 const stats = await servers[0].videoStats.getOverallStats({ videoId: vodVideoId })
f18a060a
C
133 const video = await servers[0].videos.get({ id: vodVideoId })
134
135 expect(video.views).to.equal(2)
b2111066
C
136 expect(stats.averageWatchTime).to.equal(3)
137 expect(stats.totalWatchTime).to.equal(11)
305ec384 138 expect(stats.totalViewers).to.equal(4)
b2111066
C
139 }
140
141 {
142 const stats = await servers[0].videoStats.getOverallStats({ videoId: liveVideoId })
f18a060a
C
143 const video = await servers[0].videos.get({ id: liveVideoId })
144
145 expect(video.views).to.equal(2)
b2111066
C
146 expect(stats.averageWatchTime).to.equal(22)
147 expect(stats.totalWatchTime).to.equal(88)
305ec384 148 expect(stats.totalViewers).to.equal(4)
b2111066
C
149 }
150 })
151
49f0468d
C
152 it('Should filter overall stats by date', async function () {
153 this.timeout(60000)
154
155 const beforeView = new Date()
156
157 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 3 ] })
158 await processViewersStats(servers)
159
160 {
161 const stats = await servers[0].videoStats.getOverallStats({ videoId: vodVideoId, startDate: beforeView.toISOString() })
162 expect(stats.averageWatchTime).to.equal(3)
163 expect(stats.totalWatchTime).to.equal(3)
305ec384 164 expect(stats.totalViewers).to.equal(1)
49f0468d
C
165 }
166
167 {
168 const stats = await servers[0].videoStats.getOverallStats({ videoId: liveVideoId, endDate: beforeView.toISOString() })
169 expect(stats.averageWatchTime).to.equal(22)
170 expect(stats.totalWatchTime).to.equal(88)
305ec384 171 expect(stats.totalViewers).to.equal(4)
49f0468d
C
172 }
173 })
174
b2111066
C
175 after(async function () {
176 await stopFfmpeg(command)
177 })
178 })
179
180 describe('Test watchers peak stats of local videos on VOD', function () {
181 let videoUUID: string
f40712ab 182 let before2Watchers: Date
b2111066
C
183
184 before(async function () {
ac907dc7 185 this.timeout(120000);
b2111066
C
186
187 ({ vodVideoId: videoUUID } = await prepareViewsVideos({ servers, live: true, vod: true }))
188 })
189
190 it('Should not have watchers peak', async function () {
191 const stats = await servers[0].videoStats.getOverallStats({ videoId: videoUUID })
192
193 expect(stats.viewersPeak).to.equal(0)
194 expect(stats.viewersPeakDate).to.be.null
195 })
196
197 it('Should have watcher peak with 1 watcher', async function () {
198 this.timeout(60000)
199
200 const before = new Date()
201 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 0, 2 ] })
202 const after = new Date()
203
204 await processViewersStats(servers)
205
206 const stats = await servers[0].videoStats.getOverallStats({ videoId: videoUUID })
207
208 expect(stats.viewersPeak).to.equal(1)
209 expect(new Date(stats.viewersPeakDate)).to.be.above(before).and.below(after)
210 })
211
212 it('Should have watcher peak with 2 watchers', async function () {
213 this.timeout(60000)
214
f40712ab 215 before2Watchers = new Date()
b2111066
C
216 await servers[0].views.view({ id: videoUUID, currentTime: 0 })
217 await servers[1].views.view({ id: videoUUID, currentTime: 0 })
218 await servers[0].views.view({ id: videoUUID, currentTime: 2 })
219 await servers[1].views.view({ id: videoUUID, currentTime: 2 })
220 const after = new Date()
221
222 await processViewersStats(servers)
223
224 const stats = await servers[0].videoStats.getOverallStats({ videoId: videoUUID })
225
226 expect(stats.viewersPeak).to.equal(2)
f40712ab
C
227 expect(new Date(stats.viewersPeakDate)).to.be.above(before2Watchers).and.below(after)
228 })
229
230 it('Should filter peak viewers stats by date', async function () {
231 {
232 const stats = await servers[0].videoStats.getOverallStats({ videoId: videoUUID, startDate: new Date().toISOString() })
233 expect(stats.viewersPeak).to.equal(0)
234 expect(stats.viewersPeakDate).to.not.exist
235 }
236
237 {
238 const stats = await servers[0].videoStats.getOverallStats({ videoId: videoUUID, endDate: before2Watchers.toISOString() })
239 expect(stats.viewersPeak).to.equal(1)
240 expect(new Date(stats.viewersPeakDate)).to.be.below(before2Watchers)
241 }
b2111066
C
242 })
243 })
244
245 describe('Test countries', function () {
f40712ab 246 let videoUUID: string
b2111066
C
247
248 it('Should not report countries if geoip is disabled', async function () {
40fa53ac 249 this.timeout(120000)
b2111066
C
250
251 const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
252 await waitJobs(servers)
253
254 await servers[1].views.view({ id: uuid, xForwardedFor: '8.8.8.8,127.0.0.1', currentTime: 1 })
255
256 await processViewersStats(servers)
257
258 const stats = await servers[0].videoStats.getOverallStats({ videoId: uuid })
259 expect(stats.countries).to.have.lengthOf(0)
260 })
261
262 it('Should report countries if geoip is enabled', async function () {
389444e0 263 this.timeout(240000)
b2111066
C
264
265 const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
f40712ab 266 videoUUID = uuid
b2111066
C
267 await waitJobs(servers)
268
269 await Promise.all([
270 servers[0].kill(),
271 servers[1].kill()
272 ])
273
274 const config = { geo_ip: { enabled: true } }
275 await Promise.all([
276 servers[0].run(config),
277 servers[1].run(config)
278 ])
279
280 await servers[0].views.view({ id: uuid, xForwardedFor: '8.8.8.8,127.0.0.1', currentTime: 1 })
281 await servers[1].views.view({ id: uuid, xForwardedFor: '8.8.8.4,127.0.0.1', currentTime: 3 })
282 await servers[1].views.view({ id: uuid, xForwardedFor: '80.67.169.12,127.0.0.1', currentTime: 2 })
283
284 await processViewersStats(servers)
285
286 const stats = await servers[0].videoStats.getOverallStats({ videoId: uuid })
287 expect(stats.countries).to.have.lengthOf(2)
288
289 expect(stats.countries[0].isoCode).to.equal('US')
290 expect(stats.countries[0].viewers).to.equal(2)
291
292 expect(stats.countries[1].isoCode).to.equal('FR')
293 expect(stats.countries[1].viewers).to.equal(1)
294 })
f40712ab
C
295
296 it('Should filter countries stats by date', async function () {
297 const stats = await servers[0].videoStats.getOverallStats({ videoId: videoUUID, startDate: new Date().toISOString() })
298 expect(stats.countries).to.have.lengthOf(0)
299 })
b2111066
C
300 })
301
302 after(async function () {
303 await cleanupTests(servers)
304 })
305})