+ {
+ await updateVideo(servers[0].url, servers[0].accessToken, video1, { privacy: VideoPrivacy.PUBLIC })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ // We deleted the video, so even if we recreated it, the old entry is still deleted
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
+ }
+ })
+
+ it('Should update the element type if the video is blacklisted', async function () {
+ this.timeout(20000)
+
+ const name = 'video 89'
+ const position = 1
+
+ {
+ await addVideoToBlacklist(servers[0].url, servers[0].accessToken, video1, 'reason', true)
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
+ await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
+ }
+
+ {
+ await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, video1)
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ await checkPlaylistElementType(groupWithoutToken1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ await checkPlaylistElementType(group1, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ // We deleted the video (because unfederated), so even if we recreated it, the old entry is still deleted
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.DELETED, position, name, 3)
+ }
+ })
+
+ it('Should update the element type if the account or server of the video is blocked', async function () {
+ this.timeout(90000)
+
+ const command = servers[0].blocklistCommand
+
+ const name = 'video 90'
+ const position = 2
+
+ {
+ await command.addToMyBlocklist({ token: userAccessTokenServer1, account: 'root@localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+
+ await command.removeFromMyBlocklist({ token: userAccessTokenServer1, account: 'root@localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ }
+
+ {
+ await command.addToMyBlocklist({ token: userAccessTokenServer1, server: 'localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+
+ await command.removeFromMyBlocklist({ token: userAccessTokenServer1, server: 'localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ }
+
+ {
+ await command.addToServerBlocklist({ account: 'root@localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+
+ await command.removeFromServerBlocklist({ account: 'root@localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ }
+
+ {
+ await command.addToServerBlocklist({ server: 'localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(groupUser1, playlistServer1UUID2, VideoPlaylistElementType.UNAVAILABLE, position, name, 3)
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+
+ await command.removeFromServerBlocklist({ server: 'localhost:' + servers[1].port })
+ await waitJobs(servers)
+
+ await checkPlaylistElementType(group2, playlistServer1UUID2, VideoPlaylistElementType.REGULAR, position, name, 3)
+ }
+ })
+
+ it('Should hide the video if it is NSFW', async function () {
+ const res = await getPlaylistVideos(servers[0].url, userAccessTokenServer1, playlistServer1UUID2, 0, 10, { nsfw: false })
+ expect(res.body.total).to.equal(3)
+
+ const elements: VideoPlaylistElement[] = res.body.data
+ const element = elements.find(e => e.position === 3)
+
+ expect(element).to.exist
+ expect(element.video).to.be.null
+ expect(element.type).to.equal(VideoPlaylistElementType.UNAVAILABLE)
+ })
+
+ })
+
+ describe('Managing playlist elements', function () {
+
+ it('Should reorder the playlist', async function () {
+ this.timeout(30000)
+
+ {
+ await reorderVideosPlaylist({
+ url: servers[0].url,
+ token: servers[0].accessToken,
+ playlistId: playlistServer1Id,
+ elementAttrs: {
+ startPosition: 2,
+ insertAfterPosition: 3
+ }
+ })
+
+ await waitJobs(servers)
+
+ for (const server of servers) {
+ const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
+ const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name)
+
+ expect(names).to.deep.equal([
+ 'video 0 server 1',
+ 'video 2 server 3',
+ 'video 1 server 3',
+ 'video 3 server 1',
+ 'video 4 server 1',
+ 'NSFW video',
+ 'NSFW video',
+ 'NSFW video'
+ ])
+ }
+ }
+
+ {
+ await reorderVideosPlaylist({
+ url: servers[0].url,
+ token: servers[0].accessToken,
+ playlistId: playlistServer1Id,
+ elementAttrs: {
+ startPosition: 1,
+ reorderLength: 3,
+ insertAfterPosition: 4
+ }
+ })
+
+ await waitJobs(servers)
+
+ for (const server of servers) {
+ const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
+ const names = (res.body.data as VideoPlaylistElement[]).map(v => v.video.name)
+
+ expect(names).to.deep.equal([
+ 'video 3 server 1',
+ 'video 0 server 1',
+ 'video 2 server 3',
+ 'video 1 server 3',
+ 'video 4 server 1',
+ 'NSFW video',
+ 'NSFW video',
+ 'NSFW video'
+ ])
+ }
+ }
+
+ {
+ await reorderVideosPlaylist({
+ url: servers[0].url,
+ token: servers[0].accessToken,
+ playlistId: playlistServer1Id,
+ elementAttrs: {
+ startPosition: 6,
+ insertAfterPosition: 3
+ }
+ })
+
+ await waitJobs(servers)
+
+ for (const server of servers) {
+ const res = await getPlaylistVideos(server.url, server.accessToken, playlistServer1UUID, 0, 10)
+ const elements: VideoPlaylistElement[] = res.body.data
+ const names = elements.map(v => v.video.name)
+
+ expect(names).to.deep.equal([
+ 'video 3 server 1',
+ 'video 0 server 1',
+ 'video 2 server 3',
+ 'NSFW video',
+ 'video 1 server 3',
+ 'video 4 server 1',
+ 'NSFW video',
+ 'NSFW video'
+ ])
+
+ for (let i = 1; i <= elements.length; i++) {
+ expect(elements[i - 1].position).to.equal(i)
+ }
+ }
+ }
+ })
+
+ it('Should update startTimestamp/endTimestamp of some elements', async function () {
+ this.timeout(30000)
+
+ await updateVideoPlaylistElement({
+ url: servers[0].url,
+ token: servers[0].accessToken,
+ playlistId: playlistServer1Id,
+ playlistElementId: playlistElementServer1Video4,
+ elementAttrs: {
+ startTimestamp: 1
+ }
+ })
+
+ await updateVideoPlaylistElement({