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