aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/search
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api/search')
-rw-r--r--server/tests/api/search/search-activitypub-video-channels.ts171
-rw-r--r--server/tests/api/search/search-activitypub-video-playlists.ts150
-rw-r--r--server/tests/api/search/search-activitypub-videos.ts124
-rw-r--r--server/tests/api/search/search-channels.ts116
-rw-r--r--server/tests/api/search/search-index.ts422
-rw-r--r--server/tests/api/search/search-playlists.ts159
-rw-r--r--server/tests/api/search/search-videos.ts393
7 files changed, 915 insertions, 620 deletions
diff --git a/server/tests/api/search/search-activitypub-video-channels.ts b/server/tests/api/search/search-activitypub-video-channels.ts
index e83eb7171..426cbc8e1 100644
--- a/server/tests/api/search/search-activitypub-video-channels.ts
+++ b/server/tests/api/search/search-activitypub-video-channels.ts
@@ -1,69 +1,63 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai'
4import 'mocha' 3import 'mocha'
4import * as chai from 'chai'
5import { 5import {
6 addVideoChannel,
7 cleanupTests, 6 cleanupTests,
8 createUser, 7 createMultipleServers,
9 deleteVideoChannel, 8 PeerTubeServer,
10 flushAndRunMultipleServers, 9 SearchCommand,
11 getVideoChannelsList,
12 getVideoChannelVideos,
13 ServerInfo,
14 setAccessTokensToServers, 10 setAccessTokensToServers,
15 updateMyUser, 11 wait,
16 updateVideo, 12 waitJobs
17 updateVideoChannel, 13} from '@shared/extra-utils'
18 uploadVideo, 14import { VideoChannel } from '@shared/models'
19 userLogin,
20 wait
21} from '../../../../shared/extra-utils'
22import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
23import { VideoChannel } from '../../../../shared/models/videos'
24import { searchVideoChannel } from '../../../../shared/extra-utils/search/video-channels'
25 15
26const expect = chai.expect 16const expect = chai.expect
27 17
28describe('Test ActivityPub video channels search', function () { 18describe('Test ActivityPub video channels search', function () {
29 let servers: ServerInfo[] 19 let servers: PeerTubeServer[]
30 let userServer2Token: string 20 let userServer2Token: string
31 let videoServer2UUID: string 21 let videoServer2UUID: string
32 let channelIdServer2: number 22 let channelIdServer2: number
23 let command: SearchCommand
33 24
34 before(async function () { 25 before(async function () {
35 this.timeout(120000) 26 this.timeout(120000)
36 27
37 servers = await flushAndRunMultipleServers(2) 28 servers = await createMultipleServers(2)
38 29
39 await setAccessTokensToServers(servers) 30 await setAccessTokensToServers(servers)
40 31
41 { 32 {
42 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: 'user1_server1', password: 'password' }) 33 await servers[0].users.create({ username: 'user1_server1', password: 'password' })
43 const channel = { 34 const channel = {
44 name: 'channel1_server1', 35 name: 'channel1_server1',
45 displayName: 'Channel 1 server 1' 36 displayName: 'Channel 1 server 1'
46 } 37 }
47 await addVideoChannel(servers[0].url, servers[0].accessToken, channel) 38 await servers[0].channels.create({ attributes: channel })
48 } 39 }
49 40
50 { 41 {
51 const user = { username: 'user1_server2', password: 'password' } 42 const user = { username: 'user1_server2', password: 'password' }
52 await createUser({ url: servers[1].url, accessToken: servers[1].accessToken, username: user.username, password: user.password }) 43 await servers[1].users.create({ username: user.username, password: user.password })
53 userServer2Token = await userLogin(servers[1], user) 44 userServer2Token = await servers[1].login.getAccessToken(user)
54 45
55 const channel = { 46 const channel = {
56 name: 'channel1_server2', 47 name: 'channel1_server2',
57 displayName: 'Channel 1 server 2' 48 displayName: 'Channel 1 server 2'
58 } 49 }
59 const resChannel = await addVideoChannel(servers[1].url, userServer2Token, channel) 50 const created = await servers[1].channels.create({ token: userServer2Token, attributes: channel })
60 channelIdServer2 = resChannel.body.videoChannel.id 51 channelIdServer2 = created.id
61 52
62 const res = await uploadVideo(servers[1].url, userServer2Token, { name: 'video 1 server 2', channelId: channelIdServer2 }) 53 const attributes = { name: 'video 1 server 2', channelId: channelIdServer2 }
63 videoServer2UUID = res.body.video.uuid 54 const { uuid } = await servers[1].videos.upload({ token: userServer2Token, attributes })
55 videoServer2UUID = uuid
64 } 56 }
65 57
66 await waitJobs(servers) 58 await waitJobs(servers)
59
60 command = servers[0].search
67 }) 61 })
68 62
69 it('Should not find a remote video channel', async function () { 63 it('Should not find a remote video channel', async function () {
@@ -71,21 +65,21 @@ describe('Test ActivityPub video channels search', function () {
71 65
72 { 66 {
73 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server3' 67 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server3'
74 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 68 const body = await command.searchChannels({ search, token: servers[0].accessToken })
75 69
76 expect(res.body.total).to.equal(0) 70 expect(body.total).to.equal(0)
77 expect(res.body.data).to.be.an('array') 71 expect(body.data).to.be.an('array')
78 expect(res.body.data).to.have.lengthOf(0) 72 expect(body.data).to.have.lengthOf(0)
79 } 73 }
80 74
81 { 75 {
82 // Without token 76 // Without token
83 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2' 77 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
84 const res = await searchVideoChannel(servers[0].url, search) 78 const body = await command.searchChannels({ search })
85 79
86 expect(res.body.total).to.equal(0) 80 expect(body.total).to.equal(0)
87 expect(res.body.data).to.be.an('array') 81 expect(body.data).to.be.an('array')
88 expect(res.body.data).to.have.lengthOf(0) 82 expect(body.data).to.have.lengthOf(0)
89 } 83 }
90 }) 84 })
91 85
@@ -96,13 +90,13 @@ describe('Test ActivityPub video channels search', function () {
96 ] 90 ]
97 91
98 for (const search of searches) { 92 for (const search of searches) {
99 const res = await searchVideoChannel(servers[0].url, search) 93 const body = await command.searchChannels({ search })
100 94
101 expect(res.body.total).to.equal(1) 95 expect(body.total).to.equal(1)
102 expect(res.body.data).to.be.an('array') 96 expect(body.data).to.be.an('array')
103 expect(res.body.data).to.have.lengthOf(1) 97 expect(body.data).to.have.lengthOf(1)
104 expect(res.body.data[0].name).to.equal('channel1_server1') 98 expect(body.data[0].name).to.equal('channel1_server1')
105 expect(res.body.data[0].displayName).to.equal('Channel 1 server 1') 99 expect(body.data[0].displayName).to.equal('Channel 1 server 1')
106 } 100 }
107 }) 101 })
108 102
@@ -110,13 +104,13 @@ describe('Test ActivityPub video channels search', function () {
110 const search = 'http://localhost:' + servers[0].port + '/c/channel1_server1' 104 const search = 'http://localhost:' + servers[0].port + '/c/channel1_server1'
111 105
112 for (const token of [ undefined, servers[0].accessToken ]) { 106 for (const token of [ undefined, servers[0].accessToken ]) {
113 const res = await searchVideoChannel(servers[0].url, search, token) 107 const body = await command.searchChannels({ search, token })
114 108
115 expect(res.body.total).to.equal(1) 109 expect(body.total).to.equal(1)
116 expect(res.body.data).to.be.an('array') 110 expect(body.data).to.be.an('array')
117 expect(res.body.data).to.have.lengthOf(1) 111 expect(body.data).to.have.lengthOf(1)
118 expect(res.body.data[0].name).to.equal('channel1_server1') 112 expect(body.data[0].name).to.equal('channel1_server1')
119 expect(res.body.data[0].displayName).to.equal('Channel 1 server 1') 113 expect(body.data[0].displayName).to.equal('Channel 1 server 1')
120 } 114 }
121 }) 115 })
122 116
@@ -129,23 +123,23 @@ describe('Test ActivityPub video channels search', function () {
129 ] 123 ]
130 124
131 for (const search of searches) { 125 for (const search of searches) {
132 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 126 const body = await command.searchChannels({ search, token: servers[0].accessToken })
133 127
134 expect(res.body.total).to.equal(1) 128 expect(body.total).to.equal(1)
135 expect(res.body.data).to.be.an('array') 129 expect(body.data).to.be.an('array')
136 expect(res.body.data).to.have.lengthOf(1) 130 expect(body.data).to.have.lengthOf(1)
137 expect(res.body.data[0].name).to.equal('channel1_server2') 131 expect(body.data[0].name).to.equal('channel1_server2')
138 expect(res.body.data[0].displayName).to.equal('Channel 1 server 2') 132 expect(body.data[0].displayName).to.equal('Channel 1 server 2')
139 } 133 }
140 }) 134 })
141 135
142 it('Should not list this remote video channel', async function () { 136 it('Should not list this remote video channel', async function () {
143 const res = await getVideoChannelsList(servers[0].url, 0, 5) 137 const body = await servers[0].channels.list()
144 expect(res.body.total).to.equal(3) 138 expect(body.total).to.equal(3)
145 expect(res.body.data).to.have.lengthOf(3) 139 expect(body.data).to.have.lengthOf(3)
146 expect(res.body.data[0].name).to.equal('channel1_server1') 140 expect(body.data[0].name).to.equal('channel1_server1')
147 expect(res.body.data[1].name).to.equal('user1_server1_channel') 141 expect(body.data[1].name).to.equal('user1_server1_channel')
148 expect(res.body.data[2].name).to.equal('root_channel') 142 expect(body.data[2].name).to.equal('root_channel')
149 }) 143 })
150 144
151 it('Should list video channel videos of server 2 without token', async function () { 145 it('Should list video channel videos of server 2 without token', async function () {
@@ -153,34 +147,43 @@ describe('Test ActivityPub video channels search', function () {
153 147
154 await waitJobs(servers) 148 await waitJobs(servers)
155 149
156 const res = await getVideoChannelVideos(servers[0].url, null, 'channel1_server2@localhost:' + servers[1].port, 0, 5) 150 const { total, data } = await servers[0].videos.listByChannel({
157 expect(res.body.total).to.equal(0) 151 token: null,
158 expect(res.body.data).to.have.lengthOf(0) 152 handle: 'channel1_server2@localhost:' + servers[1].port
153 })
154 expect(total).to.equal(0)
155 expect(data).to.have.lengthOf(0)
159 }) 156 })
160 157
161 it('Should list video channel videos of server 2 with token', async function () { 158 it('Should list video channel videos of server 2 with token', async function () {
162 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, 'channel1_server2@localhost:' + servers[1].port, 0, 5) 159 const { total, data } = await servers[0].videos.listByChannel({
160 handle: 'channel1_server2@localhost:' + servers[1].port
161 })
163 162
164 expect(res.body.total).to.equal(1) 163 expect(total).to.equal(1)
165 expect(res.body.data[0].name).to.equal('video 1 server 2') 164 expect(data[0].name).to.equal('video 1 server 2')
166 }) 165 })
167 166
168 it('Should update video channel of server 2, and refresh it on server 1', async function () { 167 it('Should update video channel of server 2, and refresh it on server 1', async function () {
169 this.timeout(60000) 168 this.timeout(60000)
170 169
171 await updateVideoChannel(servers[1].url, userServer2Token, 'channel1_server2', { displayName: 'channel updated' }) 170 await servers[1].channels.update({
172 await updateMyUser({ url: servers[1].url, accessToken: userServer2Token, displayName: 'user updated' }) 171 token: userServer2Token,
172 channelName: 'channel1_server2',
173 attributes: { displayName: 'channel updated' }
174 })
175 await servers[1].users.updateMe({ token: userServer2Token, displayName: 'user updated' })
173 176
174 await waitJobs(servers) 177 await waitJobs(servers)
175 // Expire video channel 178 // Expire video channel
176 await wait(10000) 179 await wait(10000)
177 180
178 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2' 181 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
179 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 182 const body = await command.searchChannels({ search, token: servers[0].accessToken })
180 expect(res.body.total).to.equal(1) 183 expect(body.total).to.equal(1)
181 expect(res.body.data).to.have.lengthOf(1) 184 expect(body.data).to.have.lengthOf(1)
182 185
183 const videoChannel: VideoChannel = res.body.data[0] 186 const videoChannel: VideoChannel = body.data[0]
184 expect(videoChannel.displayName).to.equal('channel updated') 187 expect(videoChannel.displayName).to.equal('channel updated')
185 188
186 // We don't return the owner account for now 189 // We don't return the owner account for now
@@ -190,8 +193,8 @@ describe('Test ActivityPub video channels search', function () {
190 it('Should update and add a video on server 2, and update it on server 1 after a search', async function () { 193 it('Should update and add a video on server 2, and update it on server 1 after a search', async function () {
191 this.timeout(60000) 194 this.timeout(60000)
192 195
193 await updateVideo(servers[1].url, userServer2Token, videoServer2UUID, { name: 'video 1 updated' }) 196 await servers[1].videos.update({ token: userServer2Token, id: videoServer2UUID, attributes: { name: 'video 1 updated' } })
194 await uploadVideo(servers[1].url, userServer2Token, { name: 'video 2 server 2', channelId: channelIdServer2 }) 197 await servers[1].videos.upload({ token: userServer2Token, attributes: { name: 'video 2 server 2', channelId: channelIdServer2 } })
195 198
196 await waitJobs(servers) 199 await waitJobs(servers)
197 200
@@ -199,31 +202,31 @@ describe('Test ActivityPub video channels search', function () {
199 await wait(10000) 202 await wait(10000)
200 203
201 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2' 204 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
202 await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 205 await command.searchChannels({ search, token: servers[0].accessToken })
203 206
204 await waitJobs(servers) 207 await waitJobs(servers)
205 208
206 const videoChannelName = 'channel1_server2@localhost:' + servers[1].port 209 const handle = 'channel1_server2@localhost:' + servers[1].port
207 const res = await getVideoChannelVideos(servers[0].url, servers[0].accessToken, videoChannelName, 0, 5, '-createdAt') 210 const { total, data } = await servers[0].videos.listByChannel({ handle, sort: '-createdAt' })
208 211
209 expect(res.body.total).to.equal(2) 212 expect(total).to.equal(2)
210 expect(res.body.data[0].name).to.equal('video 2 server 2') 213 expect(data[0].name).to.equal('video 2 server 2')
211 expect(res.body.data[1].name).to.equal('video 1 updated') 214 expect(data[1].name).to.equal('video 1 updated')
212 }) 215 })
213 216
214 it('Should delete video channel of server 2, and delete it on server 1', async function () { 217 it('Should delete video channel of server 2, and delete it on server 1', async function () {
215 this.timeout(60000) 218 this.timeout(60000)
216 219
217 await deleteVideoChannel(servers[1].url, userServer2Token, 'channel1_server2') 220 await servers[1].channels.delete({ token: userServer2Token, channelName: 'channel1_server2' })
218 221
219 await waitJobs(servers) 222 await waitJobs(servers)
220 // Expire video 223 // Expire video
221 await wait(10000) 224 await wait(10000)
222 225
223 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2' 226 const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
224 const res = await searchVideoChannel(servers[0].url, search, servers[0].accessToken) 227 const body = await command.searchChannels({ search, token: servers[0].accessToken })
225 expect(res.body.total).to.equal(0) 228 expect(body.total).to.equal(0)
226 expect(res.body.data).to.have.lengthOf(0) 229 expect(body.data).to.have.lengthOf(0)
227 }) 230 })
228 231
229 after(async function () { 232 after(async function () {
diff --git a/server/tests/api/search/search-activitypub-video-playlists.ts b/server/tests/api/search/search-activitypub-video-playlists.ts
index 4c08e9548..33ca7be12 100644
--- a/server/tests/api/search/search-activitypub-video-playlists.ts
+++ b/server/tests/api/search/search-activitypub-video-playlists.ts
@@ -3,113 +3,102 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoInPlaylist,
7 cleanupTests, 6 cleanupTests,
8 createVideoPlaylist, 7 createMultipleServers,
9 deleteVideoPlaylist, 8 PeerTubeServer,
10 flushAndRunMultipleServers, 9 SearchCommand,
11 getVideoPlaylistsList,
12 searchVideoPlaylists,
13 ServerInfo,
14 setAccessTokensToServers, 10 setAccessTokensToServers,
15 setDefaultVideoChannel, 11 setDefaultVideoChannel,
16 uploadVideoAndGetId, 12 wait,
17 wait 13 waitJobs
18} from '../../../../shared/extra-utils' 14} from '@shared/extra-utils'
19import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 15import { VideoPlaylistPrivacy } from '@shared/models'
20import { VideoPlaylist, VideoPlaylistPrivacy } from '../../../../shared/models/videos'
21 16
22const expect = chai.expect 17const expect = chai.expect
23 18
24describe('Test ActivityPub playlists search', function () { 19describe('Test ActivityPub playlists search', function () {
25 let servers: ServerInfo[] 20 let servers: PeerTubeServer[]
26 let playlistServer1UUID: string 21 let playlistServer1UUID: string
27 let playlistServer2UUID: string 22 let playlistServer2UUID: string
28 let video2Server2: string 23 let video2Server2: string
29 24
25 let command: SearchCommand
26
30 before(async function () { 27 before(async function () {
31 this.timeout(120000) 28 this.timeout(120000)
32 29
33 servers = await flushAndRunMultipleServers(2) 30 servers = await createMultipleServers(2)
34 31
35 await setAccessTokensToServers(servers) 32 await setAccessTokensToServers(servers)
36 await setDefaultVideoChannel(servers) 33 await setDefaultVideoChannel(servers)
37 34
38 { 35 {
39 const video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 1' })).uuid 36 const video1 = (await servers[0].videos.quickUpload({ name: 'video 1' })).uuid
40 const video2 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 2' })).uuid 37 const video2 = (await servers[0].videos.quickUpload({ name: 'video 2' })).uuid
41 38
42 const attributes = { 39 const attributes = {
43 displayName: 'playlist 1 on server 1', 40 displayName: 'playlist 1 on server 1',
44 privacy: VideoPlaylistPrivacy.PUBLIC, 41 privacy: VideoPlaylistPrivacy.PUBLIC,
45 videoChannelId: servers[0].videoChannel.id 42 videoChannelId: servers[0].store.channel.id
46 } 43 }
47 const res = await createVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistAttrs: attributes }) 44 const created = await servers[0].playlists.create({ attributes })
48 playlistServer1UUID = res.body.videoPlaylist.uuid 45 playlistServer1UUID = created.uuid
49 46
50 for (const videoId of [ video1, video2 ]) { 47 for (const videoId of [ video1, video2 ]) {
51 await addVideoInPlaylist({ 48 await servers[0].playlists.addElement({ playlistId: playlistServer1UUID, attributes: { videoId } })
52 url: servers[0].url,
53 token: servers[0].accessToken,
54 playlistId: playlistServer1UUID,
55 elementAttrs: { videoId }
56 })
57 } 49 }
58 } 50 }
59 51
60 { 52 {
61 const videoId = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 1' })).uuid 53 const videoId = (await servers[1].videos.quickUpload({ name: 'video 1' })).uuid
62 video2Server2 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 2' })).uuid 54 video2Server2 = (await servers[1].videos.quickUpload({ name: 'video 2' })).uuid
63 55
64 const attributes = { 56 const attributes = {
65 displayName: 'playlist 1 on server 2', 57 displayName: 'playlist 1 on server 2',
66 privacy: VideoPlaylistPrivacy.PUBLIC, 58 privacy: VideoPlaylistPrivacy.PUBLIC,
67 videoChannelId: servers[1].videoChannel.id 59 videoChannelId: servers[1].store.channel.id
68 } 60 }
69 const res = await createVideoPlaylist({ url: servers[1].url, token: servers[1].accessToken, playlistAttrs: attributes }) 61 const created = await servers[1].playlists.create({ attributes })
70 playlistServer2UUID = res.body.videoPlaylist.uuid 62 playlistServer2UUID = created.uuid
71 63
72 await addVideoInPlaylist({ 64 await servers[1].playlists.addElement({ playlistId: playlistServer2UUID, attributes: { videoId } })
73 url: servers[1].url,
74 token: servers[1].accessToken,
75 playlistId: playlistServer2UUID,
76 elementAttrs: { videoId }
77 })
78 } 65 }
79 66
80 await waitJobs(servers) 67 await waitJobs(servers)
68
69 command = servers[0].search
81 }) 70 })
82 71
83 it('Should not find a remote playlist', async function () { 72 it('Should not find a remote playlist', async function () {
84 { 73 {
85 const search = 'http://localhost:' + servers[1].port + '/video-playlists/43' 74 const search = 'http://localhost:' + servers[1].port + '/video-playlists/43'
86 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken) 75 const body = await command.searchPlaylists({ search, token: servers[0].accessToken })
87 76
88 expect(res.body.total).to.equal(0) 77 expect(body.total).to.equal(0)
89 expect(res.body.data).to.be.an('array') 78 expect(body.data).to.be.an('array')
90 expect(res.body.data).to.have.lengthOf(0) 79 expect(body.data).to.have.lengthOf(0)
91 } 80 }
92 81
93 { 82 {
94 // Without token 83 // Without token
95 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID 84 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
96 const res = await searchVideoPlaylists(servers[0].url, search) 85 const body = await command.searchPlaylists({ search })
97 86
98 expect(res.body.total).to.equal(0) 87 expect(body.total).to.equal(0)
99 expect(res.body.data).to.be.an('array') 88 expect(body.data).to.be.an('array')
100 expect(res.body.data).to.have.lengthOf(0) 89 expect(body.data).to.have.lengthOf(0)
101 } 90 }
102 }) 91 })
103 92
104 it('Should search a local playlist', async function () { 93 it('Should search a local playlist', async function () {
105 const search = 'http://localhost:' + servers[0].port + '/video-playlists/' + playlistServer1UUID 94 const search = 'http://localhost:' + servers[0].port + '/video-playlists/' + playlistServer1UUID
106 const res = await searchVideoPlaylists(servers[0].url, search) 95 const body = await command.searchPlaylists({ search })
107 96
108 expect(res.body.total).to.equal(1) 97 expect(body.total).to.equal(1)
109 expect(res.body.data).to.be.an('array') 98 expect(body.data).to.be.an('array')
110 expect(res.body.data).to.have.lengthOf(1) 99 expect(body.data).to.have.lengthOf(1)
111 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 1') 100 expect(body.data[0].displayName).to.equal('playlist 1 on server 1')
112 expect(res.body.data[0].videosLength).to.equal(2) 101 expect(body.data[0].videosLength).to.equal(2)
113 }) 102 })
114 103
115 it('Should search a local playlist with an alternative URL', async function () { 104 it('Should search a local playlist with an alternative URL', async function () {
@@ -120,13 +109,13 @@ describe('Test ActivityPub playlists search', function () {
120 109
121 for (const search of searches) { 110 for (const search of searches) {
122 for (const token of [ undefined, servers[0].accessToken ]) { 111 for (const token of [ undefined, servers[0].accessToken ]) {
123 const res = await searchVideoPlaylists(servers[0].url, search, token) 112 const body = await command.searchPlaylists({ search, token })
124 113
125 expect(res.body.total).to.equal(1) 114 expect(body.total).to.equal(1)
126 expect(res.body.data).to.be.an('array') 115 expect(body.data).to.be.an('array')
127 expect(res.body.data).to.have.lengthOf(1) 116 expect(body.data).to.have.lengthOf(1)
128 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 1') 117 expect(body.data[0].displayName).to.equal('playlist 1 on server 1')
129 expect(res.body.data[0].videosLength).to.equal(2) 118 expect(body.data[0].videosLength).to.equal(2)
130 } 119 }
131 } 120 }
132 }) 121 })
@@ -139,32 +128,27 @@ describe('Test ActivityPub playlists search', function () {
139 ] 128 ]
140 129
141 for (const search of searches) { 130 for (const search of searches) {
142 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken) 131 const body = await command.searchPlaylists({ search, token: servers[0].accessToken })
143 132
144 expect(res.body.total).to.equal(1) 133 expect(body.total).to.equal(1)
145 expect(res.body.data).to.be.an('array') 134 expect(body.data).to.be.an('array')
146 expect(res.body.data).to.have.lengthOf(1) 135 expect(body.data).to.have.lengthOf(1)
147 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 2') 136 expect(body.data[0].displayName).to.equal('playlist 1 on server 2')
148 expect(res.body.data[0].videosLength).to.equal(1) 137 expect(body.data[0].videosLength).to.equal(1)
149 } 138 }
150 }) 139 })
151 140
152 it('Should not list this remote playlist', async function () { 141 it('Should not list this remote playlist', async function () {
153 const res = await getVideoPlaylistsList(servers[0].url, 0, 10) 142 const body = await servers[0].playlists.list({ start: 0, count: 10 })
154 expect(res.body.total).to.equal(1) 143 expect(body.total).to.equal(1)
155 expect(res.body.data).to.have.lengthOf(1) 144 expect(body.data).to.have.lengthOf(1)
156 expect(res.body.data[0].displayName).to.equal('playlist 1 on server 1') 145 expect(body.data[0].displayName).to.equal('playlist 1 on server 1')
157 }) 146 })
158 147
159 it('Should update the playlist of server 2, and refresh it on server 1', async function () { 148 it('Should update the playlist of server 2, and refresh it on server 1', async function () {
160 this.timeout(60000) 149 this.timeout(60000)
161 150
162 await addVideoInPlaylist({ 151 await servers[1].playlists.addElement({ playlistId: playlistServer2UUID, attributes: { videoId: video2Server2 } })
163 url: servers[1].url,
164 token: servers[1].accessToken,
165 playlistId: playlistServer2UUID,
166 elementAttrs: { videoId: video2Server2 }
167 })
168 152
169 await waitJobs(servers) 153 await waitJobs(servers)
170 // Expire playlist 154 // Expire playlist
@@ -172,23 +156,23 @@ describe('Test ActivityPub playlists search', function () {
172 156
173 // Will run refresh async 157 // Will run refresh async
174 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID 158 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
175 await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken) 159 await command.searchPlaylists({ search, token: servers[0].accessToken })
176 160
177 // Wait refresh 161 // Wait refresh
178 await wait(5000) 162 await wait(5000)
179 163
180 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken) 164 const body = await command.searchPlaylists({ search, token: servers[0].accessToken })
181 expect(res.body.total).to.equal(1) 165 expect(body.total).to.equal(1)
182 expect(res.body.data).to.have.lengthOf(1) 166 expect(body.data).to.have.lengthOf(1)
183 167
184 const playlist: VideoPlaylist = res.body.data[0] 168 const playlist = body.data[0]
185 expect(playlist.videosLength).to.equal(2) 169 expect(playlist.videosLength).to.equal(2)
186 }) 170 })
187 171
188 it('Should delete playlist of server 2, and delete it on server 1', async function () { 172 it('Should delete playlist of server 2, and delete it on server 1', async function () {
189 this.timeout(60000) 173 this.timeout(60000)
190 174
191 await deleteVideoPlaylist(servers[1].url, servers[1].accessToken, playlistServer2UUID) 175 await servers[1].playlists.delete({ playlistId: playlistServer2UUID })
192 176
193 await waitJobs(servers) 177 await waitJobs(servers)
194 // Expiration 178 // Expiration
@@ -196,14 +180,14 @@ describe('Test ActivityPub playlists search', function () {
196 180
197 // Will run refresh async 181 // Will run refresh async
198 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID 182 const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
199 await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken) 183 await command.searchPlaylists({ search, token: servers[0].accessToken })
200 184
201 // Wait refresh 185 // Wait refresh
202 await wait(5000) 186 await wait(5000)
203 187
204 const res = await searchVideoPlaylists(servers[0].url, search, servers[0].accessToken) 188 const body = await command.searchPlaylists({ search, token: servers[0].accessToken })
205 expect(res.body.total).to.equal(0) 189 expect(body.total).to.equal(0)
206 expect(res.body.data).to.have.lengthOf(0) 190 expect(body.data).to.have.lengthOf(0)
207 }) 191 })
208 192
209 after(async function () { 193 after(async function () {
diff --git a/server/tests/api/search/search-activitypub-videos.ts b/server/tests/api/search/search-activitypub-videos.ts
index e9b4978da..b3cfcacca 100644
--- a/server/tests/api/search/search-activitypub-videos.ts
+++ b/server/tests/api/search/search-activitypub-videos.ts
@@ -1,92 +1,90 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai'
4import 'mocha' 3import 'mocha'
4import * as chai from 'chai'
5import { 5import {
6 addVideoChannel,
7 cleanupTests, 6 cleanupTests,
8 flushAndRunMultipleServers, 7 createMultipleServers,
9 getVideosList, 8 PeerTubeServer,
10 removeVideo, 9 SearchCommand,
11 searchVideo,
12 searchVideoWithToken,
13 ServerInfo,
14 setAccessTokensToServers, 10 setAccessTokensToServers,
15 updateVideo, 11 wait,
16 uploadVideo, 12 waitJobs
17 wait 13} from '@shared/extra-utils'
18} from '../../../../shared/extra-utils' 14import { VideoPrivacy } from '@shared/models'
19import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
20import { Video, VideoPrivacy } from '../../../../shared/models/videos'
21 15
22const expect = chai.expect 16const expect = chai.expect
23 17
24describe('Test ActivityPub videos search', function () { 18describe('Test ActivityPub videos search', function () {
25 let servers: ServerInfo[] 19 let servers: PeerTubeServer[]
26 let videoServer1UUID: string 20 let videoServer1UUID: string
27 let videoServer2UUID: string 21 let videoServer2UUID: string
28 22
23 let command: SearchCommand
24
29 before(async function () { 25 before(async function () {
30 this.timeout(120000) 26 this.timeout(120000)
31 27
32 servers = await flushAndRunMultipleServers(2) 28 servers = await createMultipleServers(2)
33 29
34 await setAccessTokensToServers(servers) 30 await setAccessTokensToServers(servers)
35 31
36 { 32 {
37 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video 1 on server 1' }) 33 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'video 1 on server 1' } })
38 videoServer1UUID = res.body.video.uuid 34 videoServer1UUID = uuid
39 } 35 }
40 36
41 { 37 {
42 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 on server 2' }) 38 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 1 on server 2' } })
43 videoServer2UUID = res.body.video.uuid 39 videoServer2UUID = uuid
44 } 40 }
45 41
46 await waitJobs(servers) 42 await waitJobs(servers)
43
44 command = servers[0].search
47 }) 45 })
48 46
49 it('Should not find a remote video', async function () { 47 it('Should not find a remote video', async function () {
50 { 48 {
51 const search = 'http://localhost:' + servers[1].port + '/videos/watch/43' 49 const search = 'http://localhost:' + servers[1].port + '/videos/watch/43'
52 const res = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 50 const body = await command.searchVideos({ search, token: servers[0].accessToken })
53 51
54 expect(res.body.total).to.equal(0) 52 expect(body.total).to.equal(0)
55 expect(res.body.data).to.be.an('array') 53 expect(body.data).to.be.an('array')
56 expect(res.body.data).to.have.lengthOf(0) 54 expect(body.data).to.have.lengthOf(0)
57 } 55 }
58 56
59 { 57 {
60 // Without token 58 // Without token
61 const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID 59 const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
62 const res = await searchVideo(servers[0].url, search) 60 const body = await command.searchVideos({ search })
63 61
64 expect(res.body.total).to.equal(0) 62 expect(body.total).to.equal(0)
65 expect(res.body.data).to.be.an('array') 63 expect(body.data).to.be.an('array')
66 expect(res.body.data).to.have.lengthOf(0) 64 expect(body.data).to.have.lengthOf(0)
67 } 65 }
68 }) 66 })
69 67
70 it('Should search a local video', async function () { 68 it('Should search a local video', async function () {
71 const search = 'http://localhost:' + servers[0].port + '/videos/watch/' + videoServer1UUID 69 const search = 'http://localhost:' + servers[0].port + '/videos/watch/' + videoServer1UUID
72 const res = await searchVideo(servers[0].url, search) 70 const body = await command.searchVideos({ search })
73 71
74 expect(res.body.total).to.equal(1) 72 expect(body.total).to.equal(1)
75 expect(res.body.data).to.be.an('array') 73 expect(body.data).to.be.an('array')
76 expect(res.body.data).to.have.lengthOf(1) 74 expect(body.data).to.have.lengthOf(1)
77 expect(res.body.data[0].name).to.equal('video 1 on server 1') 75 expect(body.data[0].name).to.equal('video 1 on server 1')
78 }) 76 })
79 77
80 it('Should search a local video with an alternative URL', async function () { 78 it('Should search a local video with an alternative URL', async function () {
81 const search = 'http://localhost:' + servers[0].port + '/w/' + videoServer1UUID 79 const search = 'http://localhost:' + servers[0].port + '/w/' + videoServer1UUID
82 const res1 = await searchVideo(servers[0].url, search) 80 const body1 = await command.searchVideos({ search })
83 const res2 = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 81 const body2 = await command.searchVideos({ search, token: servers[0].accessToken })
84 82
85 for (const res of [ res1, res2 ]) { 83 for (const body of [ body1, body2 ]) {
86 expect(res.body.total).to.equal(1) 84 expect(body.total).to.equal(1)
87 expect(res.body.data).to.be.an('array') 85 expect(body.data).to.be.an('array')
88 expect(res.body.data).to.have.lengthOf(1) 86 expect(body.data).to.have.lengthOf(1)
89 expect(res.body.data[0].name).to.equal('video 1 on server 1') 87 expect(body.data[0].name).to.equal('video 1 on server 1')
90 } 88 }
91 }) 89 })
92 90
@@ -97,20 +95,20 @@ describe('Test ActivityPub videos search', function () {
97 ] 95 ]
98 96
99 for (const search of searches) { 97 for (const search of searches) {
100 const res = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 98 const body = await command.searchVideos({ search, token: servers[0].accessToken })
101 99
102 expect(res.body.total).to.equal(1) 100 expect(body.total).to.equal(1)
103 expect(res.body.data).to.be.an('array') 101 expect(body.data).to.be.an('array')
104 expect(res.body.data).to.have.lengthOf(1) 102 expect(body.data).to.have.lengthOf(1)
105 expect(res.body.data[0].name).to.equal('video 1 on server 2') 103 expect(body.data[0].name).to.equal('video 1 on server 2')
106 } 104 }
107 }) 105 })
108 106
109 it('Should not list this remote video', async function () { 107 it('Should not list this remote video', async function () {
110 const res = await getVideosList(servers[0].url) 108 const { total, data } = await servers[0].videos.list()
111 expect(res.body.total).to.equal(1) 109 expect(total).to.equal(1)
112 expect(res.body.data).to.have.lengthOf(1) 110 expect(data).to.have.lengthOf(1)
113 expect(res.body.data[0].name).to.equal('video 1 on server 1') 111 expect(data[0].name).to.equal('video 1 on server 1')
114 }) 112 })
115 113
116 it('Should update video of server 2, and refresh it on server 1', async function () { 114 it('Should update video of server 2, and refresh it on server 1', async function () {
@@ -120,8 +118,8 @@ describe('Test ActivityPub videos search', function () {
120 name: 'super_channel', 118 name: 'super_channel',
121 displayName: 'super channel' 119 displayName: 'super channel'
122 } 120 }
123 const resChannel = await addVideoChannel(servers[1].url, servers[1].accessToken, channelAttributes) 121 const created = await servers[1].channels.create({ attributes: channelAttributes })
124 const videoChannelId = resChannel.body.videoChannel.id 122 const videoChannelId = created.id
125 123
126 const attributes = { 124 const attributes = {
127 name: 'updated', 125 name: 'updated',
@@ -129,7 +127,7 @@ describe('Test ActivityPub videos search', function () {
129 privacy: VideoPrivacy.UNLISTED, 127 privacy: VideoPrivacy.UNLISTED,
130 channelId: videoChannelId 128 channelId: videoChannelId
131 } 129 }
132 await updateVideo(servers[1].url, servers[1].accessToken, videoServer2UUID, attributes) 130 await servers[1].videos.update({ id: videoServer2UUID, attributes })
133 131
134 await waitJobs(servers) 132 await waitJobs(servers)
135 // Expire video 133 // Expire video
@@ -137,16 +135,16 @@ describe('Test ActivityPub videos search', function () {
137 135
138 // Will run refresh async 136 // Will run refresh async
139 const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID 137 const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
140 await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 138 await command.searchVideos({ search, token: servers[0].accessToken })
141 139
142 // Wait refresh 140 // Wait refresh
143 await wait(5000) 141 await wait(5000)
144 142
145 const res = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 143 const body = await command.searchVideos({ search, token: servers[0].accessToken })
146 expect(res.body.total).to.equal(1) 144 expect(body.total).to.equal(1)
147 expect(res.body.data).to.have.lengthOf(1) 145 expect(body.data).to.have.lengthOf(1)
148 146
149 const video: Video = res.body.data[0] 147 const video = body.data[0]
150 expect(video.name).to.equal('updated') 148 expect(video.name).to.equal('updated')
151 expect(video.channel.name).to.equal('super_channel') 149 expect(video.channel.name).to.equal('super_channel')
152 expect(video.privacy.id).to.equal(VideoPrivacy.UNLISTED) 150 expect(video.privacy.id).to.equal(VideoPrivacy.UNLISTED)
@@ -155,7 +153,7 @@ describe('Test ActivityPub videos search', function () {
155 it('Should delete video of server 2, and delete it on server 1', async function () { 153 it('Should delete video of server 2, and delete it on server 1', async function () {
156 this.timeout(120000) 154 this.timeout(120000)
157 155
158 await removeVideo(servers[1].url, servers[1].accessToken, videoServer2UUID) 156 await servers[1].videos.remove({ id: videoServer2UUID })
159 157
160 await waitJobs(servers) 158 await waitJobs(servers)
161 // Expire video 159 // Expire video
@@ -163,14 +161,14 @@ describe('Test ActivityPub videos search', function () {
163 161
164 // Will run refresh async 162 // Will run refresh async
165 const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID 163 const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
166 await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 164 await command.searchVideos({ search, token: servers[0].accessToken })
167 165
168 // Wait refresh 166 // Wait refresh
169 await wait(5000) 167 await wait(5000)
170 168
171 const res = await searchVideoWithToken(servers[0].url, search, servers[0].accessToken) 169 const body = await command.searchVideos({ search, token: servers[0].accessToken })
172 expect(res.body.total).to.equal(0) 170 expect(body.total).to.equal(0)
173 expect(res.body.data).to.have.lengthOf(0) 171 expect(body.data).to.have.lengthOf(0)
174 }) 172 })
175 173
176 after(async function () { 174 after(async function () {
diff --git a/server/tests/api/search/search-channels.ts b/server/tests/api/search/search-channels.ts
index daca2aebe..8a01aff90 100644
--- a/server/tests/api/search/search-channels.ts
+++ b/server/tests/api/search/search-channels.ts
@@ -2,44 +2,65 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { searchVideoChannel, advancedVideoChannelSearch } from '@shared/extra-utils/search/video-channels'
6import { 5import {
7 addVideoChannel,
8 cleanupTests, 6 cleanupTests,
9 createUser, 7 createSingleServer,
10 flushAndRunServer, 8 doubleFollow,
11 ServerInfo, 9 PeerTubeServer,
10 SearchCommand,
12 setAccessTokensToServers 11 setAccessTokensToServers
13} from '../../../../shared/extra-utils' 12} from '@shared/extra-utils'
14import { VideoChannel } from '@shared/models' 13import { VideoChannel } from '@shared/models'
15 14
16const expect = chai.expect 15const expect = chai.expect
17 16
18describe('Test channels search', function () { 17describe('Test channels search', function () {
19 let server: ServerInfo = null 18 let server: PeerTubeServer
19 let remoteServer: PeerTubeServer
20 let command: SearchCommand
20 21
21 before(async function () { 22 before(async function () {
22 this.timeout(30000) 23 this.timeout(120000)
23 24
24 server = await flushAndRunServer(1) 25 const servers = await Promise.all([
26 createSingleServer(1),
27 createSingleServer(2, { transcoding: { enabled: false } })
28 ])
29 server = servers[0]
30 remoteServer = servers[1]
25 31
26 await setAccessTokensToServers([ server ]) 32 await setAccessTokensToServers([ server, remoteServer ])
27 33
28 { 34 {
29 await createUser({ url: server.url, accessToken: server.accessToken, username: 'user1', password: 'password' }) 35 await server.users.create({ username: 'user1' })
30 const channel = { 36 const channel = {
31 name: 'squall_channel', 37 name: 'squall_channel',
32 displayName: 'Squall channel' 38 displayName: 'Squall channel'
33 } 39 }
34 await addVideoChannel(server.url, server.accessToken, channel) 40 await server.channels.create({ attributes: channel })
35 } 41 }
42
43 {
44 await remoteServer.users.create({ username: 'user1' })
45 const channel = {
46 name: 'zell_channel',
47 displayName: 'Zell channel'
48 }
49 const { id } = await remoteServer.channels.create({ attributes: channel })
50
51 await remoteServer.videos.upload({ attributes: { channelId: id } })
52 }
53
54 await doubleFollow(server, remoteServer)
55
56 command = server.search
36 }) 57 })
37 58
38 it('Should make a simple search and not have results', async function () { 59 it('Should make a simple search and not have results', async function () {
39 const res = await searchVideoChannel(server.url, 'abc') 60 const body = await command.searchChannels({ search: 'abc' })
40 61
41 expect(res.body.total).to.equal(0) 62 expect(body.total).to.equal(0)
42 expect(res.body.data).to.have.lengthOf(0) 63 expect(body.data).to.have.lengthOf(0)
43 }) 64 })
44 65
45 it('Should make a search and have results', async function () { 66 it('Should make a search and have results', async function () {
@@ -49,11 +70,11 @@ describe('Test channels search', function () {
49 start: 0, 70 start: 0,
50 count: 1 71 count: 1
51 } 72 }
52 const res = await advancedVideoChannelSearch(server.url, search) 73 const body = await command.advancedChannelSearch({ search })
53 expect(res.body.total).to.equal(1) 74 expect(body.total).to.equal(1)
54 expect(res.body.data).to.have.lengthOf(1) 75 expect(body.data).to.have.lengthOf(1)
55 76
56 const channel: VideoChannel = res.body.data[0] 77 const channel: VideoChannel = body.data[0]
57 expect(channel.name).to.equal('squall_channel') 78 expect(channel.name).to.equal('squall_channel')
58 expect(channel.displayName).to.equal('Squall channel') 79 expect(channel.displayName).to.equal('Squall channel')
59 } 80 }
@@ -65,15 +86,64 @@ describe('Test channels search', function () {
65 count: 1 86 count: 1
66 } 87 }
67 88
68 const res = await advancedVideoChannelSearch(server.url, search) 89 const body = await command.advancedChannelSearch({ search })
90 expect(body.total).to.equal(1)
91 expect(body.data).to.have.lengthOf(0)
92 }
93 })
94
95 it('Should filter by host', async function () {
96 {
97 const search = { search: 'channel', host: remoteServer.host }
69 98
70 expect(res.body.total).to.equal(1) 99 const body = await command.advancedChannelSearch({ search })
100 expect(body.total).to.equal(1)
101 expect(body.data).to.have.lengthOf(1)
102 expect(body.data[0].displayName).to.equal('Zell channel')
103 }
104
105 {
106 const search = { search: 'Sq', host: server.host }
71 107
72 expect(res.body.data).to.have.lengthOf(0) 108 const body = await command.advancedChannelSearch({ search })
109 expect(body.total).to.equal(1)
110 expect(body.data).to.have.lengthOf(1)
111 expect(body.data[0].displayName).to.equal('Squall channel')
112 }
113
114 {
115 const search = { search: 'Squall', host: 'example.com' }
116
117 const body = await command.advancedChannelSearch({ search })
118 expect(body.total).to.equal(0)
119 expect(body.data).to.have.lengthOf(0)
120 }
121 })
122
123 it('Should filter by names', async function () {
124 {
125 const body = await command.advancedChannelSearch({ search: { handles: [ 'squall_channel', 'zell_channel' ] } })
126 expect(body.total).to.equal(1)
127 expect(body.data).to.have.lengthOf(1)
128 expect(body.data[0].displayName).to.equal('Squall channel')
129 }
130
131 {
132 const body = await command.advancedChannelSearch({ search: { handles: [ 'chocobozzz_channel' ] } })
133 expect(body.total).to.equal(0)
134 expect(body.data).to.have.lengthOf(0)
135 }
136
137 {
138 const body = await command.advancedChannelSearch({ search: { handles: [ 'squall_channel', 'zell_channel@' + remoteServer.host ] } })
139 expect(body.total).to.equal(2)
140 expect(body.data).to.have.lengthOf(2)
141 expect(body.data[0].displayName).to.equal('Squall channel')
142 expect(body.data[1].displayName).to.equal('Zell channel')
73 } 143 }
74 }) 144 })
75 145
76 after(async function () { 146 after(async function () {
77 await cleanupTests([ server ]) 147 await cleanupTests([ server, remoteServer ])
78 }) 148 })
79}) 149})
diff --git a/server/tests/api/search/search-index.ts b/server/tests/api/search/search-index.ts
index 00f79232a..4c8b1f608 100644
--- a/server/tests/api/search/search-index.ts
+++ b/server/tests/api/search/search-index.ts
@@ -2,36 +2,34 @@
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' 5import { cleanupTests, createSingleServer, PeerTubeServer, SearchCommand, setAccessTokensToServers } from '@shared/extra-utils'
6import { Video, VideoChannel, VideoPlaylist, VideoPlaylistPrivacy, VideoPlaylistType, VideosSearchQuery } from '@shared/models'
7import { 6import {
8 advancedVideoPlaylistSearch, 7 BooleanBothQuery,
9 advancedVideosSearch, 8 VideoChannelsSearchQuery,
10 cleanupTests, 9 VideoPlaylistPrivacy,
11 flushAndRunServer, 10 VideoPlaylistsSearchQuery,
12 immutableAssign, 11 VideoPlaylistType,
13 searchVideo, 12 VideosSearchQuery
14 searchVideoPlaylists, 13} from '@shared/models'
15 ServerInfo,
16 setAccessTokensToServers,
17 updateCustomSubConfig,
18 uploadVideo
19} from '../../../../shared/extra-utils'
20 14
21const expect = chai.expect 15const expect = chai.expect
22 16
23describe('Test videos search', function () { 17describe('Test videos search', function () {
24 let server: ServerInfo = null
25 const localVideoName = 'local video' + new Date().toISOString() 18 const localVideoName = 'local video' + new Date().toISOString()
26 19
20 let server: PeerTubeServer = null
21 let command: SearchCommand
22
27 before(async function () { 23 before(async function () {
28 this.timeout(30000) 24 this.timeout(30000)
29 25
30 server = await flushAndRunServer(1) 26 server = await createSingleServer(1)
31 27
32 await setAccessTokensToServers([ server ]) 28 await setAccessTokensToServers([ server ])
33 29
34 await uploadVideo(server.url, server.accessToken, { name: localVideoName }) 30 await server.videos.upload({ attributes: { name: localVideoName } })
31
32 command = server.search
35 }) 33 })
36 34
37 describe('Default search', async function () { 35 describe('Default search', async function () {
@@ -39,163 +37,213 @@ describe('Test videos search', function () {
39 it('Should make a local videos search by default', async function () { 37 it('Should make a local videos search by default', async function () {
40 this.timeout(10000) 38 this.timeout(10000)
41 39
42 await updateCustomSubConfig(server.url, server.accessToken, { 40 await server.config.updateCustomSubConfig({
43 search: { 41 newConfig: {
44 searchIndex: { 42 search: {
45 enabled: true, 43 searchIndex: {
46 isDefaultSearch: false, 44 enabled: true,
47 disableLocalSearch: false 45 isDefaultSearch: false,
46 disableLocalSearch: false
47 }
48 } 48 }
49 } 49 }
50 }) 50 })
51 51
52 const res = await searchVideo(server.url, 'local video') 52 const body = await command.searchVideos({ search: 'local video' })
53 53
54 expect(res.body.total).to.equal(1) 54 expect(body.total).to.equal(1)
55 expect(res.body.data[0].name).to.equal(localVideoName) 55 expect(body.data[0].name).to.equal(localVideoName)
56 }) 56 })
57 57
58 it('Should make a local channels search by default', async function () { 58 it('Should make a local channels search by default', async function () {
59 const res = await searchVideoChannel(server.url, 'root') 59 const body = await command.searchChannels({ search: 'root' })
60 60
61 expect(res.body.total).to.equal(1) 61 expect(body.total).to.equal(1)
62 expect(res.body.data[0].name).to.equal('root_channel') 62 expect(body.data[0].name).to.equal('root_channel')
63 expect(res.body.data[0].host).to.equal('localhost:' + server.port) 63 expect(body.data[0].host).to.equal('localhost:' + server.port)
64 }) 64 })
65 65
66 it('Should make an index videos search by default', async function () { 66 it('Should make an index videos search by default', async function () {
67 await updateCustomSubConfig(server.url, server.accessToken, { 67 await server.config.updateCustomSubConfig({
68 search: { 68 newConfig: {
69 searchIndex: { 69 search: {
70 enabled: true, 70 searchIndex: {
71 isDefaultSearch: true, 71 enabled: true,
72 disableLocalSearch: false 72 isDefaultSearch: true,
73 disableLocalSearch: false
74 }
73 } 75 }
74 } 76 }
75 }) 77 })
76 78
77 const res = await searchVideo(server.url, 'local video') 79 const body = await command.searchVideos({ search: 'local video' })
78 expect(res.body.total).to.be.greaterThan(2) 80 expect(body.total).to.be.greaterThan(2)
79 }) 81 })
80 82
81 it('Should make an index channels search by default', async function () { 83 it('Should make an index channels search by default', async function () {
82 const res = await searchVideoChannel(server.url, 'root') 84 const body = await command.searchChannels({ search: 'root' })
83 expect(res.body.total).to.be.greaterThan(2) 85 expect(body.total).to.be.greaterThan(2)
84 }) 86 })
85 87
86 it('Should make an index videos search if local search is disabled', async function () { 88 it('Should make an index videos search if local search is disabled', async function () {
87 await updateCustomSubConfig(server.url, server.accessToken, { 89 await server.config.updateCustomSubConfig({
88 search: { 90 newConfig: {
89 searchIndex: { 91 search: {
90 enabled: true, 92 searchIndex: {
91 isDefaultSearch: false, 93 enabled: true,
92 disableLocalSearch: true 94 isDefaultSearch: false,
95 disableLocalSearch: true
96 }
93 } 97 }
94 } 98 }
95 }) 99 })
96 100
97 const res = await searchVideo(server.url, 'local video') 101 const body = await command.searchVideos({ search: 'local video' })
98 expect(res.body.total).to.be.greaterThan(2) 102 expect(body.total).to.be.greaterThan(2)
99 }) 103 })
100 104
101 it('Should make an index channels search if local search is disabled', async function () { 105 it('Should make an index channels search if local search is disabled', async function () {
102 const res = await searchVideoChannel(server.url, 'root') 106 const body = await command.searchChannels({ search: 'root' })
103 expect(res.body.total).to.be.greaterThan(2) 107 expect(body.total).to.be.greaterThan(2)
104 }) 108 })
105 }) 109 })
106 110
107 describe('Videos search', async function () { 111 describe('Videos search', async function () {
108 112
113 async function check (search: VideosSearchQuery, exists = true) {
114 const body = await command.advancedVideoSearch({ search })
115
116 if (exists === false) {
117 expect(body.total).to.equal(0)
118 expect(body.data).to.have.lengthOf(0)
119 return
120 }
121
122 expect(body.total).to.equal(1)
123 expect(body.data).to.have.lengthOf(1)
124
125 const video = body.data[0]
126
127 expect(video.name).to.equal('What is PeerTube?')
128 expect(video.category.label).to.equal('Science & Technology')
129 expect(video.licence.label).to.equal('Attribution - Share Alike')
130 expect(video.privacy.label).to.equal('Public')
131 expect(video.duration).to.equal(113)
132 expect(video.thumbnailUrl.startsWith('https://framatube.org/static/thumbnails')).to.be.true
133
134 expect(video.account.host).to.equal('framatube.org')
135 expect(video.account.name).to.equal('framasoft')
136 expect(video.account.url).to.equal('https://framatube.org/accounts/framasoft')
137 expect(video.account.avatar).to.exist
138
139 expect(video.channel.host).to.equal('framatube.org')
140 expect(video.channel.name).to.equal('bf54d359-cfad-4935-9d45-9d6be93f63e8')
141 expect(video.channel.url).to.equal('https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8')
142 expect(video.channel.avatar).to.exist
143 }
144
145 const baseSearch: VideosSearchQuery = {
146 search: 'what is peertube',
147 start: 0,
148 count: 2,
149 categoryOneOf: [ 15 ],
150 licenceOneOf: [ 2 ],
151 tagsAllOf: [ 'framasoft', 'peertube' ],
152 startDate: '2018-10-01T10:50:46.396Z',
153 endDate: '2018-10-01T10:55:46.396Z'
154 }
155
109 it('Should make a simple search and not have results', async function () { 156 it('Should make a simple search and not have results', async function () {
110 const res = await searchVideo(server.url, 'djidane'.repeat(50)) 157 const body = await command.searchVideos({ search: 'djidane'.repeat(50) })
111 158
112 expect(res.body.total).to.equal(0) 159 expect(body.total).to.equal(0)
113 expect(res.body.data).to.have.lengthOf(0) 160 expect(body.data).to.have.lengthOf(0)
114 }) 161 })
115 162
116 it('Should make a simple search and have results', async function () { 163 it('Should make a simple search and have results', async function () {
117 const res = await searchVideo(server.url, 'What is PeerTube') 164 const body = await command.searchVideos({ search: 'What is PeerTube' })
118 165
119 expect(res.body.total).to.be.greaterThan(1) 166 expect(body.total).to.be.greaterThan(1)
120 }) 167 })
121 168
122 it('Should make a complex search', async function () { 169 it('Should make a simple search', async function () {
123 170 await check(baseSearch)
124 async function check (search: VideosSearchQuery, exists = true) { 171 })
125 const res = await advancedVideosSearch(server.url, search)
126
127 if (exists === false) {
128 expect(res.body.total).to.equal(0)
129 expect(res.body.data).to.have.lengthOf(0)
130 return
131 }
132
133 expect(res.body.total).to.equal(1)
134 expect(res.body.data).to.have.lengthOf(1)
135
136 const video: Video = res.body.data[0]
137
138 expect(video.name).to.equal('What is PeerTube?')
139 expect(video.category.label).to.equal('Science & Technology')
140 expect(video.licence.label).to.equal('Attribution - Share Alike')
141 expect(video.privacy.label).to.equal('Public')
142 expect(video.duration).to.equal(113)
143 expect(video.thumbnailUrl.startsWith('https://framatube.org/static/thumbnails')).to.be.true
144 172
145 expect(video.account.host).to.equal('framatube.org') 173 it('Should search by start date', async function () {
146 expect(video.account.name).to.equal('framasoft') 174 const search = { ...baseSearch, startDate: '2018-10-01T10:54:46.396Z' }
147 expect(video.account.url).to.equal('https://framatube.org/accounts/framasoft') 175 await check(search, false)
148 expect(video.account.avatar).to.exist 176 })
149 177
150 expect(video.channel.host).to.equal('framatube.org') 178 it('Should search by tags', async function () {
151 expect(video.channel.name).to.equal('bf54d359-cfad-4935-9d45-9d6be93f63e8') 179 const search = { ...baseSearch, tagsAllOf: [ 'toto', 'framasoft' ] }
152 expect(video.channel.url).to.equal('https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8') 180 await check(search, false)
153 expect(video.channel.avatar).to.exist 181 })
154 }
155 182
156 const baseSearch: VideosSearchQuery = { 183 it('Should search by duration', async function () {
157 search: 'what is peertube', 184 const search = { ...baseSearch, durationMin: 2000 }
158 start: 0, 185 await check(search, false)
159 count: 2, 186 })
160 categoryOneOf: [ 15 ],
161 licenceOneOf: [ 2 ],
162 tagsAllOf: [ 'framasoft', 'peertube' ],
163 startDate: '2018-10-01T10:50:46.396Z',
164 endDate: '2018-10-01T10:55:46.396Z'
165 }
166 187
188 it('Should search by nsfw attribute', async function () {
167 { 189 {
168 await check(baseSearch) 190 const search = { ...baseSearch, nsfw: 'true' as BooleanBothQuery }
191 await check(search, false)
169 } 192 }
170 193
171 { 194 {
172 const search = immutableAssign(baseSearch, { startDate: '2018-10-01T10:54:46.396Z' }) 195 const search = { ...baseSearch, nsfw: 'false' as BooleanBothQuery }
173 await check(search, false) 196 await check(search, true)
174 } 197 }
175 198
176 { 199 {
177 const search = immutableAssign(baseSearch, { tagsAllOf: [ 'toto', 'framasoft' ] }) 200 const search = { ...baseSearch, nsfw: 'both' as BooleanBothQuery }
178 await check(search, false) 201 await check(search, true)
179 } 202 }
203 })
180 204
205 it('Should search by host', async function () {
181 { 206 {
182 const search = immutableAssign(baseSearch, { durationMin: 2000 }) 207 const search = { ...baseSearch, host: 'example.com' }
183 await check(search, false) 208 await check(search, false)
184 } 209 }
185 210
186 { 211 {
187 const search = immutableAssign(baseSearch, { nsfw: 'true' }) 212 const search = { ...baseSearch, host: 'framatube.org' }
188 await check(search, false) 213 await check(search, true)
189 } 214 }
215 })
216
217 it('Should search by uuids', async function () {
218 const goodUUID = '9c9de5e8-0a1e-484a-b099-e80766180a6d'
219 const goodShortUUID = 'kkGMgK9ZtnKfYAgnEtQxbv'
220 const badUUID = 'c29c5b77-4a04-493d-96a9-2e9267e308f0'
221 const badShortUUID = 'rP5RgUeX9XwTSrspCdkDej'
190 222
191 { 223 {
192 const search = immutableAssign(baseSearch, { nsfw: 'false' }) 224 const uuidsMatrix = [
193 await check(search, true) 225 [ goodUUID ],
226 [ goodUUID, badShortUUID ],
227 [ badShortUUID, goodShortUUID ],
228 [ goodUUID, goodShortUUID ]
229 ]
230
231 for (const uuids of uuidsMatrix) {
232 const search = { ...baseSearch, uuids }
233 await check(search, true)
234 }
194 } 235 }
195 236
196 { 237 {
197 const search = immutableAssign(baseSearch, { nsfw: 'both' }) 238 const uuidsMatrix = [
198 await check(search, true) 239 [ badUUID ],
240 [ badShortUUID ]
241 ]
242
243 for (const uuids of uuidsMatrix) {
244 const search = { ...baseSearch, uuids }
245 await check(search, false)
246 }
199 } 247 }
200 }) 248 })
201 249
@@ -206,37 +254,44 @@ describe('Test videos search', function () {
206 count: 5 254 count: 5
207 } 255 }
208 256
209 const res = await advancedVideosSearch(server.url, search) 257 const body = await command.advancedVideoSearch({ search })
210 258
211 expect(res.body.total).to.be.greaterThan(5) 259 expect(body.total).to.be.greaterThan(5)
212 expect(res.body.data).to.have.lengthOf(5) 260 expect(body.data).to.have.lengthOf(5)
213 }) 261 })
214 262
215 it('Should use the nsfw instance policy as default', async function () { 263 it('Should use the nsfw instance policy as default', async function () {
216 let nsfwUUID: string 264 let nsfwUUID: string
217 265
218 { 266 {
219 await updateCustomSubConfig(server.url, server.accessToken, { instance: { defaultNSFWPolicy: 'display' } }) 267 await server.config.updateCustomSubConfig({
268 newConfig: {
269 instance: { defaultNSFWPolicy: 'display' }
270 }
271 })
220 272
221 const res = await searchVideo(server.url, 'NSFW search index', '-match') 273 const body = await command.searchVideos({ search: 'NSFW search index', sort: '-match' })
222 const video = res.body.data[0] as Video 274 expect(body.data).to.have.length.greaterThan(0)
223 275
224 expect(res.body.data).to.have.length.greaterThan(0) 276 const video = body.data[0]
225 expect(video.nsfw).to.be.true 277 expect(video.nsfw).to.be.true
226 278
227 nsfwUUID = video.uuid 279 nsfwUUID = video.uuid
228 } 280 }
229 281
230 { 282 {
231 await updateCustomSubConfig(server.url, server.accessToken, { instance: { defaultNSFWPolicy: 'do_not_list' } }) 283 await server.config.updateCustomSubConfig({
284 newConfig: {
285 instance: { defaultNSFWPolicy: 'do_not_list' }
286 }
287 })
232 288
233 const res = await searchVideo(server.url, 'NSFW search index', '-match') 289 const body = await command.searchVideos({ search: 'NSFW search index', sort: '-match' })
234 290
235 try { 291 try {
236 expect(res.body.data).to.have.lengthOf(0) 292 expect(body.data).to.have.lengthOf(0)
237 } catch (err) { 293 } catch {
238 // 294 const video = body.data[0]
239 const video = res.body.data[0] as Video
240 295
241 expect(video.uuid).not.equal(nsfwUUID) 296 expect(video.uuid).not.equal(nsfwUUID)
242 } 297 }
@@ -246,20 +301,19 @@ describe('Test videos search', function () {
246 301
247 describe('Channels search', async function () { 302 describe('Channels search', async function () {
248 303
249 it('Should make a simple search and not have results', async function () { 304 async function check (search: VideoChannelsSearchQuery, exists = true) {
250 const res = await searchVideoChannel(server.url, 'a'.repeat(500)) 305 const body = await command.advancedChannelSearch({ search })
251 306
252 expect(res.body.total).to.equal(0) 307 if (exists === false) {
253 expect(res.body.data).to.have.lengthOf(0) 308 expect(body.total).to.equal(0)
254 }) 309 expect(body.data).to.have.lengthOf(0)
255 310 return
256 it('Should make a search and have results', async function () { 311 }
257 const res = await advancedVideoChannelSearch(server.url, { search: 'Framasoft', sort: 'createdAt' })
258 312
259 expect(res.body.total).to.be.greaterThan(0) 313 expect(body.total).to.be.greaterThan(0)
260 expect(res.body.data).to.have.length.greaterThan(0) 314 expect(body.data).to.have.length.greaterThan(0)
261 315
262 const videoChannel: VideoChannel = res.body.data[0] 316 const videoChannel = body.data[0]
263 expect(videoChannel.url).to.equal('https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8') 317 expect(videoChannel.url).to.equal('https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8')
264 expect(videoChannel.host).to.equal('framatube.org') 318 expect(videoChannel.host).to.equal('framatube.org')
265 expect(videoChannel.avatar).to.exist 319 expect(videoChannel.avatar).to.exist
@@ -269,32 +323,53 @@ describe('Test videos search', function () {
269 expect(videoChannel.ownerAccount.name).to.equal('framasoft') 323 expect(videoChannel.ownerAccount.name).to.equal('framasoft')
270 expect(videoChannel.ownerAccount.host).to.equal('framatube.org') 324 expect(videoChannel.ownerAccount.host).to.equal('framatube.org')
271 expect(videoChannel.ownerAccount.avatar).to.exist 325 expect(videoChannel.ownerAccount.avatar).to.exist
326 }
327
328 it('Should make a simple search and not have results', async function () {
329 const body = await command.searchChannels({ search: 'a'.repeat(500) })
330
331 expect(body.total).to.equal(0)
332 expect(body.data).to.have.lengthOf(0)
333 })
334
335 it('Should make a search and have results', async function () {
336 await check({ search: 'Framasoft', sort: 'createdAt' }, true)
337 })
338
339 it('Should make host search and have appropriate results', async function () {
340 await check({ search: 'Framasoft', host: 'example.com' }, false)
341 await check({ search: 'Framasoft', host: 'framatube.org' }, true)
342 })
343
344 it('Should make handles search and have appropriate results', async function () {
345 await check({ handles: [ 'bf54d359-cfad-4935-9d45-9d6be93f63e8@framatube.org' ] }, true)
346 await check({ handles: [ 'jeanine', 'bf54d359-cfad-4935-9d45-9d6be93f63e8@framatube.org' ] }, true)
347 await check({ handles: [ 'jeanine', 'chocobozzz_channel2@peertube2.cpy.re' ] }, false)
272 }) 348 })
273 349
274 it('Should have a correct pagination', async function () { 350 it('Should have a correct pagination', async function () {
275 const res = await advancedVideoChannelSearch(server.url, { search: 'root', start: 0, count: 2 }) 351 const body = await command.advancedChannelSearch({ search: { search: 'root', start: 0, count: 2 } })
276 352
277 expect(res.body.total).to.be.greaterThan(2) 353 expect(body.total).to.be.greaterThan(2)
278 expect(res.body.data).to.have.lengthOf(2) 354 expect(body.data).to.have.lengthOf(2)
279 }) 355 })
280 }) 356 })
281 357
282 describe('Playlists search', async function () { 358 describe('Playlists search', async function () {
283 359
284 it('Should make a simple search and not have results', async function () { 360 async function check (search: VideoPlaylistsSearchQuery, exists = true) {
285 const res = await searchVideoPlaylists(server.url, 'a'.repeat(500)) 361 const body = await command.advancedPlaylistSearch({ search })
286 362
287 expect(res.body.total).to.equal(0) 363 if (exists === false) {
288 expect(res.body.data).to.have.lengthOf(0) 364 expect(body.total).to.equal(0)
289 }) 365 expect(body.data).to.have.lengthOf(0)
290 366 return
291 it('Should make a search and have results', async function () { 367 }
292 const res = await advancedVideoPlaylistSearch(server.url, { search: 'E2E playlist', sort: '-match' })
293 368
294 expect(res.body.total).to.be.greaterThan(0) 369 expect(body.total).to.be.greaterThan(0)
295 expect(res.body.data).to.have.length.greaterThan(0) 370 expect(body.data).to.have.length.greaterThan(0)
296 371
297 const videoPlaylist: VideoPlaylist = res.body.data[0] 372 const videoPlaylist = body.data[0]
298 373
299 expect(videoPlaylist.url).to.equal('https://peertube2.cpy.re/videos/watch/playlist/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a') 374 expect(videoPlaylist.url).to.equal('https://peertube2.cpy.re/videos/watch/playlist/73804a40-da9a-40c2-b1eb-2c6d9eec8f0a')
300 expect(videoPlaylist.thumbnailUrl).to.exist 375 expect(videoPlaylist.thumbnailUrl).to.exist
@@ -319,13 +394,62 @@ describe('Test videos search', function () {
319 expect(videoPlaylist.videoChannel.name).to.equal('chocobozzz_channel') 394 expect(videoPlaylist.videoChannel.name).to.equal('chocobozzz_channel')
320 expect(videoPlaylist.videoChannel.host).to.equal('peertube2.cpy.re') 395 expect(videoPlaylist.videoChannel.host).to.equal('peertube2.cpy.re')
321 expect(videoPlaylist.videoChannel.avatar).to.exist 396 expect(videoPlaylist.videoChannel.avatar).to.exist
397 }
398
399 it('Should make a simple search and not have results', async function () {
400 const body = await command.searchPlaylists({ search: 'a'.repeat(500) })
401
402 expect(body.total).to.equal(0)
403 expect(body.data).to.have.lengthOf(0)
404 })
405
406 it('Should make a search and have results', async function () {
407 await check({ search: 'E2E playlist', sort: '-match' }, true)
408 })
409
410 it('Should make host search and have appropriate results', async function () {
411 await check({ search: 'E2E playlist', host: 'example.com' }, false)
412 await check({ search: 'E2E playlist', host: 'peertube2.cpy.re', sort: '-match' }, true)
413 })
414
415 it('Should make a search by uuids and have appropriate results', async function () {
416 const goodUUID = '73804a40-da9a-40c2-b1eb-2c6d9eec8f0a'
417 const goodShortUUID = 'fgei1ws1oa6FCaJ2qZPG29'
418 const badUUID = 'c29c5b77-4a04-493d-96a9-2e9267e308f0'
419 const badShortUUID = 'rP5RgUeX9XwTSrspCdkDej'
420
421 {
422 const uuidsMatrix = [
423 [ goodUUID ],
424 [ goodUUID, badShortUUID ],
425 [ badShortUUID, goodShortUUID ],
426 [ goodUUID, goodShortUUID ]
427 ]
428
429 for (const uuids of uuidsMatrix) {
430 const search = { search: 'E2E playlist', sort: '-match', uuids }
431 await check(search, true)
432 }
433 }
434
435 {
436 const uuidsMatrix = [
437 [ badUUID ],
438 [ badShortUUID ]
439 ]
440
441 for (const uuids of uuidsMatrix) {
442 const search = { search: 'E2E playlist', sort: '-match', uuids }
443 await check(search, false)
444 }
445 }
322 }) 446 })
323 447
324 it('Should have a correct pagination', async function () { 448 it('Should have a correct pagination', async function () {
325 const res = await advancedVideoChannelSearch(server.url, { search: 'root', start: 0, count: 2 }) 449 const body = await command.advancedChannelSearch({ search: { search: 'root', start: 0, count: 2 } })
326 450
327 expect(res.body.total).to.be.greaterThan(2) 451 expect(body.total).to.be.greaterThan(2)
328 expect(res.body.data).to.have.lengthOf(2) 452 expect(body.data).to.have.lengthOf(2)
329 }) 453 })
330 }) 454 })
331 455
diff --git a/server/tests/api/search/search-playlists.ts b/server/tests/api/search/search-playlists.ts
index ab17d55e9..15aac029a 100644
--- a/server/tests/api/search/search-playlists.ts
+++ b/server/tests/api/search/search-playlists.ts
@@ -2,82 +2,86 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { VideoPlaylist, VideoPlaylistPrivacy } from '@shared/models'
6import { 5import {
7 addVideoInPlaylist,
8 advancedVideoPlaylistSearch,
9 cleanupTests, 6 cleanupTests,
10 createVideoPlaylist, 7 createSingleServer,
11 flushAndRunServer, 8 doubleFollow,
12 searchVideoPlaylists, 9 PeerTubeServer,
13 ServerInfo, 10 SearchCommand,
14 setAccessTokensToServers, 11 setAccessTokensToServers,
15 setDefaultVideoChannel, 12 setDefaultVideoChannel
16 uploadVideoAndGetId 13} from '@shared/extra-utils'
17} from '../../../../shared/extra-utils' 14import { VideoPlaylistPrivacy } from '@shared/models'
18 15
19const expect = chai.expect 16const expect = chai.expect
20 17
21describe('Test playlists search', function () { 18describe('Test playlists search', function () {
22 let server: ServerInfo = null 19 let server: PeerTubeServer
20 let remoteServer: PeerTubeServer
21 let command: SearchCommand
22 let playlistUUID: string
23 let playlistShortUUID: string
23 24
24 before(async function () { 25 before(async function () {
25 this.timeout(30000) 26 this.timeout(120000)
26 27
27 server = await flushAndRunServer(1) 28 const servers = await Promise.all([
29 createSingleServer(1),
30 createSingleServer(2, { transcoding: { enabled: false } })
31 ])
32 server = servers[0]
33 remoteServer = servers[1]
28 34
29 await setAccessTokensToServers([ server ]) 35 await setAccessTokensToServers([ remoteServer, server ])
30 await setDefaultVideoChannel([ server ]) 36 await setDefaultVideoChannel([ remoteServer, server ])
31
32 const videoId = (await uploadVideoAndGetId({ server: server, videoName: 'video' })).uuid
33 37
34 { 38 {
39 const videoId = (await server.videos.upload()).uuid
40
35 const attributes = { 41 const attributes = {
36 displayName: 'Dr. Kenzo Tenma hospital videos', 42 displayName: 'Dr. Kenzo Tenma hospital videos',
37 privacy: VideoPlaylistPrivacy.PUBLIC, 43 privacy: VideoPlaylistPrivacy.PUBLIC,
38 videoChannelId: server.videoChannel.id 44 videoChannelId: server.store.channel.id
39 } 45 }
40 const res = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes }) 46 const created = await server.playlists.create({ attributes })
41 47 playlistUUID = created.uuid
42 await addVideoInPlaylist({ 48 playlistShortUUID = created.shortUUID
43 url: server.url, 49
44 token: server.accessToken, 50 await server.playlists.addElement({ playlistId: created.id, attributes: { videoId } })
45 playlistId: res.body.videoPlaylist.id,
46 elementAttrs: { videoId }
47 })
48 } 51 }
49 52
50 { 53 {
54 const videoId = (await remoteServer.videos.upload()).uuid
55
51 const attributes = { 56 const attributes = {
52 displayName: 'Johan & Anna Libert musics', 57 displayName: 'Johan & Anna Libert music videos',
53 privacy: VideoPlaylistPrivacy.PUBLIC, 58 privacy: VideoPlaylistPrivacy.PUBLIC,
54 videoChannelId: server.videoChannel.id 59 videoChannelId: remoteServer.store.channel.id
55 } 60 }
56 const res = await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes }) 61 const created = await remoteServer.playlists.create({ attributes })
57 62
58 await addVideoInPlaylist({ 63 await remoteServer.playlists.addElement({ playlistId: created.id, attributes: { videoId } })
59 url: server.url,
60 token: server.accessToken,
61 playlistId: res.body.videoPlaylist.id,
62 elementAttrs: { videoId }
63 })
64 } 64 }
65 65
66 { 66 {
67 const attributes = { 67 const attributes = {
68 displayName: 'Inspector Lunge playlist', 68 displayName: 'Inspector Lunge playlist',
69 privacy: VideoPlaylistPrivacy.PUBLIC, 69 privacy: VideoPlaylistPrivacy.PUBLIC,
70 videoChannelId: server.videoChannel.id 70 videoChannelId: server.store.channel.id
71 } 71 }
72 await createVideoPlaylist({ url: server.url, token: server.accessToken, playlistAttrs: attributes }) 72 await server.playlists.create({ attributes })
73 } 73 }
74
75 await doubleFollow(server, remoteServer)
76
77 command = server.search
74 }) 78 })
75 79
76 it('Should make a simple search and not have results', async function () { 80 it('Should make a simple search and not have results', async function () {
77 const res = await searchVideoPlaylists(server.url, 'abc') 81 const body = await command.searchPlaylists({ search: 'abc' })
78 82
79 expect(res.body.total).to.equal(0) 83 expect(body.total).to.equal(0)
80 expect(res.body.data).to.have.lengthOf(0) 84 expect(body.data).to.have.lengthOf(0)
81 }) 85 })
82 86
83 it('Should make a search and have results', async function () { 87 it('Should make a search and have results', async function () {
@@ -87,27 +91,72 @@ describe('Test playlists search', function () {
87 start: 0, 91 start: 0,
88 count: 1 92 count: 1
89 } 93 }
90 const res = await advancedVideoPlaylistSearch(server.url, search) 94 const body = await command.advancedPlaylistSearch({ search })
91 expect(res.body.total).to.equal(1) 95 expect(body.total).to.equal(1)
92 expect(res.body.data).to.have.lengthOf(1) 96 expect(body.data).to.have.lengthOf(1)
93 97
94 const playlist: VideoPlaylist = res.body.data[0] 98 const playlist = body.data[0]
95 expect(playlist.displayName).to.equal('Dr. Kenzo Tenma hospital videos') 99 expect(playlist.displayName).to.equal('Dr. Kenzo Tenma hospital videos')
96 expect(playlist.url).to.equal(server.url + '/video-playlists/' + playlist.uuid) 100 expect(playlist.url).to.equal(server.url + '/video-playlists/' + playlist.uuid)
97 } 101 }
98 102
99 { 103 {
100 const search = { 104 const search = {
101 search: 'Anna Livert', 105 search: 'Anna Livert music',
102 start: 0, 106 start: 0,
103 count: 1 107 count: 1
104 } 108 }
105 const res = await advancedVideoPlaylistSearch(server.url, search) 109 const body = await command.advancedPlaylistSearch({ search })
106 expect(res.body.total).to.equal(1) 110 expect(body.total).to.equal(1)
107 expect(res.body.data).to.have.lengthOf(1) 111 expect(body.data).to.have.lengthOf(1)
112
113 const playlist = body.data[0]
114 expect(playlist.displayName).to.equal('Johan & Anna Libert music videos')
115 }
116 })
117
118 it('Should filter by host', async function () {
119 {
120 const search = { search: 'tenma', host: server.host }
121 const body = await command.advancedPlaylistSearch({ search })
122 expect(body.total).to.equal(1)
123 expect(body.data).to.have.lengthOf(1)
124
125 const playlist = body.data[0]
126 expect(playlist.displayName).to.equal('Dr. Kenzo Tenma hospital videos')
127 }
128
129 {
130 const search = { search: 'Anna', host: 'example.com' }
131 const body = await command.advancedPlaylistSearch({ search })
132 expect(body.total).to.equal(0)
133 expect(body.data).to.have.lengthOf(0)
134 }
135
136 {
137 const search = { search: 'video', host: remoteServer.host }
138 const body = await command.advancedPlaylistSearch({ search })
139 expect(body.total).to.equal(1)
140 expect(body.data).to.have.lengthOf(1)
141
142 const playlist = body.data[0]
143 expect(playlist.displayName).to.equal('Johan & Anna Libert music videos')
144 }
145 })
146
147 it('Should filter by UUIDs', async function () {
148 for (const uuid of [ playlistUUID, playlistShortUUID ]) {
149 const body = await command.advancedPlaylistSearch({ search: { uuids: [ uuid ] } })
150
151 expect(body.total).to.equal(1)
152 expect(body.data[0].displayName).to.equal('Dr. Kenzo Tenma hospital videos')
153 }
154
155 {
156 const body = await command.advancedPlaylistSearch({ search: { uuids: [ 'dfd70b83-639f-4980-94af-304a56ab4b35' ] } })
108 157
109 const playlist: VideoPlaylist = res.body.data[0] 158 expect(body.total).to.equal(0)
110 expect(playlist.displayName).to.equal('Johan & Anna Libert musics') 159 expect(body.data).to.have.lengthOf(0)
111 } 160 }
112 }) 161 })
113 162
@@ -117,12 +166,12 @@ describe('Test playlists search', function () {
117 start: 0, 166 start: 0,
118 count: 1 167 count: 1
119 } 168 }
120 const res = await advancedVideoPlaylistSearch(server.url, search) 169 const body = await command.advancedPlaylistSearch({ search })
121 expect(res.body.total).to.equal(0) 170 expect(body.total).to.equal(0)
122 expect(res.body.data).to.have.lengthOf(0) 171 expect(body.data).to.have.lengthOf(0)
123 }) 172 })
124 173
125 after(async function () { 174 after(async function () {
126 await cleanupTests([ server ]) 175 await cleanupTests([ server, remoteServer ])
127 }) 176 })
128}) 177})
diff --git a/server/tests/api/search/search-videos.ts b/server/tests/api/search/search-videos.ts
index 5b8907961..bd1e4d266 100644
--- a/server/tests/api/search/search-videos.ts
+++ b/server/tests/api/search/search-videos.ts
@@ -2,40 +2,42 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { VideoPrivacy } from '@shared/models'
6import { 5import {
7 advancedVideosSearch,
8 cleanupTests, 6 cleanupTests,
9 createLive, 7 createSingleServer,
10 flushAndRunServer, 8 doubleFollow,
11 immutableAssign, 9 PeerTubeServer,
12 searchVideo, 10 SearchCommand,
13 sendRTMPStreamInVideo,
14 ServerInfo,
15 setAccessTokensToServers, 11 setAccessTokensToServers,
16 setDefaultVideoChannel, 12 setDefaultVideoChannel,
17 stopFfmpeg, 13 stopFfmpeg,
18 updateCustomSubConfig, 14 wait
19 uploadVideo, 15} from '@shared/extra-utils'
20 wait, 16import { VideoPrivacy } from '@shared/models'
21 waitUntilLivePublished
22} from '../../../../shared/extra-utils'
23import { createVideoCaption } from '../../../../shared/extra-utils/videos/video-captions'
24 17
25const expect = chai.expect 18const expect = chai.expect
26 19
27describe('Test videos search', function () { 20describe('Test videos search', function () {
28 let server: ServerInfo = null 21 let server: PeerTubeServer
22 let remoteServer: PeerTubeServer
29 let startDate: string 23 let startDate: string
30 let videoUUID: string 24 let videoUUID: string
25 let videoShortUUID: string
26
27 let command: SearchCommand
31 28
32 before(async function () { 29 before(async function () {
33 this.timeout(60000) 30 this.timeout(120000)
34 31
35 server = await flushAndRunServer(1) 32 const servers = await Promise.all([
33 createSingleServer(1),
34 createSingleServer(2)
35 ])
36 server = servers[0]
37 remoteServer = servers[1]
36 38
37 await setAccessTokensToServers([ server ]) 39 await setAccessTokensToServers([ server, remoteServer ])
38 await setDefaultVideoChannel([ server ]) 40 await setDefaultVideoChannel([ server, remoteServer ])
39 41
40 { 42 {
41 const attributes1 = { 43 const attributes1 = {
@@ -46,57 +48,50 @@ describe('Test videos search', function () {
46 nsfw: false, 48 nsfw: false,
47 language: 'fr' 49 language: 'fr'
48 } 50 }
49 await uploadVideo(server.url, server.accessToken, attributes1) 51 await server.videos.upload({ attributes: attributes1 })
50 52
51 const attributes2 = immutableAssign(attributes1, { name: attributes1.name + ' - 2', fixture: 'video_short.mp4' }) 53 const attributes2 = { ...attributes1, name: attributes1.name + ' - 2', fixture: 'video_short.mp4' }
52 await uploadVideo(server.url, server.accessToken, attributes2) 54 await server.videos.upload({ attributes: attributes2 })
53 55
54 { 56 {
55 const attributes3 = immutableAssign(attributes1, { name: attributes1.name + ' - 3', language: undefined }) 57 const attributes3 = { ...attributes1, name: attributes1.name + ' - 3', language: undefined }
56 const res = await uploadVideo(server.url, server.accessToken, attributes3) 58 const { id, uuid, shortUUID } = await server.videos.upload({ attributes: attributes3 })
57 const videoId = res.body.video.id 59 videoUUID = uuid
58 videoUUID = res.body.video.uuid 60 videoShortUUID = shortUUID
59 61
60 await createVideoCaption({ 62 await server.captions.add({
61 url: server.url,
62 accessToken: server.accessToken,
63 language: 'en', 63 language: 'en',
64 videoId, 64 videoId: id,
65 fixture: 'subtitle-good2.vtt', 65 fixture: 'subtitle-good2.vtt',
66 mimeType: 'application/octet-stream' 66 mimeType: 'application/octet-stream'
67 }) 67 })
68 68
69 await createVideoCaption({ 69 await server.captions.add({
70 url: server.url,
71 accessToken: server.accessToken,
72 language: 'aa', 70 language: 'aa',
73 videoId, 71 videoId: id,
74 fixture: 'subtitle-good2.vtt', 72 fixture: 'subtitle-good2.vtt',
75 mimeType: 'application/octet-stream' 73 mimeType: 'application/octet-stream'
76 }) 74 })
77 } 75 }
78 76
79 const attributes4 = immutableAssign(attributes1, { name: attributes1.name + ' - 4', language: 'pl', nsfw: true }) 77 const attributes4 = { ...attributes1, name: attributes1.name + ' - 4', language: 'pl', nsfw: true }
80 await uploadVideo(server.url, server.accessToken, attributes4) 78 await server.videos.upload({ attributes: attributes4 })
81 79
82 await wait(1000) 80 await wait(1000)
83 81
84 startDate = new Date().toISOString() 82 startDate = new Date().toISOString()
85 83
86 const attributes5 = immutableAssign(attributes1, { name: attributes1.name + ' - 5', licence: 2, language: undefined }) 84 const attributes5 = { ...attributes1, name: attributes1.name + ' - 5', licence: 2, language: undefined }
87 await uploadVideo(server.url, server.accessToken, attributes5) 85 await server.videos.upload({ attributes: attributes5 })
88 86
89 const attributes6 = immutableAssign(attributes1, { name: attributes1.name + ' - 6', tags: [ 't1', 't2' ] }) 87 const attributes6 = { ...attributes1, name: attributes1.name + ' - 6', tags: [ 't1', 't2' ] }
90 await uploadVideo(server.url, server.accessToken, attributes6) 88 await server.videos.upload({ attributes: attributes6 })
91 89
92 const attributes7 = immutableAssign(attributes1, { 90 const attributes7 = { ...attributes1, name: attributes1.name + ' - 7', originallyPublishedAt: '2019-02-12T09:58:08.286Z' }
93 name: attributes1.name + ' - 7', 91 await server.videos.upload({ attributes: attributes7 })
94 originallyPublishedAt: '2019-02-12T09:58:08.286Z'
95 })
96 await uploadVideo(server.url, server.accessToken, attributes7)
97 92
98 const attributes8 = immutableAssign(attributes1, { name: attributes1.name + ' - 8', licence: 4 }) 93 const attributes8 = { ...attributes1, name: attributes1.name + ' - 8', licence: 4 }
99 await uploadVideo(server.url, server.accessToken, attributes8) 94 await server.videos.upload({ attributes: attributes8 })
100 } 95 }
101 96
102 { 97 {
@@ -107,9 +102,9 @@ describe('Test videos search', function () {
107 licence: 2, 102 licence: 2,
108 language: 'en' 103 language: 'en'
109 } 104 }
110 await uploadVideo(server.url, server.accessToken, attributes) 105 await server.videos.upload({ attributes: attributes })
111 106
112 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes, { name: attributes.name + ' duplicate' })) 107 await server.videos.upload({ attributes: { ...attributes, name: attributes.name + ' duplicate' } })
113 } 108 }
114 109
115 { 110 {
@@ -120,7 +115,7 @@ describe('Test videos search', function () {
120 licence: 3, 115 licence: 3,
121 language: 'pl' 116 language: 'pl'
122 } 117 }
123 await uploadVideo(server.url, server.accessToken, attributes) 118 await server.videos.upload({ attributes: attributes })
124 } 119 }
125 120
126 { 121 {
@@ -129,11 +124,11 @@ describe('Test videos search', function () {
129 tags: [ 'aaaa', 'bbbb', 'cccc' ], 124 tags: [ 'aaaa', 'bbbb', 'cccc' ],
130 category: 1 125 category: 1
131 } 126 }
132 await uploadVideo(server.url, server.accessToken, attributes1) 127 await server.videos.upload({ attributes: attributes1 })
133 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { category: 2 })) 128 await server.videos.upload({ attributes: { ...attributes1, category: 2 } })
134 129
135 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { tags: [ 'cccc', 'dddd' ] })) 130 await server.videos.upload({ attributes: { ...attributes1, tags: [ 'cccc', 'dddd' ] } })
136 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { tags: [ 'eeee', 'ffff' ] })) 131 await server.videos.upload({ attributes: { ...attributes1, tags: [ 'eeee', 'ffff' ] } })
137 } 132 }
138 133
139 { 134 {
@@ -141,24 +136,33 @@ describe('Test videos search', function () {
141 name: 'aaaa 2', 136 name: 'aaaa 2',
142 category: 1 137 category: 1
143 } 138 }
144 await uploadVideo(server.url, server.accessToken, attributes1) 139 await server.videos.upload({ attributes: attributes1 })
145 await uploadVideo(server.url, server.accessToken, immutableAssign(attributes1, { category: 2 })) 140 await server.videos.upload({ attributes: { ...attributes1, category: 2 } })
141 }
142
143 {
144 await remoteServer.videos.upload({ attributes: { name: 'remote video 1' } })
145 await remoteServer.videos.upload({ attributes: { name: 'remote video 2' } })
146 } 146 }
147
148 await doubleFollow(server, remoteServer)
149
150 command = server.search
147 }) 151 })
148 152
149 it('Should make a simple search and not have results', async function () { 153 it('Should make a simple search and not have results', async function () {
150 const res = await searchVideo(server.url, 'abc') 154 const body = await command.searchVideos({ search: 'abc' })
151 155
152 expect(res.body.total).to.equal(0) 156 expect(body.total).to.equal(0)
153 expect(res.body.data).to.have.lengthOf(0) 157 expect(body.data).to.have.lengthOf(0)
154 }) 158 })
155 159
156 it('Should make a simple search and have results', async function () { 160 it('Should make a simple search and have results', async function () {
157 const res = await searchVideo(server.url, '4444 5555 duplicate') 161 const body = await command.searchVideos({ search: '4444 5555 duplicate' })
158 162
159 expect(res.body.total).to.equal(2) 163 expect(body.total).to.equal(2)
160 164
161 const videos = res.body.data 165 const videos = body.data
162 expect(videos).to.have.lengthOf(2) 166 expect(videos).to.have.lengthOf(2)
163 167
164 // bestmatch 168 // bestmatch
@@ -167,15 +171,15 @@ describe('Test videos search', function () {
167 }) 171 })
168 172
169 it('Should make a search on tags too, and have results', async function () { 173 it('Should make a search on tags too, and have results', async function () {
170 const query = { 174 const search = {
171 search: 'aaaa', 175 search: 'aaaa',
172 categoryOneOf: [ 1 ] 176 categoryOneOf: [ 1 ]
173 } 177 }
174 const res = await advancedVideosSearch(server.url, query) 178 const body = await command.advancedVideoSearch({ search })
175 179
176 expect(res.body.total).to.equal(2) 180 expect(body.total).to.equal(2)
177 181
178 const videos = res.body.data 182 const videos = body.data
179 expect(videos).to.have.lengthOf(2) 183 expect(videos).to.have.lengthOf(2)
180 184
181 // bestmatch 185 // bestmatch
@@ -184,14 +188,14 @@ describe('Test videos search', function () {
184 }) 188 })
185 189
186 it('Should filter on tags without a search', async function () { 190 it('Should filter on tags without a search', async function () {
187 const query = { 191 const search = {
188 tagsAllOf: [ 'bbbb' ] 192 tagsAllOf: [ 'bbbb' ]
189 } 193 }
190 const res = await advancedVideosSearch(server.url, query) 194 const body = await command.advancedVideoSearch({ search })
191 195
192 expect(res.body.total).to.equal(2) 196 expect(body.total).to.equal(2)
193 197
194 const videos = res.body.data 198 const videos = body.data
195 expect(videos).to.have.lengthOf(2) 199 expect(videos).to.have.lengthOf(2)
196 200
197 expect(videos[0].name).to.equal('9999') 201 expect(videos[0].name).to.equal('9999')
@@ -199,14 +203,14 @@ describe('Test videos search', function () {
199 }) 203 })
200 204
201 it('Should filter on category without a search', async function () { 205 it('Should filter on category without a search', async function () {
202 const query = { 206 const search = {
203 categoryOneOf: [ 3 ] 207 categoryOneOf: [ 3 ]
204 } 208 }
205 const res = await advancedVideosSearch(server.url, query) 209 const body = await command.advancedVideoSearch({ search: search })
206 210
207 expect(res.body.total).to.equal(1) 211 expect(body.total).to.equal(1)
208 212
209 const videos = res.body.data 213 const videos = body.data
210 expect(videos).to.have.lengthOf(1) 214 expect(videos).to.have.lengthOf(1)
211 215
212 expect(videos[0].name).to.equal('6666 7777 8888') 216 expect(videos[0].name).to.equal('6666 7777 8888')
@@ -218,11 +222,16 @@ describe('Test videos search', function () {
218 categoryOneOf: [ 1 ], 222 categoryOneOf: [ 1 ],
219 tagsOneOf: [ 'aAaa', 'ffff' ] 223 tagsOneOf: [ 'aAaa', 'ffff' ]
220 } 224 }
221 const res1 = await advancedVideosSearch(server.url, query)
222 expect(res1.body.total).to.equal(2)
223 225
224 const res2 = await advancedVideosSearch(server.url, immutableAssign(query, { tagsOneOf: [ 'blabla' ] })) 226 {
225 expect(res2.body.total).to.equal(0) 227 const body = await command.advancedVideoSearch({ search: query })
228 expect(body.total).to.equal(2)
229 }
230
231 {
232 const body = await command.advancedVideoSearch({ search: { ...query, tagsOneOf: [ 'blabla' ] } })
233 expect(body.total).to.equal(0)
234 }
226 }) 235 })
227 236
228 it('Should search by tags (all of)', async function () { 237 it('Should search by tags (all of)', async function () {
@@ -231,14 +240,21 @@ describe('Test videos search', function () {
231 categoryOneOf: [ 1 ], 240 categoryOneOf: [ 1 ],
232 tagsAllOf: [ 'CCcc' ] 241 tagsAllOf: [ 'CCcc' ]
233 } 242 }
234 const res1 = await advancedVideosSearch(server.url, query)
235 expect(res1.body.total).to.equal(2)
236 243
237 const res2 = await advancedVideosSearch(server.url, immutableAssign(query, { tagsAllOf: [ 'blAbla' ] })) 244 {
238 expect(res2.body.total).to.equal(0) 245 const body = await command.advancedVideoSearch({ search: query })
246 expect(body.total).to.equal(2)
247 }
248
249 {
250 const body = await command.advancedVideoSearch({ search: { ...query, tagsAllOf: [ 'blAbla' ] } })
251 expect(body.total).to.equal(0)
252 }
239 253
240 const res3 = await advancedVideosSearch(server.url, immutableAssign(query, { tagsAllOf: [ 'bbbb', 'CCCC' ] })) 254 {
241 expect(res3.body.total).to.equal(1) 255 const body = await command.advancedVideoSearch({ search: { ...query, tagsAllOf: [ 'bbbb', 'CCCC' ] } })
256 expect(body.total).to.equal(1)
257 }
242 }) 258 })
243 259
244 it('Should search by category', async function () { 260 it('Should search by category', async function () {
@@ -246,12 +262,17 @@ describe('Test videos search', function () {
246 search: '6666', 262 search: '6666',
247 categoryOneOf: [ 3 ] 263 categoryOneOf: [ 3 ]
248 } 264 }
249 const res1 = await advancedVideosSearch(server.url, query)
250 expect(res1.body.total).to.equal(1)
251 expect(res1.body.data[0].name).to.equal('6666 7777 8888')
252 265
253 const res2 = await advancedVideosSearch(server.url, immutableAssign(query, { categoryOneOf: [ 2 ] })) 266 {
254 expect(res2.body.total).to.equal(0) 267 const body = await command.advancedVideoSearch({ search: query })
268 expect(body.total).to.equal(1)
269 expect(body.data[0].name).to.equal('6666 7777 8888')
270 }
271
272 {
273 const body = await command.advancedVideoSearch({ search: { ...query, categoryOneOf: [ 2 ] } })
274 expect(body.total).to.equal(0)
275 }
255 }) 276 })
256 277
257 it('Should search by licence', async function () { 278 it('Should search by licence', async function () {
@@ -259,13 +280,18 @@ describe('Test videos search', function () {
259 search: '4444 5555', 280 search: '4444 5555',
260 licenceOneOf: [ 2 ] 281 licenceOneOf: [ 2 ]
261 } 282 }
262 const res1 = await advancedVideosSearch(server.url, query)
263 expect(res1.body.total).to.equal(2)
264 expect(res1.body.data[0].name).to.equal('3333 4444 5555')
265 expect(res1.body.data[1].name).to.equal('3333 4444 5555 duplicate')
266 283
267 const res2 = await advancedVideosSearch(server.url, immutableAssign(query, { licenceOneOf: [ 3 ] })) 284 {
268 expect(res2.body.total).to.equal(0) 285 const body = await command.advancedVideoSearch({ search: query })
286 expect(body.total).to.equal(2)
287 expect(body.data[0].name).to.equal('3333 4444 5555')
288 expect(body.data[1].name).to.equal('3333 4444 5555 duplicate')
289 }
290
291 {
292 const body = await command.advancedVideoSearch({ search: { ...query, licenceOneOf: [ 3 ] } })
293 expect(body.total).to.equal(0)
294 }
269 }) 295 })
270 296
271 it('Should search by languages', async function () { 297 it('Should search by languages', async function () {
@@ -275,23 +301,23 @@ describe('Test videos search', function () {
275 } 301 }
276 302
277 { 303 {
278 const res = await advancedVideosSearch(server.url, query) 304 const body = await command.advancedVideoSearch({ search: query })
279 expect(res.body.total).to.equal(2) 305 expect(body.total).to.equal(2)
280 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 3') 306 expect(body.data[0].name).to.equal('1111 2222 3333 - 3')
281 expect(res.body.data[1].name).to.equal('1111 2222 3333 - 4') 307 expect(body.data[1].name).to.equal('1111 2222 3333 - 4')
282 } 308 }
283 309
284 { 310 {
285 const res = await advancedVideosSearch(server.url, immutableAssign(query, { languageOneOf: [ 'pl', 'en', '_unknown' ] })) 311 const body = await command.advancedVideoSearch({ search: { ...query, languageOneOf: [ 'pl', 'en', '_unknown' ] } })
286 expect(res.body.total).to.equal(3) 312 expect(body.total).to.equal(3)
287 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 3') 313 expect(body.data[0].name).to.equal('1111 2222 3333 - 3')
288 expect(res.body.data[1].name).to.equal('1111 2222 3333 - 4') 314 expect(body.data[1].name).to.equal('1111 2222 3333 - 4')
289 expect(res.body.data[2].name).to.equal('1111 2222 3333 - 5') 315 expect(body.data[2].name).to.equal('1111 2222 3333 - 5')
290 } 316 }
291 317
292 { 318 {
293 const res = await advancedVideosSearch(server.url, immutableAssign(query, { languageOneOf: [ 'eo' ] })) 319 const body = await command.advancedVideoSearch({ search: { ...query, languageOneOf: [ 'eo' ] } })
294 expect(res.body.total).to.equal(0) 320 expect(body.total).to.equal(0)
295 } 321 }
296 }) 322 })
297 323
@@ -301,10 +327,10 @@ describe('Test videos search', function () {
301 startDate 327 startDate
302 } 328 }
303 329
304 const res = await advancedVideosSearch(server.url, query) 330 const body = await command.advancedVideoSearch({ search: query })
305 expect(res.body.total).to.equal(4) 331 expect(body.total).to.equal(4)
306 332
307 const videos = res.body.data 333 const videos = body.data
308 expect(videos[0].name).to.equal('1111 2222 3333 - 5') 334 expect(videos[0].name).to.equal('1111 2222 3333 - 5')
309 expect(videos[1].name).to.equal('1111 2222 3333 - 6') 335 expect(videos[1].name).to.equal('1111 2222 3333 - 6')
310 expect(videos[2].name).to.equal('1111 2222 3333 - 7') 336 expect(videos[2].name).to.equal('1111 2222 3333 - 7')
@@ -320,10 +346,10 @@ describe('Test videos search', function () {
320 licenceOneOf: [ 1, 4 ] 346 licenceOneOf: [ 1, 4 ]
321 } 347 }
322 348
323 const res = await advancedVideosSearch(server.url, query) 349 const body = await command.advancedVideoSearch({ search: query })
324 expect(res.body.total).to.equal(4) 350 expect(body.total).to.equal(4)
325 351
326 const videos = res.body.data 352 const videos = body.data
327 expect(videos[0].name).to.equal('1111 2222 3333') 353 expect(videos[0].name).to.equal('1111 2222 3333')
328 expect(videos[1].name).to.equal('1111 2222 3333 - 6') 354 expect(videos[1].name).to.equal('1111 2222 3333 - 6')
329 expect(videos[2].name).to.equal('1111 2222 3333 - 7') 355 expect(videos[2].name).to.equal('1111 2222 3333 - 7')
@@ -340,10 +366,10 @@ describe('Test videos search', function () {
340 sort: '-name' 366 sort: '-name'
341 } 367 }
342 368
343 const res = await advancedVideosSearch(server.url, query) 369 const body = await command.advancedVideoSearch({ search: query })
344 expect(res.body.total).to.equal(4) 370 expect(body.total).to.equal(4)
345 371
346 const videos = res.body.data 372 const videos = body.data
347 expect(videos[0].name).to.equal('1111 2222 3333 - 8') 373 expect(videos[0].name).to.equal('1111 2222 3333 - 8')
348 expect(videos[1].name).to.equal('1111 2222 3333 - 7') 374 expect(videos[1].name).to.equal('1111 2222 3333 - 7')
349 expect(videos[2].name).to.equal('1111 2222 3333 - 6') 375 expect(videos[2].name).to.equal('1111 2222 3333 - 6')
@@ -362,10 +388,10 @@ describe('Test videos search', function () {
362 count: 1 388 count: 1
363 } 389 }
364 390
365 const res = await advancedVideosSearch(server.url, query) 391 const body = await command.advancedVideoSearch({ search: query })
366 expect(res.body.total).to.equal(4) 392 expect(body.total).to.equal(4)
367 393
368 const videos = res.body.data 394 const videos = body.data
369 expect(videos[0].name).to.equal('1111 2222 3333 - 8') 395 expect(videos[0].name).to.equal('1111 2222 3333 - 8')
370 }) 396 })
371 397
@@ -381,10 +407,10 @@ describe('Test videos search', function () {
381 count: 1 407 count: 1
382 } 408 }
383 409
384 const res = await advancedVideosSearch(server.url, query) 410 const body = await command.advancedVideoSearch({ search: query })
385 expect(res.body.total).to.equal(4) 411 expect(body.total).to.equal(4)
386 412
387 const videos = res.body.data 413 const videos = body.data
388 expect(videos[0].name).to.equal('1111 2222 3333') 414 expect(videos[0].name).to.equal('1111 2222 3333')
389 }) 415 })
390 416
@@ -398,99 +424,140 @@ describe('Test videos search', function () {
398 } 424 }
399 425
400 { 426 {
401 const query = immutableAssign(baseQuery, { originallyPublishedStartDate: '2019-02-11T09:58:08.286Z' }) 427 const query = { ...baseQuery, originallyPublishedStartDate: '2019-02-11T09:58:08.286Z' }
402 const res = await advancedVideosSearch(server.url, query) 428 const body = await command.advancedVideoSearch({ search: query })
403 429
404 expect(res.body.total).to.equal(1) 430 expect(body.total).to.equal(1)
405 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 7') 431 expect(body.data[0].name).to.equal('1111 2222 3333 - 7')
406 } 432 }
407 433
408 { 434 {
409 const query = immutableAssign(baseQuery, { originallyPublishedEndDate: '2019-03-11T09:58:08.286Z' }) 435 const query = { ...baseQuery, originallyPublishedEndDate: '2019-03-11T09:58:08.286Z' }
410 const res = await advancedVideosSearch(server.url, query) 436 const body = await command.advancedVideoSearch({ search: query })
411 437
412 expect(res.body.total).to.equal(1) 438 expect(body.total).to.equal(1)
413 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 7') 439 expect(body.data[0].name).to.equal('1111 2222 3333 - 7')
414 } 440 }
415 441
416 { 442 {
417 const query = immutableAssign(baseQuery, { originallyPublishedEndDate: '2019-01-11T09:58:08.286Z' }) 443 const query = { ...baseQuery, originallyPublishedEndDate: '2019-01-11T09:58:08.286Z' }
418 const res = await advancedVideosSearch(server.url, query) 444 const body = await command.advancedVideoSearch({ search: query })
419 445
420 expect(res.body.total).to.equal(0) 446 expect(body.total).to.equal(0)
421 } 447 }
422 448
423 { 449 {
424 const query = immutableAssign(baseQuery, { originallyPublishedStartDate: '2019-03-11T09:58:08.286Z' }) 450 const query = { ...baseQuery, originallyPublishedStartDate: '2019-03-11T09:58:08.286Z' }
425 const res = await advancedVideosSearch(server.url, query) 451 const body = await command.advancedVideoSearch({ search: query })
426 452
427 expect(res.body.total).to.equal(0) 453 expect(body.total).to.equal(0)
428 } 454 }
429 455
430 { 456 {
431 const query = immutableAssign(baseQuery, { 457 const query = {
458 ...baseQuery,
432 originallyPublishedStartDate: '2019-01-11T09:58:08.286Z', 459 originallyPublishedStartDate: '2019-01-11T09:58:08.286Z',
433 originallyPublishedEndDate: '2019-01-10T09:58:08.286Z' 460 originallyPublishedEndDate: '2019-01-10T09:58:08.286Z'
434 }) 461 }
435 const res = await advancedVideosSearch(server.url, query) 462 const body = await command.advancedVideoSearch({ search: query })
436 463
437 expect(res.body.total).to.equal(0) 464 expect(body.total).to.equal(0)
438 } 465 }
439 466
440 { 467 {
441 const query = immutableAssign(baseQuery, { 468 const query = {
469 ...baseQuery,
442 originallyPublishedStartDate: '2019-01-11T09:58:08.286Z', 470 originallyPublishedStartDate: '2019-01-11T09:58:08.286Z',
443 originallyPublishedEndDate: '2019-04-11T09:58:08.286Z' 471 originallyPublishedEndDate: '2019-04-11T09:58:08.286Z'
444 }) 472 }
445 const res = await advancedVideosSearch(server.url, query) 473 const body = await command.advancedVideoSearch({ search: query })
446 474
447 expect(res.body.total).to.equal(1) 475 expect(body.total).to.equal(1)
448 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 7') 476 expect(body.data[0].name).to.equal('1111 2222 3333 - 7')
449 } 477 }
450 }) 478 })
451 479
452 it('Should search by UUID', async function () { 480 it('Should search by UUID', async function () {
453 const search = videoUUID 481 const search = videoUUID
454 const res = await advancedVideosSearch(server.url, { search }) 482 const body = await command.advancedVideoSearch({ search: { search } })
483
484 expect(body.total).to.equal(1)
485 expect(body.data[0].name).to.equal('1111 2222 3333 - 3')
486 })
487
488 it('Should filter by UUIDs', async function () {
489 for (const uuid of [ videoUUID, videoShortUUID ]) {
490 const body = await command.advancedVideoSearch({ search: { uuids: [ uuid ] } })
491
492 expect(body.total).to.equal(1)
493 expect(body.data[0].name).to.equal('1111 2222 3333 - 3')
494 }
495
496 {
497 const body = await command.advancedVideoSearch({ search: { uuids: [ 'dfd70b83-639f-4980-94af-304a56ab4b35' ] } })
498
499 expect(body.total).to.equal(0)
500 expect(body.data).to.have.lengthOf(0)
501 }
502 })
503
504 it('Should search by host', async function () {
505 {
506 const body = await command.advancedVideoSearch({ search: { search: '6666 7777 8888', host: server.host } })
507 expect(body.total).to.equal(1)
508 expect(body.data[0].name).to.equal('6666 7777 8888')
509 }
455 510
456 expect(res.body.total).to.equal(1) 511 {
457 expect(res.body.data[0].name).to.equal('1111 2222 3333 - 3') 512 const body = await command.advancedVideoSearch({ search: { search: '1111', host: 'example.com' } })
513 expect(body.total).to.equal(0)
514 expect(body.data).to.have.lengthOf(0)
515 }
516
517 {
518 const body = await command.advancedVideoSearch({ search: { search: 'remote', host: remoteServer.host } })
519 expect(body.total).to.equal(2)
520 expect(body.data).to.have.lengthOf(2)
521 expect(body.data[0].name).to.equal('remote video 1')
522 expect(body.data[1].name).to.equal('remote video 2')
523 }
458 }) 524 })
459 525
460 it('Should search by live', async function () { 526 it('Should search by live', async function () {
461 this.timeout(30000) 527 this.timeout(60000)
462 528
463 { 529 {
464 const options = { 530 const newConfig = {
465 search: { 531 search: {
466 searchIndex: { enabled: false } 532 searchIndex: { enabled: false }
467 }, 533 },
468 live: { enabled: true } 534 live: { enabled: true }
469 } 535 }
470 await updateCustomSubConfig(server.url, server.accessToken, options) 536 await server.config.updateCustomSubConfig({ newConfig })
471 } 537 }
472 538
473 { 539 {
474 const res = await advancedVideosSearch(server.url, { isLive: true }) 540 const body = await command.advancedVideoSearch({ search: { isLive: true } })
475 541
476 expect(res.body.total).to.equal(0) 542 expect(body.total).to.equal(0)
477 expect(res.body.data).to.have.lengthOf(0) 543 expect(body.data).to.have.lengthOf(0)
478 } 544 }
479 545
480 { 546 {
481 const liveOptions = { name: 'live', privacy: VideoPrivacy.PUBLIC, channelId: server.videoChannel.id } 547 const liveCommand = server.live
482 const resLive = await createLive(server.url, server.accessToken, liveOptions) 548
483 const liveVideoId = resLive.body.video.uuid 549 const liveAttributes = { name: 'live', privacy: VideoPrivacy.PUBLIC, channelId: server.store.channel.id }
550 const live = await liveCommand.create({ fields: liveAttributes })
484 551
485 const command = await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId) 552 const ffmpegCommand = await liveCommand.sendRTMPStreamInVideo({ videoId: live.id })
486 await waitUntilLivePublished(server.url, server.accessToken, liveVideoId) 553 await liveCommand.waitUntilPublished({ videoId: live.id })
487 554
488 const res = await advancedVideosSearch(server.url, { isLive: true }) 555 const body = await command.advancedVideoSearch({ search: { isLive: true } })
489 556
490 expect(res.body.total).to.equal(1) 557 expect(body.total).to.equal(1)
491 expect(res.body.data[0].name).to.equal('live') 558 expect(body.data[0].name).to.equal('live')
492 559
493 await stopFfmpeg(command) 560 await stopFfmpeg(ffmpegCommand)
494 } 561 }
495 }) 562 })
496 563