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