aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-07-31 15:57:32 +0200
committerChocobozzz <chocobozzz@cpy.re>2019-08-01 09:11:04 +0200
commitbfbd912886eba17b4aa9a40dcef2fddc685d85bf (patch)
tree85e0f22980210a8ccd0888eb5e1790b152074677 /server/tests/api
parent85394ba22a07bde1dfccebf3f591a5d6dbe9df56 (diff)
downloadPeerTube-bfbd912886eba17b4aa9a40dcef2fddc685d85bf.tar.gz
PeerTube-bfbd912886eba17b4aa9a40dcef2fddc685d85bf.tar.zst
PeerTube-bfbd912886eba17b4aa9a40dcef2fddc685d85bf.zip
Fix broken playlist api
Diffstat (limited to 'server/tests/api')
-rw-r--r--server/tests/api/check-params/video-playlists.ts34
-rw-r--r--server/tests/api/check-params/videos-filter.ts26
-rw-r--r--server/tests/api/check-params/videos.ts2
-rw-r--r--server/tests/api/videos/video-playlists.ts1473
4 files changed, 898 insertions, 637 deletions
diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts
index 8c5e44bdd..ae5aa287f 100644
--- a/server/tests/api/check-params/video-playlists.ts
+++ b/server/tests/api/check-params/video-playlists.ts
@@ -37,6 +37,7 @@ describe('Test video playlists API validator', function () {
37 let watchLaterPlaylistId: number 37 let watchLaterPlaylistId: number
38 let videoId: number 38 let videoId: number
39 let videoId2: number 39 let videoId2: number
40 let playlistElementId: number
40 41
41 // --------------------------------------------------------------- 42 // ---------------------------------------------------------------
42 43
@@ -132,18 +133,18 @@ describe('Test video playlists API validator', function () {
132 }) 133 })
133 134
134 describe('When listing videos of a playlist', function () { 135 describe('When listing videos of a playlist', function () {
135 const path = '/api/v1/video-playlists' 136 const path = '/api/v1/video-playlists/'
136 137
137 it('Should fail with a bad start pagination', async function () { 138 it('Should fail with a bad start pagination', async function () {
138 await checkBadStartPagination(server.url, path, server.accessToken) 139 await checkBadStartPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
139 }) 140 })
140 141
141 it('Should fail with a bad count pagination', async function () { 142 it('Should fail with a bad count pagination', async function () {
142 await checkBadCountPagination(server.url, path, server.accessToken) 143 await checkBadCountPagination(server.url, path + playlistUUID + '/videos', server.accessToken)
143 }) 144 })
144 145
145 it('Should fail with a bad filter', async function () { 146 it('Should success with the correct parameters', async function () {
146 await checkBadSortPagination(server.url, path, server.accessToken) 147 await makeGetRequest({ url: server.url, path: path + playlistUUID + '/videos', statusCodeExpected: 200 })
147 }) 148 })
148 }) 149 })
149 150
@@ -296,7 +297,7 @@ describe('Test video playlists API validator', function () {
296 token: server.accessToken, 297 token: server.accessToken,
297 playlistId: playlistUUID, 298 playlistId: playlistUUID,
298 elementAttrs: Object.assign({ 299 elementAttrs: Object.assign({
299 videoId: videoId, 300 videoId,
300 startTimestamp: 2, 301 startTimestamp: 2,
301 stopTimestamp: 3 302 stopTimestamp: 3
302 }, elementAttrs) 303 }, elementAttrs)
@@ -344,7 +345,8 @@ describe('Test video playlists API validator', function () {
344 345
345 it('Succeed with the correct params', async function () { 346 it('Succeed with the correct params', async function () {
346 const params = getBase({}, { expectedStatus: 200 }) 347 const params = getBase({}, { expectedStatus: 200 })
347 await addVideoInPlaylist(params) 348 const res = await addVideoInPlaylist(params)
349 playlistElementId = res.body.videoPlaylistElement.id
348 }) 350 })
349 351
350 it('Should fail if the video was already added in the playlist', async function () { 352 it('Should fail if the video was already added in the playlist', async function () {
@@ -362,7 +364,7 @@ describe('Test video playlists API validator', function () {
362 startTimestamp: 1, 364 startTimestamp: 1,
363 stopTimestamp: 2 365 stopTimestamp: 2
364 }, elementAttrs), 366 }, elementAttrs),
365 videoId: videoId, 367 playlistElementId,
366 playlistId: playlistUUID, 368 playlistId: playlistUUID,
367 expectedStatus: 400 369 expectedStatus: 400
368 }, wrapper) 370 }, wrapper)
@@ -390,14 +392,14 @@ describe('Test video playlists API validator', function () {
390 } 392 }
391 }) 393 })
392 394
393 it('Should fail with an unknown or incorrect video id', async function () { 395 it('Should fail with an unknown or incorrect playlistElement id', async function () {
394 { 396 {
395 const params = getBase({}, { videoId: 'toto' }) 397 const params = getBase({}, { playlistElementId: 'toto' })
396 await updateVideoPlaylistElement(params) 398 await updateVideoPlaylistElement(params)
397 } 399 }
398 400
399 { 401 {
400 const params = getBase({}, { videoId: 42, expectedStatus: 404 }) 402 const params = getBase({}, { playlistElementId: 42, expectedStatus: 404 })
401 await updateVideoPlaylistElement(params) 403 await updateVideoPlaylistElement(params)
402 } 404 }
403 }) 405 })
@@ -415,7 +417,7 @@ describe('Test video playlists API validator', function () {
415 }) 417 })
416 418
417 it('Should fail with an unknown element', async function () { 419 it('Should fail with an unknown element', async function () {
418 const params = getBase({}, { videoId: videoId2, expectedStatus: 404 }) 420 const params = getBase({}, { playlistElementId: 888, expectedStatus: 404 })
419 await updateVideoPlaylistElement(params) 421 await updateVideoPlaylistElement(params)
420 }) 422 })
421 423
@@ -587,7 +589,7 @@ describe('Test video playlists API validator', function () {
587 return Object.assign({ 589 return Object.assign({
588 url: server.url, 590 url: server.url,
589 token: server.accessToken, 591 token: server.accessToken,
590 videoId: videoId, 592 playlistElementId,
591 playlistId: playlistUUID, 593 playlistId: playlistUUID,
592 expectedStatus: 400 594 expectedStatus: 400
593 }, wrapper) 595 }, wrapper)
@@ -617,18 +619,18 @@ describe('Test video playlists API validator', function () {
617 619
618 it('Should fail with an unknown or incorrect video id', async function () { 620 it('Should fail with an unknown or incorrect video id', async function () {
619 { 621 {
620 const params = getBase({ videoId: 'toto' }) 622 const params = getBase({ playlistElementId: 'toto' })
621 await removeVideoFromPlaylist(params) 623 await removeVideoFromPlaylist(params)
622 } 624 }
623 625
624 { 626 {
625 const params = getBase({ videoId: 42, expectedStatus: 404 }) 627 const params = getBase({ playlistElementId: 42, expectedStatus: 404 })
626 await removeVideoFromPlaylist(params) 628 await removeVideoFromPlaylist(params)
627 } 629 }
628 }) 630 })
629 631
630 it('Should fail with an unknown element', async function () { 632 it('Should fail with an unknown element', async function () {
631 const params = getBase({ videoId: videoId2, expectedStatus: 404 }) 633 const params = getBase({ playlistElementId: 888, expectedStatus: 404 })
632 await removeVideoFromPlaylist(params) 634 await removeVideoFromPlaylist(params)
633 }) 635 })
634 636
diff --git a/server/tests/api/check-params/videos-filter.ts b/server/tests/api/check-params/videos-filter.ts
index babef8223..5a5668665 100644
--- a/server/tests/api/check-params/videos-filter.ts
+++ b/server/tests/api/check-params/videos-filter.ts
@@ -15,13 +15,12 @@ import {
15import { UserRole } from '../../../../shared/models/users' 15import { UserRole } from '../../../../shared/models/users'
16import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' 16import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
17 17
18async function testEndpoints (server: ServerInfo, token: string, filter: string, playlistUUID: string, statusCodeExpected: number) { 18async function testEndpoints (server: ServerInfo, token: string, filter: string, statusCodeExpected: number) {
19 const paths = [ 19 const paths = [
20 '/api/v1/video-channels/root_channel/videos', 20 '/api/v1/video-channels/root_channel/videos',
21 '/api/v1/accounts/root/videos', 21 '/api/v1/accounts/root/videos',
22 '/api/v1/videos', 22 '/api/v1/videos',
23 '/api/v1/search/videos', 23 '/api/v1/search/videos'
24 '/api/v1/video-playlists/' + playlistUUID + '/videos'
25 ] 24 ]
26 25
27 for (const path of paths) { 26 for (const path of paths) {
@@ -70,39 +69,28 @@ describe('Test videos filters', function () {
70 } 69 }
71 ) 70 )
72 moderatorAccessToken = await userLogin(server, moderator) 71 moderatorAccessToken = await userLogin(server, moderator)
73
74 const res = await createVideoPlaylist({
75 url: server.url,
76 token: server.accessToken,
77 playlistAttrs: {
78 displayName: 'super playlist',
79 privacy: VideoPlaylistPrivacy.PUBLIC,
80 videoChannelId: server.videoChannel.id
81 }
82 })
83 playlistUUID = res.body.videoPlaylist.uuid
84 }) 72 })
85 73
86 describe('When setting a video filter', function () { 74 describe('When setting a video filter', function () {
87 75
88 it('Should fail with a bad filter', async function () { 76 it('Should fail with a bad filter', async function () {
89 await testEndpoints(server, server.accessToken, 'bad-filter', playlistUUID, 400) 77 await testEndpoints(server, server.accessToken, 'bad-filter', 400)
90 }) 78 })
91 79
92 it('Should succeed with a good filter', async function () { 80 it('Should succeed with a good filter', async function () {
93 await testEndpoints(server, server.accessToken,'local', playlistUUID, 200) 81 await testEndpoints(server, server.accessToken,'local', 200)
94 }) 82 })
95 83
96 it('Should fail to list all-local with a simple user', async function () { 84 it('Should fail to list all-local with a simple user', async function () {
97 await testEndpoints(server, userAccessToken, 'all-local', playlistUUID, 401) 85 await testEndpoints(server, userAccessToken, 'all-local', 401)
98 }) 86 })
99 87
100 it('Should succeed to list all-local with a moderator', async function () { 88 it('Should succeed to list all-local with a moderator', async function () {
101 await testEndpoints(server, moderatorAccessToken, 'all-local', playlistUUID, 200) 89 await testEndpoints(server, moderatorAccessToken, 'all-local', 200)
102 }) 90 })
103 91
104 it('Should succeed to list all-local with an admin', async function () { 92 it('Should succeed to list all-local with an admin', async function () {
105 await testEndpoints(server, server.accessToken, 'all-local', playlistUUID, 200) 93 await testEndpoints(server, server.accessToken, 'all-local', 200)
106 }) 94 })
107 95
108 // Because we cannot authenticate the user on the RSS endpoint 96 // Because we cannot authenticate the user on the RSS endpoint
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 51e592a15..fa6d6f622 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -62,7 +62,7 @@ describe('Test videos API validator', function () {
62 } 62 }
63 }) 63 })
64 64
65 describe('When listing a video', function () { 65 describe('When listing videos', function () {
66 it('Should fail with a bad start pagination', async function () { 66 it('Should fail with a bad start pagination', async function () {
67 await checkBadStartPagination(server.url, path) 67 await checkBadStartPagination(server.url, path)
68 }) 68 })
diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts
index f82c8cbce..7d5e3914b 100644
--- a/server/tests/api/videos/video-playlists.ts
+++ b/server/tests/api/videos/video-playlists.ts
@@ -5,6 +5,7 @@ import 'mocha'
5import { 5import {
6 addVideoChannel, 6 addVideoChannel,
7 addVideoInPlaylist, 7 addVideoInPlaylist,
8 addVideoToBlacklist,
8 checkPlaylistFilesWereRemoved, 9 checkPlaylistFilesWereRemoved,
9 cleanupTests, 10 cleanupTests,
10 createUser, 11 createUser,
@@ -14,6 +15,8 @@ import {
14 doubleFollow, 15 doubleFollow,
15 doVideosExistInMyPlaylist, 16 doVideosExistInMyPlaylist,
16 flushAndRunMultipleServers, 17 flushAndRunMultipleServers,
18 generateUserAccessToken,
19 getAccessToken,
17 getAccountPlaylistsList, 20 getAccountPlaylistsList,
18 getAccountPlaylistsListWithToken, 21 getAccountPlaylistsListWithToken,
19 getMyUserInformation, 22 getMyUserInformation,
@@ -24,6 +27,7 @@ import {
24 getVideoPlaylistsList, 27 getVideoPlaylistsList,
25 getVideoPlaylistWithToken, 28 getVideoPlaylistWithToken,
26 removeUser, 29 removeUser,
30 removeVideoFromBlacklist,
27 removeVideoFromPlaylist, 31 removeVideoFromPlaylist,
28 reorderVideosPlaylist, 32 reorderVideosPlaylist,
29 ServerInfo, 33 ServerInfo,
@@ -31,23 +35,58 @@ import {
31 setDefaultVideoChannel, 35 setDefaultVideoChannel,
32 testImage, 36 testImage,
33 unfollow, 37 unfollow,
38 updateVideo,
34 updateVideoPlaylist, 39 updateVideoPlaylist,
35 updateVideoPlaylistElement, 40 updateVideoPlaylistElement,
36 uploadVideo, 41 uploadVideo,
37 uploadVideoAndGetId, 42 uploadVideoAndGetId,
38 userLogin, 43 userLogin,
39 waitJobs, 44 waitJobs
40 generateUserAccessToken
41} from '../../../../shared/extra-utils' 45} from '../../../../shared/extra-utils'
42import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model' 46import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/video-playlist-privacy.model'
43import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model' 47import { VideoPlaylist } from '../../../../shared/models/videos/playlist/video-playlist.model'
44import { Video } from '../../../../shared/models/videos' 48import { VideoPrivacy } from '../../../../shared/models/videos'
45import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model' 49import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model'
46import { VideoExistInPlaylist } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model' 50import { VideoExistInPlaylist } from '../../../../shared/models/videos/playlist/video-exist-in-playlist.model'
47import { User } from '../../../../shared/models/users' 51import { User } from '../../../../shared/models/users'
52import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../../shared/models/videos/playlist/video-playlist-element.model'
53import {
54 addAccountToAccountBlocklist,
55 addAccountToServerBlocklist,
56 addServerToAccountBlocklist,
57 addServerToServerBlocklist,
58 removeAccountFromAccountBlocklist,
59 removeAccountFromServerBlocklist,
60 removeServerFromAccountBlocklist,
61 removeServerFromServerBlocklist
62} from '../../../../shared/extra-utils/users/blocklist'
48 63
49const expect = chai.expect 64const expect = chai.expect
50 65
66async function checkPlaylistElementType (
67 servers: ServerInfo[],
68 playlistId: string,
69 type: VideoPlaylistElementType,
70 position: number,
71 name: string,
72 total: number
73) {
74 for (const server of servers) {
75 const res = await getPlaylistVideos(server.url, server.accessToken, playlistId, 0, 10)
76 expect(res.body.total).to.equal(total)
77
78 const videoElement: VideoPlaylistElement = res.body.data.find((e: VideoPlaylistElement) => e.position === position)
79 expect(videoElement.type).to.equal(type, 'On server ' + server.url)
80
81 if (type === VideoPlaylistElementType.REGULAR) {
82 expect(videoElement.video).to.not.be.null
83 expect(videoElement.video.name).to.equal(name)
84 } else {
85 expect(videoElement.video).to.be.null
86 }
87 }
88}
89
51describe('Test video playlists', function () { 90describe('Test video playlists', function () {
52 let servers: ServerInfo[] = [] 91 let servers: ServerInfo[] = []
53 92
@@ -57,9 +96,16 @@ describe('Test video playlists', function () {
57 96
58 let playlistServer1Id: number 97 let playlistServer1Id: number
59 let playlistServer1UUID: string 98 let playlistServer1UUID: string
99 let playlistServer1UUID2: string
100
101 let playlistElementServer1Video4: number
102 let playlistElementServer1Video5: number
103 let playlistElementNSFW: number
60 104
61 let nsfwVideoServer1: number 105 let nsfwVideoServer1: number
62 106
107 let userAccessTokenServer1: string
108
63 before(async function () { 109 before(async function () {
64 this.timeout(120000) 110 this.timeout(120000)
65 111
@@ -97,814 +143,1039 @@ describe('Test video playlists', function () {
97 143
98 nsfwVideoServer1 = (await uploadVideoAndGetId({ server: servers[ 0 ], videoName: 'NSFW video', nsfw: true })).id 144 nsfwVideoServer1 = (await uploadVideoAndGetId({ server: servers[ 0 ], videoName: 'NSFW video', nsfw: true })).id
99 145
146 {
147 await createUser({
148 url: servers[ 0 ].url,
149 accessToken: servers[ 0 ].accessToken,
150 username: 'user1',
151 password: 'password'
152 })
153 userAccessTokenServer1 = await getAccessToken(servers[0].url, 'user1', 'password')
154 }
155
100 await waitJobs(servers) 156 await waitJobs(servers)
101 }) 157 })
102 158
103 it('Should list video playlist privacies', async function () { 159 describe('Get default playlists', function () {
104 const res = await getVideoPlaylistPrivacies(servers[0].url) 160 it('Should list video playlist privacies', async function () {
161 const res = await getVideoPlaylistPrivacies(servers[ 0 ].url)
105 162
106 const privacies = res.body 163 const privacies = res.body
107 expect(Object.keys(privacies)).to.have.length.at.least(3) 164 expect(Object.keys(privacies)).to.have.length.at.least(3)
108 165
109 expect(privacies[3]).to.equal('Private') 166 expect(privacies[ 3 ]).to.equal('Private')
110 }) 167 })
111 168
112 it('Should list watch later playlist', async function () { 169 it('Should list watch later playlist', async function () {
113 const url = servers[ 0 ].url 170 const url = servers[ 0 ].url
114 const accessToken = servers[ 0 ].accessToken 171 const accessToken = servers[ 0 ].accessToken
115 172
116 { 173 {
117 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER) 174 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.WATCH_LATER)
175
176 expect(res.body.total).to.equal(1)
177 expect(res.body.data).to.have.lengthOf(1)
178
179 const playlist: VideoPlaylist = res.body.data[ 0 ]
180 expect(playlist.displayName).to.equal('Watch later')
181 expect(playlist.type.id).to.equal(VideoPlaylistType.WATCH_LATER)
182 expect(playlist.type.label).to.equal('Watch later')
183 }
184
185 {
186 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.REGULAR)
187
188 expect(res.body.total).to.equal(0)
189 expect(res.body.data).to.have.lengthOf(0)
190 }
191
192 {
193 const res = await getAccountPlaylistsList(url, 'root', 0, 5)
194 expect(res.body.total).to.equal(0)
195 expect(res.body.data).to.have.lengthOf(0)
196 }
197 })
198
199 it('Should get private playlist for a classic user', async function () {
200 const token = await generateUserAccessToken(servers[ 0 ], 'toto')
201
202 const res = await getAccountPlaylistsListWithToken(servers[ 0 ].url, token, 'toto', 0, 5)
118 203
119 expect(res.body.total).to.equal(1) 204 expect(res.body.total).to.equal(1)
120 expect(res.body.data).to.have.lengthOf(1) 205 expect(res.body.data).to.have.lengthOf(1)
121 206
122 const playlist: VideoPlaylist = res.body.data[ 0 ] 207 const playlistId = res.body.data[ 0 ].id
123 expect(playlist.displayName).to.equal('Watch later') 208 await getPlaylistVideos(servers[ 0 ].url, token, playlistId, 0, 5)
124 expect(playlist.type.id).to.equal(VideoPlaylistType.WATCH_LATER) 209 })
125 expect(playlist.type.label).to.equal('Watch later') 210 })
126 }
127 211
128 { 212 describe('Create and federate playlists', function () {
129 const res = await getAccountPlaylistsListWithToken(url, accessToken, 'root', 0, 5, VideoPlaylistType.REGULAR)
130 213
131 expect(res.body.total).to.equal(0) 214 it('Should create a playlist on server 1 and have the playlist on server 2 and 3', async function () {
132 expect(res.body.data).to.have.lengthOf(0) 215 this.timeout(30000)
133 }
134 216
135 { 217 await createVideoPlaylist({
136 const res = await getAccountPlaylistsList(url, 'root', 0, 5) 218 url: servers[ 0 ].url,
137 expect(res.body.total).to.equal(0) 219 token: servers[ 0 ].accessToken,
138 expect(res.body.data).to.have.lengthOf(0) 220 playlistAttrs: {
139 } 221 displayName: 'my super playlist',
140 }) 222 privacy: VideoPlaylistPrivacy.PUBLIC,
223 description: 'my super description',
224 thumbnailfile: 'thumbnail.jpg',
225 videoChannelId: servers[ 0 ].videoChannel.id
226 }
227 })
228
229 await waitJobs(servers)
230
231 for (const server of servers) {
232 const res = await getVideoPlaylistsList(server.url, 0, 5)
233 expect(res.body.total).to.equal(1)
234 expect(res.body.data).to.have.lengthOf(1)
235
236 const playlistFromList = res.body.data[ 0 ] as VideoPlaylist
237
238 const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid)
239 const playlistFromGet = res2.body
240
241 for (const playlist of [ playlistFromGet, playlistFromList ]) {
242 expect(playlist.id).to.be.a('number')
243 expect(playlist.uuid).to.be.a('string')
244
245 expect(playlist.isLocal).to.equal(server.serverNumber === 1)
246
247 expect(playlist.displayName).to.equal('my super playlist')
248 expect(playlist.description).to.equal('my super description')
249 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC)
250 expect(playlist.privacy.label).to.equal('Public')
251 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
252 expect(playlist.type.label).to.equal('Regular')
253
254 expect(playlist.videosLength).to.equal(0)
141 255
142 it('Should get private playlist for a classic user', async function () { 256 expect(playlist.ownerAccount.name).to.equal('root')
143 const token = await generateUserAccessToken(servers[0], 'toto') 257 expect(playlist.ownerAccount.displayName).to.equal('root')
258 expect(playlist.videoChannel.name).to.equal('root_channel')
259 expect(playlist.videoChannel.displayName).to.equal('Main root channel')
260 }
261 }
262 })
144 263
145 const res = await getAccountPlaylistsListWithToken(servers[0].url, token, 'toto', 0, 5) 264 it('Should create a playlist on server 2 and have the playlist on server 1 but not on server 3', async function () {
265 this.timeout(30000)
266
267 {
268 const res = await createVideoPlaylist({
269 url: servers[ 1 ].url,
270 token: servers[ 1 ].accessToken,
271 playlistAttrs: {
272 displayName: 'playlist 2',
273 privacy: VideoPlaylistPrivacy.PUBLIC,
274 videoChannelId: servers[ 1 ].videoChannel.id
275 }
276 })
277 playlistServer2Id1 = res.body.videoPlaylist.id
278 }
146 279
147 expect(res.body.total).to.equal(1) 280 {
148 expect(res.body.data).to.have.lengthOf(1) 281 const res = await createVideoPlaylist({
282 url: servers[ 1 ].url,
283 token: servers[ 1 ].accessToken,
284 playlistAttrs: {
285 displayName: 'playlist 3',
286 privacy: VideoPlaylistPrivacy.PUBLIC,
287 thumbnailfile: 'thumbnail.jpg',
288 videoChannelId: servers[ 1 ].videoChannel.id
289 }
290 })
291
292 playlistServer2Id2 = res.body.videoPlaylist.id
293 playlistServer2UUID2 = res.body.videoPlaylist.uuid
294 }
295
296 for (let id of [ playlistServer2Id1, playlistServer2Id2 ]) {
297 await addVideoInPlaylist({
298 url: servers[ 1 ].url,
299 token: servers[ 1 ].accessToken,
300 playlistId: id,
301 elementAttrs: { videoId: servers[ 1 ].videos[ 0 ].id, startTimestamp: 1, stopTimestamp: 2 }
302 })
303 await addVideoInPlaylist({
304 url: servers[ 1 ].url,
305 token: servers[ 1 ].accessToken,
306 playlistId: id,
307 elementAttrs: { videoId: servers[ 1 ].videos[ 1 ].id }
308 })
309 }
310
311 await waitJobs(servers)
312
313 for (const server of [ servers[ 0 ], servers[ 1 ] ]) {
314 const res = await getVideoPlaylistsList(server.url, 0, 5)
315
316 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
317 expect(playlist2).to.not.be.undefined
318 await testImage(server.url, 'thumbnail-playlist', playlist2.thumbnailPath)
319
320 const playlist3 = res.body.data.find(p => p.displayName === 'playlist 3')
321 expect(playlist3).to.not.be.undefined
322 await testImage(server.url, 'thumbnail', playlist3.thumbnailPath)
323 }
149 324
150 const playlistId = res.body.data[0].id 325 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5)
151 await getPlaylistVideos(servers[0].url, token, playlistId, 0, 5) 326 expect(res.body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined
327 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined
328 })
329
330 it('Should have the playlist on server 3 after a new follow', async function () {
331 this.timeout(30000)
332
333 // Server 2 and server 3 follow each other
334 await doubleFollow(servers[ 1 ], servers[ 2 ])
335
336 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5)
337
338 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2')
339 expect(playlist2).to.not.be.undefined
340 await testImage(servers[ 2 ].url, 'thumbnail-playlist', playlist2.thumbnailPath)
341
342 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined
343 })
152 }) 344 })
153 345
154 it('Should create a playlist on server 1 and have the playlist on server 2 and 3', async function () { 346 describe('List playlists', function () {
155 this.timeout(30000) 347 it('Should correctly list the playlists', async function () {
348 this.timeout(30000)
349
350 {
351 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, 'createdAt')
156 352
157 await createVideoPlaylist({ 353 expect(res.body.total).to.equal(3)
158 url: servers[0].url, 354
159 token: servers[0].accessToken, 355 const data: VideoPlaylist[] = res.body.data
160 playlistAttrs: { 356 expect(data).to.have.lengthOf(2)
161 displayName: 'my super playlist', 357 expect(data[ 0 ].displayName).to.equal('playlist 2')
162 privacy: VideoPlaylistPrivacy.PUBLIC, 358 expect(data[ 1 ].displayName).to.equal('playlist 3')
163 description: 'my super description', 359 }
164 thumbnailfile: 'thumbnail.jpg', 360
165 videoChannelId: servers[0].videoChannel.id 361 {
362 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, '-createdAt')
363
364 expect(res.body.total).to.equal(3)
365
366 const data: VideoPlaylist[] = res.body.data
367 expect(data).to.have.lengthOf(2)
368 expect(data[ 0 ].displayName).to.equal('playlist 2')
369 expect(data[ 1 ].displayName).to.equal('my super playlist')
166 } 370 }
167 }) 371 })
168 372
169 await waitJobs(servers) 373 it('Should list video channel playlists', async function () {
374 this.timeout(30000)
170 375
171 for (const server of servers) { 376 {
172 const res = await getVideoPlaylistsList(server.url, 0, 5) 377 const res = await getVideoChannelPlaylistsList(servers[ 0 ].url, 'root_channel', 0, 2, '-createdAt')
173 expect(res.body.total).to.equal(1)
174 expect(res.body.data).to.have.lengthOf(1)
175 378
176 const playlistFromList = res.body.data[0] as VideoPlaylist 379 expect(res.body.total).to.equal(1)
177 380
178 const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid) 381 const data: VideoPlaylist[] = res.body.data
179 const playlistFromGet = res2.body 382 expect(data).to.have.lengthOf(1)
383 expect(data[ 0 ].displayName).to.equal('my super playlist')
384 }
385 })
180 386
181 for (const playlist of [ playlistFromGet, playlistFromList ]) { 387 it('Should list account playlists', async function () {
182 expect(playlist.id).to.be.a('number') 388 this.timeout(30000)
183 expect(playlist.uuid).to.be.a('string')
184 389
185 expect(playlist.isLocal).to.equal(server.serverNumber === 1) 390 {
391 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, '-createdAt')
186 392
187 expect(playlist.displayName).to.equal('my super playlist') 393 expect(res.body.total).to.equal(2)
188 expect(playlist.description).to.equal('my super description') 394
189 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.PUBLIC) 395 const data: VideoPlaylist[] = res.body.data
190 expect(playlist.privacy.label).to.equal('Public') 396 expect(data).to.have.lengthOf(1)
191 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR) 397 expect(data[ 0 ].displayName).to.equal('playlist 2')
192 expect(playlist.type.label).to.equal('Regular') 398 }
193 399
194 expect(playlist.videosLength).to.equal(0) 400 {
401 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, 'createdAt')
195 402
196 expect(playlist.ownerAccount.name).to.equal('root') 403 expect(res.body.total).to.equal(2)
197 expect(playlist.ownerAccount.displayName).to.equal('root') 404
198 expect(playlist.videoChannel.name).to.equal('root_channel') 405 const data: VideoPlaylist[] = res.body.data
199 expect(playlist.videoChannel.displayName).to.equal('Main root channel') 406 expect(data).to.have.lengthOf(1)
407 expect(data[ 0 ].displayName).to.equal('playlist 3')
200 } 408 }
201 } 409 })
202 })
203 410
204 it('Should create a playlist on server 2 and have the playlist on server 1 but not on server 3', async function () { 411 it('Should not list unlisted or private playlists', async function () {
205 this.timeout(30000) 412 this.timeout(30000)
206 413
207 { 414 await createVideoPlaylist({
208 const res = await createVideoPlaylist({ 415 url: servers[ 1 ].url,
209 url: servers[1].url, 416 token: servers[ 1 ].accessToken,
210 token: servers[1].accessToken,
211 playlistAttrs: { 417 playlistAttrs: {
212 displayName: 'playlist 2', 418 displayName: 'playlist unlisted',
213 privacy: VideoPlaylistPrivacy.PUBLIC, 419 privacy: VideoPlaylistPrivacy.UNLISTED
214 videoChannelId: servers[1].videoChannel.id
215 } 420 }
216 }) 421 })
217 playlistServer2Id1 = res.body.videoPlaylist.id
218 }
219 422
220 { 423 await createVideoPlaylist({
221 const res = await createVideoPlaylist({
222 url: servers[ 1 ].url, 424 url: servers[ 1 ].url,
223 token: servers[ 1 ].accessToken, 425 token: servers[ 1 ].accessToken,
224 playlistAttrs: { 426 playlistAttrs: {
225 displayName: 'playlist 3', 427 displayName: 'playlist private',
226 privacy: VideoPlaylistPrivacy.PUBLIC, 428 privacy: VideoPlaylistPrivacy.PRIVATE
227 thumbnailfile: 'thumbnail.jpg',
228 videoChannelId: servers[1].videoChannel.id
229 } 429 }
230 }) 430 })
231 431
232 playlistServer2Id2 = res.body.videoPlaylist.id 432 await waitJobs(servers)
233 playlistServer2UUID2 = res.body.videoPlaylist.uuid
234 }
235 433
236 for (let id of [ playlistServer2Id1, playlistServer2Id2 ]) { 434 for (const server of servers) {
237 await addVideoInPlaylist({ 435 const results = [
238 url: servers[ 1 ].url, 436 await getAccountPlaylistsList(server.url, 'root@localhost:' + servers[ 1 ].port, 0, 5, '-createdAt'),
239 token: servers[ 1 ].accessToken, 437 await getVideoPlaylistsList(server.url, 0, 2, '-createdAt')
240 playlistId: id, 438 ]
241 elementAttrs: { videoId: servers[ 1 ].videos[ 0 ].id, startTimestamp: 1, stopTimestamp: 2 } 439
242 }) 440 expect(results[ 0 ].body.total).to.equal(2)
243 await addVideoInPlaylist({ 441 expect(results[ 1 ].body.total).to.equal(3)
244 url: servers[ 1 ].url, 442
245 token: servers[ 1 ].accessToken, 443 for (const res of results) {
246 playlistId: id, 444 const data: VideoPlaylist[] = res.body.data
247 elementAttrs: { videoId: servers[ 1 ].videos[ 1 ].id } 445 expect(data).to.have.lengthOf(2)
248 }) 446 expect(data[ 0 ].displayName).to.equal('playlist 3')
249 } 447 expect(data[ 1 ].displayName).to.equal('playlist 2')
448 }
449 }
450 })
451 })
250 452
251 await waitJobs(servers) 453 describe('Update playlists', function () {
252 454
253 for (const server of [ servers[0], servers[1] ]) { 455 it('Should update a playlist', async function () {
254 const res = await getVideoPlaylistsList(server.url, 0, 5) 456 this.timeout(30000)
255 457
256 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2') 458 await updateVideoPlaylist({
257 expect(playlist2).to.not.be.undefined 459 url: servers[1].url,
258 await testImage(server.url, 'thumbnail-playlist', playlist2.thumbnailPath) 460 token: servers[1].accessToken,
461 playlistAttrs: {
462 displayName: 'playlist 3 updated',
463 description: 'description updated',
464 privacy: VideoPlaylistPrivacy.UNLISTED,
465 thumbnailfile: 'thumbnail.jpg',
466 videoChannelId: servers[1].videoChannel.id
467 },
468 playlistId: playlistServer2Id2
469 })
259 470
260 const playlist3 = res.body.data.find(p => p.displayName === 'playlist 3') 471 await waitJobs(servers)
261 expect(playlist3).to.not.be.undefined
262 await testImage(server.url, 'thumbnail', playlist3.thumbnailPath)
263 }
264 472
265 const res = await getVideoPlaylistsList(servers[2].url, 0, 5) 473 for (const server of servers) {
266 expect(res.body.data.find(p => p.displayName === 'playlist 2')).to.be.undefined 474 const res = await getVideoPlaylist(server.url, playlistServer2UUID2)
267 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.be.undefined 475 const playlist: VideoPlaylist = res.body
268 })
269 476
270 it('Should have the playlist on server 3 after a new follow', async function () { 477 expect(playlist.displayName).to.equal('playlist 3 updated')
271 this.timeout(30000) 478 expect(playlist.description).to.equal('description updated')
272 479
273 // Server 2 and server 3 follow each other 480 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.UNLISTED)
274 await doubleFollow(servers[1], servers[2]) 481 expect(playlist.privacy.label).to.equal('Unlisted')
275 482
276 const res = await getVideoPlaylistsList(servers[2].url, 0, 5) 483 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
484 expect(playlist.type.label).to.equal('Regular')
277 485
278 const playlist2 = res.body.data.find(p => p.displayName === 'playlist 2') 486 expect(playlist.videosLength).to.equal(2)
279 expect(playlist2).to.not.be.undefined
280 await testImage(servers[2].url, 'thumbnail-playlist', playlist2.thumbnailPath)
281 487
282 expect(res.body.data.find(p => p.displayName === 'playlist 3')).to.not.be.undefined 488 expect(playlist.ownerAccount.name).to.equal('root')
489 expect(playlist.ownerAccount.displayName).to.equal('root')
490 expect(playlist.videoChannel.name).to.equal('root_channel')
491 expect(playlist.videoChannel.displayName).to.equal('Main root channel')
492 }
493 })
283 }) 494 })
284 495
285 it('Should correctly list the playlists', async function () { 496 describe('Element timestamps', function () {
286 this.timeout(30000)
287 497
288 { 498 it('Should create a playlist containing different startTimestamp/endTimestamp videos', async function () {
289 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, 'createdAt') 499 this.timeout(30000)
290 500
291 expect(res.body.total).to.equal(3) 501 const addVideo = (elementAttrs: any) => {
502 return addVideoInPlaylist({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, playlistId: playlistServer1Id, elementAttrs })
503 }
292 504
293 const data: VideoPlaylist[] = res.body.data 505 const res = await createVideoPlaylist({
294 expect(data).to.have.lengthOf(2) 506 url: servers[ 0 ].url,
295 expect(data[ 0 ].displayName).to.equal('playlist 2') 507 token: servers[ 0 ].accessToken,
296 expect(data[ 1 ].displayName).to.equal('playlist 3') 508 playlistAttrs: {
297 } 509 displayName: 'playlist 4',
510 privacy: VideoPlaylistPrivacy.PUBLIC,
511 videoChannelId: servers[ 0 ].videoChannel.id
512 }
513 })
298 514
299 { 515 playlistServer1Id = res.body.videoPlaylist.id
300 const res = await getVideoPlaylistsList(servers[ 2 ].url, 1, 2, '-createdAt') 516 playlistServer1UUID = res.body.videoPlaylist.uuid
301 517
302 expect(res.body.total).to.equal(3) 518 await addVideo({ videoId: servers[ 0 ].videos[ 0 ].uuid, startTimestamp: 15, stopTimestamp: 28 })
519 await addVideo({ videoId: servers[ 2 ].videos[ 1 ].uuid, startTimestamp: 35 })
520 await addVideo({ videoId: servers[ 2 ].videos[ 2 ].uuid })
521 {
522 const res = await addVideo({ videoId: servers[ 0 ].videos[ 3 ].uuid, stopTimestamp: 35 })
523 playlistElementServer1Video4 = res.body.videoPlaylistElement.id
524 }
303 525
304 const data: VideoPlaylist[] = res.body.data 526 {
305 expect(data).to.have.lengthOf(2) 527 const res = await addVideo({ videoId: servers[ 0 ].videos[ 4 ].uuid, startTimestamp: 45, stopTimestamp: 60 })
306 expect(data[ 0 ].displayName).to.equal('playlist 2') 528 playlistElementServer1Video5 = res.body.videoPlaylistElement.id
307 expect(data[ 1 ].displayName).to.equal('my super playlist') 529 }
308 }
309 })
310 530
311 it('Should list video channel playlists', async function () { 531 {
312 this.timeout(30000) 532 const res = await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 5 })
533 playlistElementNSFW = res.body.videoPlaylistElement.id
534 }
313 535
314 { 536 await waitJobs(servers)
315 const res = await getVideoChannelPlaylistsList(servers[ 0 ].url, 'root_channel', 0, 2, '-createdAt') 537 })
316 538
317 expect(res.body.total).to.equal(1) 539 it('Should correctly list playlist videos', async function () {
540 this.timeout(30000)
318 541
319 const data: VideoPlaylist[] = res.body.data 542 for (const server of servers) {
320 expect(data).to.have.lengthOf(1) 543 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
321 expect(data[ 0 ].displayName).to.equal('my super playlist')
322 }
323 })
324 544
325 it('Should list account playlists', async function () { 545 expect(res.body.total).to.equal(6)
326 this.timeout(30000)
327 546
328 { 547 const videoElements: VideoPlaylistElement[] = res.body.data
329 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, '-createdAt') 548 expect(videoElements).to.have.lengthOf(6)
330 549
331 expect(res.body.total).to.equal(2) 550 expect(videoElements[ 0 ].video.name).to.equal('video 0 server 1')
551 expect(videoElements[ 0 ].position).to.equal(1)
552 expect(videoElements[ 0 ].startTimestamp).to.equal(15)
553 expect(videoElements[ 0 ].stopTimestamp).to.equal(28)
332 554
333 const data: VideoPlaylist[] = res.body.data 555 expect(videoElements[ 1 ].video.name).to.equal('video 1 server 3')
334 expect(data).to.have.lengthOf(1) 556 expect(videoElements[ 1 ].position).to.equal(2)
335 expect(data[ 0 ].displayName).to.equal('playlist 2') 557 expect(videoElements[ 1 ].startTimestamp).to.equal(35)
336 } 558 expect(videoElements[ 1 ].stopTimestamp).to.be.null
337 559
338 { 560 expect(videoElements[ 2 ].video.name).to.equal('video 2 server 3')
339 const res = await getAccountPlaylistsList(servers[ 1 ].url, 'root', 1, 2, 'createdAt') 561 expect(videoElements[ 2 ].position).to.equal(3)
562 expect(videoElements[ 2 ].startTimestamp).to.be.null
563 expect(videoElements[ 2 ].stopTimestamp).to.be.null
340 564
341 expect(res.body.total).to.equal(2) 565 expect(videoElements[ 3 ].video.name).to.equal('video 3 server 1')
566 expect(videoElements[ 3 ].position).to.equal(4)
567 expect(videoElements[ 3 ].startTimestamp).to.be.null
568 expect(videoElements[ 3 ].stopTimestamp).to.equal(35)
342 569
343 const data: VideoPlaylist[] = res.body.data 570 expect(videoElements[ 4 ].video.name).to.equal('video 4 server 1')
344 expect(data).to.have.lengthOf(1) 571 expect(videoElements[ 4 ].position).to.equal(5)
345 expect(data[ 0 ].displayName).to.equal('playlist 3') 572 expect(videoElements[ 4 ].startTimestamp).to.equal(45)
346 } 573 expect(videoElements[ 4 ].stopTimestamp).to.equal(60)
347 })
348 574
349 it('Should not list unlisted or private playlists', async function () { 575 expect(videoElements[ 5 ].video.name).to.equal('NSFW video')
350 this.timeout(30000) 576 expect(videoElements[ 5 ].position).to.equal(6)
577 expect(videoElements[ 5 ].startTimestamp).to.equal(5)
578 expect(videoElements[ 5 ].stopTimestamp).to.be.null
351 579
352 await createVideoPlaylist({ 580 const res3 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 2)
353 url: servers[ 1 ].url, 581 expect(res3.body.data).to.have.lengthOf(2)
354 token: servers[ 1 ].accessToken,
355 playlistAttrs: {
356 displayName: 'playlist unlisted',
357 privacy: VideoPlaylistPrivacy.UNLISTED
358 } 582 }
359 }) 583 })
584 })
360 585
361 await createVideoPlaylist({ 586 describe('Element type', function () {
362 url: servers[ 1 ].url, 587 let groupUser1: ServerInfo[]
363 token: servers[ 1 ].accessToken, 588 let groupWithoutToken1: ServerInfo[]
364 playlistAttrs: { 589 let group1: ServerInfo[]
365 displayName: 'playlist private', 590 let group2: ServerInfo[]
366 privacy: VideoPlaylistPrivacy.PRIVATE
367 }
368 })
369 591
370 await waitJobs(servers) 592 let video1: string
593 let video2: string
594 let video3: string
371 595
372 for (const server of servers) { 596 before(async function () {
373 const results = [ 597 this.timeout(30000)
374 await getAccountPlaylistsList(server.url, 'root@localhost:' + servers[1].port, 0, 5, '-createdAt'),
375 await getVideoPlaylistsList(server.url, 0, 2, '-createdAt')
376 ]
377 598
378 expect(results[0].body.total).to.equal(2) 599 groupUser1 = [ Object.assign({}, servers[ 0 ], { accessToken: userAccessTokenServer1 }) ]
379 expect(results[1].body.total).to.equal(3) 600 groupWithoutToken1 = [ Object.assign({}, servers[ 0 ], { accessToken: undefined }) ]
601 group1 = [ servers[ 0 ] ]
602 group2 = [ servers[ 1 ], servers[ 2 ] ]
380 603
381 for (const res of results) { 604 const res = await createVideoPlaylist({
382 const data: VideoPlaylist[] = res.body.data 605 url: servers[ 0 ].url,
383 expect(data).to.have.lengthOf(2) 606 token: userAccessTokenServer1,
384 expect(data[ 0 ].displayName).to.equal('playlist 3') 607 playlistAttrs: {
385 expect(data[ 1 ].displayName).to.equal('playlist 2') 608 displayName: 'playlist 56',
386 } 609 privacy: VideoPlaylistPrivacy.PUBLIC,
387 } 610 videoChannelId: servers[ 0 ].videoChannel.id
388 }) 611 }
612 })
389 613
390 it('Should update a playlist', async function () { 614 const playlistServer1Id2 = res.body.videoPlaylist.id
391 this.timeout(30000) 615 playlistServer1UUID2 = res.body.videoPlaylist.uuid
392
393 await updateVideoPlaylist({
394 url: servers[1].url,
395 token: servers[1].accessToken,
396 playlistAttrs: {
397 displayName: 'playlist 3 updated',
398 description: 'description updated',
399 privacy: VideoPlaylistPrivacy.UNLISTED,
400 thumbnailfile: 'thumbnail.jpg',
401 videoChannelId: servers[1].videoChannel.id
402 },
403 playlistId: playlistServer2Id2
404 })
405 616
406 await waitJobs(servers) 617 const addVideo = (elementAttrs: any) => {
618 return addVideoInPlaylist({ url: servers[ 0 ].url, token: userAccessTokenServer1, playlistId: playlistServer1Id2, elementAttrs })
619 }
407 620
408 for (const server of servers) { 621 video1 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 89', token: userAccessTokenServer1 })).uuid
409 const res = await getVideoPlaylist(server.url, playlistServer2UUID2) 622 video2 = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 90' })).uuid
410 const playlist: VideoPlaylist = res.body 623 video3 = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video 91', nsfw: true })).uuid
411 624
412 expect(playlist.displayName).to.equal('playlist 3 updated') 625 await addVideo({ videoId: video1, startTimestamp: 15, stopTimestamp: 28 })
413 expect(playlist.description).to.equal('description updated') 626 await addVideo({ videoId: video2, startTimestamp: 35 })
627 await addVideo({ videoId: video3 })
414 628
415 expect(playlist.privacy.id).to.equal(VideoPlaylistPrivacy.UNLISTED) 629 await waitJobs(servers)
416 expect(playlist.privacy.label).to.equal('Unlisted') 630 })
417 631
418 expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR) 632 it('Should update the element type if the video is private', async function () {
419 expect(playlist.type.label).to.equal('Regular') 633 this.timeout(20000)
420 634
421 expect(playlist.videosLength).to.equal(2) 635 const name = 'video 89'
636 const position = 1
422 637
423 expect(playlist.ownerAccount.name).to.equal('root') 638 {
424 expect(playlist.ownerAccount.displayName).to.equal('root') 639 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video1, { privacy: VideoPrivacy.PRIVATE })
425 expect(playlist.videoChannel.name).to.equal('root_channel') 640 await waitJobs(servers)
426 expect(playlist.videoChannel.displayName).to.equal('Main root channel')
427 }
428 })
429 641
430 it('Should create a playlist containing different startTimestamp/endTimestamp videos', async function () { 642 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
431 this.timeout(30000) 643 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.PRIVATE, position, name, 3)
644 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.PRIVATE, position, name, 3)
645 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
646 }
432 647
433 const addVideo = (elementAttrs: any) => { 648 {
434 return addVideoInPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: playlistServer1Id, elementAttrs }) 649 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video1, { privacy: VideoPrivacy.PUBLIC })
435 } 650 await waitJobs(servers)
436 651
437 const res = await createVideoPlaylist({ 652 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
438 url: servers[ 0 ].url, 653 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
439 token: servers[ 0 ].accessToken, 654 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
440 playlistAttrs: { 655 // We deleted the video, so even if we recreated it, the old entry is still deleted
441 displayName: 'playlist 4', 656 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
442 privacy: VideoPlaylistPrivacy.PUBLIC,
443 videoChannelId: servers[0].videoChannel.id
444 } 657 }
445 }) 658 })
446 659
447 playlistServer1Id = res.body.videoPlaylist.id 660 it('Should update the element type if the video is blacklisted', async function () {
448 playlistServer1UUID = res.body.videoPlaylist.uuid 661 this.timeout(20000)
449 662
450 await addVideo({ videoId: servers[0].videos[0].uuid, startTimestamp: 15, stopTimestamp: 28 }) 663 const name = 'video 89'
451 await addVideo({ videoId: servers[2].videos[1].uuid, startTimestamp: 35 }) 664 const position = 1
452 await addVideo({ videoId: servers[2].videos[2].uuid })
453 await addVideo({ videoId: servers[0].videos[3].uuid, stopTimestamp: 35 })
454 await addVideo({ videoId: servers[0].videos[4].uuid, startTimestamp: 45, stopTimestamp: 60 })
455 await addVideo({ videoId: nsfwVideoServer1, startTimestamp: 5 })
456 665
457 await waitJobs(servers) 666 {
458 }) 667 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video1, 'reason', true)
668 await waitJobs(servers)
459 669
460 it('Should correctly list playlist videos', async function () { 670 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
461 this.timeout(30000) 671 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
672 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
673 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
674 }
462 675
463 for (const server of servers) { 676 {
464 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) 677 await removeVideoFromBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video1)
678 await waitJobs(servers)
465 679
466 expect(res.body.total).to.equal(6) 680 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
681 await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
682 await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
683 // We deleted the video (because unfederated), so even if we recreated it, the old entry is still deleted
684 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
685 }
686 })
467 687
468 const videos: Video[] = res.body.data 688 it('Should update the element type if the account or server of the video is blocked', async function () {
469 expect(videos).to.have.lengthOf(6) 689 this.timeout(90000)
470 690
471 expect(videos[0].name).to.equal('video 0 server 1') 691 const name = 'video 90'
472 expect(videos[0].playlistElement.position).to.equal(1) 692 const position = 2
473 expect(videos[0].playlistElement.startTimestamp).to.equal(15)
474 expect(videos[0].playlistElement.stopTimestamp).to.equal(28)
475 693
476 expect(videos[1].name).to.equal('video 1 server 3') 694 {
477 expect(videos[1].playlistElement.position).to.equal(2) 695 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'root@localhost:' + servers[1].port)
478 expect(videos[1].playlistElement.startTimestamp).to.equal(35) 696 await waitJobs(servers)
479 expect(videos[1].playlistElement.stopTimestamp).to.be.null
480 697
481 expect(videos[2].name).to.equal('video 2 server 3') 698 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
482 expect(videos[2].playlistElement.position).to.equal(3) 699 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
483 expect(videos[2].playlistElement.startTimestamp).to.be.null
484 expect(videos[2].playlistElement.stopTimestamp).to.be.null
485 700
486 expect(videos[3].name).to.equal('video 3 server 1') 701 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'root@localhost:' + servers[1].port)
487 expect(videos[3].playlistElement.position).to.equal(4) 702 await waitJobs(servers)
488 expect(videos[3].playlistElement.startTimestamp).to.be.null
489 expect(videos[3].playlistElement.stopTimestamp).to.equal(35)
490 703
491 expect(videos[4].name).to.equal('video 4 server 1') 704 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
492 expect(videos[4].playlistElement.position).to.equal(5) 705 }
493 expect(videos[4].playlistElement.startTimestamp).to.equal(45)
494 expect(videos[4].playlistElement.stopTimestamp).to.equal(60)
495 706
496 expect(videos[5].name).to.equal('NSFW video') 707 {
497 expect(videos[5].playlistElement.position).to.equal(6) 708 await addServerToAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'localhost:' + servers[1].port)
498 expect(videos[5].playlistElement.startTimestamp).to.equal(5) 709 await waitJobs(servers)
499 expect(videos[5].playlistElement.stopTimestamp).to.be.null
500 710
501 const res2 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10, { nsfw: false }) 711 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
502 expect(res2.body.total).to.equal(5) 712 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
503 expect(res2.body.data.find(v => v.name === 'NSFW video')).to.be.undefined
504 713
505 const res3 = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 2) 714 await removeServerFromAccountBlocklist(servers[ 0 ].url, userAccessTokenServer1, 'localhost:' + servers[1].port)
506 expect(res3.body.data).to.have.lengthOf(2) 715 await waitJobs(servers)
507 }
508 })
509 716
510 it('Should reorder the playlist', async function () { 717 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
511 this.timeout(30000) 718 }
512 719
513 { 720 {
514 await reorderVideosPlaylist({ 721 await addAccountToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'root@localhost:' + servers[1].port)
515 url: servers[ 0 ].url, 722 await waitJobs(servers)
516 token: servers[ 0 ].accessToken,
517 playlistId: playlistServer1Id,
518 elementAttrs: {
519 startPosition: 2,
520 insertAfterPosition: 3
521 }
522 })
523 723
524 await waitJobs(servers) 724 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
725 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
525 726
526 for (const server of servers) { 727 await removeAccountFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'root@localhost:' + servers[1].port)
527 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) 728 await waitJobs(servers)
528 const names = res.body.data.map(v => v.name)
529 729
530 expect(names).to.deep.equal([ 730 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
531 'video 0 server 1',
532 'video 2 server 3',
533 'video 1 server 3',
534 'video 3 server 1',
535 'video 4 server 1',
536 'NSFW video'
537 ])
538 } 731 }
539 }
540 732
541 { 733 {
542 await reorderVideosPlaylist({ 734 await addServerToServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port)
543 url: servers[0].url, 735 await waitJobs(servers)
544 token: servers[0].accessToken,
545 playlistId: playlistServer1Id,
546 elementAttrs: {
547 startPosition: 1,
548 reorderLength: 3,
549 insertAfterPosition: 4
550 }
551 })
552 736
553 await waitJobs(servers) 737 await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
738 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
554 739
555 for (const server of servers) { 740 await removeServerFromServerBlocklist(servers[ 0 ].url, servers[ 0 ].accessToken, 'localhost:' + servers[1].port)
556 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) 741 await waitJobs(servers)
557 const names = res.body.data.map(v => v.name)
558 742
559 expect(names).to.deep.equal([ 743 await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
560 'video 3 server 1',
561 'video 0 server 1',
562 'video 2 server 3',
563 'video 1 server 3',
564 'video 4 server 1',
565 'NSFW video'
566 ])
567 } 744 }
568 } 745 })
569
570 {
571 await reorderVideosPlaylist({
572 url: servers[0].url,
573 token: servers[0].accessToken,
574 playlistId: playlistServer1Id,
575 elementAttrs: {
576 startPosition: 6,
577 insertAfterPosition: 3
578 }
579 })
580 746
581 await waitJobs(servers) 747 it('Should hide the video if it is NSFW', async function () {
748 const res = await getPlaylistVideos(servers[0].url, userAccessTokenServer1, playlistServer1UUID2, 0, 10, { nsfw: false })
749 expect(res.body.total).to.equal(3)
582 750
583 for (const server of servers) { 751 const elements: VideoPlaylistElement[] = res.body.data
584 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) 752 const element = elements.find(e => e.position === 3)
585 const videos: Video[] = res.body.data
586 753
587 const names = videos.map(v => v.name) 754 expect(element).to.exist
755 expect(element.video).to.be.null
756 expect(element.type).to.equal(VideoPlaylistElementType.UNAVAILABLE)
757 })
588 758
589 expect(names).to.deep.equal([ 759 })
590 'video 3 server 1',
591 'video 0 server 1',
592 'video 2 server 3',
593 'NSFW video',
594 'video 1 server 3',
595 'video 4 server 1'
596 ])
597 760
598 for (let i = 1; i <= videos.length; i++) { 761 describe('Managing playlist elements', function () {
599 expect(videos[i - 1].playlistElement.position).to.equal(i) 762
763 it('Should reorder the playlist', async function () {
764 this.timeout(30000)
765
766 {
767 await reorderVideosPlaylist({
768 url: servers[ 0 ].url,
769 token: servers[ 0 ].accessToken,
770 playlistId: playlistServer1Id,
771 elementAttrs: {
772 startPosition: 2,
773 insertAfterPosition: 3
774 }
775 })
776
777 await waitJobs(servers)
778
779 for (const server of servers) {
780 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
781 const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name)
782
783 expect(names).to.deep.equal([
784 'video 0 server 1',
785 'video 2 server 3',
786 'video 1 server 3',
787 'video 3 server 1',
788 'video 4 server 1',
789 'NSFW video'
790 ])
600 } 791 }
601 } 792 }
602 }
603 })
604
605 it('Should update startTimestamp/endTimestamp of some elements', async function () {
606 this.timeout(30000)
607 793
608 await updateVideoPlaylistElement({ 794 {
609 url: servers[0].url, 795 await reorderVideosPlaylist({
610 token: servers[0].accessToken, 796 url: servers[ 0 ].url,
611 playlistId: playlistServer1Id, 797 token: servers[ 0 ].accessToken,
612 videoId: servers[0].videos[3].uuid, 798 playlistId: playlistServer1Id,
613 elementAttrs: { 799 elementAttrs: {
614 startTimestamp: 1 800 startPosition: 1,
801 reorderLength: 3,
802 insertAfterPosition: 4
803 }
804 })
805
806 await waitJobs(servers)
807
808 for (const server of servers) {
809 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
810 const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name)
811
812 expect(names).to.deep.equal([
813 'video 3 server 1',
814 'video 0 server 1',
815 'video 2 server 3',
816 'video 1 server 3',
817 'video 4 server 1',
818 'NSFW video'
819 ])
820 }
615 } 821 }
616 })
617 822
618 await updateVideoPlaylistElement({ 823 {
619 url: servers[0].url, 824 await reorderVideosPlaylist({
620 token: servers[0].accessToken, 825 url: servers[ 0 ].url,
621 playlistId: playlistServer1Id, 826 token: servers[ 0 ].accessToken,
622 videoId: servers[0].videos[4].uuid, 827 playlistId: playlistServer1Id,
623 elementAttrs: { 828 elementAttrs: {
624 stopTimestamp: null 829 startPosition: 6,
830 insertAfterPosition: 3
831 }
832 })
833
834 await waitJobs(servers)
835
836 for (const server of servers) {
837 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
838 const elements: VideoPlaylistElement[] = res.body.data
839 const names = elements.map(v => v.video.name)
840
841 expect(names).to.deep.equal([
842 'video 3 server 1',
843 'video 0 server 1',
844 'video 2 server 3',
845 'NSFW video',
846 'video 1 server 3',
847 'video 4 server 1'
848 ])
849
850 for (let i = 1; i <= elements.length; i++) {
851 expect(elements[ i - 1 ].position).to.equal(i)
852 }
853 }
625 } 854 }
626 }) 855 })
627 856
628 await waitJobs(servers) 857 it('Should update startTimestamp/endTimestamp of some elements', async function () {
858 this.timeout(30000)
859
860 await updateVideoPlaylistElement({
861 url: servers[ 0 ].url,
862 token: servers[ 0 ].accessToken,
863 playlistId: playlistServer1Id,
864 playlistElementId: playlistElementServer1Video4,
865 elementAttrs: {
866 startTimestamp: 1
867 }
868 })
629 869
630 for (const server of servers) { 870 await updateVideoPlaylistElement({
631 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) 871 url: servers[ 0 ].url,
632 const videos: Video[] = res.body.data 872 token: servers[ 0 ].accessToken,
873 playlistId: playlistServer1Id,
874 playlistElementId: playlistElementServer1Video5,
875 elementAttrs: {
876 stopTimestamp: null
877 }
878 })
633 879
634 expect(videos[0].name).to.equal('video 3 server 1') 880 await waitJobs(servers)
635 expect(videos[0].playlistElement.position).to.equal(1)
636 expect(videos[0].playlistElement.startTimestamp).to.equal(1)
637 expect(videos[0].playlistElement.stopTimestamp).to.equal(35)
638 881
639 expect(videos[5].name).to.equal('video 4 server 1') 882 for (const server of servers) {
640 expect(videos[5].playlistElement.position).to.equal(6) 883 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
641 expect(videos[5].playlistElement.startTimestamp).to.equal(45) 884 const elements: VideoPlaylistElement[] = res.body.data
642 expect(videos[5].playlistElement.stopTimestamp).to.be.null
643 }
644 })
645 885
646 it('Should check videos existence in my playlist', async function () { 886 expect(elements[ 0 ].video.name).to.equal('video 3 server 1')
647 const videoIds = [ 887 expect(elements[ 0 ].position).to.equal(1)
648 servers[0].videos[0].id, 888 expect(elements[ 0 ].startTimestamp).to.equal(1)
649 42000, 889 expect(elements[ 0 ].stopTimestamp).to.equal(35)
650 servers[0].videos[3].id,
651 43000,
652 servers[0].videos[4].id
653 ]
654 const res = await doVideosExistInMyPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, videoIds)
655 const obj = res.body as VideoExistInPlaylist
656 890
657 { 891 expect(elements[ 5 ].video.name).to.equal('video 4 server 1')
658 const elem = obj[servers[0].videos[0].id] 892 expect(elements[ 5 ].position).to.equal(6)
659 expect(elem).to.have.lengthOf(1) 893 expect(elements[ 5 ].startTimestamp).to.equal(45)
660 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) 894 expect(elements[ 5 ].stopTimestamp).to.be.null
661 expect(elem[ 0 ].startTimestamp).to.equal(15) 895 }
662 expect(elem[ 0 ].stopTimestamp).to.equal(28) 896 })
663 }
664 897
665 { 898 it('Should check videos existence in my playlist', async function () {
666 const elem = obj[servers[0].videos[3].id] 899 const videoIds = [
667 expect(elem).to.have.lengthOf(1) 900 servers[ 0 ].videos[ 0 ].id,
668 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) 901 42000,
669 expect(elem[ 0 ].startTimestamp).to.equal(1) 902 servers[ 0 ].videos[ 3 ].id,
670 expect(elem[ 0 ].stopTimestamp).to.equal(35) 903 43000,
671 } 904 servers[ 0 ].videos[ 4 ].id
905 ]
906 const res = await doVideosExistInMyPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, videoIds)
907 const obj = res.body as VideoExistInPlaylist
908
909 {
910 const elem = obj[ servers[ 0 ].videos[ 0 ].id ]
911 expect(elem).to.have.lengthOf(1)
912 expect(elem[ 0 ].playlistElementId).to.exist
913 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
914 expect(elem[ 0 ].startTimestamp).to.equal(15)
915 expect(elem[ 0 ].stopTimestamp).to.equal(28)
916 }
672 917
673 { 918 {
674 const elem = obj[servers[0].videos[4].id] 919 const elem = obj[ servers[ 0 ].videos[ 3 ].id ]
675 expect(elem).to.have.lengthOf(1) 920 expect(elem).to.have.lengthOf(1)
676 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id) 921 expect(elem[ 0 ].playlistElementId).to.equal(playlistElementServer1Video4)
677 expect(elem[ 0 ].startTimestamp).to.equal(45) 922 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
678 expect(elem[ 0 ].stopTimestamp).to.equal(null) 923 expect(elem[ 0 ].startTimestamp).to.equal(1)
679 } 924 expect(elem[ 0 ].stopTimestamp).to.equal(35)
925 }
680 926
681 expect(obj[42000]).to.have.lengthOf(0) 927 {
682 expect(obj[43000]).to.have.lengthOf(0) 928 const elem = obj[ servers[ 0 ].videos[ 4 ].id ]
683 }) 929 expect(elem).to.have.lengthOf(1)
930 expect(elem[ 0 ].playlistId).to.equal(playlistServer1Id)
931 expect(elem[ 0 ].startTimestamp).to.equal(45)
932 expect(elem[ 0 ].stopTimestamp).to.equal(null)
933 }
684 934
685 it('Should automatically update updatedAt field of playlists', async function () { 935 expect(obj[ 42000 ]).to.have.lengthOf(0)
686 const server = servers[1] 936 expect(obj[ 43000 ]).to.have.lengthOf(0)
687 const videoId = servers[1].videos[5].id 937 })
688 938
689 async function getPlaylistNames () { 939 it('Should automatically update updatedAt field of playlists', async function () {
690 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, undefined, '-updatedAt') 940 const server = servers[ 1 ]
941 const videoId = servers[ 1 ].videos[ 5 ].id
691 942
692 return (res.body.data as VideoPlaylist[]).map(p => p.displayName) 943 async function getPlaylistNames () {
693 } 944 const res = await getAccountPlaylistsListWithToken(server.url, server.accessToken, 'root', 0, 5, undefined, '-updatedAt')
694 945
695 const elementAttrs = { videoId } 946 return (res.body.data as VideoPlaylist[]).map(p => p.displayName)
696 await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id1, elementAttrs }) 947 }
697 await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id2, elementAttrs })
698 948
699 const names1 = await getPlaylistNames() 949 const elementAttrs = { videoId }
700 expect(names1[0]).to.equal('playlist 3 updated') 950 const res1 = await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id1, elementAttrs })
701 expect(names1[1]).to.equal('playlist 2') 951 const res2 = await addVideoInPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id2, elementAttrs })
702 952
703 await removeVideoFromPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id1, videoId }) 953 const element1 = res1.body.videoPlaylistElement.id
954 const element2 = res2.body.videoPlaylistElement.id
704 955
705 const names2 = await getPlaylistNames() 956 const names1 = await getPlaylistNames()
706 expect(names2[0]).to.equal('playlist 2') 957 expect(names1[ 0 ]).to.equal('playlist 3 updated')
707 expect(names2[1]).to.equal('playlist 3 updated') 958 expect(names1[ 1 ]).to.equal('playlist 2')
708 959
709 await removeVideoFromPlaylist({ url: server.url, token: server.accessToken, playlistId: playlistServer2Id2, videoId }) 960 await removeVideoFromPlaylist({
961 url: server.url,
962 token: server.accessToken,
963 playlistId: playlistServer2Id1,
964 playlistElementId: element1
965 })
710 966
711 const names3 = await getPlaylistNames() 967 const names2 = await getPlaylistNames()
712 expect(names3[0]).to.equal('playlist 3 updated') 968 expect(names2[ 0 ]).to.equal('playlist 2')
713 expect(names3[1]).to.equal('playlist 2') 969 expect(names2[ 1 ]).to.equal('playlist 3 updated')
714 })
715 970
716 it('Should delete some elements', async function () { 971 await removeVideoFromPlaylist({
717 this.timeout(30000) 972 url: server.url,
973 token: server.accessToken,
974 playlistId: playlistServer2Id2,
975 playlistElementId: element2
976 })
718 977
719 await removeVideoFromPlaylist({ 978 const names3 = await getPlaylistNames()
720 url: servers[0].url, 979 expect(names3[ 0 ]).to.equal('playlist 3 updated')
721 token: servers[0].accessToken, 980 expect(names3[ 1 ]).to.equal('playlist 2')
722 playlistId: playlistServer1Id,
723 videoId: servers[0].videos[3].uuid
724 }) 981 })
725 982
726 await removeVideoFromPlaylist({ 983 it('Should delete some elements', async function () {
727 url: servers[0].url, 984 this.timeout(30000)
728 token: servers[0].accessToken,
729 playlistId: playlistServer1Id,
730 videoId: nsfwVideoServer1
731 })
732 985
733 await waitJobs(servers) 986 await removeVideoFromPlaylist({
987 url: servers[ 0 ].url,
988 token: servers[ 0 ].accessToken,
989 playlistId: playlistServer1Id,
990 playlistElementId: playlistElementServer1Video4
991 })
734 992
735 for (const server of servers) { 993 await removeVideoFromPlaylist({
736 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10) 994 url: servers[ 0 ].url,
995 token: servers[ 0 ].accessToken,
996 playlistId: playlistServer1Id,
997 playlistElementId: playlistElementNSFW
998 })
737 999
738 expect(res.body.total).to.equal(4) 1000 await waitJobs(servers)
739 1001
740 const videos: Video[] = res.body.data 1002 for (const server of servers) {
741 expect(videos).to.have.lengthOf(4) 1003 const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
742 1004
743 expect(videos[ 0 ].name).to.equal('video 0 server 1') 1005 expect(res.body.total).to.equal(4)
744 expect(videos[ 0 ].playlistElement.position).to.equal(1)
745 1006
746 expect(videos[ 1 ].name).to.equal('video 2 server 3') 1007 const elements: VideoPlaylistElement[] = res.body.data
747 expect(videos[ 1 ].playlistElement.position).to.equal(2) 1008 expect(elements).to.have.lengthOf(4)
748 1009
749 expect(videos[ 2 ].name).to.equal('video 1 server 3') 1010 expect(elements[ 0 ].video.name).to.equal('video 0 server 1')
750 expect(videos[ 2 ].playlistElement.position).to.equal(3) 1011 expect(elements[ 0 ].position).to.equal(1)
751 1012
752 expect(videos[ 3 ].name).to.equal('video 4 server 1') 1013 expect(elements[ 1 ].video.name).to.equal('video 2 server 3')
753 expect(videos[ 3 ].playlistElement.position).to.equal(4) 1014 expect(elements[ 1 ].position).to.equal(2)
754 }
755 })
756 1015
757 it('Should be able to create a public playlist, and set it to private', async function () { 1016 expect(elements[ 2 ].video.name).to.equal('video 1 server 3')
758 this.timeout(30000) 1017 expect(elements[ 2 ].position).to.equal(3)
759 1018
760 const res = await createVideoPlaylist({ 1019 expect(elements[ 3 ].video.name).to.equal('video 4 server 1')
761 url: servers[0].url, 1020 expect(elements[ 3 ].position).to.equal(4)
762 token: servers[0].accessToken,
763 playlistAttrs: {
764 displayName: 'my super public playlist',
765 privacy: VideoPlaylistPrivacy.PUBLIC,
766 videoChannelId: servers[0].videoChannel.id
767 } 1021 }
768 }) 1022 })
769 const videoPlaylistIds = res.body.videoPlaylist
770 1023
771 await waitJobs(servers) 1024 it('Should be able to create a public playlist, and set it to private', async function () {
1025 this.timeout(30000)
772 1026
773 for (const server of servers) { 1027 const res = await createVideoPlaylist({
774 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 200) 1028 url: servers[ 0 ].url,
775 } 1029 token: servers[ 0 ].accessToken,
1030 playlistAttrs: {
1031 displayName: 'my super public playlist',
1032 privacy: VideoPlaylistPrivacy.PUBLIC,
1033 videoChannelId: servers[ 0 ].videoChannel.id
1034 }
1035 })
1036 const videoPlaylistIds = res.body.videoPlaylist
776 1037
777 const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE } 1038 await waitJobs(servers)
778 await updateVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: videoPlaylistIds.id, playlistAttrs })
779 1039
780 await waitJobs(servers) 1040 for (const server of servers) {
1041 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 200)
1042 }
781 1043
782 for (const server of [ servers[1], servers[2] ]) { 1044 const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE }
783 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 404) 1045 await updateVideoPlaylist({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, playlistId: videoPlaylistIds.id, playlistAttrs })
784 }
785 await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, 401)
786 1046
787 await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, 200) 1047 await waitJobs(servers)
788 })
789 1048
790 it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () { 1049 for (const server of [ servers[ 1 ], servers[ 2 ] ]) {
791 this.timeout(30000) 1050 await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 404)
1051 }
1052 await getVideoPlaylist(servers[ 0 ].url, videoPlaylistIds.uuid, 401)
792 1053
793 await deleteVideoPlaylist(servers[0].url, servers[0].accessToken, playlistServer1Id) 1054 await getVideoPlaylistWithToken(servers[ 0 ].url, servers[ 0 ].accessToken, videoPlaylistIds.uuid, 200)
1055 })
1056 })
794 1057
795 await waitJobs(servers) 1058 describe('Playlist deletion', function () {
796 1059
797 for (const server of servers) { 1060 it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () {
798 await getVideoPlaylist(server.url, playlistServer1UUID, 404) 1061 this.timeout(30000)
799 }
800 })
801 1062
802 it('Should have deleted the thumbnail on server 1, 2 and 3', async function () { 1063 await deleteVideoPlaylist(servers[ 0 ].url, servers[ 0 ].accessToken, playlistServer1Id)
803 this.timeout(30000)
804 1064
805 for (const server of servers) { 1065 await waitJobs(servers)
806 await checkPlaylistFilesWereRemoved(playlistServer1UUID, server.internalServerNumber)
807 }
808 })
809 1066
810 it('Should unfollow servers 1 and 2 and hide their playlists', async function () { 1067 for (const server of servers) {
811 this.timeout(30000) 1068 await getVideoPlaylist(server.url, playlistServer1UUID, 404)
1069 }
1070 })
812 1071
813 const finder = data => data.find(p => p.displayName === 'my super playlist') 1072 it('Should have deleted the thumbnail on server 1, 2 and 3', async function () {
1073 this.timeout(30000)
814 1074
815 { 1075 for (const server of servers) {
816 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5) 1076 await checkPlaylistFilesWereRemoved(playlistServer1UUID, server.internalServerNumber)
817 expect(res.body.total).to.equal(2) 1077 }
818 expect(finder(res.body.data)).to.not.be.undefined 1078 })
819 }
820 1079
821 await unfollow(servers[2].url, servers[2].accessToken, servers[0]) 1080 it('Should unfollow servers 1 and 2 and hide their playlists', async function () {
1081 this.timeout(30000)
822 1082
823 { 1083 const finder = data => data.find(p => p.displayName === 'my super playlist')
824 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5)
825 expect(res.body.total).to.equal(1)
826 1084
827 expect(finder(res.body.data)).to.be.undefined 1085 {
828 } 1086 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5)
829 }) 1087 expect(res.body.total).to.equal(3)
1088 expect(finder(res.body.data)).to.not.be.undefined
1089 }
830 1090
831 it('Should delete a channel and put the associated playlist in private mode', async function () { 1091 await unfollow(servers[ 2 ].url, servers[ 2 ].accessToken, servers[ 0 ])
832 this.timeout(30000)
833 1092
834 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, { name: 'super_channel', displayName: 'super channel' }) 1093 {
835 const videoChannelId = res.body.videoChannel.id 1094 const res = await getVideoPlaylistsList(servers[ 2 ].url, 0, 5)
1095 expect(res.body.total).to.equal(1)
836 1096
837 const res2 = await createVideoPlaylist({ 1097 expect(finder(res.body.data)).to.be.undefined
838 url: servers[0].url,
839 token: servers[0].accessToken,
840 playlistAttrs: {
841 displayName: 'channel playlist',
842 privacy: VideoPlaylistPrivacy.PUBLIC,
843 videoChannelId
844 } 1098 }
845 }) 1099 })
846 const videoPlaylistUUID = res2.body.videoPlaylist.uuid
847 1100
848 await waitJobs(servers) 1101 it('Should delete a channel and put the associated playlist in private mode', async function () {
1102 this.timeout(30000)
849 1103
850 await deleteVideoChannel(servers[0].url, servers[0].accessToken, 'super_channel') 1104 const res = await addVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'super_channel', displayName: 'super channel' })
1105 const videoChannelId = res.body.videoChannel.id
851 1106
852 await waitJobs(servers) 1107 const res2 = await createVideoPlaylist({
1108 url: servers[ 0 ].url,
1109 token: servers[ 0 ].accessToken,
1110 playlistAttrs: {
1111 displayName: 'channel playlist',
1112 privacy: VideoPlaylistPrivacy.PUBLIC,
1113 videoChannelId
1114 }
1115 })
1116 const videoPlaylistUUID = res2.body.videoPlaylist.uuid
1117
1118 await waitJobs(servers)
853 1119
854 const res3 = await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistUUID) 1120 await deleteVideoChannel(servers[ 0 ].url, servers[ 0 ].accessToken, 'super_channel')
855 expect(res3.body.displayName).to.equal('channel playlist')
856 expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE)
857 1121
858 await getVideoPlaylist(servers[1].url, videoPlaylistUUID, 404) 1122 await waitJobs(servers)
859 })
860 1123
861 it('Should delete an account and delete its playlists', async function () { 1124 const res3 = await getVideoPlaylistWithToken(servers[ 0 ].url, servers[ 0 ].accessToken, videoPlaylistUUID)
862 this.timeout(30000) 1125 expect(res3.body.displayName).to.equal('channel playlist')
1126 expect(res3.body.privacy.id).to.equal(VideoPlaylistPrivacy.PRIVATE)
863 1127
864 const user = { username: 'user_1', password: 'password' } 1128 await getVideoPlaylist(servers[ 1 ].url, videoPlaylistUUID, 404)
865 const res = await createUser({
866 url: servers[ 0 ].url,
867 accessToken: servers[ 0 ].accessToken,
868 username: user.username,
869 password: user.password
870 }) 1129 })
871 1130
872 const userId = res.body.user.id 1131 it('Should delete an account and delete its playlists', async function () {
873 const userAccessToken = await userLogin(servers[0], user) 1132 this.timeout(30000)
874 1133
875 const resChannel = await getMyUserInformation(servers[0].url, userAccessToken) 1134 const user = { username: 'user_1', password: 'password' }
876 const userChannel = (resChannel.body as User).videoChannels[0] 1135 const res = await createUser({
1136 url: servers[ 0 ].url,
1137 accessToken: servers[ 0 ].accessToken,
1138 username: user.username,
1139 password: user.password
1140 })
877 1141
878 await createVideoPlaylist({ 1142 const userId = res.body.user.id
879 url: servers[0].url, 1143 const userAccessToken = await userLogin(servers[ 0 ], user)
880 token: userAccessToken,
881 playlistAttrs: {
882 displayName: 'playlist to be deleted',
883 privacy: VideoPlaylistPrivacy.PUBLIC,
884 videoChannelId: userChannel.id
885 }
886 })
887 1144
888 await waitJobs(servers) 1145 const resChannel = await getMyUserInformation(servers[ 0 ].url, userAccessToken)
1146 const userChannel = (resChannel.body as User).videoChannels[ 0 ]
889 1147
890 const finder = data => data.find(p => p.displayName === 'playlist to be deleted') 1148 await createVideoPlaylist({
1149 url: servers[ 0 ].url,
1150 token: userAccessToken,
1151 playlistAttrs: {
1152 displayName: 'playlist to be deleted',
1153 privacy: VideoPlaylistPrivacy.PUBLIC,
1154 videoChannelId: userChannel.id
1155 }
1156 })
891 1157
892 { 1158 await waitJobs(servers)
893 for (const server of [ servers[0], servers[1] ]) { 1159
894 const res = await getVideoPlaylistsList(server.url, 0, 15) 1160 const finder = data => data.find(p => p.displayName === 'playlist to be deleted')
895 expect(finder(res.body.data)).to.not.be.undefined 1161
1162 {
1163 for (const server of [ servers[ 0 ], servers[ 1 ] ]) {
1164 const res = await getVideoPlaylistsList(server.url, 0, 15)
1165 expect(finder(res.body.data)).to.not.be.undefined
1166 }
896 } 1167 }
897 }
898 1168
899 await removeUser(servers[0].url, userId, servers[0].accessToken) 1169 await removeUser(servers[ 0 ].url, userId, servers[ 0 ].accessToken)
900 await waitJobs(servers) 1170 await waitJobs(servers)
901 1171
902 { 1172 {
903 for (const server of [ servers[0], servers[1] ]) { 1173 for (const server of [ servers[ 0 ], servers[ 1 ] ]) {
904 const res = await getVideoPlaylistsList(server.url, 0, 15) 1174 const res = await getVideoPlaylistsList(server.url, 0, 15)
905 expect(finder(res.body.data)).to.be.undefined 1175 expect(finder(res.body.data)).to.be.undefined
1176 }
906 } 1177 }
907 } 1178 })
908 }) 1179 })
909 1180
910 after(async function () { 1181 after(async function () {