]>
Commit | Line | Data |
---|---|---|
a1587156 | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
fe3a55b0 | 2 | |
479b2696 | 3 | import * as chai from 'chai' |
2d28b0c2 | 4 | import { XMLParser, XMLValidator } from 'fast-xml-parser' |
d0800f76 | 5 | import { HttpStatusCode, VideoPrivacy } from '@shared/models' |
696d83fd | 6 | import { |
7c3b7976 | 7 | cleanupTests, |
254d3579 C |
8 | createMultipleServers, |
9 | createSingleServer, | |
4c7e60bc | 10 | doubleFollow, |
20bafcb6 | 11 | makeGetRequest, |
5e1bd869 | 12 | makeRawRequest, |
254d3579 | 13 | PeerTubeServer, |
fe3a55b0 | 14 | setAccessTokensToServers, |
d0800f76 | 15 | setDefaultChannelAvatar, |
7a5c3d77 | 16 | stopFfmpeg, |
5f8bd4cb | 17 | waitJobs |
bf54587a | 18 | } from '@shared/server-commands' |
fe3a55b0 C |
19 | |
20 | chai.use(require('chai-xml')) | |
21 | chai.use(require('chai-json-schema')) | |
22 | chai.config.includeStack = true | |
479b2696 | 23 | |
e5d771a3 C |
24 | const expect = chai.expect |
25 | ||
fe3a55b0 | 26 | describe('Test syndication feeds', () => { |
254d3579 C |
27 | let servers: PeerTubeServer[] = [] |
28 | let serverHLSOnly: PeerTubeServer | |
662fb3ab | 29 | let userAccessToken: string |
57cfff78 C |
30 | let rootAccountId: number |
31 | let rootChannelId: number | |
32 | let userAccountId: number | |
33 | let userChannelId: number | |
afff310e | 34 | let userFeedToken: string |
7a5c3d77 | 35 | let liveId: string |
fe3a55b0 C |
36 | |
37 | before(async function () { | |
38 | this.timeout(120000) | |
39 | ||
40 | // Run servers | |
254d3579 C |
41 | servers = await createMultipleServers(2) |
42 | serverHLSOnly = await createSingleServer(3, { | |
97816649 C |
43 | transcoding: { |
44 | enabled: true, | |
45 | webtorrent: { enabled: false }, | |
46 | hls: { enabled: true } | |
47 | } | |
48 | }) | |
fe3a55b0 | 49 | |
97816649 | 50 | await setAccessTokensToServers([ ...servers, serverHLSOnly ]) |
d0800f76 | 51 | await setDefaultChannelAvatar(servers[0]) |
fe3a55b0 C |
52 | await doubleFollow(servers[0], servers[1]) |
53 | ||
7a5c3d77 C |
54 | await servers[0].config.enableLive({ allowReplay: false, transcoding: false }) |
55 | ||
662fb3ab | 56 | { |
89d241a7 | 57 | const user = await servers[0].users.getMyInfo() |
57cfff78 C |
58 | rootAccountId = user.account.id |
59 | rootChannelId = user.videoChannels[0].id | |
fe3a55b0 | 60 | } |
fe3a55b0 | 61 | |
662fb3ab | 62 | { |
20bafcb6 | 63 | userAccessToken = await servers[0].users.generateUserAndToken('john') |
662fb3ab | 64 | |
89d241a7 | 65 | const user = await servers[0].users.getMyInfo({ token: userAccessToken }) |
57cfff78 C |
66 | userAccountId = user.account.id |
67 | userChannelId = user.videoChannels[0].id | |
afff310e | 68 | |
89d241a7 | 69 | const token = await servers[0].users.getMyScopedTokens({ token: userAccessToken }) |
afff310e | 70 | userFeedToken = token.feedToken |
662fb3ab C |
71 | } |
72 | ||
73 | { | |
89d241a7 | 74 | await servers[0].videos.upload({ token: userAccessToken, attributes: { name: 'user video' } }) |
662fb3ab C |
75 | } |
76 | ||
77 | { | |
d23dd9fb | 78 | const attributes = { |
662fb3ab C |
79 | name: 'my super name for server 1', |
80 | description: 'my super description for server 1', | |
81 | fixture: 'video_short.webm' | |
82 | } | |
89d241a7 | 83 | const { id } = await servers[0].videos.upload({ attributes }) |
662fb3ab | 84 | |
89d241a7 C |
85 | await servers[0].comments.createThread({ videoId: id, text: 'super comment 1' }) |
86 | await servers[0].comments.createThread({ videoId: id, text: 'super comment 2' }) | |
662fb3ab | 87 | } |
fe3a55b0 | 88 | |
68b6fd21 | 89 | { |
d23dd9fb | 90 | const attributes = { name: 'unlisted video', privacy: VideoPrivacy.UNLISTED } |
89d241a7 | 91 | const { id } = await servers[0].videos.upload({ attributes }) |
68b6fd21 | 92 | |
89d241a7 | 93 | await servers[0].comments.createThread({ videoId: id, text: 'comment on unlisted video' }) |
68b6fd21 C |
94 | } |
95 | ||
3cd0734f | 96 | await waitJobs(servers) |
fe3a55b0 C |
97 | }) |
98 | ||
99 | describe('All feed', function () { | |
100 | ||
101 | it('Should be well formed XML (covers RSS 2.0 and ATOM 1.0 endpoints)', async function () { | |
102 | for (const feed of [ 'video-comments' as 'video-comments', 'videos' as 'videos' ]) { | |
41e74ec9 | 103 | const rss = await servers[0].feed.getXML({ feed, ignoreCache: true }) |
c1bc8ee4 | 104 | expect(rss).xml.to.be.valid() |
fe3a55b0 | 105 | |
41e74ec9 | 106 | const atom = await servers[0].feed.getXML({ feed, format: 'atom', ignoreCache: true }) |
c1bc8ee4 | 107 | expect(atom).xml.to.be.valid() |
fe3a55b0 C |
108 | } |
109 | }) | |
110 | ||
111 | it('Should be well formed JSON (covers JSON feed 1.0 endpoint)', async function () { | |
112 | for (const feed of [ 'video-comments' as 'video-comments', 'videos' as 'videos' ]) { | |
41e74ec9 | 113 | const jsonText = await servers[0].feed.getJSON({ feed, ignoreCache: true }) |
c1bc8ee4 | 114 | expect(JSON.parse(jsonText)).to.be.jsonSchema({ type: 'object' }) |
fe3a55b0 C |
115 | } |
116 | }) | |
20bafcb6 C |
117 | |
118 | it('Should serve the endpoint with a classic request', async function () { | |
119 | await makeGetRequest({ | |
120 | url: servers[0].url, | |
121 | path: '/feeds/videos.xml', | |
122 | accept: 'application/xml', | |
123 | expectedStatus: HttpStatusCode.OK_200 | |
124 | }) | |
125 | }) | |
126 | ||
127 | it('Should serve the endpoint as a cached request', async function () { | |
128 | const res = await makeGetRequest({ | |
129 | url: servers[0].url, | |
130 | path: '/feeds/videos.xml', | |
131 | accept: 'application/xml', | |
132 | expectedStatus: HttpStatusCode.OK_200 | |
133 | }) | |
134 | ||
135 | expect(res.headers['x-api-cache-cached']).to.equal('true') | |
136 | }) | |
137 | ||
138 | it('Should not serve the endpoint as a cached request', async function () { | |
139 | const res = await makeGetRequest({ | |
140 | url: servers[0].url, | |
141 | path: '/feeds/videos.xml?v=186', | |
142 | accept: 'application/xml', | |
143 | expectedStatus: HttpStatusCode.OK_200 | |
144 | }) | |
145 | ||
146 | expect(res.headers['x-api-cache-cached']).to.not.exist | |
147 | }) | |
148 | ||
149 | it('Should refuse to serve the endpoint without accept header', async function () { | |
150 | await makeGetRequest({ url: servers[0].url, path: '/feeds/videos.xml', expectedStatus: HttpStatusCode.NOT_ACCEPTABLE_406 }) | |
151 | }) | |
fe3a55b0 C |
152 | }) |
153 | ||
154 | describe('Videos feed', function () { | |
97816649 | 155 | |
fe3a55b0 C |
156 | it('Should contain a valid enclosure (covers RSS 2.0 endpoint)', async function () { |
157 | for (const server of servers) { | |
41e74ec9 | 158 | const rss = await server.feed.getXML({ feed: 'videos', ignoreCache: true }) |
2d28b0c2 | 159 | expect(XMLValidator.validate(rss)).to.be.true |
b70025bf | 160 | |
2d28b0c2 C |
161 | const parser = new XMLParser({ parseAttributeValue: true, ignoreAttributes: false }) |
162 | const xmlDoc = parser.parse(rss) | |
b70025bf C |
163 | |
164 | const enclosure = xmlDoc.rss.channel.item[0].enclosure | |
165 | expect(enclosure).to.exist | |
4393b255 C |
166 | |
167 | expect(enclosure['@_type']).to.equal('video/webm') | |
b70025bf | 168 | expect(enclosure['@_length']).to.equal(218910) |
4393b255 | 169 | expect(enclosure['@_url']).to.contain('-720.webm') |
fe3a55b0 C |
170 | } |
171 | }) | |
172 | ||
173 | it('Should contain a valid \'attachments\' object (covers JSON feed 1.0 endpoint)', async function () { | |
174 | for (const server of servers) { | |
41e74ec9 | 175 | const json = await server.feed.getJSON({ feed: 'videos', ignoreCache: true }) |
c1bc8ee4 | 176 | const jsonObj = JSON.parse(json) |
662fb3ab | 177 | expect(jsonObj.items.length).to.be.equal(2) |
a1587156 C |
178 | expect(jsonObj.items[0].attachments).to.exist |
179 | expect(jsonObj.items[0].attachments.length).to.be.eq(1) | |
180 | expect(jsonObj.items[0].attachments[0].mime_type).to.be.eq('application/x-bittorrent') | |
181 | expect(jsonObj.items[0].attachments[0].size_in_bytes).to.be.eq(218910) | |
182 | expect(jsonObj.items[0].attachments[0].url).to.contain('720.torrent') | |
fe3a55b0 C |
183 | } |
184 | }) | |
662fb3ab C |
185 | |
186 | it('Should filter by account', async function () { | |
57cfff78 | 187 | { |
41e74ec9 | 188 | const json = await servers[0].feed.getJSON({ feed: 'videos', query: { accountId: rootAccountId }, ignoreCache: true }) |
c1bc8ee4 | 189 | const jsonObj = JSON.parse(json) |
57cfff78 | 190 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 191 | expect(jsonObj.items[0].title).to.equal('my super name for server 1') |
ec3ce76f | 192 | expect(jsonObj.items[0].author.name).to.equal('Main root channel') |
57cfff78 C |
193 | } |
194 | ||
195 | { | |
41e74ec9 | 196 | const json = await servers[0].feed.getJSON({ feed: 'videos', query: { accountId: userAccountId }, ignoreCache: true }) |
c1bc8ee4 | 197 | const jsonObj = JSON.parse(json) |
57cfff78 | 198 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 199 | expect(jsonObj.items[0].title).to.equal('user video') |
ec3ce76f | 200 | expect(jsonObj.items[0].author.name).to.equal('Main john channel') |
57cfff78 C |
201 | } |
202 | ||
662fb3ab C |
203 | for (const server of servers) { |
204 | { | |
41e74ec9 | 205 | const json = await server.feed.getJSON({ feed: 'videos', query: { accountName: 'root@' + servers[0].host }, ignoreCache: true }) |
c1bc8ee4 | 206 | const jsonObj = JSON.parse(json) |
662fb3ab | 207 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 208 | expect(jsonObj.items[0].title).to.equal('my super name for server 1') |
662fb3ab C |
209 | } |
210 | ||
211 | { | |
41e74ec9 | 212 | const json = await server.feed.getJSON({ feed: 'videos', query: { accountName: 'john@' + servers[0].host }, ignoreCache: true }) |
c1bc8ee4 | 213 | const jsonObj = JSON.parse(json) |
662fb3ab | 214 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 215 | expect(jsonObj.items[0].title).to.equal('user video') |
662fb3ab C |
216 | } |
217 | } | |
57cfff78 | 218 | }) |
662fb3ab | 219 | |
57cfff78 | 220 | it('Should filter by video channel', async function () { |
662fb3ab | 221 | { |
41e74ec9 | 222 | const json = await servers[0].feed.getJSON({ feed: 'videos', query: { videoChannelId: rootChannelId }, ignoreCache: true }) |
c1bc8ee4 | 223 | const jsonObj = JSON.parse(json) |
662fb3ab | 224 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 225 | expect(jsonObj.items[0].title).to.equal('my super name for server 1') |
ec3ce76f | 226 | expect(jsonObj.items[0].author.name).to.equal('Main root channel') |
662fb3ab C |
227 | } |
228 | ||
229 | { | |
41e74ec9 | 230 | const json = await servers[0].feed.getJSON({ feed: 'videos', query: { videoChannelId: userChannelId }, ignoreCache: true }) |
c1bc8ee4 | 231 | const jsonObj = JSON.parse(json) |
662fb3ab | 232 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 233 | expect(jsonObj.items[0].title).to.equal('user video') |
ec3ce76f | 234 | expect(jsonObj.items[0].author.name).to.equal('Main john channel') |
662fb3ab | 235 | } |
662fb3ab | 236 | |
662fb3ab C |
237 | for (const server of servers) { |
238 | { | |
41e74ec9 C |
239 | const query = { videoChannelName: 'root_channel@' + servers[0].host } |
240 | const json = await server.feed.getJSON({ feed: 'videos', query, ignoreCache: true }) | |
c1bc8ee4 | 241 | const jsonObj = JSON.parse(json) |
662fb3ab | 242 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 243 | expect(jsonObj.items[0].title).to.equal('my super name for server 1') |
662fb3ab C |
244 | } |
245 | ||
246 | { | |
41e74ec9 C |
247 | const query = { videoChannelName: 'john_channel@' + servers[0].host } |
248 | const json = await server.feed.getJSON({ feed: 'videos', query, ignoreCache: true }) | |
c1bc8ee4 | 249 | const jsonObj = JSON.parse(json) |
662fb3ab | 250 | expect(jsonObj.items.length).to.be.equal(1) |
a1587156 | 251 | expect(jsonObj.items[0].title).to.equal('user video') |
662fb3ab C |
252 | } |
253 | } | |
662fb3ab | 254 | }) |
97816649 C |
255 | |
256 | it('Should correctly have videos feed with HLS only', async function () { | |
257 | this.timeout(120000) | |
258 | ||
89d241a7 | 259 | await serverHLSOnly.videos.upload({ attributes: { name: 'hls only video' } }) |
97816649 C |
260 | |
261 | await waitJobs([ serverHLSOnly ]) | |
262 | ||
41e74ec9 | 263 | const json = await serverHLSOnly.feed.getJSON({ feed: 'videos', ignoreCache: true }) |
c1bc8ee4 | 264 | const jsonObj = JSON.parse(json) |
97816649 C |
265 | expect(jsonObj.items.length).to.be.equal(1) |
266 | expect(jsonObj.items[0].attachments).to.exist | |
267 | expect(jsonObj.items[0].attachments.length).to.be.eq(4) | |
268 | ||
269 | for (let i = 0; i < 4; i++) { | |
270 | expect(jsonObj.items[0].attachments[i].mime_type).to.be.eq('application/x-bittorrent') | |
271 | expect(jsonObj.items[0].attachments[i].size_in_bytes).to.be.greaterThan(0) | |
272 | expect(jsonObj.items[0].attachments[i].url).to.exist | |
273 | } | |
274 | }) | |
7a5c3d77 C |
275 | |
276 | it('Should not display waiting live videos', async function () { | |
277 | const { uuid } = await servers[0].live.create({ | |
278 | fields: { | |
279 | name: 'live', | |
280 | privacy: VideoPrivacy.PUBLIC, | |
281 | channelId: rootChannelId | |
282 | } | |
283 | }) | |
284 | liveId = uuid | |
285 | ||
41e74ec9 | 286 | const json = await servers[0].feed.getJSON({ feed: 'videos', ignoreCache: true }) |
7a5c3d77 C |
287 | |
288 | const jsonObj = JSON.parse(json) | |
289 | expect(jsonObj.items.length).to.be.equal(2) | |
290 | expect(jsonObj.items[0].title).to.equal('my super name for server 1') | |
291 | expect(jsonObj.items[1].title).to.equal('user video') | |
292 | }) | |
293 | ||
41e74ec9 | 294 | it('Should display published live videos', async function () { |
7a5c3d77 C |
295 | this.timeout(120000) |
296 | ||
297 | const ffmpeg = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveId, copyCodecs: true, fixtureName: 'video_short.mp4' }) | |
298 | await servers[0].live.waitUntilPublished({ videoId: liveId }) | |
299 | ||
41e74ec9 | 300 | const json = await servers[0].feed.getJSON({ feed: 'videos', ignoreCache: true }) |
7a5c3d77 C |
301 | |
302 | const jsonObj = JSON.parse(json) | |
303 | expect(jsonObj.items.length).to.be.equal(3) | |
41e74ec9 C |
304 | expect(jsonObj.items[0].title).to.equal('live') |
305 | expect(jsonObj.items[1].title).to.equal('my super name for server 1') | |
306 | expect(jsonObj.items[2].title).to.equal('user video') | |
7a5c3d77 C |
307 | |
308 | await stopFfmpeg(ffmpeg) | |
309 | }) | |
5e1bd869 AM |
310 | |
311 | it('Should have the channel avatar as feed icon', async function () { | |
312 | const json = await servers[0].feed.getJSON({ feed: 'videos', query: { videoChannelId: rootChannelId }, ignoreCache: true }) | |
313 | ||
314 | const jsonObj = JSON.parse(json) | |
315 | const imageUrl = jsonObj.icon | |
316 | expect(imageUrl).to.include('/lazy-static/avatars/') | |
b3ce3606 | 317 | await makeRawRequest({ url: imageUrl, expectedStatus: HttpStatusCode.OK_200 }) |
5e1bd869 | 318 | }) |
fe3a55b0 C |
319 | }) |
320 | ||
321 | describe('Video comments feed', function () { | |
68b6fd21 C |
322 | |
323 | it('Should contain valid comments (covers JSON feed 1.0 endpoint) and not from unlisted videos', async function () { | |
fe3a55b0 | 324 | for (const server of servers) { |
41e74ec9 | 325 | const json = await server.feed.getJSON({ feed: 'video-comments', ignoreCache: true }) |
fe3a55b0 | 326 | |
c1bc8ee4 | 327 | const jsonObj = JSON.parse(json) |
fe3a55b0 | 328 | expect(jsonObj.items.length).to.be.equal(2) |
4393b255 C |
329 | expect(jsonObj.items[0].content_html).to.contain('<p>super comment 2</p>') |
330 | expect(jsonObj.items[1].content_html).to.contain('<p>super comment 1</p>') | |
fe3a55b0 C |
331 | } |
332 | }) | |
1df8a4d7 C |
333 | |
334 | it('Should not list comments from muted accounts or instances', async function () { | |
696d83fd C |
335 | this.timeout(30000) |
336 | ||
41e74ec9 | 337 | const remoteHandle = 'root@' + servers[0].host |
696d83fd | 338 | |
89d241a7 | 339 | await servers[1].blocklist.addToServerBlocklist({ account: remoteHandle }) |
1df8a4d7 C |
340 | |
341 | { | |
41e74ec9 | 342 | const json = await servers[1].feed.getJSON({ feed: 'video-comments', ignoreCache: true }) |
c1bc8ee4 | 343 | const jsonObj = JSON.parse(json) |
1df8a4d7 C |
344 | expect(jsonObj.items.length).to.be.equal(0) |
345 | } | |
346 | ||
89d241a7 | 347 | await servers[1].blocklist.removeFromServerBlocklist({ account: remoteHandle }) |
696d83fd C |
348 | |
349 | { | |
89d241a7 | 350 | const videoUUID = (await servers[1].videos.quickUpload({ name: 'server 2' })).uuid |
696d83fd | 351 | await waitJobs(servers) |
89d241a7 | 352 | await servers[0].comments.createThread({ videoId: videoUUID, text: 'super comment' }) |
696d83fd C |
353 | await waitJobs(servers) |
354 | ||
41e74ec9 | 355 | const json = await servers[1].feed.getJSON({ feed: 'video-comments', ignoreCache: true }) |
c1bc8ee4 | 356 | const jsonObj = JSON.parse(json) |
696d83fd C |
357 | expect(jsonObj.items.length).to.be.equal(3) |
358 | } | |
359 | ||
89d241a7 | 360 | await servers[1].blocklist.addToMyBlocklist({ account: remoteHandle }) |
696d83fd C |
361 | |
362 | { | |
41e74ec9 | 363 | const json = await servers[1].feed.getJSON({ feed: 'video-comments', ignoreCache: true }) |
c1bc8ee4 | 364 | const jsonObj = JSON.parse(json) |
696d83fd C |
365 | expect(jsonObj.items.length).to.be.equal(2) |
366 | } | |
1df8a4d7 | 367 | }) |
fe3a55b0 C |
368 | }) |
369 | ||
afff310e | 370 | describe('Video feed from my subscriptions', function () { |
18490b07 C |
371 | let feeduserAccountId: number |
372 | let feeduserFeedToken: string | |
afff310e RK |
373 | |
374 | it('Should list no videos for a user with no videos and no subscriptions', async function () { | |
afff310e | 375 | const attr = { username: 'feeduser', password: 'password' } |
89d241a7 C |
376 | await servers[0].users.create({ username: attr.username, password: attr.password }) |
377 | const feeduserAccessToken = await servers[0].login.getAccessToken(attr) | |
afff310e RK |
378 | |
379 | { | |
89d241a7 | 380 | const user = await servers[0].users.getMyInfo({ token: feeduserAccessToken }) |
afff310e RK |
381 | feeduserAccountId = user.account.id |
382 | } | |
383 | ||
384 | { | |
89d241a7 | 385 | const token = await servers[0].users.getMyScopedTokens({ token: feeduserAccessToken }) |
afff310e RK |
386 | feeduserFeedToken = token.feedToken |
387 | } | |
388 | ||
389 | { | |
692ae8c3 | 390 | const body = await servers[0].videos.listMySubscriptionVideos({ token: feeduserAccessToken }) |
2c27e704 | 391 | expect(body.total).to.equal(0) |
afff310e | 392 | |
c1bc8ee4 | 393 | const query = { accountId: feeduserAccountId, token: feeduserFeedToken } |
41e74ec9 | 394 | const json = await servers[0].feed.getJSON({ feed: 'subscriptions', query, ignoreCache: true }) |
c1bc8ee4 | 395 | const jsonObj = JSON.parse(json) |
afff310e RK |
396 | expect(jsonObj.items.length).to.be.equal(0) // no subscription, it should not list the instance's videos but list 0 videos |
397 | } | |
398 | }) | |
399 | ||
18490b07 | 400 | it('Should fail with an invalid token', async function () { |
c1bc8ee4 | 401 | const query = { accountId: feeduserAccountId, token: 'toto' } |
41e74ec9 | 402 | await servers[0].feed.getJSON({ feed: 'subscriptions', query, expectedStatus: HttpStatusCode.FORBIDDEN_403, ignoreCache: true }) |
18490b07 C |
403 | }) |
404 | ||
405 | it('Should fail with a token of another user', async function () { | |
c1bc8ee4 | 406 | const query = { accountId: feeduserAccountId, token: userFeedToken } |
41e74ec9 | 407 | await servers[0].feed.getJSON({ feed: 'subscriptions', query, expectedStatus: HttpStatusCode.FORBIDDEN_403, ignoreCache: true }) |
18490b07 C |
408 | }) |
409 | ||
afff310e | 410 | it('Should list no videos for a user with videos but no subscriptions', async function () { |
692ae8c3 | 411 | const body = await servers[0].videos.listMySubscriptionVideos({ token: userAccessToken }) |
2c27e704 | 412 | expect(body.total).to.equal(0) |
afff310e | 413 | |
c1bc8ee4 | 414 | const query = { accountId: userAccountId, token: userFeedToken } |
41e74ec9 | 415 | const json = await servers[0].feed.getJSON({ feed: 'subscriptions', query, ignoreCache: true }) |
c1bc8ee4 | 416 | const jsonObj = JSON.parse(json) |
18490b07 | 417 | expect(jsonObj.items.length).to.be.equal(0) // no subscription, it should not list the instance's videos but list 0 videos |
afff310e RK |
418 | }) |
419 | ||
420 | it('Should list self videos for a user with a subscription to themselves', async function () { | |
421 | this.timeout(30000) | |
422 | ||
41e74ec9 | 423 | await servers[0].subscriptions.add({ token: userAccessToken, targetUri: 'john_channel@' + servers[0].host }) |
afff310e RK |
424 | await waitJobs(servers) |
425 | ||
426 | { | |
692ae8c3 | 427 | const body = await servers[0].videos.listMySubscriptionVideos({ token: userAccessToken }) |
2c27e704 C |
428 | expect(body.total).to.equal(1) |
429 | expect(body.data[0].name).to.equal('user video') | |
afff310e | 430 | |
41e74ec9 C |
431 | const query = { accountId: userAccountId, token: userFeedToken } |
432 | const json = await servers[0].feed.getJSON({ feed: 'subscriptions', query, ignoreCache: true }) | |
c1bc8ee4 | 433 | const jsonObj = JSON.parse(json) |
afff310e RK |
434 | expect(jsonObj.items.length).to.be.equal(1) // subscribed to self, it should not list the instance's videos but list john's |
435 | } | |
436 | }) | |
437 | ||
438 | it('Should list videos of a user\'s subscription', async function () { | |
439 | this.timeout(30000) | |
440 | ||
41e74ec9 | 441 | await servers[0].subscriptions.add({ token: userAccessToken, targetUri: 'root_channel@' + servers[0].host }) |
afff310e RK |
442 | await waitJobs(servers) |
443 | ||
444 | { | |
692ae8c3 | 445 | const body = await servers[0].videos.listMySubscriptionVideos({ token: userAccessToken }) |
7e0f50d6 | 446 | expect(body.total).to.equal(2, 'there should be 2 videos part of the subscription') |
afff310e | 447 | |
41e74ec9 C |
448 | const query = { accountId: userAccountId, token: userFeedToken } |
449 | const json = await servers[0].feed.getJSON({ feed: 'subscriptions', query, ignoreCache: true }) | |
c1bc8ee4 | 450 | const jsonObj = JSON.parse(json) |
afff310e RK |
451 | expect(jsonObj.items.length).to.be.equal(2) // subscribed to root, it should not list the instance's videos but list root/john's |
452 | } | |
453 | }) | |
454 | ||
18490b07 | 455 | it('Should renew the token, and so have an invalid old token', async function () { |
89d241a7 | 456 | await servers[0].users.renewMyScopedTokens({ token: userAccessToken }) |
18490b07 | 457 | |
41e74ec9 C |
458 | const query = { accountId: userAccountId, token: userFeedToken } |
459 | await servers[0].feed.getJSON({ feed: 'subscriptions', query, expectedStatus: HttpStatusCode.FORBIDDEN_403, ignoreCache: true }) | |
18490b07 C |
460 | }) |
461 | ||
462 | it('Should succeed with the new token', async function () { | |
89d241a7 | 463 | const token = await servers[0].users.getMyScopedTokens({ token: userAccessToken }) |
18490b07 C |
464 | userFeedToken = token.feedToken |
465 | ||
41e74ec9 C |
466 | const query = { accountId: userAccountId, token: userFeedToken } |
467 | await servers[0].feed.getJSON({ feed: 'subscriptions', query, ignoreCache: true }) | |
18490b07 C |
468 | }) |
469 | ||
afff310e RK |
470 | }) |
471 | ||
7c3b7976 | 472 | after(async function () { |
97816649 | 473 | await cleanupTests([ ...servers, serverHLSOnly ]) |
fe3a55b0 C |
474 | }) |
475 | }) |