diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/videos/index.ts | 22 | ||||
-rw-r--r-- | server/initializers/constants.ts | 6 | ||||
-rw-r--r-- | server/middlewares/index.ts | 1 | ||||
-rw-r--r-- | server/middlewares/search.ts | 14 | ||||
-rw-r--r-- | server/middlewares/validators/videos.ts | 5 | ||||
-rw-r--r-- | server/models/video/video-interface.ts | 1 | ||||
-rw-r--r-- | server/models/video/video.ts | 47 | ||||
-rw-r--r-- | server/tests/api/single-server.ts | 112 | ||||
-rw-r--r-- | server/tests/utils/videos.ts | 20 |
9 files changed, 98 insertions, 130 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index e2798830e..2b70d535e 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -26,7 +26,6 @@ import { | |||
26 | authenticate, | 26 | authenticate, |
27 | paginationValidator, | 27 | paginationValidator, |
28 | setPagination, | 28 | setPagination, |
29 | setVideosSearch, | ||
30 | setVideosSort, | 29 | setVideosSort, |
31 | videosAddValidator, | 30 | videosAddValidator, |
32 | videosGetValidator, | 31 | videosGetValidator, |
@@ -84,6 +83,14 @@ videosRouter.get('/', | |||
84 | setPagination, | 83 | setPagination, |
85 | asyncMiddleware(listVideos) | 84 | asyncMiddleware(listVideos) |
86 | ) | 85 | ) |
86 | videosRouter.get('/search', | ||
87 | videosSearchValidator, | ||
88 | paginationValidator, | ||
89 | videosSortValidator, | ||
90 | setVideosSort, | ||
91 | setPagination, | ||
92 | asyncMiddleware(searchVideos) | ||
93 | ) | ||
87 | videosRouter.put('/:id', | 94 | videosRouter.put('/:id', |
88 | authenticate, | 95 | authenticate, |
89 | asyncMiddleware(videosUpdateValidator), | 96 | asyncMiddleware(videosUpdateValidator), |
@@ -115,16 +122,6 @@ videosRouter.delete('/:id', | |||
115 | asyncMiddleware(removeVideoRetryWrapper) | 122 | asyncMiddleware(removeVideoRetryWrapper) |
116 | ) | 123 | ) |
117 | 124 | ||
118 | videosRouter.get('/search/:value', | ||
119 | videosSearchValidator, | ||
120 | paginationValidator, | ||
121 | videosSortValidator, | ||
122 | setVideosSort, | ||
123 | setPagination, | ||
124 | setVideosSearch, | ||
125 | asyncMiddleware(searchVideos) | ||
126 | ) | ||
127 | |||
128 | // --------------------------------------------------------------------------- | 125 | // --------------------------------------------------------------------------- |
129 | 126 | ||
130 | export { | 127 | export { |
@@ -378,8 +375,7 @@ async function removeVideo (req: express.Request, res: express.Response) { | |||
378 | 375 | ||
379 | async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) { | 376 | async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) { |
380 | const resultList = await db.Video.searchAndPopulateAccountAndServerAndTags( | 377 | const resultList = await db.Video.searchAndPopulateAccountAndServerAndTags( |
381 | req.params.value, | 378 | req.query.search, |
382 | req.query.field, | ||
383 | req.query.start, | 379 | req.query.start, |
384 | req.query.count, | 380 | req.query.count, |
385 | req.query.sort | 381 | req.query.sort |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 144a4edbf..3e083fd92 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -25,11 +25,6 @@ const API_VERSION = 'v1' | |||
25 | const PAGINATION_COUNT_DEFAULT = 15 | 25 | const PAGINATION_COUNT_DEFAULT = 15 |
26 | 26 | ||
27 | // Sortable columns per schema | 27 | // Sortable columns per schema |
28 | const SEARCHABLE_COLUMNS = { | ||
29 | VIDEOS: [ 'name', 'magnetUri', 'host', 'account', 'tags' ] | ||
30 | } | ||
31 | |||
32 | // Sortable columns per schema | ||
33 | const SORTABLE_COLUMNS = { | 28 | const SORTABLE_COLUMNS = { |
34 | USERS: [ 'id', 'username', 'createdAt' ], | 29 | USERS: [ 'id', 'username', 'createdAt' ], |
35 | JOBS: [ 'id', 'createdAt' ], | 30 | JOBS: [ 'id', 'createdAt' ], |
@@ -361,7 +356,6 @@ export { | |||
361 | REMOTE_SCHEME, | 356 | REMOTE_SCHEME, |
362 | FOLLOW_STATES, | 357 | FOLLOW_STATES, |
363 | AVATARS_DIR, | 358 | AVATARS_DIR, |
364 | SEARCHABLE_COLUMNS, | ||
365 | SERVER_ACCOUNT_NAME, | 359 | SERVER_ACCOUNT_NAME, |
366 | PRIVATE_RSA_KEY_SIZE, | 360 | PRIVATE_RSA_KEY_SIZE, |
367 | SORTABLE_COLUMNS, | 361 | SORTABLE_COLUMNS, |
diff --git a/server/middlewares/index.ts b/server/middlewares/index.ts index aafcad2d9..0cef26953 100644 --- a/server/middlewares/index.ts +++ b/server/middlewares/index.ts | |||
@@ -4,6 +4,5 @@ export * from './async' | |||
4 | export * from './oauth' | 4 | export * from './oauth' |
5 | export * from './pagination' | 5 | export * from './pagination' |
6 | export * from './servers' | 6 | export * from './servers' |
7 | export * from './search' | ||
8 | export * from './sort' | 7 | export * from './sort' |
9 | export * from './user-right' | 8 | export * from './user-right' |
diff --git a/server/middlewares/search.ts b/server/middlewares/search.ts deleted file mode 100644 index 6fe83d25b..000000000 --- a/server/middlewares/search.ts +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | import 'express-validator' | ||
2 | import * as express from 'express' | ||
3 | |||
4 | function setVideosSearch (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
5 | if (!req.query.field) req.query.field = 'name' | ||
6 | |||
7 | return next() | ||
8 | } | ||
9 | |||
10 | // --------------------------------------------------------------------------- | ||
11 | |||
12 | export { | ||
13 | setVideosSearch | ||
14 | } | ||
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts index f21680aa0..ee2ac50c8 100644 --- a/server/middlewares/validators/videos.ts +++ b/server/middlewares/validators/videos.ts | |||
@@ -18,7 +18,7 @@ import { | |||
18 | } from '../../helpers/custom-validators/videos' | 18 | } from '../../helpers/custom-validators/videos' |
19 | import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils' | 19 | import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils' |
20 | import { logger } from '../../helpers/logger' | 20 | import { logger } from '../../helpers/logger' |
21 | import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' | 21 | import { CONSTRAINTS_FIELDS } from '../../initializers' |
22 | import { database as db } from '../../initializers/database' | 22 | import { database as db } from '../../initializers/database' |
23 | import { UserInstance } from '../../models/account/user-interface' | 23 | import { UserInstance } from '../../models/account/user-interface' |
24 | import { VideoInstance } from '../../models/video/video-interface' | 24 | import { VideoInstance } from '../../models/video/video-interface' |
@@ -172,8 +172,7 @@ const videosRemoveValidator = [ | |||
172 | ] | 172 | ] |
173 | 173 | ||
174 | const videosSearchValidator = [ | 174 | const videosSearchValidator = [ |
175 | param('value').not().isEmpty().withMessage('Should have a valid search'), | 175 | query('search').not().isEmpty().withMessage('Should have a valid search'), |
176 | query('field').optional().isIn(SEARCHABLE_COLUMNS.VIDEOS).withMessage('Should have correct searchable column'), | ||
177 | 176 | ||
178 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 177 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
179 | logger.debug('Checking videosSearch parameters', { parameters: req.params }) | 178 | logger.debug('Checking videosSearch parameters', { parameters: req.params }) |
diff --git a/server/models/video/video-interface.ts b/server/models/video/video-interface.ts index be140de86..2a63350af 100644 --- a/server/models/video/video-interface.ts +++ b/server/models/video/video-interface.ts | |||
@@ -50,7 +50,6 @@ export namespace VideoMethods { | |||
50 | export type ListUserVideosForApi = (userId: number, start: number, count: number, sort: string) => Bluebird< ResultList<VideoInstance> > | 50 | export type ListUserVideosForApi = (userId: number, start: number, count: number, sort: string) => Bluebird< ResultList<VideoInstance> > |
51 | export type SearchAndPopulateAccountAndServerAndTags = ( | 51 | export type SearchAndPopulateAccountAndServerAndTags = ( |
52 | value: string, | 52 | value: string, |
53 | field: string, | ||
54 | start: number, | 53 | start: number, |
55 | count: number, | 54 | count: number, |
56 | sort: string | 55 | sort: string |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index f3469c1de..4dce8e2fc 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -1070,7 +1070,7 @@ loadByUUIDAndPopulateAccountAndServerAndTags = function (uuid: string) { | |||
1070 | return Video.findOne(options) | 1070 | return Video.findOne(options) |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | searchAndPopulateAccountAndServerAndTags = function (value: string, field: string, start: number, count: number, sort: string) { | 1073 | searchAndPopulateAccountAndServerAndTags = function (value: string, start: number, count: number, sort: string) { |
1074 | const serverInclude: Sequelize.IncludeOptions = { | 1074 | const serverInclude: Sequelize.IncludeOptions = { |
1075 | model: Video['sequelize'].models.Server, | 1075 | model: Video['sequelize'].models.Server, |
1076 | required: false | 1076 | required: false |
@@ -1099,33 +1099,24 @@ searchAndPopulateAccountAndServerAndTags = function (value: string, field: strin | |||
1099 | order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ] | 1099 | order: [ getSort(sort), [ Video['sequelize'].models.Tag, 'name', 'ASC' ] ] |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | if (field === 'tags') { | 1102 | // TODO: search on tags too |
1103 | const escapedValue = Video['sequelize'].escape('%' + value + '%') | 1103 | // const escapedValue = Video['sequelize'].escape('%' + value + '%') |
1104 | query.where['id'][Sequelize.Op.in] = Video['sequelize'].literal( | 1104 | // query.where['id'][Sequelize.Op.in] = Video['sequelize'].literal( |
1105 | `(SELECT "VideoTags"."videoId" | 1105 | // `(SELECT "VideoTags"."videoId" |
1106 | FROM "Tags" | 1106 | // FROM "Tags" |
1107 | INNER JOIN "VideoTags" ON "Tags"."id" = "VideoTags"."tagId" | 1107 | // INNER JOIN "VideoTags" ON "Tags"."id" = "VideoTags"."tagId" |
1108 | WHERE name ILIKE ${escapedValue} | 1108 | // WHERE name ILIKE ${escapedValue} |
1109 | )` | 1109 | // )` |
1110 | ) | 1110 | // ) |
1111 | } else if (field === 'host') { | 1111 | |
1112 | // FIXME: Include our server? (not stored in the database) | 1112 | // TODO: search on account too |
1113 | serverInclude.where = { | 1113 | // accountInclude.where = { |
1114 | host: { | 1114 | // name: { |
1115 | [Sequelize.Op.iLike]: '%' + value + '%' | 1115 | // [Sequelize.Op.iLike]: '%' + value + '%' |
1116 | } | 1116 | // } |
1117 | } | 1117 | // } |
1118 | serverInclude.required = true | 1118 | query.where['name'] = { |
1119 | } else if (field === 'account') { | 1119 | [Sequelize.Op.iLike]: '%' + value + '%' |
1120 | accountInclude.where = { | ||
1121 | name: { | ||
1122 | [Sequelize.Op.iLike]: '%' + value + '%' | ||
1123 | } | ||
1124 | } | ||
1125 | } else { | ||
1126 | query.where[field] = { | ||
1127 | [Sequelize.Op.iLike]: '%' + value + '%' | ||
1128 | } | ||
1129 | } | 1120 | } |
1130 | 1121 | ||
1131 | query.include = [ | 1122 | query.include = [ |
diff --git a/server/tests/api/single-server.ts b/server/tests/api/single-server.ts index 041d13225..fe192d391 100644 --- a/server/tests/api/single-server.ts +++ b/server/tests/api/single-server.ts | |||
@@ -225,7 +225,7 @@ describe('Test a single server', function () { | |||
225 | expect(video.views).to.equal(3) | 225 | expect(video.views).to.equal(3) |
226 | }) | 226 | }) |
227 | 227 | ||
228 | it('Should search the video by name by default', async function () { | 228 | it('Should search the video by name', async function () { |
229 | const res = await searchVideo(server.url, 'my') | 229 | const res = await searchVideo(server.url, 'my') |
230 | 230 | ||
231 | expect(res.body.total).to.equal(1) | 231 | expect(res.body.total).to.equal(1) |
@@ -279,35 +279,36 @@ describe('Test a single server', function () { | |||
279 | // }) | 279 | // }) |
280 | // }) | 280 | // }) |
281 | 281 | ||
282 | it('Should search the video by tag', async function () { | 282 | // Not implemented yet |
283 | const res = await searchVideo(server.url, 'tag1', 'tags') | 283 | // it('Should search the video by tag', async function () { |
284 | 284 | // const res = await searchVideo(server.url, 'tag1') | |
285 | expect(res.body.total).to.equal(1) | 285 | // |
286 | expect(res.body.data).to.be.an('array') | 286 | // expect(res.body.total).to.equal(1) |
287 | expect(res.body.data.length).to.equal(1) | 287 | // expect(res.body.data).to.be.an('array') |
288 | 288 | // expect(res.body.data.length).to.equal(1) | |
289 | const video = res.body.data[0] | 289 | // |
290 | expect(video.name).to.equal('my super name') | 290 | // const video = res.body.data[0] |
291 | expect(video.category).to.equal(2) | 291 | // expect(video.name).to.equal('my super name') |
292 | expect(video.categoryLabel).to.equal('Films') | 292 | // expect(video.category).to.equal(2) |
293 | expect(video.licence).to.equal(6) | 293 | // expect(video.categoryLabel).to.equal('Films') |
294 | expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') | 294 | // expect(video.licence).to.equal(6) |
295 | expect(video.language).to.equal(3) | 295 | // expect(video.licenceLabel).to.equal('Attribution - Non Commercial - No Derivatives') |
296 | expect(video.languageLabel).to.equal('Mandarin') | 296 | // expect(video.language).to.equal(3) |
297 | expect(video.nsfw).to.be.ok | 297 | // expect(video.languageLabel).to.equal('Mandarin') |
298 | expect(video.description).to.equal('my super description') | 298 | // expect(video.nsfw).to.be.ok |
299 | expect(video.serverHost).to.equal('localhost:9001') | 299 | // expect(video.description).to.equal('my super description') |
300 | expect(video.account).to.equal('root') | 300 | // expect(video.serverHost).to.equal('localhost:9001') |
301 | expect(video.isLocal).to.be.true | 301 | // expect(video.account).to.equal('root') |
302 | expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) | 302 | // expect(video.isLocal).to.be.true |
303 | expect(dateIsValid(video.createdAt)).to.be.true | 303 | // expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) |
304 | expect(dateIsValid(video.updatedAt)).to.be.true | 304 | // expect(dateIsValid(video.createdAt)).to.be.true |
305 | 305 | // expect(dateIsValid(video.updatedAt)).to.be.true | |
306 | const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) | 306 | // |
307 | expect(test).to.equal(true) | 307 | // const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath) |
308 | }) | 308 | // expect(test).to.equal(true) |
309 | // }) | ||
309 | 310 | ||
310 | it('Should not find a search by name by default', async function () { | 311 | it('Should not find a search by name', async function () { |
311 | const res = await searchVideo(server.url, 'hello') | 312 | const res = await searchVideo(server.url, 'hello') |
312 | 313 | ||
313 | expect(res.body.total).to.equal(0) | 314 | expect(res.body.total).to.equal(0) |
@@ -315,21 +316,23 @@ describe('Test a single server', function () { | |||
315 | expect(res.body.data.length).to.equal(0) | 316 | expect(res.body.data.length).to.equal(0) |
316 | }) | 317 | }) |
317 | 318 | ||
318 | it('Should not find a search by author', async function () { | 319 | // Not implemented yet |
319 | const res = await searchVideo(server.url, 'hello', 'account') | 320 | // it('Should not find a search by author', async function () { |
320 | 321 | // const res = await searchVideo(server.url, 'hello') | |
321 | expect(res.body.total).to.equal(0) | 322 | // |
322 | expect(res.body.data).to.be.an('array') | 323 | // expect(res.body.total).to.equal(0) |
323 | expect(res.body.data.length).to.equal(0) | 324 | // expect(res.body.data).to.be.an('array') |
324 | }) | 325 | // expect(res.body.data.length).to.equal(0) |
325 | 326 | // }) | |
326 | it('Should not find a search by tag', async function () { | 327 | // |
327 | const res = await searchVideo(server.url, 'hello', 'tags') | 328 | // Not implemented yet |
328 | 329 | // it('Should not find a search by tag', async function () { | |
329 | expect(res.body.total).to.equal(0) | 330 | // const res = await searchVideo(server.url, 'hello') |
330 | expect(res.body.data).to.be.an('array') | 331 | // |
331 | expect(res.body.data.length).to.equal(0) | 332 | // expect(res.body.total).to.equal(0) |
332 | }) | 333 | // expect(res.body.data).to.be.an('array') |
334 | // expect(res.body.data.length).to.equal(0) | ||
335 | // }) | ||
333 | 336 | ||
334 | it('Should remove the video', async function () { | 337 | it('Should remove the video', async function () { |
335 | await removeVideo(server.url, server.accessToken, videoId) | 338 | await removeVideo(server.url, server.accessToken, videoId) |
@@ -443,7 +446,7 @@ describe('Test a single server', function () { | |||
443 | }) | 446 | }) |
444 | 447 | ||
445 | it('Should search the first video', async function () { | 448 | it('Should search the first video', async function () { |
446 | const res = await searchVideoWithPagination(server.url, 'webm', 'name', 0, 1, 'name') | 449 | const res = await searchVideoWithPagination(server.url, 'webm', 0, 1, 'name') |
447 | 450 | ||
448 | const videos = res.body.data | 451 | const videos = res.body.data |
449 | expect(res.body.total).to.equal(4) | 452 | expect(res.body.total).to.equal(4) |
@@ -452,7 +455,7 @@ describe('Test a single server', function () { | |||
452 | }) | 455 | }) |
453 | 456 | ||
454 | it('Should search the last two videos', async function () { | 457 | it('Should search the last two videos', async function () { |
455 | const res = await searchVideoWithPagination(server.url, 'webm', 'name', 2, 2, 'name') | 458 | const res = await searchVideoWithPagination(server.url, 'webm', 2, 2, 'name') |
456 | 459 | ||
457 | const videos = res.body.data | 460 | const videos = res.body.data |
458 | expect(res.body.total).to.equal(4) | 461 | expect(res.body.total).to.equal(4) |
@@ -462,20 +465,21 @@ describe('Test a single server', function () { | |||
462 | }) | 465 | }) |
463 | 466 | ||
464 | it('Should search all the webm videos', async function () { | 467 | it('Should search all the webm videos', async function () { |
465 | const res = await searchVideoWithPagination(server.url, 'webm', 'name', 0, 15) | 468 | const res = await searchVideoWithPagination(server.url, 'webm', 0, 15) |
466 | 469 | ||
467 | const videos = res.body.data | 470 | const videos = res.body.data |
468 | expect(res.body.total).to.equal(4) | 471 | expect(res.body.total).to.equal(4) |
469 | expect(videos.length).to.equal(4) | 472 | expect(videos.length).to.equal(4) |
470 | }) | 473 | }) |
471 | 474 | ||
472 | it('Should search all the root author videos', async function () { | 475 | // Not implemented yet |
473 | const res = await searchVideoWithPagination(server.url, 'root', 'account', 0, 15) | 476 | // it('Should search all the root author videos', async function () { |
474 | 477 | // const res = await searchVideoWithPagination(server.url, 'root', 0, 15) | |
475 | const videos = res.body.data | 478 | // |
476 | expect(res.body.total).to.equal(6) | 479 | // const videos = res.body.data |
477 | expect(videos.length).to.equal(6) | 480 | // expect(res.body.total).to.equal(6) |
478 | }) | 481 | // expect(videos.length).to.equal(6) |
482 | // }) | ||
479 | 483 | ||
480 | // Not implemented yet | 484 | // Not implemented yet |
481 | // it('Should search all the 9001 port videos', async function () { | 485 | // it('Should search all the 9001 port videos', async function () { |
diff --git a/server/tests/utils/videos.ts b/server/tests/utils/videos.ts index 73a9f1a0a..ff7da9bb2 100644 --- a/server/tests/utils/videos.ts +++ b/server/tests/utils/videos.ts | |||
@@ -145,26 +145,25 @@ function removeVideo (url: string, token: string, id: number, expectedStatus = 2 | |||
145 | .expect(expectedStatus) | 145 | .expect(expectedStatus) |
146 | } | 146 | } |
147 | 147 | ||
148 | function searchVideo (url: string, search: string, field?: string) { | 148 | function searchVideo (url: string, search: string) { |
149 | const path = '/api/v1/videos' | 149 | const path = '/api/v1/videos' |
150 | const req = request(url) | 150 | const req = request(url) |
151 | .get(path + '/search/' + search) | 151 | .get(path + '/search') |
152 | .set('Accept', 'application/json') | 152 | .query({ search }) |
153 | 153 | .set('Accept', 'application/json') | |
154 | if (field) req.query({ field }) | ||
155 | 154 | ||
156 | return req.expect(200) | 155 | return req.expect(200) |
157 | .expect('Content-Type', /json/) | 156 | .expect('Content-Type', /json/) |
158 | } | 157 | } |
159 | 158 | ||
160 | function searchVideoWithPagination (url: string, search: string, field: string, start: number, count: number, sort?: string) { | 159 | function searchVideoWithPagination (url: string, search: string, start: number, count: number, sort?: string) { |
161 | const path = '/api/v1/videos' | 160 | const path = '/api/v1/videos' |
162 | 161 | ||
163 | const req = request(url) | 162 | const req = request(url) |
164 | .get(path + '/search/' + search) | 163 | .get(path + '/search') |
165 | .query({ start }) | 164 | .query({ start }) |
165 | .query({ search }) | ||
166 | .query({ count }) | 166 | .query({ count }) |
167 | .query({ field }) | ||
168 | 167 | ||
169 | if (sort) req.query({ sort }) | 168 | if (sort) req.query({ sort }) |
170 | 169 | ||
@@ -177,7 +176,8 @@ function searchVideoWithSort (url: string, search: string, sort: string) { | |||
177 | const path = '/api/v1/videos' | 176 | const path = '/api/v1/videos' |
178 | 177 | ||
179 | return request(url) | 178 | return request(url) |
180 | .get(path + '/search/' + search) | 179 | .get(path + '/search') |
180 | .query({ search }) | ||
181 | .query({ sort }) | 181 | .query({ sort }) |
182 | .set('Accept', 'application/json') | 182 | .set('Accept', 'application/json') |
183 | .expect(200) | 183 | .expect(200) |