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