aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/search
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-06-17 16:02:38 +0200
committerChocobozzz <chocobozzz@cpy.re>2021-06-25 14:44:01 +0200
commit37a44fc915eef2140e22ceb96aba6b6eb2509007 (patch)
treedd4a370ecc96cf38c99b940261aadc27065da7ae /server/tests/api/search
parent33eb19e5199cc9fa4d73c6675c97508e3e072ef9 (diff)
downloadPeerTube-37a44fc915eef2140e22ceb96aba6b6eb2509007.tar.gz
PeerTube-37a44fc915eef2140e22ceb96aba6b6eb2509007.tar.zst
PeerTube-37a44fc915eef2140e22ceb96aba6b6eb2509007.zip
Add ability to search playlists
Diffstat (limited to 'server/tests/api/search')
-rw-r--r--server/tests/api/search/index.ts4
-rw-r--r--server/tests/api/search/search-activitypub-video-channels.ts16
-rw-r--r--server/tests/api/search/search-activitypub-video-playlists.ts212
-rw-r--r--server/tests/api/search/search-activitypub-videos.ts35
-rw-r--r--server/tests/api/search/search-index.ts62
-rw-r--r--server/tests/api/search/search-playlists.ts128
6 files changed, 443 insertions, 14 deletions
diff --git a/server/tests/api/search/index.ts b/server/tests/api/search/index.ts
index 232c1f2a4..a976d210d 100644
--- a/server/tests/api/search/index.ts
+++ b/server/tests/api/search/index.ts
@@ -1,5 +1,7 @@
1import './search-activitypub-video-playlists'
1import './search-activitypub-video-channels' 2import './search-activitypub-video-channels'
2import './search-activitypub-videos' 3import './search-activitypub-videos'
4import './search-channels'
3import './search-index' 5import './search-index'
6import './search-playlists'
4import './search-videos' 7import './search-videos'
5import './search-channels'
diff --git a/server/tests/api/search/search-activitypub-video-channels.ts b/server/tests/api/search/search-activitypub-video-channels.ts
index d7e3ed5be..e83eb7171 100644
--- a/server/tests/api/search/search-activitypub-video-channels.ts
+++ b/server/tests/api/search/search-activitypub-video-channels.ts
@@ -106,9 +106,25 @@ describe('Test ActivityPub video channels search', function () {
106 } 106 }
107 }) 107 })
108 108
109 it('Should search a local video channel with an alternative URL', async function () {
110 const search = 'http://localhost:' + servers[0].port + '/c/channel1_server1'
111
112 for (const token of [ undefined, servers[0].accessToken ]) {
113 const res = await searchVideoChannel(servers[0].url, search, token)
114
115 expect(res.body.total).to.equal(1)
116 expect(res.body.data).to.be.an('array')
117 expect(res.body.data).to.have.lengthOf(1)
118 expect(res.body.data[0].name).to.equal('channel1_server1')
119 expect(res.body.data[0].displayName).to.equal('Channel 1 server 1')
120 }
121 })
122
109 it('Should search a remote video channel with URL or handle', async function () { 123 it('Should search a remote video channel with URL or handle', async function () {
110 const searches = [ 124 const searches = [
111 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2', 125 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2',
126 'http://localhost:' + servers[1].port + '/c/channel1_server2',
127 'http://localhost:' + servers[1].port + '/c/channel1_server2/videos',
112 'channel1_server2@localhost:' + servers[1].port 128 'channel1_server2@localhost:' + servers[1].port
113 ] 129 ]
114 130
diff --git a/server/tests/api/search/search-activitypub-video-playlists.ts b/server/tests/api/search/search-activitypub-video-playlists.ts
new file mode 100644
index 000000000..4c08e9548
--- /dev/null
+++ b/server/tests/api/search/search-activitypub-video-playlists.ts
@@ -0,0 +1,212 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import 'mocha'
4import * as chai from 'chai'
5import {
6 addVideoInPlaylist,
7 cleanupTests,
8 createVideoPlaylist,
9 deleteVideoPlaylist,
10 flushAndRunMultipleServers,
11 getVideoPlaylistsList,
12 searchVideoPlaylists,
13 ServerInfo,
14 setAccessTokensToServers,
15 setDefaultVideoChannel,
16 uploadVideoAndGetId,
17 wait
18} from '../../../../shared/extra-utils'
19import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
20import { VideoPlaylist, VideoPlaylistPrivacy } from '../../../../shared/models/videos'
21
22const expect = chai.expect
23
24describe('Test ActivityPub playlists search', function () {
25 let servers: ServerInfo[]
26 let playlistServer1UUID: string
27 let playlistServer2UUID: string
28 let video2Server2: string
29
30 before(async function () {
31 this.timeout(120000)
32
33 servers = await flushAndRunMultipleServers(2)
34
35 await setAccessTokensToServers(servers)
36 await setDefaultVideoChannel(servers)
37
38 {
39 const video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 1' })).uuid
40 const video2 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 2' })).uuid
41
42 const attributes = {
43 displayName: 'playlist 1 on server 1',
44 privacy: VideoPlaylistPrivacy.PUBLIC,
45 videoChannelId: servers[0].videoChannel.id
46 }
47 const res = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs: attributes })
48 playlistServer1UUID = res.body.videoPlaylist.uuid
49
50 for (const videoId of [ video1, video2 ]) {
51 await addVideoInPlaylist({
52 url: servers[0].url,
53 token: servers[0].accessToken,
54 playlistId: playlistServer1UUID,
55 elementAttrs: { videoId }
56 })
57 }
58 }
59
60 {
61 const videoId = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 1' })).uuid
62 video2Server2 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 2' })).uuid
63
64 const attributes = {
65 displayName: 'playlist 1 on server 2',
66 privacy: VideoPlaylistPrivacy.PUBLIC,
67 videoChannelId: servers[1].videoChannel.id
68 }
69 const res = await createVideoPlaylist({ url: servers[1].url, token: servers[1].accessToken, playlistAttrs: attributes })
70 playlistServer2UUID = res.body.videoPlaylist.uuid
71
72 await addVideoInPlaylist({
73 url: servers[1].url,
74 token: servers[1].accessToken,
75 playlistId: playlistServer2UUID,
76 elementAttrs: { videoId }
77 })
78 }
79
80 await waitJobs(servers)
81 })
82
83 it('Should not find a remote playlist', async function () {
84 {
85 const search = 'http://localhost:' + servers[1].port + '/video-playlists/43'
86 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken)
87
88 expect(res.body.total).to.equal(0)
89 expect(res.body.data).to.be.an('array')
90 expect(res.body.data).to.have.lengthOf(0)
91 }
92
93 {
94 // Without token
95 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
96 const res = await searchVideoPlaylists(servers[0].url, search)
97
98 expect(res.body.total).to.equal(0)
99 expect(res.body.data).to.be.an('array')
100 expect(res.body.data).to.have.lengthOf(0)
101 }
102 })
103
104 it('Should search a local playlist', async function () {
105 const search = 'http://localhost:' + servers[0].port + '/video-playlists/' + playlistServer1UUID
106 const res = await searchVideoPlaylists(servers[0].url, search)
107
108 expect(res.body.total).to.equal(1)
109 expect(res.body.data).to.be.an('array')
110 expect(res.body.data).to.have.lengthOf(1)
111 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 1')
112 expect(res.body.data[0].videosLength).to.equal(2)
113 })
114
115 it('Should search a local playlist with an alternative URL', async function () {
116 const searches = [
117 'http://localhost:' + servers[0].port + '/videos/watch/playlist/' + playlistServer1UUID,
118 'http://localhost:' + servers[0].port + '/w/p/' + playlistServer1UUID
119 ]
120
121 for (const search of searches) {
122 for (const token of [ undefined, servers[0].accessToken ]) {
123 const res = await searchVideoPlaylists(servers[0].url, search, token)
124
125 expect(res.body.total).to.equal(1)
126 expect(res.body.data).to.be.an('array')
127 expect(res.body.data).to.have.lengthOf(1)
128 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 1')
129 expect(res.body.data[0].videosLength).to.equal(2)
130 }
131 }
132 })
133
134 it('Should search a remote playlist', async function () {
135 const searches = [
136 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID,
137 'http://localhost:' + servers[1].port + '/videos/watch/playlist/' + playlistServer2UUID,
138 'http://localhost:' + servers[1].port + '/w/p/' + playlistServer2UUID
139 ]
140
141 for (const search of searches) {
142 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken)
143
144 expect(res.body.total).to.equal(1)
145 expect(res.body.data).to.be.an('array')
146 expect(res.body.data).to.have.lengthOf(1)
147 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 2')
148 expect(res.body.data[0].videosLength).to.equal(1)
149 }
150 })
151
152 it('Should not list this remote playlist', async function () {
153 const res = await getVideoPlaylistsList(servers[0].url, 0, 10)
154 expect(res.body.total).to.equal(1)
155 expect(res.body.data).to.have.lengthOf(1)
156 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 1')
157 })
158
159 it('Should update the playlist of server 2, and refresh it on server 1', async function () {
160 this.timeout(60000)
161
162 await addVideoInPlaylist({
163 url: servers[1].url,
164 token: servers[1].accessToken,
165 playlistId: playlistServer2UUID,
166 elementAttrs: { videoId: video2Server2 }
167 })
168
169 await waitJobs(servers)
170 // Expire playlist
171 await wait(10000)
172
173 // Will run refresh async
174 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
175 await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken)
176
177 // Wait refresh
178 await wait(5000)
179
180 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken)
181 expect(res.body.total).to.equal(1)
182 expect(res.body.data).to.have.lengthOf(1)
183
184 const playlist: VideoPlaylist = res.body.data[0]
185 expect(playlist.videosLength).to.equal(2)
186 })
187
188 it('Should delete playlist of server 2, and delete it on server 1', async function () {
189 this.timeout(60000)
190
191 await deleteVideoPlaylist(servers[1].url, servers[1].accessToken, playlistServer2UUID)
192
193 await waitJobs(servers)
194 // Expiration
195 await wait(10000)
196
197 // Will run refresh async
198 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
199 await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken)
200
201 // Wait refresh
202 await wait(5000)
203
204 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken)
205 expect(res.body.total).to.equal(0)
206 expect(res.body.data).to.have.lengthOf(0)
207 })
208
209 after(async function () {
210 await cleanupTests(servers)
211 })
212})
diff --git a/server/tests/api/search/search-activitypub-videos.ts b/server/tests/api/search/search-activitypub-videos.ts
index c62dfca0d..e9b4978da 100644
--- a/server/tests/api/search/search-activitypub-videos.ts
+++ b/server/tests/api/search/search-activitypub-videos.ts
@@ -77,14 +77,33 @@ describe('Test ActivityPub videos search', function () {
77 expect(res.body.data[0].name).to.equal('video 1 on server 1') 77 expect(res.body.data[0].name).to.equal('video 1 on server 1')
78 }) 78 })
79 79
80 it('Should search a local video with an alternative URL', async function () {
81 const search = 'http://localhost:' + servers[0].port + '/w/' + videoServer1UUID
82 const res1 = await searchVideo(servers[0].url, search)
83 const res2 = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken)
84
85 for (const res of [ res1, res2 ]) {
86 expect(res.body.total).to.equal(1)
87 expect(res.body.data).to.be.an('array')
88 expect(res.body.data).to.have.lengthOf(1)
89 expect(res.body.data[0].name).to.equal('video 1 on server 1')
90 }
91 })
92
80 it('Should search a remote video', async function () { 93 it('Should search a remote video', async function () {
81 const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID 94 const searches = [
82 const res = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 95 'http://localhost:' + servers[1].port + '/w/' + videoServer2UUID,
96 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
97 ]
83 98
84 expect(res.body.total).to.equal(1) 99 for (const search of searches) {
85 expect(res.body.data).to.be.an('array') 100 const res = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken)
86 expect(res.body.data).to.have.lengthOf(1) 101
87 expect(res.body.data[0].name).to.equal('video 1 on server 2') 102 expect(res.body.total).to.equal(1)
103 expect(res.body.data).to.be.an('array')
104 expect(res.body.data).to.have.lengthOf(1)
105 expect(res.body.data[0].name).to.equal('video 1 on server 2')
106 }
88 }) 107 })
89 108
90 it('Should not list this remote video', async function () { 109 it('Should not list this remote video', async function () {
@@ -95,7 +114,7 @@ describe('Test ActivityPub videos search', function () {
95 }) 114 })
96 115
97 it('Should update video of server 2, and refresh it on server 1', async function () { 116 it('Should update video of server 2, and refresh it on server 1', async function () {
98 this.timeout(60000) 117 this.timeout(120000)
99 118
100 const channelAttributes = { 119 const channelAttributes = {
101 name: 'super_channel', 120 name: 'super_channel',
@@ -134,7 +153,7 @@ describe('Test ActivityPub videos search', function () {
134 }) 153 })
135 154
136 it('Should delete video of server 2, and delete it on server 1', async function () { 155 it('Should delete video of server 2, and delete it on server 1', async function () {
137 this.timeout(60000) 156 this.timeout(120000)
138 157
139 await removeVideo(servers[1].url, servers[1].accessToken, videoServer2UUID) 158 await removeVideo(servers[1].url, servers[1].accessToken, videoServer2UUID)
140 159
diff --git a/server/tests/api/search/search-index.ts b/server/tests/api/search/search-index.ts
index 849a8a893..00f79232a 100644
--- a/server/tests/api/search/search-index.ts
+++ b/server/tests/api/search/search-index.ts
@@ -2,19 +2,21 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { advancedVideoChannelSearch, searchVideoChannel } from '@shared/extra-utils/search/video-channels'
6import { Video, VideoChannel, VideoPlaylist, VideoPlaylistPrivacy, VideoPlaylistType, VideosSearchQuery } from '@shared/models'
5import { 7import {
8 advancedVideoPlaylistSearch,
9 advancedVideosSearch,
6 cleanupTests, 10 cleanupTests,
7 flushAndRunServer, 11 flushAndRunServer,
12 immutableAssign,
8 searchVideo, 13 searchVideo,
14 searchVideoPlaylists,
9 ServerInfo, 15 ServerInfo,
10 setAccessTokensToServers, 16 setAccessTokensToServers,
11 updateCustomSubConfig, 17 updateCustomSubConfig,
12 uploadVideo, 18 uploadVideo
13 advancedVideosSearch,
14 immutableAssign
15} from '../../../../shared/extra-utils' 19} from '../../../../shared/extra-utils'
16import { searchVideoChannel, advancedVideoChannelSearch } from '@shared/extra-utils/search/video-channels'
17import { VideosSearchQuery, Video, VideoChannel } from '@shared/models'
18 20
19const expect = chai.expect 21const expect = chai.expect
20 22
@@ -277,6 +279,56 @@ describe('Test videos search', function () {
277 }) 279 })
278 }) 280 })
279 281
282 describe('Playlists search', async function () {
283
284 it('Should make a simple search and not have results', async function () {
285 const res = await searchVideoPlaylists(server.url, 'a'.repeat(500))
286
287 expect(res.body.total).to.equal(0)
288 expect(res.body.data).to.have.lengthOf(0)
289 })
290
291 it('Should make a search and have results', async function () {
292 const res = await advancedVideoPlaylistSearch(server.url, { search: 'E2E playlist', sort: '-match' })
293
294 expect(res.body.total).to.be.greaterThan(0)
295 expect(res.body.data).to.have.length.greaterThan(0)
296
297 const videoPlaylist: VideoPlaylist = res.body.data[0]
298
299 expect(videoPlaylist.url).to.equal('https://peertube2.cpy.re/videos/watch/playlist/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
300 expect(videoPlaylist.thumbnailUrl).to.exist
301 expect(videoPlaylist.embedUrl).to.equal('https://peertube2.cpy.re/video-playlists/embed/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
302
303 expect(videoPlaylist.type.id).to.equal(VideoPlaylistType.REGULAR)
304 expect(videoPlaylist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC)
305 expect(videoPlaylist.videosLength).to.exist
306
307 expect(videoPlaylist.createdAt).to.exist
308 expect(videoPlaylist.updatedAt).to.exist
309
310 expect(videoPlaylist.uuid).to.equal('73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
311 expect(videoPlaylist.displayName).to.exist
312
313 expect(videoPlaylist.ownerAccount.url).to.equal('https://peertube2.cpy.re/accounts/chocobozzz')
314 expect(videoPlaylist.ownerAccount.name).to.equal('chocobozzz')
315 expect(videoPlaylist.ownerAccount.host).to.equal('peertube2.cpy.re')
316 expect(videoPlaylist.ownerAccount.avatar).to.exist
317
318 expect(videoPlaylist.videoChannel.url).to.equal('https://peertube2.cpy.re/video-channels/chocobozzz_channel')
319 expect(videoPlaylist.videoChannel.name).to.equal('chocobozzz_channel')
320 expect(videoPlaylist.videoChannel.host).to.equal('peertube2.cpy.re')
321 expect(videoPlaylist.videoChannel.avatar).to.exist
322 })
323
324 it('Should have a correct pagination', async function () {
325 const res = await advancedVideoChannelSearch(server.url, { search: 'root', start: 0, count: 2 })
326
327 expect(res.body.total).to.be.greaterThan(2)
328 expect(res.body.data).to.have.lengthOf(2)
329 })
330 })
331
280 after(async function () { 332 after(async function () {
281 await cleanupTests([ server ]) 333 await cleanupTests([ server ])
282 }) 334 })
diff --git a/server/tests/api/search/search-playlists.ts b/server/tests/api/search/search-playlists.ts
new file mode 100644
index 000000000..ab17d55e9
--- /dev/null
+++ b/server/tests/api/search/search-playlists.ts
@@ -0,0 +1,128 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import 'mocha'
4import * as chai from 'chai'
5import { VideoPlaylist, VideoPlaylistPrivacy } from '@shared/models'
6import {
7 addVideoInPlaylist,
8 advancedVideoPlaylistSearch,
9 cleanupTests,
10 createVideoPlaylist,
11 flushAndRunServer,
12 searchVideoPlaylists,
13 ServerInfo,
14 setAccessTokensToServers,
15 setDefaultVideoChannel,
16 uploadVideoAndGetId
17} from '../../../../shared/extra-utils'
18
19const expect = chai.expect
20
21describe('Test playlists search', function () {
22 let server: ServerInfo = null
23
24 before(async function () {
25 this.timeout(30000)
26
27 server = await flushAndRunServer(1)
28
29 await setAccessTokensToServers([ server ])
30 await setDefaultVideoChannel([ server ])
31
32 const videoId = (await uploadVideoAndGetId({ server: server, videoName: 'video' })).uuid
33
34 {
35 const attributes = {
36 displayName: 'Dr. Kenzo Tenma hospital videos',
37 privacy: VideoPlaylistPrivacy.PUBLIC,
38 videoChannelId: server.videoChannel.id
39 }
40 const res = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes })
41
42 await addVideoInPlaylist({
43 url: server.url,
44 token: server.accessToken,
45 playlistId: res.body.videoPlaylist.id,
46 elementAttrs: { videoId }
47 })
48 }
49
50 {
51 const attributes = {
52 displayName: 'Johan & Anna Libert musics',
53 privacy: VideoPlaylistPrivacy.PUBLIC,
54 videoChannelId: server.videoChannel.id
55 }
56 const res = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes })
57
58 await addVideoInPlaylist({
59 url: server.url,
60 token: server.accessToken,
61 playlistId: res.body.videoPlaylist.id,
62 elementAttrs: { videoId }
63 })
64 }
65
66 {
67 const attributes = {
68 displayName: 'Inspector Lunge playlist',
69 privacy: VideoPlaylistPrivacy.PUBLIC,
70 videoChannelId: server.videoChannel.id
71 }
72 await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes })
73 }
74 })
75
76 it('Should make a simple search and not have results', async function () {
77 const res = await searchVideoPlaylists(server.url, 'abc')
78
79 expect(res.body.total).to.equal(0)
80 expect(res.body.data).to.have.lengthOf(0)
81 })
82
83 it('Should make a search and have results', async function () {
84 {
85 const search = {
86 search: 'tenma',
87 start: 0,
88 count: 1
89 }
90 const res = await advancedVideoPlaylistSearch(server.url, search)
91 expect(res.body.total).to.equal(1)
92 expect(res.body.data).to.have.lengthOf(1)
93
94 const playlist: VideoPlaylist = res.body.data[0]
95 expect(playlist.displayName).to.equal('Dr. Kenzo Tenma hospital videos')
96 expect(playlist.url).to.equal(server.url + '/video-playlists/' + playlist.uuid)
97 }
98
99 {
100 const search = {
101 search: 'Anna Livert',
102 start: 0,
103 count: 1
104 }
105 const res = await advancedVideoPlaylistSearch(server.url, search)
106 expect(res.body.total).to.equal(1)
107 expect(res.body.data).to.have.lengthOf(1)
108
109 const playlist: VideoPlaylist = res.body.data[0]
110 expect(playlist.displayName).to.equal('Johan & Anna Libert musics')
111 }
112 })
113
114 it('Should not display playlists without videos', async function () {
115 const search = {
116 search: 'Lunge',
117 start: 0,
118 count: 1
119 }
120 const res = await advancedVideoPlaylistSearch(server.url, search)
121 expect(res.body.total).to.equal(0)
122 expect(res.body.data).to.have.lengthOf(0)
123 })
124
125 after(async function () {
126 await cleanupTests([ server ])
127 })
128})