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