diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-11-30 10:51:13 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-11-30 10:55:06 +0100 |
commit | 5cd80545422bba855cc9a730a2e13cc9d982c34b (patch) | |
tree | 9a60cd7c9218c296a1460938d11e3bce784f7cc0 /server | |
parent | 1f3e9feca2caf68024168b0ea9ed39d8438fa235 (diff) | |
download | PeerTube-5cd80545422bba855cc9a730a2e13cc9d982c34b.tar.gz PeerTube-5cd80545422bba855cc9a730a2e13cc9d982c34b.tar.zst PeerTube-5cd80545422bba855cc9a730a2e13cc9d982c34b.zip |
Add ability to list jobs
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/index.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/jobs.ts | 34 | ||||
-rw-r--r-- | server/initializers/constants.ts | 1 | ||||
-rw-r--r-- | server/middlewares/sort.ts | 9 | ||||
-rw-r--r-- | server/middlewares/validators/sort.ts | 5 | ||||
-rw-r--r-- | server/models/account/user-interface.ts | 8 | ||||
-rw-r--r-- | server/models/job/job-interface.ts | 15 | ||||
-rw-r--r-- | server/models/job/job.ts | 52 | ||||
-rw-r--r-- | server/tests/api/check-params/index.ts | 1 | ||||
-rw-r--r-- | server/tests/api/check-params/jobs.ts | 84 | ||||
-rw-r--r-- | server/tests/api/index-slow.ts | 1 | ||||
-rw-r--r-- | server/tests/api/jobs.ts | 64 | ||||
-rw-r--r-- | server/tests/utils/follows.ts | 2 | ||||
-rw-r--r-- | server/tests/utils/jobs.ts | 33 |
14 files changed, 287 insertions, 24 deletions
diff --git a/server/controllers/api/index.ts b/server/controllers/api/index.ts index b00fb7467..737ea4602 100644 --- a/server/controllers/api/index.ts +++ b/server/controllers/api/index.ts | |||
@@ -7,6 +7,7 @@ import { configRouter } from './config' | |||
7 | import { serverRouter } from './server' | 7 | import { serverRouter } from './server' |
8 | import { usersRouter } from './users' | 8 | import { usersRouter } from './users' |
9 | import { videosRouter } from './videos' | 9 | import { videosRouter } from './videos' |
10 | import { jobsRouter } from './jobs' | ||
10 | 11 | ||
11 | const apiRouter = express.Router() | 12 | const apiRouter = express.Router() |
12 | 13 | ||
@@ -15,6 +16,7 @@ apiRouter.use('/oauth-clients', oauthClientsRouter) | |||
15 | apiRouter.use('/config', configRouter) | 16 | apiRouter.use('/config', configRouter) |
16 | apiRouter.use('/users', usersRouter) | 17 | apiRouter.use('/users', usersRouter) |
17 | apiRouter.use('/videos', videosRouter) | 18 | apiRouter.use('/videos', videosRouter) |
19 | apiRouter.use('/jobs', jobsRouter) | ||
18 | apiRouter.use('/ping', pong) | 20 | apiRouter.use('/ping', pong) |
19 | apiRouter.use('/*', badRequest) | 21 | apiRouter.use('/*', badRequest) |
20 | 22 | ||
diff --git a/server/controllers/api/jobs.ts b/server/controllers/api/jobs.ts new file mode 100644 index 000000000..f6fbff369 --- /dev/null +++ b/server/controllers/api/jobs.ts | |||
@@ -0,0 +1,34 @@ | |||
1 | import * as express from 'express' | ||
2 | import { asyncMiddleware, jobsSortValidator, setJobsSort, setPagination } from '../../middlewares' | ||
3 | import { paginationValidator } from '../../middlewares/validators/pagination' | ||
4 | import { database as db } from '../../initializers' | ||
5 | import { getFormattedObjects } from '../../helpers/utils' | ||
6 | import { authenticate } from '../../middlewares/oauth' | ||
7 | import { ensureUserHasRight } from '../../middlewares/user-right' | ||
8 | import { UserRight } from '../../../shared/models/users/user-right.enum' | ||
9 | |||
10 | const jobsRouter = express.Router() | ||
11 | |||
12 | jobsRouter.get('/', | ||
13 | authenticate, | ||
14 | ensureUserHasRight(UserRight.MANAGE_JOBS), | ||
15 | paginationValidator, | ||
16 | jobsSortValidator, | ||
17 | setJobsSort, | ||
18 | setPagination, | ||
19 | asyncMiddleware(listJobs) | ||
20 | ) | ||
21 | |||
22 | // --------------------------------------------------------------------------- | ||
23 | |||
24 | export { | ||
25 | jobsRouter | ||
26 | } | ||
27 | |||
28 | // --------------------------------------------------------------------------- | ||
29 | |||
30 | async function listJobs (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
31 | const resultList = await db.Job.listForApi(req.query.start, req.query.count, req.query.sort) | ||
32 | |||
33 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | ||
34 | } | ||
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 6d8aa7332..8f278fb0b 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -32,6 +32,7 @@ const SEARCHABLE_COLUMNS = { | |||
32 | // Sortable columns per schema | 32 | // Sortable columns per schema |
33 | const SORTABLE_COLUMNS = { | 33 | const SORTABLE_COLUMNS = { |
34 | USERS: [ 'id', 'username', 'createdAt' ], | 34 | USERS: [ 'id', 'username', 'createdAt' ], |
35 | JOBS: [ 'id', 'createdAt' ], | ||
35 | VIDEO_ABUSES: [ 'id', 'createdAt' ], | 36 | VIDEO_ABUSES: [ 'id', 'createdAt' ], |
36 | VIDEO_CHANNELS: [ 'id', 'name', 'updatedAt', 'createdAt' ], | 37 | VIDEO_CHANNELS: [ 'id', 'name', 'updatedAt', 'createdAt' ], |
37 | VIDEOS: [ 'name', 'duration', 'createdAt', 'views', 'likes' ], | 38 | VIDEOS: [ 'name', 'duration', 'createdAt', 'views', 'likes' ], |
diff --git a/server/middlewares/sort.ts b/server/middlewares/sort.ts index 279b29e65..7b60920de 100644 --- a/server/middlewares/sort.ts +++ b/server/middlewares/sort.ts | |||
@@ -10,6 +10,12 @@ function setUsersSort (req: express.Request, res: express.Response, next: expres | |||
10 | return next() | 10 | return next() |
11 | } | 11 | } |
12 | 12 | ||
13 | function setJobsSort (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
14 | if (!req.query.sort) req.query.sort = '-createdAt' | ||
15 | |||
16 | return next() | ||
17 | } | ||
18 | |||
13 | function setVideoAbusesSort (req: express.Request, res: express.Response, next: express.NextFunction) { | 19 | function setVideoAbusesSort (req: express.Request, res: express.Response, next: express.NextFunction) { |
14 | if (!req.query.sort) req.query.sort = '-createdAt' | 20 | if (!req.query.sort) req.query.sort = '-createdAt' |
15 | 21 | ||
@@ -70,5 +76,6 @@ export { | |||
70 | setVideosSort, | 76 | setVideosSort, |
71 | setBlacklistSort, | 77 | setBlacklistSort, |
72 | setFollowersSort, | 78 | setFollowersSort, |
73 | setFollowingSort | 79 | setFollowingSort, |
80 | setJobsSort | ||
74 | } | 81 | } |
diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts index 636f68885..d5822ac81 100644 --- a/server/middlewares/validators/sort.ts +++ b/server/middlewares/validators/sort.ts | |||
@@ -7,6 +7,7 @@ import { areValidationErrors } from './utils' | |||
7 | 7 | ||
8 | // Initialize constants here for better performances | 8 | // Initialize constants here for better performances |
9 | const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS) | 9 | const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS) |
10 | const SORTABLE_JOBS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.JOBS) | ||
10 | const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES) | 11 | const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES) |
11 | const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS) | 12 | const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS) |
12 | const SORTABLE_BLACKLISTS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.BLACKLISTS) | 13 | const SORTABLE_BLACKLISTS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.BLACKLISTS) |
@@ -15,6 +16,7 @@ const SORTABLE_FOLLOWERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOW | |||
15 | const SORTABLE_FOLLOWING_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOWING) | 16 | const SORTABLE_FOLLOWING_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOWING) |
16 | 17 | ||
17 | const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS) | 18 | const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS) |
19 | const jobsSortValidator = checkSort(SORTABLE_JOBS_COLUMNS) | ||
18 | const videoAbusesSortValidator = checkSort(SORTABLE_VIDEO_ABUSES_COLUMNS) | 20 | const videoAbusesSortValidator = checkSort(SORTABLE_VIDEO_ABUSES_COLUMNS) |
19 | const videosSortValidator = checkSort(SORTABLE_VIDEOS_COLUMNS) | 21 | const videosSortValidator = checkSort(SORTABLE_VIDEOS_COLUMNS) |
20 | const blacklistSortValidator = checkSort(SORTABLE_BLACKLISTS_COLUMNS) | 22 | const blacklistSortValidator = checkSort(SORTABLE_BLACKLISTS_COLUMNS) |
@@ -31,7 +33,8 @@ export { | |||
31 | videosSortValidator, | 33 | videosSortValidator, |
32 | blacklistSortValidator, | 34 | blacklistSortValidator, |
33 | followersSortValidator, | 35 | followersSortValidator, |
34 | followingSortValidator | 36 | followingSortValidator, |
37 | jobsSortValidator | ||
35 | } | 38 | } |
36 | 39 | ||
37 | // --------------------------------------------------------------------------- | 40 | // --------------------------------------------------------------------------- |
diff --git a/server/models/account/user-interface.ts b/server/models/account/user-interface.ts index 1a04fb750..0f0b72063 100644 --- a/server/models/account/user-interface.ts +++ b/server/models/account/user-interface.ts | |||
@@ -1,12 +1,10 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
3 | 2 | import * as Sequelize from 'sequelize' | |
4 | // Don't use barrel, import just what we need | ||
5 | import { AccountInstance } from './account-interface' | ||
6 | import { User as FormattedUser } from '../../../shared/models/users/user.model' | ||
7 | import { ResultList } from '../../../shared/models/result-list.model' | 3 | import { ResultList } from '../../../shared/models/result-list.model' |
8 | import { UserRight } from '../../../shared/models/users/user-right.enum' | 4 | import { UserRight } from '../../../shared/models/users/user-right.enum' |
9 | import { UserRole } from '../../../shared/models/users/user-role' | 5 | import { UserRole } from '../../../shared/models/users/user-role' |
6 | import { User as FormattedUser } from '../../../shared/models/users/user.model' | ||
7 | import { AccountInstance } from './account-interface' | ||
10 | 8 | ||
11 | export namespace UserMethods { | 9 | export namespace UserMethods { |
12 | export type HasRight = (this: UserInstance, right: UserRight) => boolean | 10 | export type HasRight = (this: UserInstance, right: UserRight) => boolean |
diff --git a/server/models/job/job-interface.ts b/server/models/job/job-interface.ts index 411a05029..3cfc0fbed 100644 --- a/server/models/job/job-interface.ts +++ b/server/models/job/job-interface.ts | |||
@@ -1,18 +1,23 @@ | |||
1 | import * as Bluebird from 'bluebird' | ||
1 | import * as Sequelize from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | 3 | import { Job as FormattedJob, JobCategory, JobState } from '../../../shared/models/job.model' |
3 | 4 | import { ResultList } from '../../../shared/models/result-list.model' | |
4 | import { JobCategory, JobState } from '../../../shared/models/job.model' | ||
5 | 5 | ||
6 | export namespace JobMethods { | 6 | export namespace JobMethods { |
7 | export type ListWithLimitByCategory = (limit: number, state: JobState, category: JobCategory) => Promise<JobInstance[]> | 7 | export type ListWithLimitByCategory = (limit: number, state: JobState, category: JobCategory) => Bluebird<JobInstance[]> |
8 | export type ListForApi = (start: number, count: number, sort: string) => Bluebird< ResultList<JobInstance> > | ||
9 | |||
10 | export type ToFormattedJSON = (this: JobInstance) => FormattedJob | ||
8 | } | 11 | } |
9 | 12 | ||
10 | export interface JobClass { | 13 | export interface JobClass { |
11 | listWithLimitByCategory: JobMethods.ListWithLimitByCategory | 14 | listWithLimitByCategory: JobMethods.ListWithLimitByCategory |
15 | listForApi: JobMethods.ListForApi, | ||
12 | } | 16 | } |
13 | 17 | ||
14 | export interface JobAttributes { | 18 | export interface JobAttributes { |
15 | state: JobState | 19 | state: JobState |
20 | category: JobCategory | ||
16 | handlerName: string | 21 | handlerName: string |
17 | handlerInputData: any | 22 | handlerInputData: any |
18 | } | 23 | } |
@@ -21,6 +26,8 @@ export interface JobInstance extends JobClass, JobAttributes, Sequelize.Instance | |||
21 | id: number | 26 | id: number |
22 | createdAt: Date | 27 | createdAt: Date |
23 | updatedAt: Date | 28 | updatedAt: Date |
29 | |||
30 | toFormattedJSON: JobMethods.ToFormattedJSON | ||
24 | } | 31 | } |
25 | 32 | ||
26 | export interface JobModel extends JobClass, Sequelize.Model<JobInstance, JobAttributes> {} | 33 | export interface JobModel extends JobClass, Sequelize.Model<JobInstance, JobAttributes> {} |
diff --git a/server/models/job/job.ts b/server/models/job/job.ts index c2d088090..f428e26db 100644 --- a/server/models/job/job.ts +++ b/server/models/job/job.ts | |||
@@ -1,19 +1,14 @@ | |||
1 | import { values } from 'lodash' | 1 | import { values } from 'lodash' |
2 | import * as Sequelize from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
3 | |||
4 | import { JOB_STATES, JOB_CATEGORIES } from '../../initializers' | ||
5 | |||
6 | import { addMethodsToModel } from '../utils' | ||
7 | import { | ||
8 | JobInstance, | ||
9 | JobAttributes, | ||
10 | |||
11 | JobMethods | ||
12 | } from './job-interface' | ||
13 | import { JobCategory, JobState } from '../../../shared/models/job.model' | 3 | import { JobCategory, JobState } from '../../../shared/models/job.model' |
4 | import { JOB_CATEGORIES, JOB_STATES } from '../../initializers' | ||
5 | import { addMethodsToModel, getSort } from '../utils' | ||
6 | import { JobAttributes, JobInstance, JobMethods } from './job-interface' | ||
14 | 7 | ||
15 | let Job: Sequelize.Model<JobInstance, JobAttributes> | 8 | let Job: Sequelize.Model<JobInstance, JobAttributes> |
16 | let listWithLimitByCategory: JobMethods.ListWithLimitByCategory | 9 | let listWithLimitByCategory: JobMethods.ListWithLimitByCategory |
10 | let listForApi: JobMethods.ListForApi | ||
11 | let toFormattedJSON: JobMethods.ToFormattedJSON | ||
17 | 12 | ||
18 | export default function defineJob (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { | 13 | export default function defineJob (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { |
19 | Job = sequelize.define<JobInstance, JobAttributes>('Job', | 14 | Job = sequelize.define<JobInstance, JobAttributes>('Job', |
@@ -44,12 +39,30 @@ export default function defineJob (sequelize: Sequelize.Sequelize, DataTypes: Se | |||
44 | } | 39 | } |
45 | ) | 40 | ) |
46 | 41 | ||
47 | const classMethods = [ listWithLimitByCategory ] | 42 | const classMethods = [ |
48 | addMethodsToModel(Job, classMethods) | 43 | listWithLimitByCategory, |
44 | listForApi | ||
45 | ] | ||
46 | const instanceMethods = [ | ||
47 | toFormattedJSON | ||
48 | ] | ||
49 | addMethodsToModel(Job, classMethods, instanceMethods) | ||
49 | 50 | ||
50 | return Job | 51 | return Job |
51 | } | 52 | } |
52 | 53 | ||
54 | toFormattedJSON = function (this: JobInstance) { | ||
55 | return { | ||
56 | id: this.id, | ||
57 | state: this.state, | ||
58 | category: this.category, | ||
59 | handlerName: this.handlerName, | ||
60 | handlerInputData: this.handlerInputData, | ||
61 | createdAt: this.createdAt, | ||
62 | updatedAt: this.updatedAt | ||
63 | } | ||
64 | } | ||
65 | |||
53 | // --------------------------------------------------------------------------- | 66 | // --------------------------------------------------------------------------- |
54 | 67 | ||
55 | listWithLimitByCategory = function (limit: number, state: JobState, jobCategory: JobCategory) { | 68 | listWithLimitByCategory = function (limit: number, state: JobState, jobCategory: JobCategory) { |
@@ -66,3 +79,18 @@ listWithLimitByCategory = function (limit: number, state: JobState, jobCategory: | |||
66 | 79 | ||
67 | return Job.findAll(query) | 80 | return Job.findAll(query) |
68 | } | 81 | } |
82 | |||
83 | listForApi = function (start: number, count: number, sort: string) { | ||
84 | const query = { | ||
85 | offset: start, | ||
86 | limit: count, | ||
87 | order: [ getSort(sort) ] | ||
88 | } | ||
89 | |||
90 | return Job.findAndCountAll(query).then(({ rows, count }) => { | ||
91 | return { | ||
92 | data: rows, | ||
93 | total: count | ||
94 | } | ||
95 | }) | ||
96 | } | ||
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts index 287480808..b22bf054a 100644 --- a/server/tests/api/check-params/index.ts +++ b/server/tests/api/check-params/index.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | // Order of the tests we want to execute | 1 | // Order of the tests we want to execute |
2 | import './follows' | 2 | import './follows' |
3 | import './jobs' | ||
3 | import './users' | 4 | import './users' |
4 | import './services' | 5 | import './services' |
5 | import './videos' | 6 | import './videos' |
diff --git a/server/tests/api/check-params/jobs.ts b/server/tests/api/check-params/jobs.ts new file mode 100644 index 000000000..7a0dd6e8c --- /dev/null +++ b/server/tests/api/check-params/jobs.ts | |||
@@ -0,0 +1,84 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | ||
2 | |||
3 | import 'mocha' | ||
4 | import * as request from 'supertest' | ||
5 | |||
6 | import { createUser, flushTests, getUserAccessToken, killallServers, runServer, ServerInfo, setAccessTokensToServers } from '../../utils' | ||
7 | |||
8 | describe('Test jobs API validators', function () { | ||
9 | const path = '/api/v1/jobs/' | ||
10 | let server: ServerInfo | ||
11 | let userAccessToken = '' | ||
12 | |||
13 | // --------------------------------------------------------------- | ||
14 | |||
15 | before(async function () { | ||
16 | this.timeout(120000) | ||
17 | |||
18 | await flushTests() | ||
19 | |||
20 | server = await runServer(1) | ||
21 | |||
22 | await setAccessTokensToServers([ server ]) | ||
23 | |||
24 | const user = { | ||
25 | username: 'user1', | ||
26 | password: 'my super password' | ||
27 | } | ||
28 | await createUser(server.url, server.accessToken, user.username, user.password) | ||
29 | userAccessToken = await getUserAccessToken(server, user) | ||
30 | }) | ||
31 | |||
32 | describe('When listing jobs', function () { | ||
33 | it('Should fail with a bad start pagination', async function () { | ||
34 | await request(server.url) | ||
35 | .get(path) | ||
36 | .query({ start: 'hello' }) | ||
37 | .set('Accept', 'application/json') | ||
38 | .set('Authorization', 'Bearer ' + server.accessToken) | ||
39 | .expect(400) | ||
40 | }) | ||
41 | |||
42 | it('Should fail with a bad count pagination', async function () { | ||
43 | await request(server.url) | ||
44 | .get(path) | ||
45 | .query({ count: 'hello' }) | ||
46 | .set('Accept', 'application/json') | ||
47 | .set('Authorization', 'Bearer ' + server.accessToken) | ||
48 | .expect(400) | ||
49 | }) | ||
50 | |||
51 | it('Should fail with an incorrect sort', async function () { | ||
52 | await request(server.url) | ||
53 | .get(path) | ||
54 | .query({ sort: 'hello' }) | ||
55 | .set('Accept', 'application/json') | ||
56 | .set('Authorization', 'Bearer ' + server.accessToken) | ||
57 | .expect(400) | ||
58 | }) | ||
59 | |||
60 | it('Should fail with a non authenticated user', async function () { | ||
61 | await request(server.url) | ||
62 | .get(path) | ||
63 | .set('Accept', 'application/json') | ||
64 | .expect(401) | ||
65 | }) | ||
66 | |||
67 | it('Should fail with a non admin user', async function () { | ||
68 | await request(server.url) | ||
69 | .get(path) | ||
70 | .set('Accept', 'application/json') | ||
71 | .set('Authorization', 'Bearer ' + userAccessToken) | ||
72 | .expect(403) | ||
73 | }) | ||
74 | }) | ||
75 | |||
76 | after(async function () { | ||
77 | killallServers([ server ]) | ||
78 | |||
79 | // Keep the logs if the test failed | ||
80 | if (this['ok']) { | ||
81 | await flushTests() | ||
82 | } | ||
83 | }) | ||
84 | }) | ||
diff --git a/server/tests/api/index-slow.ts b/server/tests/api/index-slow.ts index 2448147d8..4cd5b09a2 100644 --- a/server/tests/api/index-slow.ts +++ b/server/tests/api/index-slow.ts | |||
@@ -3,3 +3,4 @@ | |||
3 | import './video-transcoder' | 3 | import './video-transcoder' |
4 | import './multiple-servers' | 4 | import './multiple-servers' |
5 | import './follows' | 5 | import './follows' |
6 | import './jobs' | ||
diff --git a/server/tests/api/jobs.ts b/server/tests/api/jobs.ts new file mode 100644 index 000000000..4d9b61392 --- /dev/null +++ b/server/tests/api/jobs.ts | |||
@@ -0,0 +1,64 @@ | |||
1 | /* tslint:disable:no-unused-expression */ | ||
2 | |||
3 | import * as chai from 'chai' | ||
4 | import 'mocha' | ||
5 | import { flushTests, killallServers, ServerInfo, setAccessTokensToServers, wait } from '../utils' | ||
6 | import { doubleFollow } from '../utils/follows' | ||
7 | import { getJobsList, getJobsListPaginationAndSort } from '../utils/jobs' | ||
8 | import { flushAndRunMultipleServers } from '../utils/servers' | ||
9 | import { uploadVideo } from '../utils/videos' | ||
10 | import { dateIsValid } from '../utils/miscs' | ||
11 | |||
12 | const expect = chai.expect | ||
13 | |||
14 | describe('Test jobs', function () { | ||
15 | let servers: ServerInfo[] | ||
16 | |||
17 | before(async function () { | ||
18 | this.timeout(30000) | ||
19 | |||
20 | servers = await flushAndRunMultipleServers(2) | ||
21 | |||
22 | await setAccessTokensToServers(servers) | ||
23 | |||
24 | // Server 1 and server 2 follow each other | ||
25 | await doubleFollow(servers[0], servers[1]) | ||
26 | }) | ||
27 | |||
28 | it('Should create some jobs', async function () { | ||
29 | this.timeout(30000) | ||
30 | |||
31 | await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video1' }) | ||
32 | await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video2' }) | ||
33 | |||
34 | await wait(15000) | ||
35 | }) | ||
36 | |||
37 | it('Should list jobs', async function () { | ||
38 | const res = await getJobsList(servers[1].url, servers[1].accessToken) | ||
39 | expect(res.body.total).to.be.above(2) | ||
40 | expect(res.body.data).to.have.length.above(2) | ||
41 | }) | ||
42 | |||
43 | it('Should list jobs with sort and pagination', async function () { | ||
44 | const res = await getJobsListPaginationAndSort(servers[1].url, servers[1].accessToken, 4, 1, 'createdAt') | ||
45 | expect(res.body.total).to.be.above(2) | ||
46 | expect(res.body.data).to.have.lengthOf(1) | ||
47 | |||
48 | const job = res.body.data[0] | ||
49 | expect(job.state).to.equal('success') | ||
50 | expect(job.category).to.equal('transcoding') | ||
51 | expect(job.handlerName).to.have.length.above(3) | ||
52 | expect(dateIsValid(job.createdAt)).to.be.true | ||
53 | expect(dateIsValid(job.updatedAt)).to.be.true | ||
54 | }) | ||
55 | |||
56 | after(async function () { | ||
57 | killallServers(servers) | ||
58 | |||
59 | // Keep the logs if the test failed | ||
60 | if (this['ok']) { | ||
61 | await flushTests() | ||
62 | } | ||
63 | }) | ||
64 | }) | ||
diff --git a/server/tests/utils/follows.ts b/server/tests/utils/follows.ts index b88776011..033c6a719 100644 --- a/server/tests/utils/follows.ts +++ b/server/tests/utils/follows.ts | |||
@@ -61,7 +61,7 @@ async function doubleFollow (server1: ServerInfo, server2: ServerInfo) { | |||
61 | ]) | 61 | ]) |
62 | 62 | ||
63 | // Wait request propagation | 63 | // Wait request propagation |
64 | await wait(20000) | 64 | await wait(10000) |
65 | 65 | ||
66 | return true | 66 | return true |
67 | } | 67 | } |
diff --git a/server/tests/utils/jobs.ts b/server/tests/utils/jobs.ts new file mode 100644 index 000000000..0a8c51575 --- /dev/null +++ b/server/tests/utils/jobs.ts | |||
@@ -0,0 +1,33 @@ | |||
1 | import * as request from 'supertest' | ||
2 | |||
3 | function getJobsList (url: string, accessToken: string) { | ||
4 | const path = '/api/v1/jobs' | ||
5 | |||
6 | return request(url) | ||
7 | .get(path) | ||
8 | .set('Accept', 'application/json') | ||
9 | .set('Authorization', 'Bearer ' + accessToken) | ||
10 | .expect(200) | ||
11 | .expect('Content-Type', /json/) | ||
12 | } | ||
13 | |||
14 | function getJobsListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string) { | ||
15 | const path = '/api/v1/jobs' | ||
16 | |||
17 | return request(url) | ||
18 | .get(path) | ||
19 | .query({ start }) | ||
20 | .query({ count }) | ||
21 | .query({ sort }) | ||
22 | .set('Accept', 'application/json') | ||
23 | .set('Authorization', 'Bearer ' + accessToken) | ||
24 | .expect(200) | ||
25 | .expect('Content-Type', /json/) | ||
26 | } | ||
27 | |||
28 | // --------------------------------------------------------------------------- | ||
29 | |||
30 | export { | ||
31 | getJobsList, | ||
32 | getJobsListPaginationAndSort | ||
33 | } | ||