aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/tests/feeds/feeds.ts122
-rw-r--r--shared/extra-utils/feeds/feeds.ts55
-rw-r--r--shared/extra-utils/feeds/index.ts1
-rw-r--r--shared/extra-utils/requests/requests.ts9
-rw-r--r--shared/extra-utils/server/servers.ts3
-rw-r--r--shared/extra-utils/shared/abstract-command.ts28
6 files changed, 128 insertions, 90 deletions
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts
index 7bad81751..4d29a2e39 100644
--- a/server/tests/feeds/feeds.ts
+++ b/server/tests/feeds/feeds.ts
@@ -11,16 +11,15 @@ import {
11import { addUserSubscription, listUserSubscriptionVideos } from '@shared/extra-utils/users/user-subscriptions' 11import { addUserSubscription, listUserSubscriptionVideos } from '@shared/extra-utils/users/user-subscriptions'
12import { VideoPrivacy } from '@shared/models' 12import { VideoPrivacy } from '@shared/models'
13import { ScopedToken } from '@shared/models/users/user-scoped-token' 13import { ScopedToken } from '@shared/models/users/user-scoped-token'
14import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
14import { 15import {
15 cleanupTests, 16 cleanupTests,
16 createUser, 17 createUser,
17 doubleFollow, 18 doubleFollow,
18 flushAndRunMultipleServers, 19 flushAndRunMultipleServers,
19 flushAndRunServer, 20 flushAndRunServer,
20 getJSONfeed,
21 getMyUserInformation, 21 getMyUserInformation,
22 getUserScopedTokens, 22 getUserScopedTokens,
23 getXMLfeed,
24 renewUserScopedTokens, 23 renewUserScopedTokens,
25 ServerInfo, 24 ServerInfo,
26 setAccessTokensToServers, 25 setAccessTokensToServers,
@@ -31,7 +30,6 @@ import {
31import { waitJobs } from '../../../shared/extra-utils/server/jobs' 30import { waitJobs } from '../../../shared/extra-utils/server/jobs'
32import { addVideoCommentThread } from '../../../shared/extra-utils/videos/video-comments' 31import { addVideoCommentThread } from '../../../shared/extra-utils/videos/video-comments'
33import { User } from '../../../shared/models/users' 32import { User } from '../../../shared/models/users'
34import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
35 33
36chai.use(require('chai-xml')) 34chai.use(require('chai-xml'))
37chai.use(require('chai-json-schema')) 35chai.use(require('chai-json-schema'))
@@ -118,18 +116,18 @@ describe('Test syndication feeds', () => {
118 116
119 it('Should be well formed XML (covers RSS 2.0 and ATOM 1.0 endpoints)', async function () { 117 it('Should be well formed XML (covers RSS 2.0 and ATOM 1.0 endpoints)', async function () {
120 for (const feed of [ 'video-comments' as 'video-comments', 'videos' as 'videos' ]) { 118 for (const feed of [ 'video-comments' as 'video-comments', 'videos' as 'videos' ]) {
121 const rss = await getXMLfeed(servers[0].url, feed) 119 const rss = await servers[0].feedCommand.getXML({ feed })
122 expect(rss.text).xml.to.be.valid() 120 expect(rss).xml.to.be.valid()
123 121
124 const atom = await getXMLfeed(servers[0].url, feed, 'atom') 122 const atom = await servers[0].feedCommand.getXML({ feed, format: 'atom' })
125 expect(atom.text).xml.to.be.valid() 123 expect(atom).xml.to.be.valid()
126 } 124 }
127 }) 125 })
128 126
129 it('Should be well formed JSON (covers JSON feed 1.0 endpoint)', async function () { 127 it('Should be well formed JSON (covers JSON feed 1.0 endpoint)', async function () {
130 for (const feed of [ 'video-comments' as 'video-comments', 'videos' as 'videos' ]) { 128 for (const feed of [ 'video-comments' as 'video-comments', 'videos' as 'videos' ]) {
131 const json = await getJSONfeed(servers[0].url, feed) 129 const jsonText = await servers[0].feedCommand.getJSON({ feed })
132 expect(JSON.parse(json.text)).to.be.jsonSchema({ type: 'object' }) 130 expect(JSON.parse(jsonText)).to.be.jsonSchema({ type: 'object' })
133 } 131 }
134 }) 132 })
135 }) 133 })
@@ -138,10 +136,10 @@ describe('Test syndication feeds', () => {
138 136
139 it('Should contain a valid enclosure (covers RSS 2.0 endpoint)', async function () { 137 it('Should contain a valid enclosure (covers RSS 2.0 endpoint)', async function () {
140 for (const server of servers) { 138 for (const server of servers) {
141 const rss = await getXMLfeed(server.url, 'videos') 139 const rss = await server.feedCommand.getXML({ feed: 'videos' })
142 expect(xmlParser.validate(rss.text)).to.be.true 140 expect(xmlParser.validate(rss)).to.be.true
143 141
144 const xmlDoc = xmlParser.parse(rss.text, { parseAttributeValue: true, ignoreAttributes: false }) 142 const xmlDoc = xmlParser.parse(rss, { parseAttributeValue: true, ignoreAttributes: false })
145 143
146 const enclosure = xmlDoc.rss.channel.item[0].enclosure 144 const enclosure = xmlDoc.rss.channel.item[0].enclosure
147 expect(enclosure).to.exist 145 expect(enclosure).to.exist
@@ -153,8 +151,8 @@ describe('Test syndication feeds', () => {
153 151
154 it('Should contain a valid \'attachments\' object (covers JSON feed 1.0 endpoint)', async function () { 152 it('Should contain a valid \'attachments\' object (covers JSON feed 1.0 endpoint)', async function () {
155 for (const server of servers) { 153 for (const server of servers) {
156 const json = await getJSONfeed(server.url, 'videos') 154 const json = await server.feedCommand.getJSON({ feed: 'videos' })
157 const jsonObj = JSON.parse(json.text) 155 const jsonObj = JSON.parse(json)
158 expect(jsonObj.items.length).to.be.equal(2) 156 expect(jsonObj.items.length).to.be.equal(2)
159 expect(jsonObj.items[0].attachments).to.exist 157 expect(jsonObj.items[0].attachments).to.exist
160 expect(jsonObj.items[0].attachments.length).to.be.eq(1) 158 expect(jsonObj.items[0].attachments.length).to.be.eq(1)
@@ -166,16 +164,16 @@ describe('Test syndication feeds', () => {
166 164
167 it('Should filter by account', async function () { 165 it('Should filter by account', async function () {
168 { 166 {
169 const json = await getJSONfeed(servers[0].url, 'videos', { accountId: rootAccountId }) 167 const json = await servers[0].feedCommand.getJSON({ feed: 'videos', query: { accountId: rootAccountId } })
170 const jsonObj = JSON.parse(json.text) 168 const jsonObj = JSON.parse(json)
171 expect(jsonObj.items.length).to.be.equal(1) 169 expect(jsonObj.items.length).to.be.equal(1)
172 expect(jsonObj.items[0].title).to.equal('my super name for server 1') 170 expect(jsonObj.items[0].title).to.equal('my super name for server 1')
173 expect(jsonObj.items[0].author.name).to.equal('root') 171 expect(jsonObj.items[0].author.name).to.equal('root')
174 } 172 }
175 173
176 { 174 {
177 const json = await getJSONfeed(servers[0].url, 'videos', { accountId: userAccountId }) 175 const json = await servers[0].feedCommand.getJSON({ feed: 'videos', query: { accountId: userAccountId } })
178 const jsonObj = JSON.parse(json.text) 176 const jsonObj = JSON.parse(json)
179 expect(jsonObj.items.length).to.be.equal(1) 177 expect(jsonObj.items.length).to.be.equal(1)
180 expect(jsonObj.items[0].title).to.equal('user video') 178 expect(jsonObj.items[0].title).to.equal('user video')
181 expect(jsonObj.items[0].author.name).to.equal('john') 179 expect(jsonObj.items[0].author.name).to.equal('john')
@@ -183,15 +181,15 @@ describe('Test syndication feeds', () => {
183 181
184 for (const server of servers) { 182 for (const server of servers) {
185 { 183 {
186 const json = await getJSONfeed(server.url, 'videos', { accountName: 'root@localhost:' + servers[0].port }) 184 const json = await server.feedCommand.getJSON({ feed: 'videos', query: { accountName: 'root@localhost:' + servers[0].port } })
187 const jsonObj = JSON.parse(json.text) 185 const jsonObj = JSON.parse(json)
188 expect(jsonObj.items.length).to.be.equal(1) 186 expect(jsonObj.items.length).to.be.equal(1)
189 expect(jsonObj.items[0].title).to.equal('my super name for server 1') 187 expect(jsonObj.items[0].title).to.equal('my super name for server 1')
190 } 188 }
191 189
192 { 190 {
193 const json = await getJSONfeed(server.url, 'videos', { accountName: 'john@localhost:' + servers[0].port }) 191 const json = await server.feedCommand.getJSON({ feed: 'videos', query: { accountName: 'john@localhost:' + servers[0].port } })
194 const jsonObj = JSON.parse(json.text) 192 const jsonObj = JSON.parse(json)
195 expect(jsonObj.items.length).to.be.equal(1) 193 expect(jsonObj.items.length).to.be.equal(1)
196 expect(jsonObj.items[0].title).to.equal('user video') 194 expect(jsonObj.items[0].title).to.equal('user video')
197 } 195 }
@@ -200,16 +198,16 @@ describe('Test syndication feeds', () => {
200 198
201 it('Should filter by video channel', async function () { 199 it('Should filter by video channel', async function () {
202 { 200 {
203 const json = await getJSONfeed(servers[0].url, 'videos', { videoChannelId: rootChannelId }) 201 const json = await servers[0].feedCommand.getJSON({ feed: 'videos', query: { videoChannelId: rootChannelId } })
204 const jsonObj = JSON.parse(json.text) 202 const jsonObj = JSON.parse(json)
205 expect(jsonObj.items.length).to.be.equal(1) 203 expect(jsonObj.items.length).to.be.equal(1)
206 expect(jsonObj.items[0].title).to.equal('my super name for server 1') 204 expect(jsonObj.items[0].title).to.equal('my super name for server 1')
207 expect(jsonObj.items[0].author.name).to.equal('root') 205 expect(jsonObj.items[0].author.name).to.equal('root')
208 } 206 }
209 207
210 { 208 {
211 const json = await getJSONfeed(servers[0].url, 'videos', { videoChannelId: userChannelId }) 209 const json = await servers[0].feedCommand.getJSON({ feed: 'videos', query: { videoChannelId: userChannelId } })
212 const jsonObj = JSON.parse(json.text) 210 const jsonObj = JSON.parse(json)
213 expect(jsonObj.items.length).to.be.equal(1) 211 expect(jsonObj.items.length).to.be.equal(1)
214 expect(jsonObj.items[0].title).to.equal('user video') 212 expect(jsonObj.items[0].title).to.equal('user video')
215 expect(jsonObj.items[0].author.name).to.equal('john') 213 expect(jsonObj.items[0].author.name).to.equal('john')
@@ -217,15 +215,17 @@ describe('Test syndication feeds', () => {
217 215
218 for (const server of servers) { 216 for (const server of servers) {
219 { 217 {
220 const json = await getJSONfeed(server.url, 'videos', { videoChannelName: 'root_channel@localhost:' + servers[0].port }) 218 const query = { videoChannelName: 'root_channel@localhost:' + servers[0].port }
221 const jsonObj = JSON.parse(json.text) 219 const json = await server.feedCommand.getJSON({ feed: 'videos', query })
220 const jsonObj = JSON.parse(json)
222 expect(jsonObj.items.length).to.be.equal(1) 221 expect(jsonObj.items.length).to.be.equal(1)
223 expect(jsonObj.items[0].title).to.equal('my super name for server 1') 222 expect(jsonObj.items[0].title).to.equal('my super name for server 1')
224 } 223 }
225 224
226 { 225 {
227 const json = await getJSONfeed(server.url, 'videos', { videoChannelName: 'john_channel@localhost:' + servers[0].port }) 226 const query = { videoChannelName: 'john_channel@localhost:' + servers[0].port }
228 const jsonObj = JSON.parse(json.text) 227 const json = await server.feedCommand.getJSON({ feed: 'videos', query })
228 const jsonObj = JSON.parse(json)
229 expect(jsonObj.items.length).to.be.equal(1) 229 expect(jsonObj.items.length).to.be.equal(1)
230 expect(jsonObj.items[0].title).to.equal('user video') 230 expect(jsonObj.items[0].title).to.equal('user video')
231 } 231 }
@@ -239,8 +239,8 @@ describe('Test syndication feeds', () => {
239 239
240 await waitJobs([ serverHLSOnly ]) 240 await waitJobs([ serverHLSOnly ])
241 241
242 const json = await getJSONfeed(serverHLSOnly.url, 'videos') 242 const json = await serverHLSOnly.feedCommand.getJSON({ feed: 'videos' })
243 const jsonObj = JSON.parse(json.text) 243 const jsonObj = JSON.parse(json)
244 expect(jsonObj.items.length).to.be.equal(1) 244 expect(jsonObj.items.length).to.be.equal(1)
245 expect(jsonObj.items[0].attachments).to.exist 245 expect(jsonObj.items[0].attachments).to.exist
246 expect(jsonObj.items[0].attachments.length).to.be.eq(4) 246 expect(jsonObj.items[0].attachments.length).to.be.eq(4)
@@ -257,9 +257,9 @@ describe('Test syndication feeds', () => {
257 257
258 it('Should contain valid comments (covers JSON feed 1.0 endpoint) and not from unlisted videos', async function () { 258 it('Should contain valid comments (covers JSON feed 1.0 endpoint) and not from unlisted videos', async function () {
259 for (const server of servers) { 259 for (const server of servers) {
260 const json = await getJSONfeed(server.url, 'video-comments') 260 const json = await server.feedCommand.getJSON({ feed: 'video-comments' })
261 261
262 const jsonObj = JSON.parse(json.text) 262 const jsonObj = JSON.parse(json)
263 expect(jsonObj.items.length).to.be.equal(2) 263 expect(jsonObj.items.length).to.be.equal(2)
264 expect(jsonObj.items[0].html_content).to.equal('super comment 2') 264 expect(jsonObj.items[0].html_content).to.equal('super comment 2')
265 expect(jsonObj.items[1].html_content).to.equal('super comment 1') 265 expect(jsonObj.items[1].html_content).to.equal('super comment 1')
@@ -274,8 +274,8 @@ describe('Test syndication feeds', () => {
274 await addAccountToServerBlocklist(servers[1].url, servers[1].accessToken, remoteHandle) 274 await addAccountToServerBlocklist(servers[1].url, servers[1].accessToken, remoteHandle)
275 275
276 { 276 {
277 const json = await getJSONfeed(servers[1].url, 'video-comments', { version: 2 }) 277 const json = await servers[1].feedCommand.getJSON({ feed: 'video-comments', query: { version: 2 } })
278 const jsonObj = JSON.parse(json.text) 278 const jsonObj = JSON.parse(json)
279 expect(jsonObj.items.length).to.be.equal(0) 279 expect(jsonObj.items.length).to.be.equal(0)
280 } 280 }
281 281
@@ -287,16 +287,16 @@ describe('Test syndication feeds', () => {
287 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'super comment') 287 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'super comment')
288 await waitJobs(servers) 288 await waitJobs(servers)
289 289
290 const json = await getJSONfeed(servers[1].url, 'video-comments', { version: 3 }) 290 const json = await servers[1].feedCommand.getJSON({ feed: 'video-comments', query: { version: 3 } })
291 const jsonObj = JSON.parse(json.text) 291 const jsonObj = JSON.parse(json)
292 expect(jsonObj.items.length).to.be.equal(3) 292 expect(jsonObj.items.length).to.be.equal(3)
293 } 293 }
294 294
295 await addAccountToAccountBlocklist(servers[1].url, servers[1].accessToken, remoteHandle) 295 await addAccountToAccountBlocklist(servers[1].url, servers[1].accessToken, remoteHandle)
296 296
297 { 297 {
298 const json = await getJSONfeed(servers[1].url, 'video-comments', { version: 4 }) 298 const json = await servers[1].feedCommand.getJSON({ feed: 'video-comments', query: { version: 4 } })
299 const jsonObj = JSON.parse(json.text) 299 const jsonObj = JSON.parse(json)
300 expect(jsonObj.items.length).to.be.equal(2) 300 expect(jsonObj.items.length).to.be.equal(2)
301 } 301 }
302 }) 302 })
@@ -327,31 +327,30 @@ describe('Test syndication feeds', () => {
327 const res = await listUserSubscriptionVideos(servers[0].url, feeduserAccessToken) 327 const res = await listUserSubscriptionVideos(servers[0].url, feeduserAccessToken)
328 expect(res.body.total).to.equal(0) 328 expect(res.body.total).to.equal(0)
329 329
330 const json = await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: feeduserFeedToken }) 330 const query = { accountId: feeduserAccountId, token: feeduserFeedToken }
331 const jsonObj = JSON.parse(json.text) 331 const json = await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query })
332 const jsonObj = JSON.parse(json)
332 expect(jsonObj.items.length).to.be.equal(0) // no subscription, it should not list the instance's videos but list 0 videos 333 expect(jsonObj.items.length).to.be.equal(0) // no subscription, it should not list the instance's videos but list 0 videos
333 } 334 }
334 }) 335 })
335 336
336 it('Should fail with an invalid token', async function () { 337 it('Should fail with an invalid token', async function () {
337 await getJSONfeed(servers[0].url, 'subscriptions', { accountId: feeduserAccountId, token: 'toto' }, HttpStatusCode.FORBIDDEN_403) 338 const query = { accountId: feeduserAccountId, token: 'toto' }
339 await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
338 }) 340 })
339 341
340 it('Should fail with a token of another user', async function () { 342 it('Should fail with a token of another user', async function () {
341 await getJSONfeed( 343 const query = { accountId: feeduserAccountId, token: userFeedToken }
342 servers[0].url, 344 await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
343 'subscriptions',
344 { accountId: feeduserAccountId, token: userFeedToken },
345 HttpStatusCode.FORBIDDEN_403
346 )
347 }) 345 })
348 346
349 it('Should list no videos for a user with videos but no subscriptions', async function () { 347 it('Should list no videos for a user with videos but no subscriptions', async function () {
350 const res = await listUserSubscriptionVideos(servers[0].url, userAccessToken) 348 const res = await listUserSubscriptionVideos(servers[0].url, userAccessToken)
351 expect(res.body.total).to.equal(0) 349 expect(res.body.total).to.equal(0)
352 350
353 const json = await getJSONfeed(servers[0].url, 'subscriptions', { accountId: userAccountId, token: userFeedToken }) 351 const query = { accountId: userAccountId, token: userFeedToken }
354 const jsonObj = JSON.parse(json.text) 352 const json = await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query })
353 const jsonObj = JSON.parse(json)
355 expect(jsonObj.items.length).to.be.equal(0) // no subscription, it should not list the instance's videos but list 0 videos 354 expect(jsonObj.items.length).to.be.equal(0) // no subscription, it should not list the instance's videos but list 0 videos
356 }) 355 })
357 356
@@ -366,8 +365,9 @@ describe('Test syndication feeds', () => {
366 expect(res.body.total).to.equal(1) 365 expect(res.body.total).to.equal(1)
367 expect(res.body.data[0].name).to.equal('user video') 366 expect(res.body.data[0].name).to.equal('user video')
368 367
369 const json = await getJSONfeed(servers[0].url, 'subscriptions', { accountId: userAccountId, token: userFeedToken, version: 1 }) 368 const query = { accountId: userAccountId, token: userFeedToken, version: 1 }
370 const jsonObj = JSON.parse(json.text) 369 const json = await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query })
370 const jsonObj = JSON.parse(json)
371 expect(jsonObj.items.length).to.be.equal(1) // subscribed to self, it should not list the instance's videos but list john's 371 expect(jsonObj.items.length).to.be.equal(1) // subscribed to self, it should not list the instance's videos but list john's
372 } 372 }
373 }) 373 })
@@ -382,8 +382,9 @@ describe('Test syndication feeds', () => {
382 const res = await listUserSubscriptionVideos(servers[0].url, userAccessToken) 382 const res = await listUserSubscriptionVideos(servers[0].url, userAccessToken)
383 expect(res.body.total).to.equal(2, "there should be 2 videos part of the subscription") 383 expect(res.body.total).to.equal(2, "there should be 2 videos part of the subscription")
384 384
385 const json = await getJSONfeed(servers[0].url, 'subscriptions', { accountId: userAccountId, token: userFeedToken, version: 2 }) 385 const query = { accountId: userAccountId, token: userFeedToken, version: 2 }
386 const jsonObj = JSON.parse(json.text) 386 const json = await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query })
387 const jsonObj = JSON.parse(json)
387 expect(jsonObj.items.length).to.be.equal(2) // subscribed to root, it should not list the instance's videos but list root/john's 388 expect(jsonObj.items.length).to.be.equal(2) // subscribed to root, it should not list the instance's videos but list root/john's
388 } 389 }
389 }) 390 })
@@ -391,12 +392,8 @@ describe('Test syndication feeds', () => {
391 it('Should renew the token, and so have an invalid old token', async function () { 392 it('Should renew the token, and so have an invalid old token', async function () {
392 await renewUserScopedTokens(servers[0].url, userAccessToken) 393 await renewUserScopedTokens(servers[0].url, userAccessToken)
393 394
394 await getJSONfeed( 395 const query = { accountId: userAccountId, token: userFeedToken, version: 3 }
395 servers[0].url, 396 await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
396 'subscriptions',
397 { accountId: userAccountId, token: userFeedToken, version: 3 },
398 HttpStatusCode.FORBIDDEN_403
399 )
400 }) 397 })
401 398
402 it('Should succeed with the new token', async function () { 399 it('Should succeed with the new token', async function () {
@@ -404,7 +401,8 @@ describe('Test syndication feeds', () => {
404 const token: ScopedToken = res2.body 401 const token: ScopedToken = res2.body
405 userFeedToken = token.feedToken 402 userFeedToken = token.feedToken
406 403
407 await getJSONfeed(servers[0].url, 'subscriptions', { accountId: userAccountId, token: userFeedToken, version: 4 }) 404 const query = { accountId: userAccountId, token: userFeedToken, version: 4 }
405 await servers[0].feedCommand.getJSON({ feed: 'subscriptions', query })
408 }) 406 })
409 407
410 }) 408 })
diff --git a/shared/extra-utils/feeds/feeds.ts b/shared/extra-utils/feeds/feeds.ts
index ce0a98c6d..012ce6cfe 100644
--- a/shared/extra-utils/feeds/feeds.ts
+++ b/shared/extra-utils/feeds/feeds.ts
@@ -1,33 +1,42 @@
1import * as request from 'supertest' 1
2import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' 2import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
3import { AbstractCommand, OverrideCommandOptions } from '../shared'
3 4
4type FeedType = 'videos' | 'video-comments' | 'subscriptions' 5type FeedType = 'videos' | 'video-comments' | 'subscriptions'
5 6
6function getXMLfeed (url: string, feed: FeedType, format?: string) { 7export class FeedCommand extends AbstractCommand {
7 const path = '/feeds/' + feed + '.xml'
8 8
9 return request(url) 9 getXML (options: OverrideCommandOptions & {
10 .get(path) 10 feed: FeedType
11 .query((format) ? { format: format } : {}) 11 format?: string
12 .set('Accept', 'application/xml') 12 }) {
13 .expect(HttpStatusCode.OK_200) 13 const { feed, format } = options
14 .expect('Content-Type', /xml/) 14 const path = '/feeds/' + feed + '.xml'
15}
16 15
17function getJSONfeed (url: string, feed: FeedType, query: any = {}, statusCodeExpected = HttpStatusCode.OK_200) { 16 return this.getRequestText({
18 const path = '/feeds/' + feed + '.json' 17 ...options,
19 18
20 return request(url) 19 path,
21 .get(path) 20 query: format ? { format } : undefined,
22 .query(query) 21 accept: 'application/xml',
23 .set('Accept', 'application/json') 22 defaultExpectedStatus: HttpStatusCode.OK_200
24 .expect(statusCodeExpected) 23 })
25 .expect('Content-Type', /json/) 24 }
26} 25
26 getJSON (options: OverrideCommandOptions & {
27 feed: FeedType
28 query?: { [ id: string ]: any }
29 }) {
30 const { feed, query } = options
31 const path = '/feeds/' + feed + '.json'
27 32
28// --------------------------------------------------------------------------- 33 return this.getRequestText({
34 ...options,
29 35
30export { 36 path,
31 getXMLfeed, 37 query,
32 getJSONfeed 38 accept: 'application/json',
39 defaultExpectedStatus: HttpStatusCode.OK_200
40 })
41 }
33} 42}
diff --git a/shared/extra-utils/feeds/index.ts b/shared/extra-utils/feeds/index.ts
new file mode 100644
index 000000000..4634cb163
--- /dev/null
+++ b/shared/extra-utils/feeds/index.ts
@@ -0,0 +1 @@
export * from './feeds'
diff --git a/shared/extra-utils/requests/requests.ts b/shared/extra-utils/requests/requests.ts
index eb59ca600..8c26a3699 100644
--- a/shared/extra-utils/requests/requests.ts
+++ b/shared/extra-utils/requests/requests.ts
@@ -182,10 +182,14 @@ function decodeQueryString (path: string) {
182 return decode(path.split('?')[1]) 182 return decode(path.split('?')[1])
183} 183}
184 184
185function unwrap <T> (test: request.Test): Promise<T> { 185function unwrapBody <T> (test: request.Test): Promise<T> {
186 return test.then(res => res.body) 186 return test.then(res => res.body)
187} 187}
188 188
189function unwrapText (test: request.Test): Promise<string> {
190 return test.then(res => res.text)
191}
192
189// --------------------------------------------------------------------------- 193// ---------------------------------------------------------------------------
190 194
191export { 195export {
@@ -198,6 +202,7 @@ export {
198 makePutBodyRequest, 202 makePutBodyRequest,
199 makeDeleteRequest, 203 makeDeleteRequest,
200 makeRawRequest, 204 makeRawRequest,
201 unwrap, 205 unwrapBody,
206 unwrapText,
202 updateImageRequest 207 updateImageRequest
203} 208}
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index e07926065..b64c9eec6 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -9,6 +9,7 @@ import { VideoChannel } from '../../models/videos'
9import { BulkCommand } from '../bulk' 9import { BulkCommand } from '../bulk'
10import { CLICommand } from '../cli' 10import { CLICommand } from '../cli'
11import { CustomPagesCommand } from '../custom-pages' 11import { CustomPagesCommand } from '../custom-pages'
12import { FeedCommand } from '../feeds'
12import { buildServerDirectory, getFileSize, isGithubCI, root, wait } from '../miscs/miscs' 13import { buildServerDirectory, getFileSize, isGithubCI, root, wait } from '../miscs/miscs'
13import { makeGetRequest } from '../requests/requests' 14import { makeGetRequest } from '../requests/requests'
14 15
@@ -67,6 +68,7 @@ interface ServerInfo {
67 bulkCommand?: BulkCommand 68 bulkCommand?: BulkCommand
68 cliCommand?: CLICommand 69 cliCommand?: CLICommand
69 customPageCommand?: CustomPagesCommand 70 customPageCommand?: CustomPagesCommand
71 feedCommand?: FeedCommand
70} 72}
71 73
72function parallelTests () { 74function parallelTests () {
@@ -275,6 +277,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = []
275 server.bulkCommand = new BulkCommand(server) 277 server.bulkCommand = new BulkCommand(server)
276 server.cliCommand = new CLICommand(server) 278 server.cliCommand = new CLICommand(server)
277 server.customPageCommand = new CustomPagesCommand(server) 279 server.customPageCommand = new CustomPagesCommand(server)
280 server.feedCommand = new FeedCommand(server)
278 281
279 res(server) 282 res(server)
280 }) 283 })
diff --git a/shared/extra-utils/shared/abstract-command.ts b/shared/extra-utils/shared/abstract-command.ts
index d8eba373d..53c644124 100644
--- a/shared/extra-utils/shared/abstract-command.ts
+++ b/shared/extra-utils/shared/abstract-command.ts
@@ -1,5 +1,5 @@
1import { HttpStatusCode } from '@shared/core-utils' 1import { HttpStatusCode } from '@shared/core-utils'
2import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, unwrap } from '../requests/requests' 2import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, unwrap, unwrapBody, unwrapText } from '../requests/requests'
3import { ServerInfo } from '../server/servers' 3import { ServerInfo } from '../server/servers'
4 4
5export interface OverrideCommandOptions { 5export interface OverrideCommandOptions {
@@ -12,6 +12,12 @@ interface CommonCommandOptions extends OverrideCommandOptions {
12 defaultExpectedStatus: number 12 defaultExpectedStatus: number
13} 13}
14 14
15interface GetCommandOptions extends CommonCommandOptions {
16 query?: { [ id: string ]: string }
17 contentType?: string
18 accept?: string
19}
20
15abstract class AbstractCommand { 21abstract class AbstractCommand {
16 22
17 private expectedStatus: HttpStatusCode 23 private expectedStatus: HttpStatusCode
@@ -30,8 +36,12 @@ abstract class AbstractCommand {
30 this.expectedStatus = status 36 this.expectedStatus = status
31 } 37 }
32 38
33 protected getRequestBody <T> (options: CommonCommandOptions) { 39 protected getRequestBody <T> (options: GetCommandOptions) {
34 return unwrap<T>(makeGetRequest(this.buildCommonRequestOptions(options))) 40 return unwrapBody<T>(this.getRequest(options))
41 }
42
43 protected getRequestText (options: GetCommandOptions) {
44 return unwrapText(this.getRequest(options))
35 } 45 }
36 46
37 protected putBodyRequest (options: CommonCommandOptions & { 47 protected putBodyRequest (options: CommonCommandOptions & {
@@ -68,6 +78,18 @@ abstract class AbstractCommand {
68 statusCodeExpected: expectedStatus ?? this.expectedStatus ?? defaultExpectedStatus 78 statusCodeExpected: expectedStatus ?? this.expectedStatus ?? defaultExpectedStatus
69 } 79 }
70 } 80 }
81
82 private getRequest (options: GetCommandOptions) {
83 const { query, contentType, accept } = options
84
85 return makeGetRequest({
86 ...this.buildCommonRequestOptions(options),
87
88 query,
89 contentType,
90 accept
91 })
92 }
71} 93}
72 94
73export { 95export {