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