]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/videos/video-channel-syncs.ts
Add ability to list imports of a channel sync
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-channel-syncs.ts
1 import 'mocha'
2 import { expect } from 'chai'
3 import { FIXTURE_URLS } from '@server/tests/shared'
4 import { areHttpImportTestsDisabled } from '@shared/core-utils'
5 import { HttpStatusCode, VideoChannelSyncState, VideoInclude, VideoPrivacy } from '@shared/models'
6 import {
7 ChannelSyncsCommand,
8 createSingleServer,
9 getServerImportConfig,
10 PeerTubeServer,
11 setAccessTokensToServers,
12 setDefaultAccountAvatar,
13 setDefaultChannelAvatar,
14 setDefaultVideoChannel,
15 waitJobs
16 } from '@shared/server-commands'
17
18 describe('Test channel synchronizations', function () {
19 if (areHttpImportTestsDisabled()) return
20
21 function runSuite (mode: 'youtube-dl' | 'yt-dlp') {
22
23 describe('Sync using ' + mode, function () {
24 let server: PeerTubeServer
25 let command: ChannelSyncsCommand
26
27 let startTestDate: Date
28
29 let rootChannelSyncId: number
30 const userInfo = {
31 accessToken: '',
32 username: 'user1',
33 channelName: 'user1_channel',
34 channelId: -1,
35 syncId: -1
36 }
37
38 async function changeDateForSync (channelSyncId: number, newDate: string) {
39 await server.sql.updateQuery(
40 `UPDATE "videoChannelSync" ` +
41 `SET "createdAt"='${newDate}', "lastSyncAt"='${newDate}' ` +
42 `WHERE id=${channelSyncId}`
43 )
44 }
45
46 before(async function () {
47 this.timeout(120_000)
48
49 startTestDate = new Date()
50
51 server = await createSingleServer(1, getServerImportConfig(mode))
52
53 await setAccessTokensToServers([ server ])
54 await setDefaultVideoChannel([ server ])
55 await setDefaultChannelAvatar([ server ])
56 await setDefaultAccountAvatar([ server ])
57
58 await server.config.enableChannelSync()
59
60 command = server.channelSyncs
61
62 {
63 userInfo.accessToken = await server.users.generateUserAndToken(userInfo.username)
64
65 const { videoChannels } = await server.users.getMyInfo({ token: userInfo.accessToken })
66 userInfo.channelId = videoChannels[0].id
67 }
68 })
69
70 it('Should fetch the latest channel videos of a remote channel', async function () {
71 this.timeout(120_000)
72
73 {
74 const { video } = await server.imports.importVideo({
75 attributes: {
76 channelId: server.store.channel.id,
77 privacy: VideoPrivacy.PUBLIC,
78 targetUrl: FIXTURE_URLS.youtube
79 }
80 })
81
82 expect(video.name).to.equal('small video - youtube')
83
84 const { total } = await server.videos.listByChannel({ handle: 'root_channel', include: VideoInclude.NOT_PUBLISHED_STATE })
85 expect(total).to.equal(1)
86 }
87
88 const { videoChannelSync } = await command.create({
89 attributes: {
90 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
91 videoChannelId: server.store.channel.id
92 },
93 token: server.accessToken,
94 expectedStatus: HttpStatusCode.OK_200
95 })
96 rootChannelSyncId = videoChannelSync.id
97
98 // Ensure any missing video not already fetched will be considered as new
99 await changeDateForSync(videoChannelSync.id, '1970-01-01')
100
101 await server.debug.sendCommand({
102 body: {
103 command: 'process-video-channel-sync-latest'
104 }
105 })
106
107 {
108 await waitJobs(server)
109
110 const { total, data } = await server.videos.listByChannel({ handle: 'root_channel', include: VideoInclude.NOT_PUBLISHED_STATE })
111 expect(total).to.equal(2)
112 expect(data[0].name).to.equal('test')
113 }
114 })
115
116 it('Should add another synchronization', async function () {
117 const externalChannelUrl = FIXTURE_URLS.youtubeChannel + '?foo=bar'
118
119 const { videoChannelSync } = await command.create({
120 attributes: {
121 externalChannelUrl,
122 videoChannelId: server.store.channel.id
123 },
124 token: server.accessToken,
125 expectedStatus: HttpStatusCode.OK_200
126 })
127
128 expect(videoChannelSync.externalChannelUrl).to.equal(externalChannelUrl)
129 expect(videoChannelSync.channel).to.include({
130 id: server.store.channel.id,
131 name: 'root_channel'
132 })
133 expect(videoChannelSync.state.id).to.equal(VideoChannelSyncState.WAITING_FIRST_RUN)
134 expect(new Date(videoChannelSync.createdAt)).to.be.above(startTestDate).and.to.be.at.most(new Date())
135 })
136
137 it('Should add a synchronization for another user', async function () {
138 const { videoChannelSync } = await command.create({
139 attributes: {
140 externalChannelUrl: FIXTURE_URLS.youtubeChannel + '?baz=qux',
141 videoChannelId: userInfo.channelId
142 },
143 token: userInfo.accessToken
144 })
145 userInfo.syncId = videoChannelSync.id
146 })
147
148 it('Should not import a channel if not asked', async function () {
149 await waitJobs(server)
150
151 const { data } = await command.listByAccount({ accountName: userInfo.username })
152
153 expect(data[0].state).to.contain({
154 id: VideoChannelSyncState.WAITING_FIRST_RUN,
155 label: 'Waiting first run'
156 })
157 })
158
159 it('Should only fetch the videos newer than the creation date', async function () {
160 this.timeout(120_000)
161
162 await changeDateForSync(userInfo.syncId, '2019-03-01')
163
164 await server.debug.sendCommand({
165 body: {
166 command: 'process-video-channel-sync-latest'
167 }
168 })
169
170 await waitJobs(server)
171
172 const { data, total } = await server.videos.listByChannel({
173 handle: userInfo.channelName,
174 include: VideoInclude.NOT_PUBLISHED_STATE
175 })
176
177 expect(total).to.equal(1)
178 expect(data[0].name).to.equal('test')
179 })
180
181 it('Should list channel synchronizations', async function () {
182 // Root
183 {
184 const { total, data } = await command.listByAccount({ accountName: 'root' })
185 expect(total).to.equal(2)
186
187 expect(data[0]).to.deep.contain({
188 externalChannelUrl: FIXTURE_URLS.youtubeChannel,
189 state: {
190 id: VideoChannelSyncState.SYNCED,
191 label: 'Synchronized'
192 }
193 })
194
195 expect(new Date(data[0].lastSyncAt)).to.be.greaterThan(startTestDate)
196
197 expect(data[0].channel).to.contain({ id: server.store.channel.id })
198 expect(data[1]).to.contain({ externalChannelUrl: FIXTURE_URLS.youtubeChannel + '?foo=bar' })
199 }
200
201 // User
202 {
203 const { total, data } = await command.listByAccount({ accountName: userInfo.username })
204 expect(total).to.equal(1)
205 expect(data[0]).to.deep.contain({
206 externalChannelUrl: FIXTURE_URLS.youtubeChannel + '?baz=qux',
207 state: {
208 id: VideoChannelSyncState.SYNCED,
209 label: 'Synchronized'
210 }
211 })
212 }
213 })
214
215 it('Should list imports of a channel synchronization', async function () {
216 const { total, data } = await server.imports.getMyVideoImports({ videoChannelSyncId: rootChannelSyncId })
217
218 expect(total).to.equal(1)
219 expect(data).to.have.lengthOf(1)
220 expect(data[0].video.name).to.equal('test')
221 })
222
223 it('Should remove user\'s channel synchronizations', async function () {
224 await command.delete({ channelSyncId: userInfo.syncId })
225
226 const { total } = await command.listByAccount({ accountName: userInfo.username })
227 expect(total).to.equal(0)
228 })
229
230 after(async function () {
231 await server?.kill()
232 })
233 })
234 }
235
236 runSuite('youtube-dl')
237 runSuite('yt-dlp')
238 })