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