aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/tests/src/api/videos/video-channel-syncs.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/tests/src/api/videos/video-channel-syncs.ts')
-rw-r--r--packages/tests/src/api/videos/video-channel-syncs.ts321
1 files changed, 321 insertions, 0 deletions
diff --git a/packages/tests/src/api/videos/video-channel-syncs.ts b/packages/tests/src/api/videos/video-channel-syncs.ts
new file mode 100644
index 000000000..54212bcb5
--- /dev/null
+++ b/packages/tests/src/api/videos/video-channel-syncs.ts
@@ -0,0 +1,321 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { areHttpImportTestsDisabled } from '@peertube/peertube-node-utils'
5import { VideoChannelSyncState, VideoInclude, VideoPrivacy } from '@peertube/peertube-models'
6import {
7 cleanupTests,
8 createMultipleServers,
9 getServerImportConfig,
10 PeerTubeServer,
11 setAccessTokensToServers,
12 setDefaultAccountAvatar,
13 setDefaultChannelAvatar,
14 setDefaultVideoChannel,
15 waitJobs
16} from '@peertube/peertube-server-commands'
17import { SQLCommand } from '@tests/shared/sql-command.js'
18import { FIXTURE_URLS } from '@tests/shared/tests.js'
19
20describe('Test channel synchronizations', function () {
21 if (areHttpImportTestsDisabled()) return
22
23 function runSuite (mode: 'youtube-dl' | 'yt-dlp') {
24
25 describe('Sync using ' + mode, function () {
26 let servers: PeerTubeServer[]
27 let sqlCommands: SQLCommand[] = []
28
29 let startTestDate: Date
30
31 let rootChannelSyncId: number
32 const userInfo = {
33 accessToken: '',
34 username: 'user1',
35 channelName: 'user1_channel',
36 channelId: -1,
37 syncId: -1
38 }
39
40 async function changeDateForSync (channelSyncId: number, newDate: string) {
41 await sqlCommands[0].updateQuery(
42 `UPDATE "videoChannelSync" ` +
43 `SET "createdAt"='${newDate}', "lastSyncAt"='${newDate}' ` +
44 `WHERE id=${channelSyncId}`
45 )
46 }
47
48 async function listAllVideosOfChannel (channelName: string) {
49 return servers[0].videos.listByChannel({
50 handle: channelName,
51 include: VideoInclude.NOT_PUBLISHED_STATE
52 })
53 }
54
55 async function forceSyncAll (videoChannelSyncId: number, fromDate = '1970-01-01') {
56 await changeDateForSync(videoChannelSyncId, fromDate)
57
58 await servers[0].debug.sendCommand({
59 body: {
60 command: 'process-video-channel-sync-latest'
61 }
62 })
63
64 await waitJobs(servers)
65 }
66
67 before(async function () {
68 this.timeout(240_000)
69
70 startTestDate = new Date()
71
72 servers = await createMultipleServers(2, getServerImportConfig(mode))
73
74 await setAccessTokensToServers(servers)
75 await setDefaultVideoChannel(servers)
76 await setDefaultChannelAvatar(servers)
77 await setDefaultAccountAvatar(servers)
78
79 await servers[0].config.enableChannelSync()
80
81 {
82 userInfo.accessToken = await servers[0].users.generateUserAndToken(userInfo.username)
83
84 const { videoChannels } = await servers[0].users.getMyInfo({ token: userInfo.accessToken })
85 userInfo.channelId = videoChannels[0].id
86 }
87
88 sqlCommands = servers.map(s => new SQLCommand(s))
89 })
90
91 it('Should fetch the latest channel videos of a remote channel', async function () {
92 this.timeout(120_000)
93
94 {
95 const { video } = await servers[0].imports.importVideo({
96 attributes: {
97 channelId: servers[0].store.channel.id,
98 privacy: VideoPrivacy.PUBLIC,
99 targetUrl: FIXTURE_URLS.youtube
100 }
101 })
102
103 expect(video.name).to.equal('small video - youtube')
104 expect(video.waitTranscoding).to.be.true
105
106 const { total } = await listAllVideosOfChannel('root_channel')
107 expect(total).to.equal(1)
108 }
109
110 const { videoChannelSync } = await servers[0].channelSyncs.create({
111 attributes: {
112 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
113 videoChannelId: servers[0].store.channel.id
114 }
115 })
116 rootChannelSyncId = videoChannelSync.id
117
118 await forceSyncAll(rootChannelSyncId)
119
120 {
121 const { total, data } = await listAllVideosOfChannel('root_channel')
122 expect(total).to.equal(2)
123 expect(data[0].name).to.equal('test')
124 expect(data[0].waitTranscoding).to.be.true
125 }
126 })
127
128 it('Should add another synchronization', async function () {
129 const externalChannelUrl = FIXTURE_URLS.youtubeChannel + '?foo=bar'
130
131 const { videoChannelSync } = await servers[0].channelSyncs.create({
132 attributes: {
133 externalChannelUrl,
134 videoChannelId: servers[0].store.channel.id
135 }
136 })
137
138 expect(videoChannelSync.externalChannelUrl).to.equal(externalChannelUrl)
139 expect(videoChannelSync.channel.id).to.equal(servers[0].store.channel.id)
140 expect(videoChannelSync.channel.name).to.equal('root_channel')
141 expect(videoChannelSync.state.id).to.equal(VideoChannelSyncState.WAITING_FIRST_RUN)
142 expect(new Date(videoChannelSync.createdAt)).to.be.above(startTestDate).and.to.be.at.most(new Date())
143 })
144
145 it('Should add a synchronization for another user', async function () {
146 const { videoChannelSync } = await servers[0].channelSyncs.create({
147 attributes: {
148 externalChannelUrl: FIXTURE_URLS.youtubeChannel + '?baz=qux',
149 videoChannelId: userInfo.channelId
150 },
151 token: userInfo.accessToken
152 })
153 userInfo.syncId = videoChannelSync.id
154 })
155
156 it('Should not import a channel if not asked', async function () {
157 await waitJobs(servers)
158
159 const { data } = await servers[0].channelSyncs.listByAccount({ accountName: userInfo.username })
160
161 expect(data[0].state).to.contain({
162 id: VideoChannelSyncState.WAITING_FIRST_RUN,
163 label: 'Waiting first run'
164 })
165 })
166
167 it('Should only fetch the videos newer than the creation date', async function () {
168 this.timeout(120_000)
169
170 await forceSyncAll(userInfo.syncId, '2019-03-01')
171
172 const { data, total } = await listAllVideosOfChannel(userInfo.channelName)
173
174 expect(total).to.equal(1)
175 expect(data[0].name).to.equal('test')
176 })
177
178 it('Should list channel synchronizations', async function () {
179 // Root
180 {
181 const { total, data } = await servers[0].channelSyncs.listByAccount({ accountName: 'root' })
182 expect(total).to.equal(2)
183
184 expect(data[0]).to.deep.contain({
185 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
186 state: {
187 id: VideoChannelSyncState.SYNCED,
188 label: 'Synchronized'
189 }
190 })
191
192 expect(new Date(data[0].lastSyncAt)).to.be.greaterThan(startTestDate)
193
194 expect(data[0].channel).to.contain({ id: servers[0].store.channel.id })
195 expect(data[1]).to.contain({ externalChannelUrl: FIXTURE_URLS.youtubeChannel + '?foo=bar' })
196 }
197
198 // User
199 {
200 const { total, data } = await servers[0].channelSyncs.listByAccount({ accountName: userInfo.username })
201 expect(total).to.equal(1)
202 expect(data[0]).to.deep.contain({
203 externalChannelUrl: FIXTURE_URLS.youtubeChannel + '?baz=qux',
204 state: {
205 id: VideoChannelSyncState.SYNCED,
206 label: 'Synchronized'
207 }
208 })
209 }
210 })
211
212 it('Should list imports of a channel synchronization', async function () {
213 const { total, data } = await servers[0].imports.getMyVideoImports({ videoChannelSyncId: rootChannelSyncId })
214
215 expect(total).to.equal(1)
216 expect(data).to.have.lengthOf(1)
217 expect(data[0].video.name).to.equal('test')
218 })
219
220 it('Should remove user\'s channel synchronizations', async function () {
221 await servers[0].channelSyncs.delete({ channelSyncId: userInfo.syncId })
222
223 const { total } = await servers[0].channelSyncs.listByAccount({ accountName: userInfo.username })
224 expect(total).to.equal(0)
225 })
226
227 // FIXME: youtube-dl/yt-dlp doesn't work when speicifying a port after the hostname
228 // it('Should import a remote PeerTube channel', async function () {
229 // this.timeout(240_000)
230
231 // await servers[1].videos.quickUpload({ name: 'remote 1' })
232 // await waitJobs(servers)
233
234 // const { videoChannelSync } = await servers[0].channelSyncs.create({
235 // attributes: {
236 // externalChannelUrl: servers[1].url + '/c/root_channel',
237 // videoChannelId: userInfo.channelId
238 // },
239 // token: userInfo.accessToken
240 // })
241 // await servers[0].channels.importVideos({
242 // channelName: userInfo.channelName,
243 // externalChannelUrl: servers[1].url + '/c/root_channel',
244 // videoChannelSyncId: videoChannelSync.id,
245 // token: userInfo.accessToken
246 // })
247
248 // await waitJobs(servers)
249
250 // const { data, total } = await servers[0].videos.listByChannel({
251 // handle: userInfo.channelName,
252 // include: VideoInclude.NOT_PUBLISHED_STATE
253 // })
254
255 // expect(total).to.equal(2)
256 // expect(data[0].name).to.equal('remote 1')
257 // })
258
259 // it('Should keep synced a remote PeerTube channel', async function () {
260 // this.timeout(240_000)
261
262 // await servers[1].videos.quickUpload({ name: 'remote 2' })
263 // await waitJobs(servers)
264
265 // await servers[0].debug.sendCommand({
266 // body: {
267 // command: 'process-video-channel-sync-latest'
268 // }
269 // })
270
271 // await waitJobs(servers)
272
273 // const { data, total } = await servers[0].videos.listByChannel({
274 // handle: userInfo.channelName,
275 // include: VideoInclude.NOT_PUBLISHED_STATE
276 // })
277 // expect(total).to.equal(2)
278 // expect(data[0].name).to.equal('remote 2')
279 // })
280
281 it('Should fetch the latest videos of a youtube playlist', async function () {
282 this.timeout(120_000)
283
284 const { id: channelId } = await servers[0].channels.create({
285 attributes: {
286 name: 'channel2'
287 }
288 })
289
290 const { videoChannelSync: { id: videoChannelSyncId } } = await servers[0].channelSyncs.create({
291 attributes: {
292 externalChannelUrl: FIXTURE_URLS.youtubePlaylist,
293 videoChannelId: channelId
294 }
295 })
296
297 await forceSyncAll(videoChannelSyncId)
298
299 {
300
301 const { total, data } = await listAllVideosOfChannel('channel2')
302 expect(total).to.equal(2)
303 expect(data[0].name).to.equal('test')
304 expect(data[1].name).to.equal('small video - youtube')
305 }
306 })
307
308 after(async function () {
309 for (const sqlCommand of sqlCommands) {
310 await sqlCommand.cleanup()
311 }
312
313 await cleanupTests(servers)
314 })
315 })
316 }
317
318 // FIXME: suite is broken with youtube-dl
319 // runSuite('youtube-dl')
320 runSuite('yt-dlp')
321})