]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/search/search-videos.ts
Introduce stats command
[github/Chocobozzz/PeerTube.git] / server / tests / api / search / search-videos.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
d525fc39 2
d525fc39 3import 'mocha'
1fd61899
C
4import * as chai from 'chai'
5import { VideoPrivacy } from '@shared/models'
d525fc39 6import {
7243f84d 7 cleanupTests,
1fd61899 8 createLive,
210feb6c 9 flushAndRunServer,
7243f84d 10 immutableAssign,
af971e06 11 SearchCommand,
1fd61899 12 sendRTMPStreamInVideo,
d525fc39
C
13 ServerInfo,
14 setAccessTokensToServers,
1fd61899
C
15 setDefaultVideoChannel,
16 stopFfmpeg,
17 updateCustomSubConfig,
d525fc39 18 uploadVideo,
1fd61899
C
19 wait,
20 waitUntilLivePublished
94565d52 21} from '../../../../shared/extra-utils'
3caf77d3 22import { createVideoCaption } from '../../../../shared/extra-utils/videos/video-captions'
d525fc39
C
23
24const expect = chai.expect
25
da3a3ab6 26describe('Test videos search', function () {
d525fc39
C
27 let server: ServerInfo = null
28 let startDate: string
3cf53828 29 let videoUUID: string
d525fc39 30
af971e06
C
31 let command: SearchCommand
32
d525fc39 33 before(async function () {
3e3ae966 34 this.timeout(60000)
d525fc39 35
210feb6c 36 server = await flushAndRunServer(1)
d525fc39
C
37
38 await setAccessTokensToServers([ server ])
1fd61899 39 await setDefaultVideoChannel([ server ])
d525fc39
C
40
41 {
42 const attributes1 = {
43 name: '1111 2222 3333',
44 fixture: '60fps_720p_small.mp4', // 2 seconds
45 category: 1,
46 licence: 1,
47 nsfw: false,
48 language: 'fr'
49 }
50 await uploadVideo(server.url, server.accessToken, attributes1)
51
52 const attributes2 = immutableAssign(attributes1, { name: attributes1.name + ' - 2', fixture: 'video_short.mp4' })
53 await uploadVideo(server.url, server.accessToken, attributes2)
54
3caf77d3
C
55 {
56 const attributes3 = immutableAssign(attributes1, { name: attributes1.name + ' - 3', language: undefined })
57 const res = await uploadVideo(server.url, server.accessToken, attributes3)
58 const videoId = res.body.video.id
3cf53828 59 videoUUID = res.body.video.uuid
3caf77d3
C
60
61 await createVideoCaption({
62 url: server.url,
63 accessToken: server.accessToken,
64 language: 'en',
65 videoId,
66 fixture: 'subtitle-good2.vtt',
67 mimeType: 'application/octet-stream'
68 })
69
70 await createVideoCaption({
71 url: server.url,
72 accessToken: server.accessToken,
73 language: 'aa',
74 videoId,
75 fixture: 'subtitle-good2.vtt',
76 mimeType: 'application/octet-stream'
77 })
78 }
d525fc39
C
79
80 const attributes4 = immutableAssign(attributes1, { name: attributes1.name + ' - 4', language: 'pl', nsfw: true })
81 await uploadVideo(server.url, server.accessToken, attributes4)
82
83 await wait(1000)
84
85 startDate = new Date().toISOString()
86
3caf77d3 87 const attributes5 = immutableAssign(attributes1, { name: attributes1.name + ' - 5', licence: 2, language: undefined })
d525fc39
C
88 await uploadVideo(server.url, server.accessToken, attributes5)
89
a1587156 90 const attributes6 = immutableAssign(attributes1, { name: attributes1.name + ' - 6', tags: [ 't1', 't2' ] })
d525fc39
C
91 await uploadVideo(server.url, server.accessToken, attributes6)
92
31d065cc
AM
93 const attributes7 = immutableAssign(attributes1, {
94 name: attributes1.name + ' - 7',
95 originallyPublishedAt: '2019-02-12T09:58:08.286Z'
96 })
d525fc39
C
97 await uploadVideo(server.url, server.accessToken, attributes7)
98
99 const attributes8 = immutableAssign(attributes1, { name: attributes1.name + ' - 8', licence: 4 })
100 await uploadVideo(server.url, server.accessToken, attributes8)
101 }
102
103 {
104 const attributes = {
105 name: '3333 4444 5555',
106 fixture: 'video_short.mp4',
107 category: 2,
108 licence: 2,
109 language: 'en'
110 }
111 await uploadVideo(server.url, server.accessToken, attributes)
112
113 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes, { name: attributes.name + ' duplicate' }))
114 }
115
116 {
117 const attributes = {
118 name: '6666 7777 8888',
119 fixture: 'video_short.mp4',
120 category: 3,
121 licence: 3,
122 language: 'pl'
123 }
124 await uploadVideo(server.url, server.accessToken, attributes)
125 }
126
127 {
128 const attributes1 = {
129 name: '9999',
130 tags: [ 'aaaa', 'bbbb', 'cccc' ],
131 category: 1
132 }
133 await uploadVideo(server.url, server.accessToken, attributes1)
134 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { category: 2 }))
135
136 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { tags: [ 'cccc', 'dddd' ] }))
137 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { tags: [ 'eeee', 'ffff' ] }))
138 }
d4112450
C
139
140 {
141 const attributes1 = {
142 name: 'aaaa 2',
143 category: 1
144 }
145 await uploadVideo(server.url, server.accessToken, attributes1)
146 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { category: 2 }))
147 }
af971e06
C
148
149 command = server.searchCommand
d525fc39
C
150 })
151
152 it('Should make a simple search and not have results', async function () {
af971e06 153 const body = await command.searchVideos({ search: 'abc' })
d525fc39 154
af971e06
C
155 expect(body.total).to.equal(0)
156 expect(body.data).to.have.lengthOf(0)
d525fc39
C
157 })
158
159 it('Should make a simple search and have results', async function () {
af971e06 160 const body = await command.searchVideos({ search: '4444 5555 duplicate' })
d525fc39 161
af971e06 162 expect(body.total).to.equal(2)
d525fc39 163
af971e06 164 const videos = body.data
d525fc39
C
165 expect(videos).to.have.lengthOf(2)
166
167 // bestmatch
168 expect(videos[0].name).to.equal('3333 4444 5555 duplicate')
169 expect(videos[1].name).to.equal('3333 4444 5555')
170 })
171
d4112450 172 it('Should make a search on tags too, and have results', async function () {
af971e06 173 const search = {
d4112450
C
174 search: 'aaaa',
175 categoryOneOf: [ 1 ]
176 }
af971e06 177 const body = await command.advancedVideoSearch({ search })
d4112450 178
af971e06 179 expect(body.total).to.equal(2)
d4112450 180
af971e06 181 const videos = body.data
d4112450
C
182 expect(videos).to.have.lengthOf(2)
183
184 // bestmatch
185 expect(videos[0].name).to.equal('aaaa 2')
186 expect(videos[1].name).to.equal('9999')
187 })
188
189 it('Should filter on tags without a search', async function () {
af971e06 190 const search = {
d4112450
C
191 tagsAllOf: [ 'bbbb' ]
192 }
af971e06 193 const body = await command.advancedVideoSearch({ search })
d4112450 194
af971e06 195 expect(body.total).to.equal(2)
d4112450 196
af971e06 197 const videos = body.data
d4112450
C
198 expect(videos).to.have.lengthOf(2)
199
200 expect(videos[0].name).to.equal('9999')
201 expect(videos[1].name).to.equal('9999')
202 })
203
204 it('Should filter on category without a search', async function () {
af971e06 205 const search = {
d4112450
C
206 categoryOneOf: [ 3 ]
207 }
af971e06 208 const body = await command.advancedVideoSearch({ search: search })
d4112450 209
af971e06 210 expect(body.total).to.equal(1)
d4112450 211
af971e06 212 const videos = body.data
d4112450
C
213 expect(videos).to.have.lengthOf(1)
214
215 expect(videos[0].name).to.equal('6666 7777 8888')
216 })
217
d525fc39
C
218 it('Should search by tags (one of)', async function () {
219 const query = {
220 search: '9999',
221 categoryOneOf: [ 1 ],
4b1f1b81 222 tagsOneOf: [ 'aAaa', 'ffff' ]
d525fc39 223 }
d525fc39 224
af971e06
C
225 {
226 const body = await command.advancedVideoSearch({ search: query })
227 expect(body.total).to.equal(2)
228 }
229
230 {
231 const body = await command.advancedVideoSearch({ search: { ...query, tagsOneOf: [ 'blabla' ] } })
232 expect(body.total).to.equal(0)
233 }
d525fc39
C
234 })
235
236 it('Should search by tags (all of)', async function () {
237 const query = {
238 search: '9999',
239 categoryOneOf: [ 1 ],
4b1f1b81 240 tagsAllOf: [ 'CCcc' ]
d525fc39 241 }
d525fc39 242
af971e06
C
243 {
244 const body = await command.advancedVideoSearch({ search: query })
245 expect(body.total).to.equal(2)
246 }
d525fc39 247
af971e06
C
248 {
249 const body = await command.advancedVideoSearch({ search: { ...query, tagsAllOf: [ 'blAbla' ] } })
250 expect(body.total).to.equal(0)
251 }
252
253 {
254 const body = await command.advancedVideoSearch({ search: { ...query, tagsAllOf: [ 'bbbb', 'CCCC' ] } })
255 expect(body.total).to.equal(1)
256 }
d525fc39
C
257 })
258
259 it('Should search by category', async function () {
260 const query = {
261 search: '6666',
262 categoryOneOf: [ 3 ]
263 }
d525fc39 264
af971e06
C
265 {
266 const body = await command.advancedVideoSearch({ search: query })
267 expect(body.total).to.equal(1)
268 expect(body.data[0].name).to.equal('6666 7777 8888')
269 }
270
271 {
272 const body = await command.advancedVideoSearch({ search: { ...query, categoryOneOf: [ 2 ] } })
273 expect(body.total).to.equal(0)
274 }
d525fc39
C
275 })
276
277 it('Should search by licence', async function () {
278 const query = {
279 search: '4444 5555',
280 licenceOneOf: [ 2 ]
281 }
d525fc39 282
af971e06
C
283 {
284 const body = await command.advancedVideoSearch({ search: query })
285 expect(body.total).to.equal(2)
286 expect(body.data[0].name).to.equal('3333 4444 5555')
287 expect(body.data[1].name).to.equal('3333 4444 5555 duplicate')
288 }
289
290 {
291 const body = await command.advancedVideoSearch({ search: { ...query, licenceOneOf: [ 3 ] } })
292 expect(body.total).to.equal(0)
293 }
d525fc39
C
294 })
295
296 it('Should search by languages', async function () {
297 const query = {
298 search: '1111 2222 3333',
299 languageOneOf: [ 'pl', 'en' ]
300 }
d525fc39 301
3caf77d3 302 {
af971e06
C
303 const body = await command.advancedVideoSearch({ search: query })
304 expect(body.total).to.equal(2)
305 expect(body.data[0].name).to.equal('1111 2222 3333 - 3')
306 expect(body.data[1].name).to.equal('1111 2222 3333 - 4')
3caf77d3
C
307 }
308
309 {
af971e06
C
310 const body = await command.advancedVideoSearch({ search: { ...query, languageOneOf: [ 'pl', 'en', '_unknown' ] } })
311 expect(body.total).to.equal(3)
312 expect(body.data[0].name).to.equal('1111 2222 3333 - 3')
313 expect(body.data[1].name).to.equal('1111 2222 3333 - 4')
314 expect(body.data[2].name).to.equal('1111 2222 3333 - 5')
3caf77d3
C
315 }
316
317 {
af971e06
C
318 const body = await command.advancedVideoSearch({ search: { ...query, languageOneOf: [ 'eo' ] } })
319 expect(body.total).to.equal(0)
3caf77d3 320 }
d525fc39
C
321 })
322
323 it('Should search by start date', async function () {
324 const query = {
325 search: '1111 2222 3333',
326 startDate
327 }
328
af971e06
C
329 const body = await command.advancedVideoSearch({ search: query })
330 expect(body.total).to.equal(4)
d525fc39 331
af971e06 332 const videos = body.data
d525fc39
C
333 expect(videos[0].name).to.equal('1111 2222 3333 - 5')
334 expect(videos[1].name).to.equal('1111 2222 3333 - 6')
335 expect(videos[2].name).to.equal('1111 2222 3333 - 7')
336 expect(videos[3].name).to.equal('1111 2222 3333 - 8')
337 })
338
339 it('Should make an advanced search', async function () {
340 const query = {
341 search: '1111 2222 3333',
342 languageOneOf: [ 'pl', 'fr' ],
343 durationMax: 4,
0b18f4aa 344 nsfw: 'false' as 'false',
d525fc39
C
345 licenceOneOf: [ 1, 4 ]
346 }
347
af971e06
C
348 const body = await command.advancedVideoSearch({ search: query })
349 expect(body.total).to.equal(4)
d525fc39 350
af971e06 351 const videos = body.data
d525fc39
C
352 expect(videos[0].name).to.equal('1111 2222 3333')
353 expect(videos[1].name).to.equal('1111 2222 3333 - 6')
354 expect(videos[2].name).to.equal('1111 2222 3333 - 7')
355 expect(videos[3].name).to.equal('1111 2222 3333 - 8')
356 })
357
358 it('Should make an advanced search and sort results', async function () {
359 const query = {
360 search: '1111 2222 3333',
361 languageOneOf: [ 'pl', 'fr' ],
362 durationMax: 4,
0b18f4aa 363 nsfw: 'false' as 'false',
d525fc39
C
364 licenceOneOf: [ 1, 4 ],
365 sort: '-name'
366 }
367
af971e06
C
368 const body = await command.advancedVideoSearch({ search: query })
369 expect(body.total).to.equal(4)
d525fc39 370
af971e06 371 const videos = body.data
d525fc39
C
372 expect(videos[0].name).to.equal('1111 2222 3333 - 8')
373 expect(videos[1].name).to.equal('1111 2222 3333 - 7')
374 expect(videos[2].name).to.equal('1111 2222 3333 - 6')
375 expect(videos[3].name).to.equal('1111 2222 3333')
376 })
377
378 it('Should make an advanced search and only show the first result', async function () {
379 const query = {
380 search: '1111 2222 3333',
381 languageOneOf: [ 'pl', 'fr' ],
382 durationMax: 4,
0b18f4aa 383 nsfw: 'false' as 'false',
d525fc39
C
384 licenceOneOf: [ 1, 4 ],
385 sort: '-name',
386 start: 0,
387 count: 1
388 }
389
af971e06
C
390 const body = await command.advancedVideoSearch({ search: query })
391 expect(body.total).to.equal(4)
d525fc39 392
af971e06 393 const videos = body.data
d525fc39
C
394 expect(videos[0].name).to.equal('1111 2222 3333 - 8')
395 })
396
397 it('Should make an advanced search and only show the last result', async function () {
398 const query = {
399 search: '1111 2222 3333',
400 languageOneOf: [ 'pl', 'fr' ],
401 durationMax: 4,
0b18f4aa 402 nsfw: 'false' as 'false',
d525fc39
C
403 licenceOneOf: [ 1, 4 ],
404 sort: '-name',
405 start: 3,
406 count: 1
407 }
408
af971e06
C
409 const body = await command.advancedVideoSearch({ search: query })
410 expect(body.total).to.equal(4)
d525fc39 411
af971e06 412 const videos = body.data
d525fc39
C
413 expect(videos[0].name).to.equal('1111 2222 3333')
414 })
415
31d065cc
AM
416 it('Should search on originally published date', async function () {
417 const baseQuery = {
418 search: '1111 2222 3333',
419 languageOneOf: [ 'pl', 'fr' ],
420 durationMax: 4,
421 nsfw: 'false' as 'false',
422 licenceOneOf: [ 1, 4 ]
423 }
424
425 {
426 const query = immutableAssign(baseQuery, { originallyPublishedStartDate: '2019-02-11T09:58:08.286Z' })
af971e06 427 const body = await command.advancedVideoSearch({ search: query })
31d065cc 428
af971e06
C
429 expect(body.total).to.equal(1)
430 expect(body.data[0].name).to.equal('1111 2222 3333 - 7')
31d065cc
AM
431 }
432
433 {
434 const query = immutableAssign(baseQuery, { originallyPublishedEndDate: '2019-03-11T09:58:08.286Z' })
af971e06 435 const body = await command.advancedVideoSearch({ search: query })
31d065cc 436
af971e06
C
437 expect(body.total).to.equal(1)
438 expect(body.data[0].name).to.equal('1111 2222 3333 - 7')
31d065cc
AM
439 }
440
441 {
442 const query = immutableAssign(baseQuery, { originallyPublishedEndDate: '2019-01-11T09:58:08.286Z' })
af971e06 443 const body = await command.advancedVideoSearch({ search: query })
31d065cc 444
af971e06 445 expect(body.total).to.equal(0)
31d065cc
AM
446 }
447
448 {
449 const query = immutableAssign(baseQuery, { originallyPublishedStartDate: '2019-03-11T09:58:08.286Z' })
af971e06 450 const body = await command.advancedVideoSearch({ search: query })
31d065cc 451
af971e06 452 expect(body.total).to.equal(0)
31d065cc
AM
453 }
454
455 {
456 const query = immutableAssign(baseQuery, {
457 originallyPublishedStartDate: '2019-01-11T09:58:08.286Z',
458 originallyPublishedEndDate: '2019-01-10T09:58:08.286Z'
459 })
af971e06 460 const body = await command.advancedVideoSearch({ search: query })
31d065cc 461
af971e06 462 expect(body.total).to.equal(0)
31d065cc
AM
463 }
464
465 {
466 const query = immutableAssign(baseQuery, {
467 originallyPublishedStartDate: '2019-01-11T09:58:08.286Z',
468 originallyPublishedEndDate: '2019-04-11T09:58:08.286Z'
469 })
af971e06 470 const body = await command.advancedVideoSearch({ search: query })
31d065cc 471
af971e06
C
472 expect(body.total).to.equal(1)
473 expect(body.data[0].name).to.equal('1111 2222 3333 - 7')
31d065cc
AM
474 }
475 })
476
3cf53828
C
477 it('Should search by UUID', async function () {
478 const search = videoUUID
af971e06 479 const body = await command.advancedVideoSearch({ search: { search } })
3cf53828 480
af971e06
C
481 expect(body.total).to.equal(1)
482 expect(body.data[0].name).to.equal('1111 2222 3333 - 3')
3cf53828
C
483 })
484
1fd61899
C
485 it('Should search by live', async function () {
486 this.timeout(30000)
487
488 {
489 const options = {
490 search: {
491 searchIndex: { enabled: false }
492 },
493 live: { enabled: true }
494 }
495 await updateCustomSubConfig(server.url, server.accessToken, options)
496 }
497
498 {
af971e06 499 const body = await command.advancedVideoSearch({ search: { isLive: true } })
1fd61899 500
af971e06
C
501 expect(body.total).to.equal(0)
502 expect(body.data).to.have.lengthOf(0)
1fd61899
C
503 }
504
505 {
506 const liveOptions = { name: 'live', privacy: VideoPrivacy.PUBLIC, channelId: server.videoChannel.id }
507 const resLive = await createLive(server.url, server.accessToken, liveOptions)
508 const liveVideoId = resLive.body.video.uuid
509
af971e06 510 const ffmpegCommand = await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId)
1fd61899
C
511 await waitUntilLivePublished(server.url, server.accessToken, liveVideoId)
512
af971e06 513 const body = await command.advancedVideoSearch({ search: { isLive: true } })
1fd61899 514
af971e06
C
515 expect(body.total).to.equal(1)
516 expect(body.data[0].name).to.equal('live')
1fd61899 517
af971e06 518 await stopFfmpeg(ffmpegCommand)
1fd61899
C
519 }
520 })
521
7c3b7976
C
522 after(async function () {
523 await cleanupTests([ server ])
d525fc39
C
524 })
525})