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