aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/tests/src/api/search/search-index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/tests/src/api/search/search-index.ts')
-rw-r--r--packages/tests/src/api/search/search-index.ts438
1 files changed, 438 insertions, 0 deletions
diff --git a/packages/tests/src/api/search/search-index.ts b/packages/tests/src/api/search/search-index.ts
new file mode 100644
index 000000000..4bac7ea94
--- /dev/null
+++ b/packages/tests/src/api/search/search-index.ts
@@ -0,0 +1,438 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import {
5 BooleanBothQuery,
6 VideoChannelsSearchQuery,
7 VideoPlaylistPrivacy,
8 VideoPlaylistsSearchQuery,
9 VideoPlaylistType,
10 VideosSearchQuery
11} from '@peertube/peertube-models'
12import {
13 cleanupTests,
14 createSingleServer,
15 PeerTubeServer,
16 SearchCommand,
17 setAccessTokensToServers
18} from '@peertube/peertube-server-commands'
19
20describe('Test index search', function () {
21 const localVideoName = 'local video' + new Date().toISOString()
22
23 let server: PeerTubeServer = null
24 let command: SearchCommand
25
26 before(async function () {
27 this.timeout(30000)
28
29 server = await createSingleServer(1)
30
31 await setAccessTokensToServers([ server ])
32
33 await server.videos.upload({ attributes: { name: localVideoName } })
34
35 command = server.search
36 })
37
38 describe('Default search', async function () {
39
40 it('Should make a local videos search by default', async function () {
41 await server.config.updateCustomSubConfig({
42 newConfig: {
43 search: {
44 searchIndex: {
45 enabled: true,
46 isDefaultSearch: false,
47 disableLocalSearch: false
48 }
49 }
50 }
51 })
52
53 const body = await command.searchVideos({ search: 'local video' })
54
55 expect(body.total).to.equal(1)
56 expect(body.data[0].name).to.equal(localVideoName)
57 })
58
59 it('Should make a local channels search by default', async function () {
60 const body = await command.searchChannels({ search: 'root' })
61
62 expect(body.total).to.equal(1)
63 expect(body.data[0].name).to.equal('root_channel')
64 expect(body.data[0].host).to.equal(server.host)
65 })
66
67 it('Should make an index videos search by default', async function () {
68 await server.config.updateCustomSubConfig({
69 newConfig: {
70 search: {
71 searchIndex: {
72 enabled: true,
73 isDefaultSearch: true,
74 disableLocalSearch: false
75 }
76 }
77 }
78 })
79
80 const body = await command.searchVideos({ search: 'local video' })
81 expect(body.total).to.be.greaterThan(2)
82 })
83
84 it('Should make an index channels search by default', async function () {
85 const body = await command.searchChannels({ search: 'root' })
86 expect(body.total).to.be.greaterThan(2)
87 })
88 })
89
90 describe('Videos search', async function () {
91
92 async function check (search: VideosSearchQuery, exists = true) {
93 const body = await command.advancedVideoSearch({ search })
94
95 if (exists === false) {
96 expect(body.total).to.equal(0)
97 expect(body.data).to.have.lengthOf(0)
98 return
99 }
100
101 expect(body.total).to.equal(1)
102 expect(body.data).to.have.lengthOf(1)
103
104 const video = body.data[0]
105
106 expect(video.name).to.equal('What is PeerTube?')
107 expect(video.category.label).to.equal('Science & Technology')
108 expect(video.licence.label).to.equal('Attribution - Share Alike')
109 expect(video.privacy.label).to.equal('Public')
110 expect(video.duration).to.equal(113)
111 expect(video.thumbnailUrl.startsWith('https://framatube.org/static/thumbnails')).to.be.true
112
113 expect(video.account.host).to.equal('framatube.org')
114 expect(video.account.name).to.equal('framasoft')
115 expect(video.account.url).to.equal('https://framatube.org/accounts/framasoft')
116 expect(video.account.avatars.length).to.equal(2, 'Account should have one avatar image')
117
118 expect(video.channel.host).to.equal('framatube.org')
119 expect(video.channel.name).to.equal('joinpeertube')
120 expect(video.channel.url).to.equal('https://framatube.org/video-channels/joinpeertube')
121 expect(video.channel.avatars.length).to.equal(2, 'Channel should have one avatar image')
122 }
123
124 const baseSearch: VideosSearchQuery = {
125 search: 'what is peertube',
126 start: 0,
127 count: 2,
128 categoryOneOf: [ 15 ],
129 licenceOneOf: [ 2 ],
130 tagsAllOf: [ 'framasoft', 'peertube' ],
131 startDate: '2018-10-01T10:50:46.396Z',
132 endDate: '2018-10-01T10:55:46.396Z'
133 }
134
135 it('Should make a simple search and not have results', async function () {
136 const body = await command.searchVideos({ search: 'djidane'.repeat(50) })
137
138 expect(body.total).to.equal(0)
139 expect(body.data).to.have.lengthOf(0)
140 })
141
142 it('Should make a simple search and have results', async function () {
143 const body = await command.searchVideos({ search: 'What is PeerTube' })
144
145 expect(body.total).to.be.greaterThan(1)
146 })
147
148 it('Should make a simple search', async function () {
149 await check(baseSearch)
150 })
151
152 it('Should search by start date', async function () {
153 const search = { ...baseSearch, startDate: '2018-10-01T10:54:46.396Z' }
154 await check(search, false)
155 })
156
157 it('Should search by tags', async function () {
158 const search = { ...baseSearch, tagsAllOf: [ 'toto', 'framasoft' ] }
159 await check(search, false)
160 })
161
162 it('Should search by duration', async function () {
163 const search = { ...baseSearch, durationMin: 2000 }
164 await check(search, false)
165 })
166
167 it('Should search by nsfw attribute', async function () {
168 {
169 const search = { ...baseSearch, nsfw: 'true' as BooleanBothQuery }
170 await check(search, false)
171 }
172
173 {
174 const search = { ...baseSearch, nsfw: 'false' as BooleanBothQuery }
175 await check(search, true)
176 }
177
178 {
179 const search = { ...baseSearch, nsfw: 'both' as BooleanBothQuery }
180 await check(search, true)
181 }
182 })
183
184 it('Should search by host', async function () {
185 {
186 const search = { ...baseSearch, host: 'example.com' }
187 await check(search, false)
188 }
189
190 {
191 const search = { ...baseSearch, host: 'framatube.org' }
192 await check(search, true)
193 }
194 })
195
196 it('Should search by uuids', async function () {
197 const goodUUID = '9c9de5e8-0a1e-484a-b099-e80766180a6d'
198 const goodShortUUID = 'kkGMgK9ZtnKfYAgnEtQxbv'
199 const badUUID = 'c29c5b77-4a04-493d-96a9-2e9267e308f0'
200 const badShortUUID = 'rP5RgUeX9XwTSrspCdkDej'
201
202 {
203 const uuidsMatrix = [
204 [ goodUUID ],
205 [ goodUUID, badShortUUID ],
206 [ badShortUUID, goodShortUUID ],
207 [ goodUUID, goodShortUUID ]
208 ]
209
210 for (const uuids of uuidsMatrix) {
211 const search = { ...baseSearch, uuids }
212 await check(search, true)
213 }
214 }
215
216 {
217 const uuidsMatrix = [
218 [ badUUID ],
219 [ badShortUUID ]
220 ]
221
222 for (const uuids of uuidsMatrix) {
223 const search = { ...baseSearch, uuids }
224 await check(search, false)
225 }
226 }
227 })
228
229 it('Should have a correct pagination', async function () {
230 const search = {
231 search: 'video',
232 start: 0,
233 count: 5
234 }
235
236 const body = await command.advancedVideoSearch({ search })
237
238 expect(body.total).to.be.greaterThan(5)
239 expect(body.data).to.have.lengthOf(5)
240 })
241
242 it('Should use the nsfw instance policy as default', async function () {
243 let nsfwUUID: string
244
245 {
246 await server.config.updateCustomSubConfig({
247 newConfig: {
248 instance: { defaultNSFWPolicy: 'display' }
249 }
250 })
251
252 const body = await command.searchVideos({ search: 'NSFW search index', sort: '-match' })
253 expect(body.data).to.have.length.greaterThan(0)
254
255 const video = body.data[0]
256 expect(video.nsfw).to.be.true
257
258 nsfwUUID = video.uuid
259 }
260
261 {
262 await server.config.updateCustomSubConfig({
263 newConfig: {
264 instance: { defaultNSFWPolicy: 'do_not_list' }
265 }
266 })
267
268 const body = await command.searchVideos({ search: 'NSFW search index', sort: '-match' })
269
270 try {
271 expect(body.data).to.have.lengthOf(0)
272 } catch {
273 const video = body.data[0]
274
275 expect(video.uuid).not.equal(nsfwUUID)
276 }
277 }
278 })
279 })
280
281 describe('Channels search', async function () {
282
283 async function check (search: VideoChannelsSearchQuery, exists = true) {
284 const body = await command.advancedChannelSearch({ search })
285
286 if (exists === false) {
287 expect(body.total).to.equal(0)
288 expect(body.data).to.have.lengthOf(0)
289 return
290 }
291
292 expect(body.total).to.be.greaterThan(0)
293 expect(body.data).to.have.length.greaterThan(0)
294
295 const videoChannel = body.data[0]
296 expect(videoChannel.url).to.equal('https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8')
297 expect(videoChannel.host).to.equal('framatube.org')
298 expect(videoChannel.avatars.length).to.equal(2, 'Channel should have two avatar images')
299 expect(videoChannel.displayName).to.exist
300
301 expect(videoChannel.ownerAccount.url).to.equal('https://framatube.org/accounts/framasoft')
302 expect(videoChannel.ownerAccount.name).to.equal('framasoft')
303 expect(videoChannel.ownerAccount.host).to.equal('framatube.org')
304 expect(videoChannel.ownerAccount.avatars.length).to.equal(2, 'Account should have two avatar images')
305 }
306
307 it('Should make a simple search and not have results', async function () {
308 const body = await command.searchChannels({ search: 'a'.repeat(500) })
309
310 expect(body.total).to.equal(0)
311 expect(body.data).to.have.lengthOf(0)
312 })
313
314 it('Should make a search and have results', async function () {
315 await check({ search: 'Framasoft', sort: 'createdAt' }, true)
316 })
317
318 it('Should make host search and have appropriate results', async function () {
319 await check({ search: 'Framasoft videos', host: 'example.com' }, false)
320 await check({ search: 'Framasoft videos', host: 'framatube.org' }, true)
321 })
322
323 it('Should make handles search and have appropriate results', async function () {
324 await check({ handles: [ 'bf54d359-cfad-4935-9d45-9d6be93f63e8@framatube.org' ] }, true)
325 await check({ handles: [ 'jeanine', 'bf54d359-cfad-4935-9d45-9d6be93f63e8@framatube.org' ] }, true)
326 await check({ handles: [ 'jeanine', 'chocobozzz_channel2@peertube2.cpy.re' ] }, false)
327 })
328
329 it('Should have a correct pagination', async function () {
330 const body = await command.advancedChannelSearch({ search: { search: 'root', start: 0, count: 2 } })
331
332 expect(body.total).to.be.greaterThan(2)
333 expect(body.data).to.have.lengthOf(2)
334 })
335 })
336
337 describe('Playlists search', async function () {
338
339 async function check (search: VideoPlaylistsSearchQuery, exists = true) {
340 const body = await command.advancedPlaylistSearch({ search })
341
342 if (exists === false) {
343 expect(body.total).to.equal(0)
344 expect(body.data).to.have.lengthOf(0)
345 return
346 }
347
348 expect(body.total).to.be.greaterThan(0)
349 expect(body.data).to.have.length.greaterThan(0)
350
351 const videoPlaylist = body.data[0]
352
353 expect(videoPlaylist.url).to.equal('https://peertube2.cpy.re/videos/watch/playlist/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
354 expect(videoPlaylist.thumbnailUrl).to.exist
355 expect(videoPlaylist.embedUrl).to.equal('https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
356
357 expect(videoPlaylist.type.id).to.equal(VideoPlaylistType.REGULAR)
358 expect(videoPlaylist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC)
359 expect(videoPlaylist.videosLength).to.exist
360
361 expect(videoPlaylist.createdAt).to.exist
362 expect(videoPlaylist.updatedAt).to.exist
363
364 expect(videoPlaylist.uuid).to.equal('73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
365 expect(videoPlaylist.displayName).to.exist
366
367 expect(videoPlaylist.ownerAccount.url).to.equal('https://peertube2.cpy.re/accounts/chocobozzz')
368 expect(videoPlaylist.ownerAccount.name).to.equal('chocobozzz')
369 expect(videoPlaylist.ownerAccount.host).to.equal('peertube2.cpy.re')
370 expect(videoPlaylist.ownerAccount.avatars.length).to.equal(2, 'Account should have two avatar images')
371
372 expect(videoPlaylist.videoChannel.url).to.equal('https://peertube2.cpy.re/video-channels/chocobozzz_channel')
373 expect(videoPlaylist.videoChannel.name).to.equal('chocobozzz_channel')
374 expect(videoPlaylist.videoChannel.host).to.equal('peertube2.cpy.re')
375 expect(videoPlaylist.videoChannel.avatars.length).to.equal(2, 'Channel should have two avatar images')
376 }
377
378 it('Should make a simple search and not have results', async function () {
379 const body = await command.searchPlaylists({ search: 'a'.repeat(500) })
380
381 expect(body.total).to.equal(0)
382 expect(body.data).to.have.lengthOf(0)
383 })
384
385 it('Should make a search and have results', async function () {
386 await check({ search: 'E2E playlist', sort: '-match' }, true)
387 })
388
389 it('Should make host search and have appropriate results', async function () {
390 await check({ search: 'E2E playlist', host: 'example.com' }, false)
391 await check({ search: 'E2E playlist', host: 'peertube2.cpy.re', sort: '-match' }, true)
392 })
393
394 it('Should make a search by uuids and have appropriate results', async function () {
395 const goodUUID = '73804a40-da9a-40c2-b1eb-2c6d9eec8f0a'
396 const goodShortUUID = 'fgei1ws1oa6FCaJ2qZPG29'
397 const badUUID = 'c29c5b77-4a04-493d-96a9-2e9267e308f0'
398 const badShortUUID = 'rP5RgUeX9XwTSrspCdkDej'
399
400 {
401 const uuidsMatrix = [
402 [ goodUUID ],
403 [ goodUUID, badShortUUID ],
404 [ badShortUUID, goodShortUUID ],
405 [ goodUUID, goodShortUUID ]
406 ]
407
408 for (const uuids of uuidsMatrix) {
409 const search = { search: 'E2E playlist', sort: '-match', uuids }
410 await check(search, true)
411 }
412 }
413
414 {
415 const uuidsMatrix = [
416 [ badUUID ],
417 [ badShortUUID ]
418 ]
419
420 for (const uuids of uuidsMatrix) {
421 const search = { search: 'E2E playlist', sort: '-match', uuids }
422 await check(search, false)
423 }
424 }
425 })
426
427 it('Should have a correct pagination', async function () {
428 const body = await command.advancedChannelSearch({ search: { search: 'root', start: 0, count: 2 } })
429
430 expect(body.total).to.be.greaterThan(2)
431 expect(body.data).to.have.lengthOf(2)
432 })
433 })
434
435 after(async function () {
436 await cleanupTests([ server ])
437 })
438})