aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/tests/api/check-params/users.ts5
-rw-r--r--server/tests/api/check-params/video-channels.ts18
-rw-r--r--server/tests/api/notifications/user-notifications.ts7
-rw-r--r--server/tests/api/redundancy/redundancy-constraints.ts3
-rw-r--r--server/tests/api/search/search-activitypub-video-channels.ts30
-rw-r--r--server/tests/api/search/search-activitypub-videos.ts5
-rw-r--r--server/tests/api/search/search-channels.ts12
-rw-r--r--server/tests/api/server/plugins.ts2
-rw-r--r--server/tests/api/server/stats.ts7
-rw-r--r--server/tests/api/users/users-multiple-servers.ts15
-rw-r--r--server/tests/api/users/users.ts5
-rw-r--r--server/tests/api/videos/multiple-servers.ts8
-rw-r--r--server/tests/api/videos/video-channels.ts249
-rw-r--r--server/tests/api/videos/video-playlists.ts9
-rw-r--r--server/tests/cli/peertube.ts5
-rw-r--r--server/tests/cli/update-host.ts10
-rw-r--r--server/tests/client.ts6
-rw-r--r--server/tests/misc-endpoints.ts7
-rw-r--r--shared/extra-utils/server/servers.ts3
-rw-r--r--shared/extra-utils/shared/abstract-command.ts21
-rw-r--r--shared/extra-utils/videos/channels-command.ts157
-rw-r--r--shared/extra-utils/videos/channels.ts20
-rw-r--r--shared/extra-utils/videos/index.ts5
-rw-r--r--shared/extra-utils/videos/video-channels.ts192
-rw-r--r--shared/models/videos/channel/index.ts1
-rw-r--r--shared/models/videos/channel/video-channel-create-result.model.ts3
26 files changed, 364 insertions, 441 deletions
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
index da0f55bf8..88fc8e8b1 100644
--- a/server/tests/api/check-params/users.ts
+++ b/server/tests/api/check-params/users.ts
@@ -5,7 +5,6 @@ import { omit } from 'lodash'
5import { User, UserRole, VideoCreateResult } from '../../../../shared' 5import { User, UserRole, VideoCreateResult } from '../../../../shared'
6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' 6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
7import { 7import {
8 addVideoChannel,
9 blockUser, 8 blockUser,
10 buildAbsoluteFixturePath, 9 buildAbsoluteFixturePath,
11 cleanupTests, 10 cleanupTests,
@@ -1041,8 +1040,8 @@ describe('Test users API validators', function () {
1041 }) 1040 })
1042 1041
1043 it('Should fail with an existing channel', async function () { 1042 it('Should fail with an existing channel', async function () {
1044 const videoChannelAttributesArg = { name: 'existing_channel', displayName: 'hello', description: 'super description' } 1043 const attributes = { name: 'existing_channel', displayName: 'hello', description: 'super description' }
1045 await addVideoChannel(server.url, server.accessToken, videoChannelAttributesArg) 1044 await server.channelsCommand.create({ attributes })
1046 1045
1047 const fields = immutableAssign(baseCorrectParams, { channel: { name: 'existing_channel', displayName: 'toto' } }) 1046 const fields = immutableAssign(baseCorrectParams, { channel: { name: 'existing_channel', displayName: 'toto' } })
1048 1047
diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts
index 5c02afd31..d29346dc3 100644
--- a/server/tests/api/check-params/video-channels.ts
+++ b/server/tests/api/check-params/video-channels.ts
@@ -6,11 +6,10 @@ import { omit } from 'lodash'
6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' 6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
7import { 7import {
8 buildAbsoluteFixturePath, 8 buildAbsoluteFixturePath,
9 ChannelsCommand,
9 cleanupTests, 10 cleanupTests,
10 createUser, 11 createUser,
11 deleteVideoChannel,
12 flushAndRunServer, 12 flushAndRunServer,
13 getAccountVideoChannelsList,
14 immutableAssign, 13 immutableAssign,
15 makeGetRequest, 14 makeGetRequest,
16 makePostBodyRequest, 15 makePostBodyRequest,
@@ -33,6 +32,7 @@ describe('Test video channels API validator', function () {
33 const videoChannelPath = '/api/v1/video-channels' 32 const videoChannelPath = '/api/v1/video-channels'
34 let server: ServerInfo 33 let server: ServerInfo
35 let accessTokenUser: string 34 let accessTokenUser: string
35 let command: ChannelsCommand
36 36
37 // --------------------------------------------------------------- 37 // ---------------------------------------------------------------
38 38
@@ -52,6 +52,8 @@ describe('Test video channels API validator', function () {
52 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) 52 await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
53 accessTokenUser = await userLogin(server, user) 53 accessTokenUser = await userLogin(server, user)
54 } 54 }
55
56 command = server.channelsCommand
55 }) 57 })
56 58
57 describe('When listing a video channels', function () { 59 describe('When listing a video channels', function () {
@@ -84,7 +86,7 @@ describe('Test video channels API validator', function () {
84 }) 86 })
85 87
86 it('Should fail with a unknown account', async function () { 88 it('Should fail with a unknown account', async function () {
87 await getAccountVideoChannelsList({ url: server.url, accountName: 'unknown', specialStatus: HttpStatusCode.NOT_FOUND_404 }) 89 await server.channelsCommand.listByAccount({ accountName: 'unknown', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
88 }) 90 })
89 91
90 it('Should succeed with the correct parameters', async function () { 92 it('Should succeed with the correct parameters', async function () {
@@ -327,23 +329,23 @@ describe('Test video channels API validator', function () {
327 329
328 describe('When deleting a video channel', function () { 330 describe('When deleting a video channel', function () {
329 it('Should fail with a non authenticated user', async function () { 331 it('Should fail with a non authenticated user', async function () {
330 await deleteVideoChannel(server.url, 'coucou', 'super_channel', HttpStatusCode.UNAUTHORIZED_401) 332 await command.delete({ token: 'coucou', channelName: 'super_channel', expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
331 }) 333 })
332 334
333 it('Should fail with another authenticated user', async function () { 335 it('Should fail with another authenticated user', async function () {
334 await deleteVideoChannel(server.url, accessTokenUser, 'super_channel', HttpStatusCode.FORBIDDEN_403) 336 await command.delete({ token: accessTokenUser, channelName: 'super_channel', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
335 }) 337 })
336 338
337 it('Should fail with an unknown video channel id', async function () { 339 it('Should fail with an unknown video channel id', async function () {
338 await deleteVideoChannel(server.url, server.accessToken, 'super_channel2', HttpStatusCode.NOT_FOUND_404) 340 await command.delete({ channelName: 'super_channel2', expectedStatus: HttpStatusCode.NOT_FOUND_404 })
339 }) 341 })
340 342
341 it('Should succeed with the correct parameters', async function () { 343 it('Should succeed with the correct parameters', async function () {
342 await deleteVideoChannel(server.url, server.accessToken, 'super_channel') 344 await command.delete({ channelName: 'super_channel' })
343 }) 345 })
344 346
345 it('Should fail to delete the last user video channel', async function () { 347 it('Should fail to delete the last user video channel', async function () {
346 await deleteVideoChannel(server.url, server.accessToken, 'root_channel', HttpStatusCode.CONFLICT_409) 348 await command.delete({ channelName: 'root_channel', expectedStatus: HttpStatusCode.CONFLICT_409 })
347 }) 349 })
348 }) 350 })
349 351
diff --git a/server/tests/api/notifications/user-notifications.ts b/server/tests/api/notifications/user-notifications.ts
index a9315c818..1d159c48f 100644
--- a/server/tests/api/notifications/user-notifications.ts
+++ b/server/tests/api/notifications/user-notifications.ts
@@ -17,7 +17,6 @@ import {
17 ServerInfo, 17 ServerInfo,
18 updateMyUser, 18 updateMyUser,
19 updateVideo, 19 updateVideo,
20 updateVideoChannel,
21 uploadRandomVideoOnServers, 20 uploadRandomVideoOnServers,
22 wait, 21 wait,
23 waitJobs 22 waitJobs
@@ -404,7 +403,11 @@ describe('Test user notifications', function () {
404 displayName: 'super root 2 name' 403 displayName: 'super root 2 name'
405 }) 404 })
406 405
407 await updateVideoChannel(servers[0].url, userAccessToken, 'user_1_channel', { displayName: myChannelName }) 406 await servers[0].channelsCommand.update({
407 token: userAccessToken,
408 channelName: 'user_1_channel',
409 attributes: { displayName: myChannelName }
410 })
408 }) 411 })
409 412
410 it('Should notify when a local channel is following one of our channel', async function () { 413 it('Should notify when a local channel is following one of our channel', async function () {
diff --git a/server/tests/api/redundancy/redundancy-constraints.ts b/server/tests/api/redundancy/redundancy-constraints.ts
index a666976b3..500b96747 100644
--- a/server/tests/api/redundancy/redundancy-constraints.ts
+++ b/server/tests/api/redundancy/redundancy-constraints.ts
@@ -1,6 +1,7 @@
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 'mocha' 3import 'mocha'
4import { expect } from 'chai'
4import { 5import {
5 cleanupTests, 6 cleanupTests,
6 flushAndRunServer, 7 flushAndRunServer,
@@ -15,8 +16,6 @@ import {
15} from '@shared/extra-utils' 16} from '@shared/extra-utils'
16import { VideoPrivacy } from '@shared/models' 17import { VideoPrivacy } from '@shared/models'
17 18
18const expect = chai.expect
19
20describe('Test redundancy constraints', function () { 19describe('Test redundancy constraints', function () {
21 let remoteServer: ServerInfo 20 let remoteServer: ServerInfo
22 let localServer: ServerInfo 21 let localServer: ServerInfo
diff --git a/server/tests/api/search/search-activitypub-video-channels.ts b/server/tests/api/search/search-activitypub-video-channels.ts
index cf5158b66..83be9cd1e 100644
--- a/server/tests/api/search/search-activitypub-video-channels.ts
+++ b/server/tests/api/search/search-activitypub-video-channels.ts
@@ -3,19 +3,15 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoChannel,
7 cleanupTests, 6 cleanupTests,
8 createUser, 7 createUser,
9 deleteVideoChannel,
10 flushAndRunMultipleServers, 8 flushAndRunMultipleServers,
11 getVideoChannelsList,
12 getVideoChannelVideos, 9 getVideoChannelVideos,
13 SearchCommand, 10 SearchCommand,
14 ServerInfo, 11 ServerInfo,
15 setAccessTokensToServers, 12 setAccessTokensToServers,
16 updateMyUser, 13 updateMyUser,
17 updateVideo, 14 updateVideo,
18 updateVideoChannel,
19 uploadVideo, 15 uploadVideo,
20 userLogin, 16 userLogin,
21 wait, 17 wait,
@@ -45,7 +41,7 @@ describe('Test ActivityPub video channels search', function () {
45 name: 'channel1_server1', 41 name: 'channel1_server1',
46 displayName: 'Channel 1 server 1' 42 displayName: 'Channel 1 server 1'
47 } 43 }
48 await addVideoChannel(servers[0].url, servers[0].accessToken, channel) 44 await servers[0].channelsCommand.create({ attributes: channel })
49 } 45 }
50 46
51 { 47 {
@@ -57,8 +53,8 @@ describe('Test ActivityPub video channels search', function () {
57 name: 'channel1_server2', 53 name: 'channel1_server2',
58 displayName: 'Channel 1 server 2' 54 displayName: 'Channel 1 server 2'
59 } 55 }
60 const resChannel = await addVideoChannel(servers[1].url, userServer2Token, channel) 56 const created = await servers[1].channelsCommand.create({ token: userServer2Token, attributes: channel })
61 channelIdServer2 = resChannel.body.videoChannel.id 57 channelIdServer2 = created.id
62 58
63 const res = await uploadVideo(servers[1].url, userServer2Token, { name: 'video 1 server 2', channelId: channelIdServer2 }) 59 const res = await uploadVideo(servers[1].url, userServer2Token, { name: 'video 1 server 2', channelId: channelIdServer2 })
64 videoServer2UUID = res.body.video.uuid 60 videoServer2UUID = res.body.video.uuid
@@ -143,12 +139,12 @@ describe('Test ActivityPub video channels search', function () {
143 }) 139 })
144 140
145 it('Should not list this remote video channel', async function () { 141 it('Should not list this remote video channel', async function () {
146 const res = await getVideoChannelsList(servers[0].url, 0, 5) 142 const body = await servers[0].channelsCommand.list()
147 expect(res.body.total).to.equal(3) 143 expect(body.total).to.equal(3)
148 expect(res.body.data).to.have.lengthOf(3) 144 expect(body.data).to.have.lengthOf(3)
149 expect(res.body.data[0].name).to.equal('channel1_server1') 145 expect(body.data[0].name).to.equal('channel1_server1')
150 expect(res.body.data[1].name).to.equal('user1_server1_channel') 146 expect(body.data[1].name).to.equal('user1_server1_channel')
151 expect(res.body.data[2].name).to.equal('root_channel') 147 expect(body.data[2].name).to.equal('root_channel')
152 }) 148 })
153 149
154 it('Should list video channel videos of server 2 without token', async function () { 150 it('Should list video channel videos of server 2 without token', async function () {
@@ -171,7 +167,11 @@ describe('Test ActivityPub video channels search', function () {
171 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 () {
172 this.timeout(60000) 168 this.timeout(60000)
173 169
174 await updateVideoChannel(servers[1].url, userServer2Token, 'channel1_server2', { displayName: 'channel updated' }) 170 await servers[1].channelsCommand.update({
171 token: userServer2Token,
172 channelName: 'channel1_server2',
173 attributes: { displayName: 'channel updated' }
174 })
175 await updateMyUser({ url: servers[1].url, accessToken: userServer2Token, displayName: 'user updated' }) 175 await updateMyUser({ url: servers[1].url, accessToken: userServer2Token, displayName: 'user updated' })
176 176
177 await waitJobs(servers) 177 await waitJobs(servers)
@@ -217,7 +217,7 @@ describe('Test ActivityPub video channels search', function () {
217 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 () {
218 this.timeout(60000) 218 this.timeout(60000)
219 219
220 await deleteVideoChannel(servers[1].url, userServer2Token, 'channel1_server2') 220 await servers[1].channelsCommand.delete({ token: userServer2Token, channelName: 'channel1_server2' })
221 221
222 await waitJobs(servers) 222 await waitJobs(servers)
223 // Expire video 223 // Expire video
diff --git a/server/tests/api/search/search-activitypub-videos.ts b/server/tests/api/search/search-activitypub-videos.ts
index 7c6455258..403c84010 100644
--- a/server/tests/api/search/search-activitypub-videos.ts
+++ b/server/tests/api/search/search-activitypub-videos.ts
@@ -3,7 +3,6 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoChannel,
7 cleanupTests, 6 cleanupTests,
8 flushAndRunMultipleServers, 7 flushAndRunMultipleServers,
9 getVideosList, 8 getVideosList,
@@ -123,8 +122,8 @@ describe('Test ActivityPub videos search', function () {
123 name: 'super_channel', 122 name: 'super_channel',
124 displayName: 'super channel' 123 displayName: 'super channel'
125 } 124 }
126 const resChannel = await addVideoChannel(servers[1].url, servers[1].accessToken, channelAttributes) 125 const created = await servers[1].channelsCommand.create({ attributes: channelAttributes })
127 const videoChannelId = resChannel.body.videoChannel.id 126 const videoChannelId = created.id
128 127
129 const attributes = { 128 const attributes = {
130 name: 'updated', 129 name: 'updated',
diff --git a/server/tests/api/search/search-channels.ts b/server/tests/api/search/search-channels.ts
index 307bc063d..6c9ee73ce 100644
--- a/server/tests/api/search/search-channels.ts
+++ b/server/tests/api/search/search-channels.ts
@@ -2,15 +2,7 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import { cleanupTests, createUser, flushAndRunServer, SearchCommand, ServerInfo, setAccessTokensToServers } from '@shared/extra-utils'
6 addVideoChannel,
7 cleanupTests,
8 createUser,
9 flushAndRunServer,
10 SearchCommand,
11 ServerInfo,
12 setAccessTokensToServers
13} from '@shared/extra-utils'
14import { VideoChannel } from '@shared/models' 6import { VideoChannel } from '@shared/models'
15 7
16const expect = chai.expect 8const expect = chai.expect
@@ -32,7 +24,7 @@ describe('Test channels search', function () {
32 name: 'squall_channel', 24 name: 'squall_channel',
33 displayName: 'Squall channel' 25 displayName: 'Squall channel'
34 } 26 }
35 await addVideoChannel(server.url, server.accessToken, channel) 27 await server.channelsCommand.create({ attributes: channel })
36 } 28 }
37 29
38 command = server.searchCommand 30 command = server.searchCommand
diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts
index 528bbbe58..e22ecfad9 100644
--- a/server/tests/api/server/plugins.ts
+++ b/server/tests/api/server/plugins.ts
@@ -37,6 +37,8 @@ describe('Test plugins', function () {
37 } 37 }
38 server = await flushAndRunServer(1, configOverride) 38 server = await flushAndRunServer(1, configOverride)
39 await setAccessTokensToServers([ server ]) 39 await setAccessTokensToServers([ server ])
40
41 command = server.pluginsCommand
40 }) 42 })
41 43
42 it('Should list and search available plugins and themes', async function () { 44 it('Should list and search available plugins and themes', async function () {
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts
index c877a65eb..9c954c347 100644
--- a/server/tests/api/server/stats.ts
+++ b/server/tests/api/server/stats.ts
@@ -3,7 +3,6 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { 5import {
6 addVideoChannel,
7 addVideoCommentThread, 6 addVideoCommentThread,
8 cleanupTests, 7 cleanupTests,
9 createUser, 8 createUser,
@@ -143,12 +142,12 @@ describe('Test stats (excluding redundancy)', function () {
143 } 142 }
144 143
145 { 144 {
146 const channelAttributes = { 145 const attributes = {
147 name: 'stats_channel', 146 name: 'stats_channel',
148 displayName: 'My stats channel' 147 displayName: 'My stats channel'
149 } 148 }
150 const resChannel = await addVideoChannel(server.url, server.accessToken, channelAttributes) 149 const created = await server.channelsCommand.create({ attributes })
151 channelId = resChannel.body.videoChannel.id 150 channelId = created.id
152 151
153 const data = await server.statsCommand.get() 152 const data = await server.statsCommand.get()
154 153
diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts
index 03fbfabeb..47056be78 100644
--- a/server/tests/api/users/users-multiple-servers.ts
+++ b/server/tests/api/users/users-multiple-servers.ts
@@ -12,7 +12,6 @@ import {
12 flushAndRunMultipleServers, 12 flushAndRunMultipleServers,
13 getAccountVideos, 13 getAccountVideos,
14 getMyUserInformation, 14 getMyUserInformation,
15 getVideoChannelsList,
16 removeUser, 15 removeUser,
17 ServerInfo, 16 ServerInfo,
18 setAccessTokensToServers, 17 setAccessTokensToServers,
@@ -23,7 +22,7 @@ import {
23 userLogin, 22 userLogin,
24 waitJobs 23 waitJobs
25} from '@shared/extra-utils' 24} from '@shared/extra-utils'
26import { User, VideoChannel } from '@shared/models' 25import { User } from '@shared/models'
27 26
28const expect = chai.expect 27const expect = chai.expect
29 28
@@ -199,10 +198,8 @@ describe('Test users with multiple servers', function () {
199 const accountDeleted = body.data.find(a => a.name === 'user1' && a.host === 'localhost:' + servers[0].port) 198 const accountDeleted = body.data.find(a => a.name === 'user1' && a.host === 'localhost:' + servers[0].port)
200 expect(accountDeleted).not.to.be.undefined 199 expect(accountDeleted).not.to.be.undefined
201 200
202 const resVideoChannels = await getVideoChannelsList(server.url, 0, 10) 201 const { data } = await server.channelsCommand.list()
203 const videoChannelDeleted = resVideoChannels.body.data.find(a => { 202 const videoChannelDeleted = data.find(a => a.displayName === 'Main user1 channel' && a.host === 'localhost:' + servers[0].port)
204 return a.displayName === 'Main user1 channel' && a.host === 'localhost:' + servers[0].port
205 }) as VideoChannel
206 expect(videoChannelDeleted).not.to.be.undefined 203 expect(videoChannelDeleted).not.to.be.undefined
207 } 204 }
208 205
@@ -216,10 +213,8 @@ describe('Test users with multiple servers', function () {
216 const accountDeleted = body.data.find(a => a.name === 'user1' && a.host === 'localhost:' + servers[0].port) 213 const accountDeleted = body.data.find(a => a.name === 'user1' && a.host === 'localhost:' + servers[0].port)
217 expect(accountDeleted).to.be.undefined 214 expect(accountDeleted).to.be.undefined
218 215
219 const resVideoChannels = await getVideoChannelsList(server.url, 0, 10) 216 const { data } = await server.channelsCommand.list()
220 const videoChannelDeleted = resVideoChannels.body.data.find(a => { 217 const videoChannelDeleted = data.find(a => a.name === 'Main user1 channel' && a.host === 'localhost:' + servers[0].port)
221 return a.name === 'Main user1 channel' && a.host === 'localhost:' + servers[0].port
222 }) as VideoChannel
223 expect(videoChannelDeleted).to.be.undefined 218 expect(videoChannelDeleted).to.be.undefined
224 } 219 }
225 }) 220 })
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index 4b9056306..ed670b3c9 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -18,7 +18,6 @@ import {
18 getUserInformation, 18 getUserInformation,
19 getUsersList, 19 getUsersList,
20 getUsersListPaginationAndSort, 20 getUsersListPaginationAndSort,
21 getVideoChannel,
22 getVideosList, 21 getVideosList,
23 killallServers, 22 killallServers,
24 login, 23 login,
@@ -864,9 +863,9 @@ describe('Test users', function () {
864 }) 863 })
865 864
866 it('Should have created the channel', async function () { 865 it('Should have created the channel', async function () {
867 const res = await getVideoChannel(server.url, 'my_user_15_channel') 866 const { displayName } = await server.channelsCommand.get({ channelName: 'my_user_15_channel' })
868 867
869 expect(res.body.displayName).to.equal('my channel rocks') 868 expect(displayName).to.equal('my channel rocks')
870 }) 869 })
871 870
872 it('Should remove me', async function () { 871 it('Should remove me', async function () {
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index a8c8a889b..a59d5a858 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -5,7 +5,6 @@ import * as chai from 'chai'
5import * as request from 'supertest' 5import * as request from 'supertest'
6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' 6import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
7import { 7import {
8 addVideoChannel,
9 buildAbsoluteFixturePath, 8 buildAbsoluteFixturePath,
10 checkTmpIsEmpty, 9 checkTmpIsEmpty,
11 checkVideoFilesWereRemoved, 10 checkVideoFilesWereRemoved,
@@ -17,7 +16,6 @@ import {
17 flushAndRunMultipleServers, 16 flushAndRunMultipleServers,
18 getLocalVideos, 17 getLocalVideos,
19 getVideo, 18 getVideo,
20 getVideoChannelsList,
21 getVideosList, 19 getVideosList,
22 rateVideo, 20 rateVideo,
23 removeVideo, 21 removeVideo,
@@ -64,9 +62,9 @@ describe('Test multiple servers', function () {
64 displayName: 'my channel', 62 displayName: 'my channel',
65 description: 'super channel' 63 description: 'super channel'
66 } 64 }
67 await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel) 65 await servers[0].channelsCommand.create({ attributes: videoChannel })
68 const channelRes = await getVideoChannelsList(servers[0].url, 0, 1) 66 const { data } = await servers[0].channelsCommand.list({ start: 0, count: 1 })
69 videoChannelId = channelRes.body.data[0].id 67 videoChannelId = data[0].id
70 } 68 }
71 69
72 // Server 1 and server 2 follow each other 70 // Server 1 and server 2 follow each other
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts
index 865098777..daf066eb1 100644
--- a/server/tests/api/videos/video-channels.ts
+++ b/server/tests/api/videos/video-channels.ts
@@ -7,43 +7,29 @@ import { ACTOR_IMAGES_SIZE } from '@server/initializers/constants'
7import { 7import {
8 cleanupTests, 8 cleanupTests,
9 createUser, 9 createUser,
10 deleteVideoChannelImage,
11 doubleFollow, 10 doubleFollow,
12 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
13 getActorImage, 12 getActorImage,
14 getVideo, 13 getVideo,
15 getVideoChannel,
16 getVideoChannelVideos, 14 getVideoChannelVideos,
17 setDefaultVideoChannel, 15 setDefaultVideoChannel,
18 testFileExistsOrNot, 16 testFileExistsOrNot,
19 testImage, 17 testImage,
20 updateVideo, 18 updateVideo,
21 updateVideoChannelImage,
22 uploadVideo, 19 uploadVideo,
23 userLogin, 20 userLogin,
24 wait 21 wait
25} from '../../../../shared/extra-utils' 22} from '../../../../shared/extra-utils'
26import { 23import { getMyUserInformation, ServerInfo, setAccessTokensToServers, viewVideo } from '../../../../shared/extra-utils/index'
27 addVideoChannel,
28 deleteVideoChannel,
29 getAccountVideoChannelsList,
30 getMyUserInformation,
31 getVideoChannelsList,
32 ServerInfo,
33 setAccessTokensToServers,
34 updateVideoChannel,
35 viewVideo
36} from '../../../../shared/extra-utils/index'
37import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 24import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
38import { User, Video, VideoChannel, VideoDetails } from '../../../../shared/index' 25import { User, Video, VideoChannel, VideoDetails } from '../../../../shared/index'
39 26
40const expect = chai.expect 27const expect = chai.expect
41 28
42async function findChannel (server: ServerInfo, channelId: number) { 29async function findChannel (server: ServerInfo, channelId: number) {
43 const res = await getVideoChannelsList(server.url, 0, 5, '-name') 30 const body = await server.channelsCommand.list({ sort: '-name' })
44 const videoChannel = res.body.data.find(c => c.id === channelId)
45 31
46 return videoChannel as VideoChannel 32 return body.data.find(c => c.id === channelId)
47} 33}
48 34
49describe('Test video channels', function () { 35describe('Test video channels', function () {
@@ -69,11 +55,11 @@ describe('Test video channels', function () {
69 }) 55 })
70 56
71 it('Should have one video channel (created with root)', async () => { 57 it('Should have one video channel (created with root)', async () => {
72 const res = await getVideoChannelsList(servers[0].url, 0, 2) 58 const body = await servers[0].channelsCommand.list({ start: 0, count: 2 })
73 59
74 expect(res.body.total).to.equal(1) 60 expect(body.total).to.equal(1)
75 expect(res.body.data).to.be.an('array') 61 expect(body.data).to.be.an('array')
76 expect(res.body.data).to.have.lengthOf(1) 62 expect(body.data).to.have.lengthOf(1)
77 }) 63 })
78 64
79 it('Should create another video channel', async function () { 65 it('Should create another video channel', async function () {
@@ -86,8 +72,8 @@ describe('Test video channels', function () {
86 description: 'super video channel description', 72 description: 'super video channel description',
87 support: 'super video channel support text' 73 support: 'super video channel support text'
88 } 74 }
89 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel) 75 const created = await servers[0].channelsCommand.create({ attributes: videoChannel })
90 secondVideoChannelId = res.body.videoChannel.id 76 secondVideoChannelId = created.id
91 } 77 }
92 78
93 // The channel is 1 is propagated to servers 2 79 // The channel is 1 is propagated to servers 2
@@ -120,16 +106,14 @@ describe('Test video channels', function () {
120 }) 106 })
121 107
122 it('Should have two video channels when getting account channels on server 1', async function () { 108 it('Should have two video channels when getting account channels on server 1', async function () {
123 const res = await getAccountVideoChannelsList({ 109 const body = await servers[0].channelsCommand.listByAccount({ accountName })
124 url: servers[0].url, 110 expect(body.total).to.equal(2)
125 accountName
126 })
127 111
128 expect(res.body.total).to.equal(2) 112 const videoChannels = body.data
129 expect(res.body.data).to.be.an('array') 113
130 expect(res.body.data).to.have.lengthOf(2) 114 expect(videoChannels).to.be.an('array')
115 expect(videoChannels).to.have.lengthOf(2)
131 116
132 const videoChannels = res.body.data
133 expect(videoChannels[0].name).to.equal('root_channel') 117 expect(videoChannels[0].name).to.equal('root_channel')
134 expect(videoChannels[0].displayName).to.equal('Main root channel') 118 expect(videoChannels[0].displayName).to.equal('Main root channel')
135 119
@@ -141,79 +125,69 @@ describe('Test video channels', function () {
141 125
142 it('Should paginate and sort account channels', async function () { 126 it('Should paginate and sort account channels', async function () {
143 { 127 {
144 const res = await getAccountVideoChannelsList({ 128 const body = await servers[0].channelsCommand.listByAccount({
145 url: servers[0].url,
146 accountName, 129 accountName,
147 start: 0, 130 start: 0,
148 count: 1, 131 count: 1,
149 sort: 'createdAt' 132 sort: 'createdAt'
150 }) 133 })
151 134
152 expect(res.body.total).to.equal(2) 135 expect(body.total).to.equal(2)
153 expect(res.body.data).to.have.lengthOf(1) 136 expect(body.data).to.have.lengthOf(1)
154 137
155 const videoChannel: VideoChannel = res.body.data[0] 138 const videoChannel: VideoChannel = body.data[0]
156 expect(videoChannel.name).to.equal('root_channel') 139 expect(videoChannel.name).to.equal('root_channel')
157 } 140 }
158 141
159 { 142 {
160 const res = await getAccountVideoChannelsList({ 143 const body = await servers[0].channelsCommand.listByAccount({
161 url: servers[0].url,
162 accountName, 144 accountName,
163 start: 0, 145 start: 0,
164 count: 1, 146 count: 1,
165 sort: '-createdAt' 147 sort: '-createdAt'
166 }) 148 })
167 149
168 expect(res.body.total).to.equal(2) 150 expect(body.total).to.equal(2)
169 expect(res.body.data).to.have.lengthOf(1) 151 expect(body.data).to.have.lengthOf(1)
170 152 expect(body.data[0].name).to.equal('second_video_channel')
171 const videoChannel: VideoChannel = res.body.data[0]
172 expect(videoChannel.name).to.equal('second_video_channel')
173 } 153 }
174 154
175 { 155 {
176 const res = await getAccountVideoChannelsList({ 156 const body = await servers[0].channelsCommand.listByAccount({
177 url: servers[0].url,
178 accountName, 157 accountName,
179 start: 1, 158 start: 1,
180 count: 1, 159 count: 1,
181 sort: '-createdAt' 160 sort: '-createdAt'
182 }) 161 })
183 162
184 expect(res.body.total).to.equal(2) 163 expect(body.total).to.equal(2)
185 expect(res.body.data).to.have.lengthOf(1) 164 expect(body.data).to.have.lengthOf(1)
186 165 expect(body.data[0].name).to.equal('root_channel')
187 const videoChannel: VideoChannel = res.body.data[0]
188 expect(videoChannel.name).to.equal('root_channel')
189 } 166 }
190 }) 167 })
191 168
192 it('Should have one video channel when getting account channels on server 2', async function () { 169 it('Should have one video channel when getting account channels on server 2', async function () {
193 const res = await getAccountVideoChannelsList({ 170 const body = await servers[1].channelsCommand.listByAccount({ accountName })
194 url: servers[1].url,
195 accountName
196 })
197 171
198 expect(res.body.total).to.equal(1) 172 expect(body.total).to.equal(1)
199 expect(res.body.data).to.be.an('array') 173 expect(body.data).to.be.an('array')
200 expect(res.body.data).to.have.lengthOf(1) 174 expect(body.data).to.have.lengthOf(1)
201 175
202 const videoChannels = res.body.data 176 const videoChannel = body.data[0]
203 expect(videoChannels[0].name).to.equal('second_video_channel') 177 expect(videoChannel.name).to.equal('second_video_channel')
204 expect(videoChannels[0].displayName).to.equal('second video channel') 178 expect(videoChannel.displayName).to.equal('second video channel')
205 expect(videoChannels[0].description).to.equal('super video channel description') 179 expect(videoChannel.description).to.equal('super video channel description')
206 expect(videoChannels[0].support).to.equal('super video channel support text') 180 expect(videoChannel.support).to.equal('super video channel support text')
207 }) 181 })
208 182
209 it('Should list video channels', async function () { 183 it('Should list video channels', async function () {
210 const res = await getVideoChannelsList(servers[0].url, 1, 1, '-name') 184 const body = await servers[0].channelsCommand.list({ start: 1, count: 1, sort: '-name' })
211 185
212 expect(res.body.total).to.equal(2) 186 expect(body.total).to.equal(2)
213 expect(res.body.data).to.be.an('array') 187 expect(body.data).to.be.an('array')
214 expect(res.body.data).to.have.lengthOf(1) 188 expect(body.data).to.have.lengthOf(1)
215 expect(res.body.data[0].name).to.equal('root_channel') 189 expect(body.data[0].name).to.equal('root_channel')
216 expect(res.body.data[0].displayName).to.equal('Main root channel') 190 expect(body.data[0].displayName).to.equal('Main root channel')
217 }) 191 })
218 192
219 it('Should update video channel', async function () { 193 it('Should update video channel', async function () {
@@ -225,22 +199,23 @@ describe('Test video channels', function () {
225 support: 'support updated' 199 support: 'support updated'
226 } 200 }
227 201
228 await updateVideoChannel(servers[0].url, servers[0].accessToken, 'second_video_channel', videoChannelAttributes) 202 await servers[0].channelsCommand.update({ channelName: 'second_video_channel', attributes: videoChannelAttributes })
229 203
230 await waitJobs(servers) 204 await waitJobs(servers)
231 }) 205 })
232 206
233 it('Should have video channel updated', async function () { 207 it('Should have video channel updated', async function () {
234 for (const server of servers) { 208 for (const server of servers) {
235 const res = await getVideoChannelsList(server.url, 0, 1, '-name') 209 const body = await server.channelsCommand.list({ start: 0, count: 1, sort: '-name' })
236 210
237 expect(res.body.total).to.equal(2) 211 expect(body.total).to.equal(2)
238 expect(res.body.data).to.be.an('array') 212 expect(body.data).to.be.an('array')
239 expect(res.body.data).to.have.lengthOf(1) 213 expect(body.data).to.have.lengthOf(1)
240 expect(res.body.data[0].name).to.equal('second_video_channel') 214
241 expect(res.body.data[0].displayName).to.equal('video channel updated') 215 expect(body.data[0].name).to.equal('second_video_channel')
242 expect(res.body.data[0].description).to.equal('video channel description updated') 216 expect(body.data[0].displayName).to.equal('video channel updated')
243 expect(res.body.data[0].support).to.equal('support updated') 217 expect(body.data[0].description).to.equal('video channel description updated')
218 expect(body.data[0].support).to.equal('support updated')
244 } 219 }
245 }) 220 })
246 221
@@ -261,7 +236,7 @@ describe('Test video channels', function () {
261 bulkVideosSupportUpdate: true 236 bulkVideosSupportUpdate: true
262 } 237 }
263 238
264 await updateVideoChannel(servers[0].url, servers[0].accessToken, 'second_video_channel', videoChannelAttributes) 239 await servers[0].channelsCommand.update({ channelName: 'second_video_channel', attributes: videoChannelAttributes })
265 240
266 await waitJobs(servers) 241 await waitJobs(servers)
267 242
@@ -278,10 +253,8 @@ describe('Test video channels', function () {
278 253
279 const fixture = 'avatar.png' 254 const fixture = 'avatar.png'
280 255
281 await updateVideoChannelImage({ 256 await servers[0].channelsCommand.updateImage({
282 url: servers[0].url, 257 channelName: 'second_video_channel',
283 accessToken: servers[0].accessToken,
284 videoChannelName: 'second_video_channel',
285 fixture, 258 fixture,
286 type: 'avatar' 259 type: 'avatar'
287 }) 260 })
@@ -306,10 +279,8 @@ describe('Test video channels', function () {
306 279
307 const fixture = 'banner.jpg' 280 const fixture = 'banner.jpg'
308 281
309 await updateVideoChannelImage({ 282 await servers[0].channelsCommand.updateImage({
310 url: servers[0].url, 283 channelName: 'second_video_channel',
311 accessToken: servers[0].accessToken,
312 videoChannelName: 'second_video_channel',
313 fixture, 284 fixture,
314 type: 'banner' 285 type: 'banner'
315 }) 286 })
@@ -317,8 +288,7 @@ describe('Test video channels', function () {
317 await waitJobs(servers) 288 await waitJobs(servers)
318 289
319 for (const server of servers) { 290 for (const server of servers) {
320 const res = await getVideoChannel(server.url, 'second_video_channel@' + servers[0].host) 291 const videoChannel = await server.channelsCommand.get({ channelName: 'second_video_channel@' + servers[0].host })
321 const videoChannel = res.body
322 292
323 bannerPaths[server.port] = videoChannel.banner.path 293 bannerPaths[server.port] = videoChannel.banner.path
324 await testImage(server.url, 'banner-resized', bannerPaths[server.port]) 294 await testImage(server.url, 'banner-resized', bannerPaths[server.port])
@@ -333,12 +303,7 @@ describe('Test video channels', function () {
333 it('Should delete the video channel avatar', async function () { 303 it('Should delete the video channel avatar', async function () {
334 this.timeout(15000) 304 this.timeout(15000)
335 305
336 await deleteVideoChannelImage({ 306 await servers[0].channelsCommand.deleteImage({ channelName: 'second_video_channel', type: 'avatar' })
337 url: servers[0].url,
338 accessToken: servers[0].accessToken,
339 videoChannelName: 'second_video_channel',
340 type: 'avatar'
341 })
342 307
343 await waitJobs(servers) 308 await waitJobs(servers)
344 309
@@ -353,12 +318,7 @@ describe('Test video channels', function () {
353 it('Should delete the video channel banner', async function () { 318 it('Should delete the video channel banner', async function () {
354 this.timeout(15000) 319 this.timeout(15000)
355 320
356 await deleteVideoChannelImage({ 321 await servers[0].channelsCommand.deleteImage({ channelName: 'second_video_channel', type: 'banner' })
357 url: servers[0].url,
358 accessToken: servers[0].accessToken,
359 videoChannelName: 'second_video_channel',
360 type: 'banner'
361 })
362 322
363 await waitJobs(servers) 323 await waitJobs(servers)
364 324
@@ -411,23 +371,23 @@ describe('Test video channels', function () {
411 }) 371 })
412 372
413 it('Should delete video channel', async function () { 373 it('Should delete video channel', async function () {
414 await deleteVideoChannel(servers[0].url, servers[0].accessToken, 'second_video_channel') 374 await servers[0].channelsCommand.delete({ channelName: 'second_video_channel' })
415 }) 375 })
416 376
417 it('Should have video channel deleted', async function () { 377 it('Should have video channel deleted', async function () {
418 const res = await getVideoChannelsList(servers[0].url, 0, 10) 378 const body = await servers[0].channelsCommand.list({ start: 0, count: 10 })
419 379
420 expect(res.body.total).to.equal(1) 380 expect(body.total).to.equal(1)
421 expect(res.body.data).to.be.an('array') 381 expect(body.data).to.be.an('array')
422 expect(res.body.data).to.have.lengthOf(1) 382 expect(body.data).to.have.lengthOf(1)
423 expect(res.body.data[0].displayName).to.equal('Main root channel') 383 expect(body.data[0].displayName).to.equal('Main root channel')
424 }) 384 })
425 385
426 it('Should create the main channel with an uuid if there is a conflict', async function () { 386 it('Should create the main channel with an uuid if there is a conflict', async function () {
427 { 387 {
428 const videoChannel = { name: 'toto_channel', displayName: 'My toto channel' } 388 const videoChannel = { name: 'toto_channel', displayName: 'My toto channel' }
429 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, videoChannel) 389 const created = await servers[0].channelsCommand.create({ attributes: videoChannel })
430 totoChannel = res.body.videoChannel.id 390 totoChannel = created.id
431 } 391 }
432 392
433 { 393 {
@@ -444,15 +404,9 @@ describe('Test video channels', function () {
444 this.timeout(10000) 404 this.timeout(10000)
445 405
446 { 406 {
447 const res = await getAccountVideoChannelsList({ 407 const { data } = await servers[0].channelsCommand.listByAccount({ accountName, withStats: true })
448 url: servers[0].url,
449 accountName,
450 withStats: true
451 })
452
453 const channels: VideoChannel[] = res.body.data
454 408
455 for (const channel of channels) { 409 for (const channel of data) {
456 expect(channel).to.haveOwnProperty('viewsPerDay') 410 expect(channel).to.haveOwnProperty('viewsPerDay')
457 expect(channel.viewsPerDay).to.have.length(30 + 1) // daysPrior + today 411 expect(channel.viewsPerDay).to.have.length(30 + 1) // daysPrior + today
458 412
@@ -471,26 +425,17 @@ describe('Test video channels', function () {
471 // Wait the repeatable job 425 // Wait the repeatable job
472 await wait(8000) 426 await wait(8000)
473 427
474 const res = await getAccountVideoChannelsList({ 428 const { data } = await servers[0].channelsCommand.listByAccount({ accountName, withStats: true })
475 url: servers[0].url, 429 const channelWithView = data.find(channel => channel.id === servers[0].videoChannel.id)
476 accountName,
477 withStats: true
478 })
479 const channelWithView = res.body.data.find((channel: VideoChannel) => channel.id === servers[0].videoChannel.id)
480 expect(channelWithView.viewsPerDay.slice(-1)[0].views).to.equal(2) 430 expect(channelWithView.viewsPerDay.slice(-1)[0].views).to.equal(2)
481 } 431 }
482 }) 432 })
483 433
484 it('Should report correct videos count', async function () { 434 it('Should report correct videos count', async function () {
485 const res = await getAccountVideoChannelsList({ 435 const { data } = await servers[0].channelsCommand.listByAccount({ accountName, withStats: true })
486 url: servers[0].url,
487 accountName,
488 withStats: true
489 })
490 const channels: VideoChannel[] = res.body.data
491 436
492 const totoChannel = channels.find(c => c.name === 'toto_channel') 437 const totoChannel = data.find(c => c.name === 'toto_channel')
493 const rootChannel = channels.find(c => c.name === 'root_channel') 438 const rootChannel = data.find(c => c.name === 'root_channel')
494 439
495 expect(rootChannel.videosCount).to.equal(1) 440 expect(rootChannel.videosCount).to.equal(1)
496 expect(totoChannel.videosCount).to.equal(0) 441 expect(totoChannel.videosCount).to.equal(0)
@@ -498,26 +443,18 @@ describe('Test video channels', function () {
498 443
499 it('Should search among account video channels', async function () { 444 it('Should search among account video channels', async function () {
500 { 445 {
501 const res = await getAccountVideoChannelsList({ 446 const body = await servers[0].channelsCommand.listByAccount({ accountName, search: 'root' })
502 url: servers[0].url, 447 expect(body.total).to.equal(1)
503 accountName,
504 search: 'root'
505 })
506 expect(res.body.total).to.equal(1)
507 448
508 const channels = res.body.data 449 const channels = body.data
509 expect(channels).to.have.lengthOf(1) 450 expect(channels).to.have.lengthOf(1)
510 } 451 }
511 452
512 { 453 {
513 const res = await getAccountVideoChannelsList({ 454 const body = await servers[0].channelsCommand.listByAccount({ accountName, search: 'does not exist' })
514 url: servers[0].url, 455 expect(body.total).to.equal(0)
515 accountName,
516 search: 'does not exist'
517 })
518 expect(res.body.total).to.equal(0)
519 456
520 const channels = res.body.data 457 const channels = body.data
521 expect(channels).to.have.lengthOf(0) 458 expect(channels).to.have.lengthOf(0)
522 } 459 }
523 }) 460 })
@@ -529,30 +466,20 @@ describe('Test video channels', function () {
529 await waitJobs(servers) 466 await waitJobs(servers)
530 467
531 for (const server of servers) { 468 for (const server of servers) {
532 const res = await getAccountVideoChannelsList({ 469 const { data } = await server.channelsCommand.listByAccount({ accountName, sort: '-updatedAt' })
533 url: server.url,
534 accountName,
535 sort: '-updatedAt'
536 })
537 470
538 const channels: VideoChannel[] = res.body.data 471 expect(data[0].name).to.equal('toto_channel')
539 expect(channels[0].name).to.equal('toto_channel') 472 expect(data[1].name).to.equal('root_channel')
540 expect(channels[1].name).to.equal('root_channel')
541 } 473 }
542 474
543 await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: servers[0].videoChannel.id }) 475 await uploadVideo(servers[0].url, servers[0].accessToken, { channelId: servers[0].videoChannel.id })
544 await waitJobs(servers) 476 await waitJobs(servers)
545 477
546 for (const server of servers) { 478 for (const server of servers) {
547 const res = await getAccountVideoChannelsList({ 479 const { data } = await server.channelsCommand.listByAccount({ accountName, sort: '-updatedAt' })
548 url: server.url,
549 accountName,
550 sort: '-updatedAt'
551 })
552 480
553 const channels: VideoChannel[] = res.body.data 481 expect(data[0].name).to.equal('root_channel')
554 expect(channels[0].name).to.equal('root_channel') 482 expect(data[1].name).to.equal('toto_channel')
555 expect(channels[1].name).to.equal('toto_channel')
556 } 483 }
557 }) 484 })
558 485
diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts
index 4de6b3abf..2bb019348 100644
--- a/server/tests/api/videos/video-playlists.ts
+++ b/server/tests/api/videos/video-playlists.ts
@@ -4,11 +4,9 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { HttpStatusCode } from '@shared/core-utils' 5import { HttpStatusCode } from '@shared/core-utils'
6import { 6import {
7 addVideoChannel,
8 checkPlaylistFilesWereRemoved, 7 checkPlaylistFilesWereRemoved,
9 cleanupTests, 8 cleanupTests,
10 createUser, 9 createUser,
11 deleteVideoChannel,
12 doubleFollow, 10 doubleFollow,
13 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
14 generateUserAccessToken, 12 generateUserAccessToken,
@@ -1096,20 +1094,19 @@ describe('Test video playlists', function () {
1096 it('Should delete a channel and put the associated playlist in private mode', async function () { 1094 it('Should delete a channel and put the associated playlist in private mode', async function () {
1097 this.timeout(30000) 1095 this.timeout(30000)
1098 1096
1099 const res = await addVideoChannel(servers[0].url, servers[0].accessToken, { name: 'super_channel', displayName: 'super channel' }) 1097 const channel = await servers[0].channelsCommand.create({ attributes: { name: 'super_channel', displayName: 'super channel' } })
1100 const videoChannelId = res.body.videoChannel.id
1101 1098
1102 const playlistCreated = await commands[0].create({ 1099 const playlistCreated = await commands[0].create({
1103 attributes: { 1100 attributes: {
1104 displayName: 'channel playlist', 1101 displayName: 'channel playlist',
1105 privacy: VideoPlaylistPrivacy.PUBLIC, 1102 privacy: VideoPlaylistPrivacy.PUBLIC,
1106 videoChannelId 1103 videoChannelId: channel.id
1107 } 1104 }
1108 }) 1105 })
1109 1106
1110 await waitJobs(servers) 1107 await waitJobs(servers)
1111 1108
1112 await deleteVideoChannel(servers[0].url, servers[0].accessToken, 'super_channel') 1109 await servers[0].channelsCommand.delete({ channelName: 'super_channel' })
1113 1110
1114 await waitJobs(servers) 1111 await waitJobs(servers)
1115 1112
diff --git a/server/tests/cli/peertube.ts b/server/tests/cli/peertube.ts
index 64a93ebb5..ef7ab5bd5 100644
--- a/server/tests/cli/peertube.ts
+++ b/server/tests/cli/peertube.ts
@@ -4,7 +4,6 @@ import 'mocha'
4import { expect } from 'chai' 4import { expect } from 'chai'
5import { Video, VideoDetails } from '../../../shared' 5import { Video, VideoDetails } from '../../../shared'
6import { 6import {
7 addVideoChannel,
8 areHttpImportTestsDisabled, 7 areHttpImportTestsDisabled,
9 buildAbsoluteFixturePath, 8 buildAbsoluteFixturePath,
10 cleanupTests, 9 cleanupTests,
@@ -44,8 +43,8 @@ describe('Test CLI wrapper', function () {
44 userAccessToken = await userLogin(server, { username: 'user_1', password: 'super_password' }) 43 userAccessToken = await userLogin(server, { username: 'user_1', password: 'super_password' })
45 44
46 { 45 {
47 const args = { name: 'user_channel', displayName: 'User channel', support: 'super support text' } 46 const attributes = { name: 'user_channel', displayName: 'User channel', support: 'super support text' }
48 await addVideoChannel(server.url, userAccessToken, args) 47 await server.channelsCommand.create({ token: userAccessToken, attributes })
49 } 48 }
50 49
51 cliCommand = server.cliCommand 50 cliCommand = server.cliCommand
diff --git a/server/tests/cli/update-host.ts b/server/tests/cli/update-host.ts
index f6131a99f..09a3dd1e7 100644
--- a/server/tests/cli/update-host.ts
+++ b/server/tests/cli/update-host.ts
@@ -2,13 +2,11 @@
2 2
3import 'mocha' 3import 'mocha'
4import { 4import {
5 addVideoChannel,
6 addVideoCommentThread, 5 addVideoCommentThread,
7 cleanupTests, 6 cleanupTests,
8 createUser, 7 createUser,
9 flushAndRunServer, 8 flushAndRunServer,
10 getVideo, 9 getVideo,
11 getVideoChannelsList,
12 getVideosList, 10 getVideosList,
13 killallServers, 11 killallServers,
14 makeActivityPubGetRequest, 12 makeActivityPubGetRequest,
@@ -53,7 +51,7 @@ describe('Test update host scripts', function () {
53 displayName: 'second video channel', 51 displayName: 'second video channel',
54 description: 'super video channel description' 52 description: 'super video channel description'
55 } 53 }
56 await addVideoChannel(server.url, server.accessToken, videoChannel) 54 await server.channelsCommand.create({ attributes: videoChannel })
57 55
58 // Create comments 56 // Create comments
59 const text = 'my super first comment' 57 const text = 'my super first comment'
@@ -91,10 +89,10 @@ describe('Test update host scripts', function () {
91 }) 89 })
92 90
93 it('Should have updated video channels url', async function () { 91 it('Should have updated video channels url', async function () {
94 const res = await getVideoChannelsList(server.url, 0, 5, '-name') 92 const { data, total } = await server.channelsCommand.list({ sort: '-name' })
95 expect(res.body.total).to.equal(3) 93 expect(total).to.equal(3)
96 94
97 for (const channel of res.body.data) { 95 for (const channel of data) {
98 const { body } = await makeActivityPubGetRequest(server.url, '/video-channels/' + channel.name) 96 const { body } = await makeActivityPubGetRequest(server.url, '/video-channels/' + channel.name)
99 97
100 expect(body.id).to.equal('http://localhost:9002/video-channels/' + channel.name) 98 expect(body.id).to.equal('http://localhost:9002/video-channels/' + channel.name)
diff --git a/server/tests/client.ts b/server/tests/client.ts
index 129f1e1c0..1bdb2eb64 100644
--- a/server/tests/client.ts
+++ b/server/tests/client.ts
@@ -16,7 +16,6 @@ import {
16 setAccessTokensToServers, 16 setAccessTokensToServers,
17 setDefaultVideoChannel, 17 setDefaultVideoChannel,
18 updateMyUser, 18 updateMyUser,
19 updateVideoChannel,
20 uploadVideo, 19 uploadVideo,
21 waitJobs 20 waitJobs
22} from '../../shared/extra-utils' 21} from '../../shared/extra-utils'
@@ -63,7 +62,10 @@ describe('Test a client controllers', function () {
63 62
64 await setDefaultVideoChannel(servers) 63 await setDefaultVideoChannel(servers)
65 64
66 await updateVideoChannel(servers[0].url, servers[0].accessToken, servers[0].videoChannel.name, { description: channelDescription }) 65 await servers[0].channelsCommand.update({
66 channelName: servers[0].videoChannel.name,
67 attributes: { description: channelDescription }
68 })
67 69
68 // Video 70 // Video
69 71
diff --git a/server/tests/misc-endpoints.ts b/server/tests/misc-endpoints.ts
index 09e5afcf9..4b7b2163d 100644
--- a/server/tests/misc-endpoints.ts
+++ b/server/tests/misc-endpoints.ts
@@ -2,8 +2,8 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { HttpStatusCode } from '@shared/core-utils'
5import { 6import {
6 addVideoChannel,
7 cleanupTests, 7 cleanupTests,
8 createUser, 8 createUser,
9 flushAndRunServer, 9 flushAndRunServer,
@@ -13,7 +13,6 @@ import {
13 uploadVideo 13 uploadVideo
14} from '../../shared/extra-utils' 14} from '../../shared/extra-utils'
15import { VideoPrivacy } from '../../shared/models/videos' 15import { VideoPrivacy } from '../../shared/models/videos'
16import { HttpStatusCode } from '@shared/core-utils'
17 16
18const expect = chai.expect 17const expect = chai.expect
19 18
@@ -171,8 +170,8 @@ describe('Test misc endpoints', function () {
171 await uploadVideo(server.url, server.accessToken, { name: 'video 2', nsfw: false }) 170 await uploadVideo(server.url, server.accessToken, { name: 'video 2', nsfw: false })
172 await uploadVideo(server.url, server.accessToken, { name: 'video 3', privacy: VideoPrivacy.PRIVATE }) 171 await uploadVideo(server.url, server.accessToken, { name: 'video 3', privacy: VideoPrivacy.PRIVATE })
173 172
174 await addVideoChannel(server.url, server.accessToken, { name: 'channel1', displayName: 'channel 1' }) 173 await server.channelsCommand.create({ attributes: { name: 'channel1', displayName: 'channel 1' } })
175 await addVideoChannel(server.url, server.accessToken, { name: 'channel2', displayName: 'channel 2' }) 174 await server.channelsCommand.create({ attributes: { name: 'channel2', displayName: 'channel 2' } })
176 175
177 await createUser({ url: server.url, accessToken: server.accessToken, username: 'user1', password: 'password' }) 176 await createUser({ url: server.url, accessToken: server.accessToken, username: 'user1', password: 'password' })
178 await createUser({ url: server.url, accessToken: server.accessToken, username: 'user2', password: 'password' }) 177 await createUser({ url: server.url, accessToken: server.accessToken, username: 'user2', password: 'password' })
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index 6a1dadbcc..68e10af5f 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -22,6 +22,7 @@ import {
22 BlacklistCommand, 22 BlacklistCommand,
23 CaptionsCommand, 23 CaptionsCommand,
24 ChangeOwnershipCommand, 24 ChangeOwnershipCommand,
25 ChannelsCommand,
25 HistoryCommand, 26 HistoryCommand,
26 ImportsCommand, 27 ImportsCommand,
27 LiveCommand, 28 LiveCommand,
@@ -119,6 +120,7 @@ interface ServerInfo {
119 historyCommand?: HistoryCommand 120 historyCommand?: HistoryCommand
120 importsCommand?: ImportsCommand 121 importsCommand?: ImportsCommand
121 streamingPlaylistsCommand?: StreamingPlaylistsCommand 122 streamingPlaylistsCommand?: StreamingPlaylistsCommand
123 channelsCommand?: ChannelsCommand
122} 124}
123 125
124function parallelTests () { 126function parallelTests () {
@@ -353,6 +355,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = []
353 server.historyCommand = new HistoryCommand(server) 355 server.historyCommand = new HistoryCommand(server)
354 server.importsCommand = new ImportsCommand(server) 356 server.importsCommand = new ImportsCommand(server)
355 server.streamingPlaylistsCommand = new StreamingPlaylistsCommand(server) 357 server.streamingPlaylistsCommand = new StreamingPlaylistsCommand(server)
358 server.channelsCommand = new ChannelsCommand(server)
356 359
357 res(server) 360 res(server)
358 }) 361 })
diff --git a/shared/extra-utils/shared/abstract-command.ts b/shared/extra-utils/shared/abstract-command.ts
index be368376f..6a9ab1348 100644
--- a/shared/extra-utils/shared/abstract-command.ts
+++ b/shared/extra-utils/shared/abstract-command.ts
@@ -1,4 +1,6 @@
1import { isAbsolute, join } from 'path'
1import { HttpStatusCode } from '@shared/core-utils' 2import { HttpStatusCode } from '@shared/core-utils'
3import { root } from '../miscs'
2import { 4import {
3 makeDeleteRequest, 5 makeDeleteRequest,
4 makeGetRequest, 6 makeGetRequest,
@@ -146,6 +148,25 @@ abstract class AbstractCommand {
146 }) 148 })
147 } 149 }
148 150
151 protected updateImageRequest (options: InternalCommonCommandOptions & {
152 fixture: string
153 fieldname: string
154 }) {
155 let filePath = ''
156 if (isAbsolute(options.fixture)) {
157 filePath = options.fixture
158 } else {
159 filePath = join(root(), 'server', 'tests', 'fixtures', options.fixture)
160 }
161
162 return this.postUploadRequest({
163 ...options,
164
165 fields: {},
166 attaches: { [options.fieldname]: filePath }
167 })
168 }
169
149 private buildCommonRequestOptions (options: InternalCommonCommandOptions) { 170 private buildCommonRequestOptions (options: InternalCommonCommandOptions) {
150 const { path } = options 171 const { path } = options
151 172
diff --git a/shared/extra-utils/videos/channels-command.ts b/shared/extra-utils/videos/channels-command.ts
new file mode 100644
index 000000000..a98c5cc93
--- /dev/null
+++ b/shared/extra-utils/videos/channels-command.ts
@@ -0,0 +1,157 @@
1import { pick } from 'lodash'
2import { ResultList, VideoChannel, VideoChannelCreateResult } from '@shared/models'
3import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes'
4import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model'
5import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model'
6import { unwrapBody } from '../requests'
7import { AbstractCommand, OverrideCommandOptions } from '../shared'
8
9export class ChannelsCommand extends AbstractCommand {
10
11 list (options: OverrideCommandOptions & {
12 start?: number
13 count?: number
14 sort?: string
15 withStats?: boolean
16 } = {}) {
17 const path = '/api/v1/video-channels'
18
19 return this.getRequestBody<ResultList<VideoChannel>>({
20 ...options,
21
22 path,
23 query: pick(options, [ 'start', 'count', 'sort', 'withStats' ]),
24 implicitToken: false,
25 defaultExpectedStatus: HttpStatusCode.OK_200
26 })
27 }
28
29 listByAccount (options: OverrideCommandOptions & {
30 accountName: string
31 start?: number
32 count?: number
33 sort?: string
34 withStats?: boolean
35 search?: string
36 }) {
37 const { accountName, sort = 'createdAt' } = options
38 const path = '/api/v1/accounts/' + accountName + '/video-channels'
39
40 return this.getRequestBody<ResultList<VideoChannel>>({
41 ...options,
42
43 path,
44 query: { sort, ...pick(options, [ 'start', 'count', 'withStats', 'search' ]) },
45 implicitToken: false,
46 defaultExpectedStatus: HttpStatusCode.OK_200
47 })
48 }
49
50 async create (options: OverrideCommandOptions & {
51 attributes: VideoChannelCreate
52 }) {
53 const path = '/api/v1/video-channels/'
54
55 // Default attributes
56 const defaultAttributes = {
57 displayName: 'my super video channel',
58 description: 'my super channel description',
59 support: 'my super channel support'
60 }
61 const attributes = { ...defaultAttributes, ...options.attributes }
62
63 const body = await unwrapBody<{ videoChannel: VideoChannelCreateResult }>(this.postBodyRequest({
64 ...options,
65
66 path,
67 fields: attributes,
68 implicitToken: true,
69 defaultExpectedStatus: HttpStatusCode.OK_200
70 }))
71
72 return body.videoChannel
73 }
74
75 update (options: OverrideCommandOptions & {
76 channelName: string
77 attributes: VideoChannelUpdate
78 }) {
79 const { channelName, attributes } = options
80 const path = '/api/v1/video-channels/' + channelName
81
82 return this.putBodyRequest({
83 ...options,
84
85 path,
86 fields: attributes,
87 implicitToken: true,
88 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
89 })
90 }
91
92 delete (options: OverrideCommandOptions & {
93 channelName: string
94 }) {
95 const path = '/api/v1/video-channels/' + options.channelName
96
97 return this.deleteRequest({
98 ...options,
99
100 path,
101 implicitToken: true,
102 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
103 })
104 }
105
106 get (options: OverrideCommandOptions & {
107 channelName: string
108 }) {
109 const path = '/api/v1/video-channels/' + options.channelName
110
111 return this.getRequestBody<VideoChannel>({
112 ...options,
113
114 path,
115 implicitToken: false,
116 defaultExpectedStatus: HttpStatusCode.OK_200
117 })
118 }
119
120 updateImage (options: OverrideCommandOptions & {
121 fixture: string
122 channelName: string | number
123 type: 'avatar' | 'banner'
124 }) {
125 const { channelName, fixture, type } = options
126
127 const path = `/api/v1/video-channels/${channelName}/${type}/pick`
128
129 return this.updateImageRequest({
130 ...options,
131
132 path,
133 fixture,
134 fieldname: type + 'file',
135
136 implicitToken: true,
137 defaultExpectedStatus: HttpStatusCode.OK_200
138 })
139 }
140
141 deleteImage (options: OverrideCommandOptions & {
142 channelName: string | number
143 type: 'avatar' | 'banner'
144 }) {
145 const { channelName, type } = options
146
147 const path = `/api/v1/video-channels/${channelName}/${type}`
148
149 return this.deleteRequest({
150 ...options,
151
152 path,
153 implicitToken: true,
154 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
155 })
156 }
157}
diff --git a/shared/extra-utils/videos/channels.ts b/shared/extra-utils/videos/channels.ts
new file mode 100644
index 000000000..a77543c92
--- /dev/null
+++ b/shared/extra-utils/videos/channels.ts
@@ -0,0 +1,20 @@
1import { User } from '../../models/users/user.model'
2import { ServerInfo } from '../server/servers'
3import { getMyUserInformation } from '../users/users'
4
5function setDefaultVideoChannel (servers: ServerInfo[]) {
6 const tasks: Promise<any>[] = []
7
8 for (const server of servers) {
9 const p = getMyUserInformation(server.url, server.accessToken)
10 .then(res => { server.videoChannel = (res.body as User).videoChannels[0] })
11
12 tasks.push(p)
13 }
14
15 return Promise.all(tasks)
16}
17
18export {
19 setDefaultVideoChannel
20}
diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts
index f87ae8eea..3bc219281 100644
--- a/shared/extra-utils/videos/index.ts
+++ b/shared/extra-utils/videos/index.ts
@@ -1,7 +1,9 @@
1export * from './blacklist-command' 1export * from './blacklist-command'
2export * from './captions'
3export * from './captions-command' 2export * from './captions-command'
3export * from './captions'
4export * from './change-ownership-command' 4export * from './change-ownership-command'
5export * from './channels'
6export * from './channels-command'
5export * from './history-command' 7export * from './history-command'
6export * from './imports-command' 8export * from './imports-command'
7export * from './live-command' 9export * from './live-command'
@@ -11,6 +13,5 @@ export * from './playlists'
11export * from './services-command' 13export * from './services-command'
12export * from './streaming-playlists-command' 14export * from './streaming-playlists-command'
13export * from './streaming-playlists' 15export * from './streaming-playlists'
14export * from './video-channels'
15export * from './video-comments' 16export * from './video-comments'
16export * from './videos' 17export * from './videos'
diff --git a/shared/extra-utils/videos/video-channels.ts b/shared/extra-utils/videos/video-channels.ts
deleted file mode 100644
index 0aab93e52..000000000
--- a/shared/extra-utils/videos/video-channels.ts
+++ /dev/null
@@ -1,192 +0,0 @@
1/* eslint-disable @typescript-eslint/no-floating-promises */
2
3import * as request from 'supertest'
4import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model'
5import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model'
6import { makeDeleteRequest, makeGetRequest, updateImageRequest } from '../requests/requests'
7import { ServerInfo } from '../server/servers'
8import { MyUser, User } from '../../models/users/user.model'
9import { getMyUserInformation } from '../users/users'
10import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
11
12function getVideoChannelsList (url: string, start: number, count: number, sort?: string, withStats?: boolean) {
13 const path = '/api/v1/video-channels'
14
15 const req = request(url)
16 .get(path)
17 .query({ start: start })
18 .query({ count: count })
19
20 if (sort) req.query({ sort })
21 if (withStats) req.query({ withStats })
22
23 return req.set('Accept', 'application/json')
24 .expect(HttpStatusCode.OK_200)
25 .expect('Content-Type', /json/)
26}
27
28function getAccountVideoChannelsList (parameters: {
29 url: string
30 accountName: string
31 start?: number
32 count?: number
33 sort?: string
34 specialStatus?: HttpStatusCode
35 withStats?: boolean
36 search?: string
37}) {
38 const {
39 url,
40 accountName,
41 start,
42 count,
43 sort = 'createdAt',
44 specialStatus = HttpStatusCode.OK_200,
45 withStats = false,
46 search
47 } = parameters
48
49 const path = '/api/v1/accounts/' + accountName + '/video-channels'
50
51 return makeGetRequest({
52 url,
53 path,
54 query: {
55 start,
56 count,
57 sort,
58 withStats,
59 search
60 },
61 statusCodeExpected: specialStatus
62 })
63}
64
65function addVideoChannel (
66 url: string,
67 token: string,
68 videoChannelAttributesArg: VideoChannelCreate,
69 expectedStatus = HttpStatusCode.OK_200
70) {
71 const path = '/api/v1/video-channels/'
72
73 // Default attributes
74 let attributes = {
75 displayName: 'my super video channel',
76 description: 'my super channel description',
77 support: 'my super channel support'
78 }
79 attributes = Object.assign(attributes, videoChannelAttributesArg)
80
81 return request(url)
82 .post(path)
83 .send(attributes)
84 .set('Accept', 'application/json')
85 .set('Authorization', 'Bearer ' + token)
86 .expect(expectedStatus)
87}
88
89function updateVideoChannel (
90 url: string,
91 token: string,
92 channelName: string,
93 attributes: VideoChannelUpdate,
94 expectedStatus = HttpStatusCode.NO_CONTENT_204
95) {
96 const body: any = {}
97 const path = '/api/v1/video-channels/' + channelName
98
99 if (attributes.displayName) body.displayName = attributes.displayName
100 if (attributes.description) body.description = attributes.description
101 if (attributes.support) body.support = attributes.support
102 if (attributes.bulkVideosSupportUpdate) body.bulkVideosSupportUpdate = attributes.bulkVideosSupportUpdate
103
104 return request(url)
105 .put(path)
106 .send(body)
107 .set('Accept', 'application/json')
108 .set('Authorization', 'Bearer ' + token)
109 .expect(expectedStatus)
110}
111
112function deleteVideoChannel (url: string, token: string, channelName: string, expectedStatus = HttpStatusCode.NO_CONTENT_204) {
113 const path = '/api/v1/video-channels/' + channelName
114
115 return request(url)
116 .delete(path)
117 .set('Accept', 'application/json')
118 .set('Authorization', 'Bearer ' + token)
119 .expect(expectedStatus)
120}
121
122function getVideoChannel (url: string, channelName: string) {
123 const path = '/api/v1/video-channels/' + channelName
124
125 return request(url)
126 .get(path)
127 .set('Accept', 'application/json')
128 .expect(HttpStatusCode.OK_200)
129 .expect('Content-Type', /json/)
130}
131
132function updateVideoChannelImage (options: {
133 url: string
134 accessToken: string
135 fixture: string
136 videoChannelName: string | number
137 type: 'avatar' | 'banner'
138}) {
139 const path = `/api/v1/video-channels/${options.videoChannelName}/${options.type}/pick`
140
141 return updateImageRequest({ ...options, path, fieldname: options.type + 'file' })
142}
143
144function deleteVideoChannelImage (options: {
145 url: string
146 accessToken: string
147 videoChannelName: string | number
148 type: 'avatar' | 'banner'
149}) {
150 const path = `/api/v1/video-channels/${options.videoChannelName}/${options.type}`
151
152 return makeDeleteRequest({
153 url: options.url,
154 token: options.accessToken,
155 path,
156 statusCodeExpected: 204
157 })
158}
159
160function setDefaultVideoChannel (servers: ServerInfo[]) {
161 const tasks: Promise<any>[] = []
162
163 for (const server of servers) {
164 const p = getMyUserInformation(server.url, server.accessToken)
165 .then(res => { server.videoChannel = (res.body as User).videoChannels[0] })
166
167 tasks.push(p)
168 }
169
170 return Promise.all(tasks)
171}
172
173async function getDefaultVideoChannel (url: string, token: string) {
174 const res = await getMyUserInformation(url, token)
175
176 return (res.body as MyUser).videoChannels[0].id
177}
178
179// ---------------------------------------------------------------------------
180
181export {
182 updateVideoChannelImage,
183 getVideoChannelsList,
184 getAccountVideoChannelsList,
185 addVideoChannel,
186 updateVideoChannel,
187 deleteVideoChannel,
188 getVideoChannel,
189 setDefaultVideoChannel,
190 deleteVideoChannelImage,
191 getDefaultVideoChannel
192}
diff --git a/shared/models/videos/channel/index.ts b/shared/models/videos/channel/index.ts
index 9dbaa42da..6cdabffbd 100644
--- a/shared/models/videos/channel/index.ts
+++ b/shared/models/videos/channel/index.ts
@@ -1,3 +1,4 @@
1export * from './video-channel-create-result.model'
1export * from './video-channel-create.model' 2export * from './video-channel-create.model'
2export * from './video-channel-update.model' 3export * from './video-channel-update.model'
3export * from './video-channel.model' 4export * from './video-channel.model'
diff --git a/shared/models/videos/channel/video-channel-create-result.model.ts b/shared/models/videos/channel/video-channel-create-result.model.ts
new file mode 100644
index 000000000..e3d7aeb4c
--- /dev/null
+++ b/shared/models/videos/channel/video-channel-create-result.model.ts
@@ -0,0 +1,3 @@
1export interface VideoChannelCreateResult {
2 id: number
3}