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