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