aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/utils
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/utils')
-rw-r--r--server/tests/utils/cli/cli.ts24
-rw-r--r--server/tests/utils/feeds/feeds.ts32
-rw-r--r--server/tests/utils/index.ts18
-rw-r--r--server/tests/utils/miscs/email.ts25
-rw-r--r--server/tests/utils/miscs/miscs.ts72
-rw-r--r--server/tests/utils/overviews/overviews.ts18
-rw-r--r--server/tests/utils/requests/check-api-params.ts40
-rw-r--r--server/tests/utils/requests/requests.ts170
-rw-r--r--server/tests/utils/search/video-channels.ts22
-rw-r--r--server/tests/utils/search/videos.ts77
-rw-r--r--server/tests/utils/server/activitypub.ts15
-rw-r--r--server/tests/utils/server/clients.ts19
-rw-r--r--server/tests/utils/server/config.ts135
-rw-r--r--server/tests/utils/server/follows.ts77
-rw-r--r--server/tests/utils/server/jobs.ts77
-rw-r--r--server/tests/utils/server/redundancy.ts17
-rw-r--r--server/tests/utils/server/servers.ts185
-rw-r--r--server/tests/utils/server/stats.ts22
-rw-r--r--server/tests/utils/users/accounts.ts63
-rw-r--r--server/tests/utils/users/login.ts62
-rw-r--r--server/tests/utils/users/user-subscriptions.ts82
-rw-r--r--server/tests/utils/users/users.ts295
-rw-r--r--server/tests/utils/videos/services.ts23
-rw-r--r--server/tests/utils/videos/video-abuses.ts65
-rw-r--r--server/tests/utils/videos/video-blacklist.ts67
-rw-r--r--server/tests/utils/videos/video-captions.ts71
-rw-r--r--server/tests/utils/videos/video-change-ownership.ts54
-rw-r--r--server/tests/utils/videos/video-channels.ts118
-rw-r--r--server/tests/utils/videos/video-comments.ts83
-rw-r--r--server/tests/utils/videos/video-history.ts14
-rw-r--r--server/tests/utils/videos/video-imports.ts51
-rw-r--r--server/tests/utils/videos/videos.ts582
32 files changed, 0 insertions, 2675 deletions
diff --git a/server/tests/utils/cli/cli.ts b/server/tests/utils/cli/cli.ts
deleted file mode 100644
index 54d05e9c6..000000000
--- a/server/tests/utils/cli/cli.ts
+++ /dev/null
@@ -1,24 +0,0 @@
1import { exec } from 'child_process'
2
3import { ServerInfo } from '../server/servers'
4
5function getEnvCli (server?: ServerInfo) {
6 return `NODE_ENV=test NODE_APP_INSTANCE=${server.serverNumber}`
7}
8
9async function execCLI (command: string) {
10 return new Promise<string>((res, rej) => {
11 exec(command, (err, stdout, stderr) => {
12 if (err) return rej(err)
13
14 return res(stdout)
15 })
16 })
17}
18
19// ---------------------------------------------------------------------------
20
21export {
22 execCLI,
23 getEnvCli
24}
diff --git a/server/tests/utils/feeds/feeds.ts b/server/tests/utils/feeds/feeds.ts
deleted file mode 100644
index af6df2b20..000000000
--- a/server/tests/utils/feeds/feeds.ts
+++ /dev/null
@@ -1,32 +0,0 @@
1import * as request from 'supertest'
2
3type FeedType = 'videos' | 'video-comments'
4
5function getXMLfeed (url: string, feed: FeedType, format?: string) {
6 const path = '/feeds/' + feed + '.xml'
7
8 return request(url)
9 .get(path)
10 .query((format) ? { format: format } : {})
11 .set('Accept', 'application/xml')
12 .expect(200)
13 .expect('Content-Type', /xml/)
14}
15
16function getJSONfeed (url: string, feed: FeedType, query: any = {}) {
17 const path = '/feeds/' + feed + '.json'
18
19 return request(url)
20 .get(path)
21 .query(query)
22 .set('Accept', 'application/json')
23 .expect(200)
24 .expect('Content-Type', /json/)
25}
26
27// ---------------------------------------------------------------------------
28
29export {
30 getXMLfeed,
31 getJSONfeed
32}
diff --git a/server/tests/utils/index.ts b/server/tests/utils/index.ts
deleted file mode 100644
index 897389824..000000000
--- a/server/tests/utils/index.ts
+++ /dev/null
@@ -1,18 +0,0 @@
1export * from './server/activitypub'
2export * from './cli/cli'
3export * from './server/clients'
4export * from './server/config'
5export * from './users/login'
6export * from './miscs/miscs'
7export * from './server/follows'
8export * from './requests/requests'
9export * from './server/servers'
10export * from './videos/services'
11export * from './users/users'
12export * from './videos/video-abuses'
13export * from './videos/video-blacklist'
14export * from './videos/video-channels'
15export * from './videos/videos'
16export * from './videos/video-change-ownership'
17export * from './feeds/feeds'
18export * from './search/videos'
diff --git a/server/tests/utils/miscs/email.ts b/server/tests/utils/miscs/email.ts
deleted file mode 100644
index 21accd09d..000000000
--- a/server/tests/utils/miscs/email.ts
+++ /dev/null
@@ -1,25 +0,0 @@
1import * as MailDev from 'maildev'
2
3function mockSmtpServer (emailsCollection: object[]) {
4 const maildev = new MailDev({
5 ip: '127.0.0.1',
6 smtp: 1025,
7 disableWeb: true,
8 silent: true
9 })
10 maildev.on('new', email => emailsCollection.push(email))
11
12 return new Promise((res, rej) => {
13 maildev.listen(err => {
14 if (err) return rej(err)
15
16 return res()
17 })
18 })
19}
20
21// ---------------------------------------------------------------------------
22
23export {
24 mockSmtpServer
25}
diff --git a/server/tests/utils/miscs/miscs.ts b/server/tests/utils/miscs/miscs.ts
deleted file mode 100644
index b2f80e9b1..000000000
--- a/server/tests/utils/miscs/miscs.ts
+++ /dev/null
@@ -1,72 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import { isAbsolute, join } from 'path'
5import * as request from 'supertest'
6import * as WebTorrent from 'webtorrent'
7import { readFile } from 'fs-extra'
8
9const expect = chai.expect
10let webtorrent = new WebTorrent()
11
12function immutableAssign <T, U> (target: T, source: U) {
13 return Object.assign<{}, T, U>({}, target, source)
14}
15
16 // Default interval -> 5 minutes
17function dateIsValid (dateString: string, interval = 300000) {
18 const dateToCheck = new Date(dateString)
19 const now = new Date()
20
21 return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval
22}
23
24function wait (milliseconds: number) {
25 return new Promise(resolve => setTimeout(resolve, milliseconds))
26}
27
28function webtorrentAdd (torrent: string, refreshWebTorrent = false) {
29 if (refreshWebTorrent === true) webtorrent = new WebTorrent()
30
31 return new Promise<WebTorrent.Torrent>(res => webtorrent.add(torrent, res))
32}
33
34function root () {
35 // We are in server/tests/utils/miscs
36 return join(__dirname, '..', '..', '..', '..')
37}
38
39async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') {
40 const res = await request(url)
41 .get(imagePath)
42 .expect(200)
43
44 const body = res.body
45
46 const data = await readFile(join(__dirname, '..', '..', 'fixtures', imageName + extension))
47 const minLength = body.length - ((20 * body.length) / 100)
48 const maxLength = body.length + ((20 * body.length) / 100)
49
50 expect(data.length).to.be.above(minLength)
51 expect(data.length).to.be.below(maxLength)
52}
53
54function buildAbsoluteFixturePath (path: string) {
55 if (isAbsolute(path)) {
56 return path
57 }
58
59 return join(__dirname, '..', '..', 'fixtures', path)
60}
61
62// ---------------------------------------------------------------------------
63
64export {
65 dateIsValid,
66 wait,
67 webtorrentAdd,
68 immutableAssign,
69 testImage,
70 buildAbsoluteFixturePath,
71 root
72}
diff --git a/server/tests/utils/overviews/overviews.ts b/server/tests/utils/overviews/overviews.ts
deleted file mode 100644
index 23e3ceb1e..000000000
--- a/server/tests/utils/overviews/overviews.ts
+++ /dev/null
@@ -1,18 +0,0 @@
1import { makeGetRequest } from '../requests/requests'
2
3function getVideosOverview (url: string, useCache = false) {
4 const path = '/api/v1/overviews/videos'
5
6 const query = {
7 t: useCache ? undefined : new Date().getTime()
8 }
9
10 return makeGetRequest({
11 url,
12 path,
13 query,
14 statusCodeExpected: 200
15 })
16}
17
18export { getVideosOverview }
diff --git a/server/tests/utils/requests/check-api-params.ts b/server/tests/utils/requests/check-api-params.ts
deleted file mode 100644
index edb47e0e9..000000000
--- a/server/tests/utils/requests/check-api-params.ts
+++ /dev/null
@@ -1,40 +0,0 @@
1import { makeGetRequest } from './requests'
2import { immutableAssign } from '..'
3
4function checkBadStartPagination (url: string, path: string, token?: string, query = {}) {
5 return makeGetRequest({
6 url,
7 path,
8 token,
9 query: immutableAssign(query, { start: 'hello' }),
10 statusCodeExpected: 400
11 })
12}
13
14function checkBadCountPagination (url: string, path: string, token?: string, query = {}) {
15 return makeGetRequest({
16 url,
17 path,
18 token,
19 query: immutableAssign(query, { count: 'hello' }),
20 statusCodeExpected: 400
21 })
22}
23
24function checkBadSortPagination (url: string, path: string, token?: string, query = {}) {
25 return makeGetRequest({
26 url,
27 path,
28 token,
29 query: immutableAssign(query, { sort: 'hello' }),
30 statusCodeExpected: 400
31 })
32}
33
34// ---------------------------------------------------------------------------
35
36export {
37 checkBadStartPagination,
38 checkBadCountPagination,
39 checkBadSortPagination
40}
diff --git a/server/tests/utils/requests/requests.ts b/server/tests/utils/requests/requests.ts
deleted file mode 100644
index 27a529eda..000000000
--- a/server/tests/utils/requests/requests.ts
+++ /dev/null
@@ -1,170 +0,0 @@
1import * as request from 'supertest'
2import { buildAbsoluteFixturePath } from '../miscs/miscs'
3import { isAbsolute, join } from 'path'
4
5function makeGetRequest (options: {
6 url: string,
7 path: string,
8 query?: any,
9 token?: string,
10 statusCodeExpected?: number,
11 contentType?: string
12}) {
13 if (!options.statusCodeExpected) options.statusCodeExpected = 400
14 if (options.contentType === undefined) options.contentType = 'application/json'
15
16 const req = request(options.url)
17 .get(options.path)
18
19 if (options.contentType) req.set('Accept', options.contentType)
20 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
21 if (options.query) req.query(options.query)
22
23 return req.expect(options.statusCodeExpected)
24}
25
26function makeDeleteRequest (options: {
27 url: string,
28 path: string,
29 token?: string,
30 statusCodeExpected?: number
31}) {
32 if (!options.statusCodeExpected) options.statusCodeExpected = 400
33
34 const req = request(options.url)
35 .delete(options.path)
36 .set('Accept', 'application/json')
37
38 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
39
40 return req
41 .expect('Content-Type', /json/)
42 .expect(options.statusCodeExpected)
43}
44
45function makeUploadRequest (options: {
46 url: string,
47 method?: 'POST' | 'PUT',
48 path: string,
49 token?: string,
50 fields: { [ fieldName: string ]: any },
51 attaches: { [ attachName: string ]: any | any[] },
52 statusCodeExpected?: number
53}) {
54 if (!options.statusCodeExpected) options.statusCodeExpected = 400
55
56 let req: request.Test
57 if (options.method === 'PUT') {
58 req = request(options.url).put(options.path)
59 } else {
60 req = request(options.url).post(options.path)
61 }
62
63 req.set('Accept', 'application/json')
64
65 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
66
67 Object.keys(options.fields).forEach(field => {
68 const value = options.fields[field]
69
70 if (Array.isArray(value)) {
71 for (let i = 0; i < value.length; i++) {
72 req.field(field + '[' + i + ']', value[i])
73 }
74 } else {
75 req.field(field, value)
76 }
77 })
78
79 Object.keys(options.attaches).forEach(attach => {
80 const value = options.attaches[attach]
81 if (Array.isArray(value)) {
82 req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1])
83 } else {
84 req.attach(attach, buildAbsoluteFixturePath(value))
85 }
86 })
87
88 return req.expect(options.statusCodeExpected)
89}
90
91function makePostBodyRequest (options: {
92 url: string,
93 path: string,
94 token?: string,
95 fields?: { [ fieldName: string ]: any },
96 statusCodeExpected?: number
97}) {
98 if (!options.fields) options.fields = {}
99 if (!options.statusCodeExpected) options.statusCodeExpected = 400
100
101 const req = request(options.url)
102 .post(options.path)
103 .set('Accept', 'application/json')
104
105 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
106
107 return req.send(options.fields)
108 .expect(options.statusCodeExpected)
109}
110
111function makePutBodyRequest (options: {
112 url: string,
113 path: string,
114 token?: string,
115 fields: { [ fieldName: string ]: any },
116 statusCodeExpected?: number
117}) {
118 if (!options.statusCodeExpected) options.statusCodeExpected = 400
119
120 const req = request(options.url)
121 .put(options.path)
122 .set('Accept', 'application/json')
123
124 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
125
126 return req.send(options.fields)
127 .expect(options.statusCodeExpected)
128}
129
130function makeHTMLRequest (url: string, path: string) {
131 return request(url)
132 .get(path)
133 .set('Accept', 'text/html')
134 .expect(200)
135}
136
137function updateAvatarRequest (options: {
138 url: string,
139 path: string,
140 accessToken: string,
141 fixture: string
142}) {
143 let filePath = ''
144 if (isAbsolute(options.fixture)) {
145 filePath = options.fixture
146 } else {
147 filePath = join(__dirname, '..', '..', 'fixtures', options.fixture)
148 }
149
150 return makeUploadRequest({
151 url: options.url,
152 path: options.path,
153 token: options.accessToken,
154 fields: {},
155 attaches: { avatarfile: filePath },
156 statusCodeExpected: 200
157 })
158}
159
160// ---------------------------------------------------------------------------
161
162export {
163 makeHTMLRequest,
164 makeGetRequest,
165 makeUploadRequest,
166 makePostBodyRequest,
167 makePutBodyRequest,
168 makeDeleteRequest,
169 updateAvatarRequest
170}
diff --git a/server/tests/utils/search/video-channels.ts b/server/tests/utils/search/video-channels.ts
deleted file mode 100644
index 0532134ae..000000000
--- a/server/tests/utils/search/video-channels.ts
+++ /dev/null
@@ -1,22 +0,0 @@
1import { makeGetRequest } from '../requests/requests'
2
3function searchVideoChannel (url: string, search: string, token?: string, statusCodeExpected = 200) {
4 const path = '/api/v1/search/video-channels'
5
6 return makeGetRequest({
7 url,
8 path,
9 query: {
10 sort: '-createdAt',
11 search
12 },
13 token,
14 statusCodeExpected
15 })
16}
17
18// ---------------------------------------------------------------------------
19
20export {
21 searchVideoChannel
22}
diff --git a/server/tests/utils/search/videos.ts b/server/tests/utils/search/videos.ts
deleted file mode 100644
index 3a0c10e42..000000000
--- a/server/tests/utils/search/videos.ts
+++ /dev/null
@@ -1,77 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import * as request from 'supertest'
4import { VideosSearchQuery } from '../../../../shared/models/search'
5import { immutableAssign } from '..'
6
7function searchVideo (url: string, search: string) {
8 const path = '/api/v1/search/videos'
9 const req = request(url)
10 .get(path)
11 .query({ sort: '-publishedAt', search })
12 .set('Accept', 'application/json')
13
14 return req.expect(200)
15 .expect('Content-Type', /json/)
16}
17
18function searchVideoWithToken (url: string, search: string, token: string, query: { nsfw?: boolean } = {}) {
19 const path = '/api/v1/search/videos'
20 const req = request(url)
21 .get(path)
22 .set('Authorization', 'Bearer ' + token)
23 .query(immutableAssign(query, { sort: '-publishedAt', search }))
24 .set('Accept', 'application/json')
25
26 return req.expect(200)
27 .expect('Content-Type', /json/)
28}
29
30function searchVideoWithPagination (url: string, search: string, start: number, count: number, sort?: string) {
31 const path = '/api/v1/search/videos'
32
33 const req = request(url)
34 .get(path)
35 .query({ start })
36 .query({ search })
37 .query({ count })
38
39 if (sort) req.query({ sort })
40
41 return req.set('Accept', 'application/json')
42 .expect(200)
43 .expect('Content-Type', /json/)
44}
45
46function searchVideoWithSort (url: string, search: string, sort: string) {
47 const path = '/api/v1/search/videos'
48
49 return request(url)
50 .get(path)
51 .query({ search })
52 .query({ sort })
53 .set('Accept', 'application/json')
54 .expect(200)
55 .expect('Content-Type', /json/)
56}
57
58function advancedVideosSearch (url: string, options: VideosSearchQuery) {
59 const path = '/api/v1/search/videos'
60
61 return request(url)
62 .get(path)
63 .query(options)
64 .set('Accept', 'application/json')
65 .expect(200)
66 .expect('Content-Type', /json/)
67}
68
69// ---------------------------------------------------------------------------
70
71export {
72 searchVideo,
73 advancedVideosSearch,
74 searchVideoWithToken,
75 searchVideoWithPagination,
76 searchVideoWithSort
77}
diff --git a/server/tests/utils/server/activitypub.ts b/server/tests/utils/server/activitypub.ts
deleted file mode 100644
index cf3c1c3b3..000000000
--- a/server/tests/utils/server/activitypub.ts
+++ /dev/null
@@ -1,15 +0,0 @@
1import * as request from 'supertest'
2
3function makeActivityPubGetRequest (url: string, path: string) {
4 return request(url)
5 .get(path)
6 .set('Accept', 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8')
7 .expect(200)
8 .expect('Content-Type', /json/)
9}
10
11// ---------------------------------------------------------------------------
12
13export {
14 makeActivityPubGetRequest
15}
diff --git a/server/tests/utils/server/clients.ts b/server/tests/utils/server/clients.ts
deleted file mode 100644
index 273aac747..000000000
--- a/server/tests/utils/server/clients.ts
+++ /dev/null
@@ -1,19 +0,0 @@
1import * as request from 'supertest'
2import * as urlUtil from 'url'
3
4function getClient (url: string) {
5 const path = '/api/v1/oauth-clients/local'
6
7 return request(url)
8 .get(path)
9 .set('Host', urlUtil.parse(url).host)
10 .set('Accept', 'application/json')
11 .expect(200)
12 .expect('Content-Type', /json/)
13}
14
15// ---------------------------------------------------------------------------
16
17export {
18 getClient
19}
diff --git a/server/tests/utils/server/config.ts b/server/tests/utils/server/config.ts
deleted file mode 100644
index b85e02ab7..000000000
--- a/server/tests/utils/server/config.ts
+++ /dev/null
@@ -1,135 +0,0 @@
1import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../'
2import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
3
4function getConfig (url: string) {
5 const path = '/api/v1/config'
6
7 return makeGetRequest({
8 url,
9 path,
10 statusCodeExpected: 200
11 })
12}
13
14function getAbout (url: string) {
15 const path = '/api/v1/config/about'
16
17 return makeGetRequest({
18 url,
19 path,
20 statusCodeExpected: 200
21 })
22}
23
24function getCustomConfig (url: string, token: string, statusCodeExpected = 200) {
25 const path = '/api/v1/config/custom'
26
27 return makeGetRequest({
28 url,
29 token,
30 path,
31 statusCodeExpected
32 })
33}
34
35function updateCustomConfig (url: string, token: string, newCustomConfig: CustomConfig, statusCodeExpected = 200) {
36 const path = '/api/v1/config/custom'
37
38 return makePutBodyRequest({
39 url,
40 token,
41 path,
42 fields: newCustomConfig,
43 statusCodeExpected
44 })
45}
46
47function updateCustomSubConfig (url: string, token: string, newConfig: any) {
48 const updateParams: CustomConfig = {
49 instance: {
50 name: 'PeerTube updated',
51 shortDescription: 'my short description',
52 description: 'my super description',
53 terms: 'my super terms',
54 defaultClientRoute: '/videos/recently-added',
55 defaultNSFWPolicy: 'blur',
56 customizations: {
57 javascript: 'alert("coucou")',
58 css: 'body { background-color: red; }'
59 }
60 },
61 services: {
62 twitter: {
63 username: '@MySuperUsername',
64 whitelisted: true
65 }
66 },
67 cache: {
68 previews: {
69 size: 2
70 },
71 captions: {
72 size: 3
73 }
74 },
75 signup: {
76 enabled: false,
77 limit: 5,
78 requiresEmailVerification: false
79 },
80 admin: {
81 email: 'superadmin1@example.com'
82 },
83 user: {
84 videoQuota: 5242881,
85 videoQuotaDaily: 318742
86 },
87 transcoding: {
88 enabled: true,
89 threads: 1,
90 resolutions: {
91 '240p': false,
92 '360p': true,
93 '480p': true,
94 '720p': false,
95 '1080p': false
96 }
97 },
98 import: {
99 videos: {
100 http: {
101 enabled: false
102 },
103 torrent: {
104 enabled: false
105 }
106 }
107 }
108 }
109
110 Object.assign(updateParams, newConfig)
111
112 return updateCustomConfig(url, token, updateParams)
113}
114
115function deleteCustomConfig (url: string, token: string, statusCodeExpected = 200) {
116 const path = '/api/v1/config/custom'
117
118 return makeDeleteRequest({
119 url,
120 token,
121 path,
122 statusCodeExpected
123 })
124}
125
126// ---------------------------------------------------------------------------
127
128export {
129 getConfig,
130 getCustomConfig,
131 updateCustomConfig,
132 getAbout,
133 deleteCustomConfig,
134 updateCustomSubConfig
135}
diff --git a/server/tests/utils/server/follows.ts b/server/tests/utils/server/follows.ts
deleted file mode 100644
index 8a65a958b..000000000
--- a/server/tests/utils/server/follows.ts
+++ /dev/null
@@ -1,77 +0,0 @@
1import * as request from 'supertest'
2import { ServerInfo } from './servers'
3import { waitJobs } from './jobs'
4
5function getFollowersListPaginationAndSort (url: string, start: number, count: number, sort: string) {
6 const path = '/api/v1/server/followers'
7
8 return request(url)
9 .get(path)
10 .query({ start })
11 .query({ count })
12 .query({ sort })
13 .set('Accept', 'application/json')
14 .expect(200)
15 .expect('Content-Type', /json/)
16}
17
18function getFollowingListPaginationAndSort (url: string, start: number, count: number, sort: string) {
19 const path = '/api/v1/server/following'
20
21 return request(url)
22 .get(path)
23 .query({ start })
24 .query({ count })
25 .query({ sort })
26 .set('Accept', 'application/json')
27 .expect(200)
28 .expect('Content-Type', /json/)
29}
30
31async function follow (follower: string, following: string[], accessToken: string, expectedStatus = 204) {
32 const path = '/api/v1/server/following'
33
34 const followingHosts = following.map(f => f.replace(/^http:\/\//, ''))
35 const res = await request(follower)
36 .post(path)
37 .set('Accept', 'application/json')
38 .set('Authorization', 'Bearer ' + accessToken)
39 .send({ 'hosts': followingHosts })
40 .expect(expectedStatus)
41
42 return res
43}
44
45async function unfollow (url: string, accessToken: string, target: ServerInfo, expectedStatus = 204) {
46 const path = '/api/v1/server/following/' + target.host
47
48 const res = await request(url)
49 .delete(path)
50 .set('Accept', 'application/json')
51 .set('Authorization', 'Bearer ' + accessToken)
52 .expect(expectedStatus)
53
54 return res
55}
56
57async function doubleFollow (server1: ServerInfo, server2: ServerInfo) {
58 await Promise.all([
59 follow(server1.url, [ server2.url ], server1.accessToken),
60 follow(server2.url, [ server1.url ], server2.accessToken)
61 ])
62
63 // Wait request propagation
64 await waitJobs([ server1, server2 ])
65
66 return true
67}
68
69// ---------------------------------------------------------------------------
70
71export {
72 getFollowersListPaginationAndSort,
73 getFollowingListPaginationAndSort,
74 unfollow,
75 follow,
76 doubleFollow
77}
diff --git a/server/tests/utils/server/jobs.ts b/server/tests/utils/server/jobs.ts
deleted file mode 100644
index 4c02cace5..000000000
--- a/server/tests/utils/server/jobs.ts
+++ /dev/null
@@ -1,77 +0,0 @@
1import * as request from 'supertest'
2import { Job, JobState } from '../../../../shared/models'
3import { ServerInfo, wait } from '../index'
4
5function getJobsList (url: string, accessToken: string, state: JobState) {
6 const path = '/api/v1/jobs/' + state
7
8 return request(url)
9 .get(path)
10 .set('Accept', 'application/json')
11 .set('Authorization', 'Bearer ' + accessToken)
12 .expect(200)
13 .expect('Content-Type', /json/)
14}
15
16function getJobsListPaginationAndSort (url: string, accessToken: string, state: JobState, start: number, count: number, sort: string) {
17 const path = '/api/v1/jobs/' + state
18
19 return request(url)
20 .get(path)
21 .query({ start })
22 .query({ count })
23 .query({ sort })
24 .set('Accept', 'application/json')
25 .set('Authorization', 'Bearer ' + accessToken)
26 .expect(200)
27 .expect('Content-Type', /json/)
28}
29
30async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
31 let servers: ServerInfo[]
32
33 if (Array.isArray(serversArg) === false) servers = [ serversArg as ServerInfo ]
34 else servers = serversArg as ServerInfo[]
35
36 const states: JobState[] = [ 'waiting', 'active', 'delayed' ]
37 const tasks: Promise<any>[] = []
38 let pendingRequests: boolean
39
40 do {
41 pendingRequests = false
42
43 // Check if each server has pending request
44 for (const server of servers) {
45 for (const state of states) {
46 const p = getJobsListPaginationAndSort(server.url, server.accessToken, state, 0, 10, '-createdAt')
47 .then(res => res.body.data)
48 .then((jobs: Job[]) => jobs.filter(j => j.type !== 'videos-views'))
49 .then(jobs => {
50 if (jobs.length !== 0) pendingRequests = true
51 })
52 tasks.push(p)
53 }
54 }
55
56 await Promise.all(tasks)
57
58 // Retry, in case of new jobs were created
59 if (pendingRequests === false) {
60 await wait(1000)
61
62 await Promise.all(tasks)
63 }
64
65 if (pendingRequests) {
66 await wait(1000)
67 }
68 } while (pendingRequests)
69}
70
71// ---------------------------------------------------------------------------
72
73export {
74 getJobsList,
75 waitJobs,
76 getJobsListPaginationAndSort
77}
diff --git a/server/tests/utils/server/redundancy.ts b/server/tests/utils/server/redundancy.ts
deleted file mode 100644
index c39ff2c8b..000000000
--- a/server/tests/utils/server/redundancy.ts
+++ /dev/null
@@ -1,17 +0,0 @@
1import { makePutBodyRequest } from '../requests/requests'
2
3async function updateRedundancy (url: string, accessToken: string, host: string, redundancyAllowed: boolean, expectedStatus = 204) {
4 const path = '/api/v1/server/redundancy/' + host
5
6 return makePutBodyRequest({
7 url,
8 path,
9 token: accessToken,
10 fields: { redundancyAllowed },
11 statusCodeExpected: expectedStatus
12 })
13}
14
15export {
16 updateRedundancy
17}
diff --git a/server/tests/utils/server/servers.ts b/server/tests/utils/server/servers.ts
deleted file mode 100644
index 3c946db27..000000000
--- a/server/tests/utils/server/servers.ts
+++ /dev/null
@@ -1,185 +0,0 @@
1import { ChildProcess, exec, fork } from 'child_process'
2import { join } from 'path'
3import { root, wait } from '../miscs/miscs'
4import { readFile } from 'fs-extra'
5
6interface ServerInfo {
7 app: ChildProcess,
8 url: string
9 host: string
10 serverNumber: number
11
12 client: {
13 id: string,
14 secret: string
15 }
16
17 user: {
18 username: string,
19 password: string,
20 email?: string
21 }
22
23 accessToken?: string
24
25 video?: {
26 id: number
27 uuid: string
28 name: string
29 account: {
30 name: string
31 }
32 }
33
34 remoteVideo?: {
35 id: number
36 uuid: string
37 }
38}
39
40function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) {
41 let apps = []
42 let i = 0
43
44 return new Promise<ServerInfo[]>(res => {
45 function anotherServerDone (serverNumber, app) {
46 apps[serverNumber - 1] = app
47 i++
48 if (i === totalServers) {
49 return res(apps)
50 }
51 }
52
53 flushTests()
54 .then(() => {
55 for (let j = 1; j <= totalServers; j++) {
56 runServer(j, configOverride).then(app => anotherServerDone(j, app))
57 }
58 })
59 })
60}
61
62function flushTests () {
63 return new Promise<void>((res, rej) => {
64 return exec('npm run clean:server:test', err => {
65 if (err) return rej(err)
66
67 return res()
68 })
69 })
70}
71
72function runServer (serverNumber: number, configOverride?: Object) {
73 const server: ServerInfo = {
74 app: null,
75 serverNumber: serverNumber,
76 url: `http://localhost:${9000 + serverNumber}`,
77 host: `localhost:${9000 + serverNumber}`,
78 client: {
79 id: null,
80 secret: null
81 },
82 user: {
83 username: null,
84 password: null
85 }
86 }
87
88 // These actions are async so we need to be sure that they have both been done
89 const serverRunString = {
90 'Server listening': false
91 }
92 const key = 'Database peertube_test' + serverNumber + ' is ready'
93 serverRunString[key] = false
94
95 const regexps = {
96 client_id: 'Client id: (.+)',
97 client_secret: 'Client secret: (.+)',
98 user_username: 'Username: (.+)',
99 user_password: 'User password: (.+)'
100 }
101
102 // Share the environment
103 const env = Object.create(process.env)
104 env['NODE_ENV'] = 'test'
105 env['NODE_APP_INSTANCE'] = serverNumber.toString()
106
107 if (configOverride !== undefined) {
108 env['NODE_CONFIG'] = JSON.stringify(configOverride)
109 }
110
111 const options = {
112 silent: true,
113 env: env,
114 detached: true
115 }
116
117 return new Promise<ServerInfo>(res => {
118 server.app = fork(join(__dirname, '..', '..', '..', '..', 'dist', 'server.js'), [], options)
119 server.app.stdout.on('data', function onStdout (data) {
120 let dontContinue = false
121
122 // Capture things if we want to
123 for (const key of Object.keys(regexps)) {
124 const regexp = regexps[key]
125 const matches = data.toString().match(regexp)
126 if (matches !== null) {
127 if (key === 'client_id') server.client.id = matches[1]
128 else if (key === 'client_secret') server.client.secret = matches[1]
129 else if (key === 'user_username') server.user.username = matches[1]
130 else if (key === 'user_password') server.user.password = matches[1]
131 }
132 }
133
134 // Check if all required sentences are here
135 for (const key of Object.keys(serverRunString)) {
136 if (data.toString().indexOf(key) !== -1) serverRunString[key] = true
137 if (serverRunString[key] === false) dontContinue = true
138 }
139
140 // If no, there is maybe one thing not already initialized (client/user credentials generation...)
141 if (dontContinue === true) return
142
143 server.app.stdout.removeListener('data', onStdout)
144 res(server)
145 })
146 })
147}
148
149async function reRunServer (server: ServerInfo, configOverride?: any) {
150 const newServer = await runServer(server.serverNumber, configOverride)
151 server.app = newServer.app
152
153 return server
154}
155
156function killallServers (servers: ServerInfo[]) {
157 for (const server of servers) {
158 process.kill(-server.app.pid)
159 }
160}
161
162async function waitUntilLog (server: ServerInfo, str: string, count = 1) {
163 const logfile = join(root(), 'test' + server.serverNumber, 'logs/peertube.log')
164
165 while (true) {
166 const buf = await readFile(logfile)
167
168 const matches = buf.toString().match(new RegExp(str, 'g'))
169 if (matches && matches.length === count) return
170
171 await wait(1000)
172 }
173}
174
175// ---------------------------------------------------------------------------
176
177export {
178 ServerInfo,
179 flushAndRunMultipleServers,
180 flushTests,
181 runServer,
182 killallServers,
183 reRunServer,
184 waitUntilLog
185}
diff --git a/server/tests/utils/server/stats.ts b/server/tests/utils/server/stats.ts
deleted file mode 100644
index 01989d952..000000000
--- a/server/tests/utils/server/stats.ts
+++ /dev/null
@@ -1,22 +0,0 @@
1import { makeGetRequest } from '../'
2
3function getStats (url: string, useCache = false) {
4 const path = '/api/v1/server/stats'
5
6 const query = {
7 t: useCache ? undefined : new Date().getTime()
8 }
9
10 return makeGetRequest({
11 url,
12 path,
13 query,
14 statusCodeExpected: 200
15 })
16}
17
18// ---------------------------------------------------------------------------
19
20export {
21 getStats
22}
diff --git a/server/tests/utils/users/accounts.ts b/server/tests/utils/users/accounts.ts
deleted file mode 100644
index f82b8d906..000000000
--- a/server/tests/utils/users/accounts.ts
+++ /dev/null
@@ -1,63 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import { expect } from 'chai'
4import { existsSync, readdir } from 'fs-extra'
5import { join } from 'path'
6import { Account } from '../../../../shared/models/actors'
7import { root } from '../index'
8import { makeGetRequest } from '../requests/requests'
9
10function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
11 const path = '/api/v1/accounts'
12
13 return makeGetRequest({
14 url,
15 query: { sort },
16 path,
17 statusCodeExpected
18 })
19}
20
21function getAccount (url: string, accountName: string, statusCodeExpected = 200) {
22 const path = '/api/v1/accounts/' + accountName
23
24 return makeGetRequest({
25 url,
26 path,
27 statusCodeExpected
28 })
29}
30
31async function expectAccountFollows (url: string, nameWithDomain: string, followersCount: number, followingCount: number) {
32 const res = await getAccountsList(url)
33 const account = res.body.data.find((a: Account) => a.name + '@' + a.host === nameWithDomain)
34
35 const message = `${nameWithDomain} on ${url}`
36 expect(account.followersCount).to.equal(followersCount, message)
37 expect(account.followingCount).to.equal(followingCount, message)
38}
39
40async function checkActorFilesWereRemoved (actorUUID: string, serverNumber: number) {
41 const testDirectory = 'test' + serverNumber
42
43 for (const directory of [ 'avatars' ]) {
44 const directoryPath = join(root(), testDirectory, directory)
45
46 const directoryExists = existsSync(directoryPath)
47 expect(directoryExists).to.be.true
48
49 const files = await readdir(directoryPath)
50 for (const file of files) {
51 expect(file).to.not.contain(actorUUID)
52 }
53 }
54}
55
56// ---------------------------------------------------------------------------
57
58export {
59 getAccount,
60 expectAccountFollows,
61 getAccountsList,
62 checkActorFilesWereRemoved
63}
diff --git a/server/tests/utils/users/login.ts b/server/tests/utils/users/login.ts
deleted file mode 100644
index ddeb9df2a..000000000
--- a/server/tests/utils/users/login.ts
+++ /dev/null
@@ -1,62 +0,0 @@
1import * as request from 'supertest'
2
3import { ServerInfo } from '../server/servers'
4
5type Client = { id: string, secret: string }
6type User = { username: string, password: string }
7type Server = { url: string, client: Client, user: User }
8
9function login (url: string, client: Client, user: User, expectedStatus = 200) {
10 const path = '/api/v1/users/token'
11
12 const body = {
13 client_id: client.id,
14 client_secret: client.secret,
15 username: user.username,
16 password: user.password,
17 response_type: 'code',
18 grant_type: 'password',
19 scope: 'upload'
20 }
21
22 return request(url)
23 .post(path)
24 .type('form')
25 .send(body)
26 .expect(expectedStatus)
27}
28
29async function serverLogin (server: Server) {
30 const res = await login(server.url, server.client, server.user, 200)
31
32 return res.body.access_token as string
33}
34
35async function userLogin (server: Server, user: User, expectedStatus = 200) {
36 const res = await login(server.url, server.client, user, expectedStatus)
37
38 return res.body.access_token as string
39}
40
41function setAccessTokensToServers (servers: ServerInfo[]) {
42 const tasks: Promise<any>[] = []
43
44 for (const server of servers) {
45 const p = serverLogin(server).then(t => server.accessToken = t)
46 tasks.push(p)
47 }
48
49 return Promise.all(tasks)
50}
51
52// ---------------------------------------------------------------------------
53
54export {
55 login,
56 serverLogin,
57 userLogin,
58 setAccessTokensToServers,
59 Server,
60 Client,
61 User
62}
diff --git a/server/tests/utils/users/user-subscriptions.ts b/server/tests/utils/users/user-subscriptions.ts
deleted file mode 100644
index b0e7da7cc..000000000
--- a/server/tests/utils/users/user-subscriptions.ts
+++ /dev/null
@@ -1,82 +0,0 @@
1import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../'
2
3function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) {
4 const path = '/api/v1/users/me/subscriptions'
5
6 return makePostBodyRequest({
7 url,
8 path,
9 token,
10 statusCodeExpected,
11 fields: { uri: targetUri }
12 })
13}
14
15function listUserSubscriptions (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
16 const path = '/api/v1/users/me/subscriptions'
17
18 return makeGetRequest({
19 url,
20 path,
21 token,
22 statusCodeExpected,
23 query: { sort }
24 })
25}
26
27function listUserSubscriptionVideos (url: string, token: string, sort = '-createdAt', statusCodeExpected = 200) {
28 const path = '/api/v1/users/me/subscriptions/videos'
29
30 return makeGetRequest({
31 url,
32 path,
33 token,
34 statusCodeExpected,
35 query: { sort }
36 })
37}
38
39function getUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 200) {
40 const path = '/api/v1/users/me/subscriptions/' + uri
41
42 return makeGetRequest({
43 url,
44 path,
45 token,
46 statusCodeExpected
47 })
48}
49
50function removeUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 204) {
51 const path = '/api/v1/users/me/subscriptions/' + uri
52
53 return makeDeleteRequest({
54 url,
55 path,
56 token,
57 statusCodeExpected
58 })
59}
60
61function areSubscriptionsExist (url: string, token: string, uris: string[], statusCodeExpected = 200) {
62 const path = '/api/v1/users/me/subscriptions/exist'
63
64 return makeGetRequest({
65 url,
66 path,
67 query: { 'uris[]': uris },
68 token,
69 statusCodeExpected
70 })
71}
72
73// ---------------------------------------------------------------------------
74
75export {
76 areSubscriptionsExist,
77 addUserSubscription,
78 listUserSubscriptions,
79 getUserSubscription,
80 listUserSubscriptionVideos,
81 removeUserSubscription
82}
diff --git a/server/tests/utils/users/users.ts b/server/tests/utils/users/users.ts
deleted file mode 100644
index 41d8ce265..000000000
--- a/server/tests/utils/users/users.ts
+++ /dev/null
@@ -1,295 +0,0 @@
1import * as request from 'supertest'
2import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../'
3
4import { UserRole } from '../../../../shared/index'
5import { NSFWPolicyType } from '../../../../shared/models/videos/nsfw-policy.type'
6
7function createUser (
8 url: string,
9 accessToken: string,
10 username: string,
11 password: string,
12 videoQuota = 1000000,
13 videoQuotaDaily = -1,
14 role: UserRole = UserRole.USER,
15 specialStatus = 200
16) {
17 const path = '/api/v1/users'
18 const body = {
19 username,
20 password,
21 role,
22 email: username + '@example.com',
23 videoQuota,
24 videoQuotaDaily
25 }
26
27 return request(url)
28 .post(path)
29 .set('Accept', 'application/json')
30 .set('Authorization', 'Bearer ' + accessToken)
31 .send(body)
32 .expect(specialStatus)
33}
34
35function registerUser (url: string, username: string, password: string, specialStatus = 204) {
36 const path = '/api/v1/users/register'
37 const body = {
38 username,
39 password,
40 email: username + '@example.com'
41 }
42
43 return request(url)
44 .post(path)
45 .set('Accept', 'application/json')
46 .send(body)
47 .expect(specialStatus)
48}
49
50function getMyUserInformation (url: string, accessToken: string, specialStatus = 200) {
51 const path = '/api/v1/users/me'
52
53 return request(url)
54 .get(path)
55 .set('Accept', 'application/json')
56 .set('Authorization', 'Bearer ' + accessToken)
57 .expect(specialStatus)
58 .expect('Content-Type', /json/)
59}
60
61function deleteMe (url: string, accessToken: string, specialStatus = 204) {
62 const path = '/api/v1/users/me'
63
64 return request(url)
65 .delete(path)
66 .set('Accept', 'application/json')
67 .set('Authorization', 'Bearer ' + accessToken)
68 .expect(specialStatus)
69}
70
71function getMyUserVideoQuotaUsed (url: string, accessToken: string, specialStatus = 200) {
72 const path = '/api/v1/users/me/video-quota-used'
73
74 return request(url)
75 .get(path)
76 .set('Accept', 'application/json')
77 .set('Authorization', 'Bearer ' + accessToken)
78 .expect(specialStatus)
79 .expect('Content-Type', /json/)
80}
81
82function getUserInformation (url: string, accessToken: string, userId: number) {
83 const path = '/api/v1/users/' + userId
84
85 return request(url)
86 .get(path)
87 .set('Accept', 'application/json')
88 .set('Authorization', 'Bearer ' + accessToken)
89 .expect(200)
90 .expect('Content-Type', /json/)
91}
92
93function getMyUserVideoRating (url: string, accessToken: string, videoId: number | string, specialStatus = 200) {
94 const path = '/api/v1/users/me/videos/' + videoId + '/rating'
95
96 return request(url)
97 .get(path)
98 .set('Accept', 'application/json')
99 .set('Authorization', 'Bearer ' + accessToken)
100 .expect(specialStatus)
101 .expect('Content-Type', /json/)
102}
103
104function getUsersList (url: string, accessToken: string) {
105 const path = '/api/v1/users'
106
107 return request(url)
108 .get(path)
109 .set('Accept', 'application/json')
110 .set('Authorization', 'Bearer ' + accessToken)
111 .expect(200)
112 .expect('Content-Type', /json/)
113}
114
115function getUsersListPaginationAndSort (url: string, accessToken: string, start: number, count: number, sort: string) {
116 const path = '/api/v1/users'
117
118 return request(url)
119 .get(path)
120 .query({ start })
121 .query({ count })
122 .query({ sort })
123 .set('Accept', 'application/json')
124 .set('Authorization', 'Bearer ' + accessToken)
125 .expect(200)
126 .expect('Content-Type', /json/)
127}
128
129function removeUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
130 const path = '/api/v1/users'
131
132 return request(url)
133 .delete(path + '/' + userId)
134 .set('Accept', 'application/json')
135 .set('Authorization', 'Bearer ' + accessToken)
136 .expect(expectedStatus)
137}
138
139function blockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204, reason?: string) {
140 const path = '/api/v1/users'
141 let body: any
142 if (reason) body = { reason }
143
144 return request(url)
145 .post(path + '/' + userId + '/block')
146 .send(body)
147 .set('Accept', 'application/json')
148 .set('Authorization', 'Bearer ' + accessToken)
149 .expect(expectedStatus)
150}
151
152function unblockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) {
153 const path = '/api/v1/users'
154
155 return request(url)
156 .post(path + '/' + userId + '/unblock')
157 .set('Accept', 'application/json')
158 .set('Authorization', 'Bearer ' + accessToken)
159 .expect(expectedStatus)
160}
161
162function updateMyUser (options: {
163 url: string
164 accessToken: string,
165 currentPassword?: string,
166 newPassword?: string,
167 nsfwPolicy?: NSFWPolicyType,
168 email?: string,
169 autoPlayVideo?: boolean
170 displayName?: string,
171 description?: string
172}) {
173 const path = '/api/v1/users/me'
174
175 const toSend = {}
176 if (options.currentPassword !== undefined && options.currentPassword !== null) toSend['currentPassword'] = options.currentPassword
177 if (options.newPassword !== undefined && options.newPassword !== null) toSend['password'] = options.newPassword
178 if (options.nsfwPolicy !== undefined && options.nsfwPolicy !== null) toSend['nsfwPolicy'] = options.nsfwPolicy
179 if (options.autoPlayVideo !== undefined && options.autoPlayVideo !== null) toSend['autoPlayVideo'] = options.autoPlayVideo
180 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
181 if (options.description !== undefined && options.description !== null) toSend['description'] = options.description
182 if (options.displayName !== undefined && options.displayName !== null) toSend['displayName'] = options.displayName
183
184 return makePutBodyRequest({
185 url: options.url,
186 path,
187 token: options.accessToken,
188 fields: toSend,
189 statusCodeExpected: 204
190 })
191}
192
193function updateMyAvatar (options: {
194 url: string,
195 accessToken: string,
196 fixture: string
197}) {
198 const path = '/api/v1/users/me/avatar/pick'
199
200 return updateAvatarRequest(Object.assign(options, { path }))
201}
202
203function updateUser (options: {
204 url: string
205 userId: number,
206 accessToken: string,
207 email?: string,
208 videoQuota?: number,
209 videoQuotaDaily?: number,
210 role?: UserRole
211}) {
212 const path = '/api/v1/users/' + options.userId
213
214 const toSend = {}
215 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
216 if (options.videoQuota !== undefined && options.videoQuota !== null) toSend['videoQuota'] = options.videoQuota
217 if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily
218 if (options.role !== undefined && options.role !== null) toSend['role'] = options.role
219
220 return makePutBodyRequest({
221 url: options.url,
222 path,
223 token: options.accessToken,
224 fields: toSend,
225 statusCodeExpected: 204
226 })
227}
228
229function askResetPassword (url: string, email: string) {
230 const path = '/api/v1/users/ask-reset-password'
231
232 return makePostBodyRequest({
233 url,
234 path,
235 fields: { email },
236 statusCodeExpected: 204
237 })
238}
239
240function resetPassword (url: string, userId: number, verificationString: string, password: string, statusCodeExpected = 204) {
241 const path = '/api/v1/users/' + userId + '/reset-password'
242
243 return makePostBodyRequest({
244 url,
245 path,
246 fields: { password, verificationString },
247 statusCodeExpected
248 })
249}
250
251function askSendVerifyEmail (url: string, email: string) {
252 const path = '/api/v1/users/ask-send-verify-email'
253
254 return makePostBodyRequest({
255 url,
256 path,
257 fields: { email },
258 statusCodeExpected: 204
259 })
260}
261
262function verifyEmail (url: string, userId: number, verificationString: string, statusCodeExpected = 204) {
263 const path = '/api/v1/users/' + userId + '/verify-email'
264
265 return makePostBodyRequest({
266 url,
267 path,
268 fields: { verificationString },
269 statusCodeExpected
270 })
271}
272
273// ---------------------------------------------------------------------------
274
275export {
276 createUser,
277 registerUser,
278 getMyUserInformation,
279 getMyUserVideoRating,
280 deleteMe,
281 getMyUserVideoQuotaUsed,
282 getUsersList,
283 getUsersListPaginationAndSort,
284 removeUser,
285 updateUser,
286 updateMyUser,
287 getUserInformation,
288 blockUser,
289 unblockUser,
290 askResetPassword,
291 resetPassword,
292 updateMyAvatar,
293 askSendVerifyEmail,
294 verifyEmail
295}
diff --git a/server/tests/utils/videos/services.ts b/server/tests/utils/videos/services.ts
deleted file mode 100644
index 1a53dd4cf..000000000
--- a/server/tests/utils/videos/services.ts
+++ /dev/null
@@ -1,23 +0,0 @@
1import * as request from 'supertest'
2
3function getOEmbed (url: string, oembedUrl: string, format?: string, maxHeight?: number, maxWidth?: number) {
4 const path = '/services/oembed'
5 const query = {
6 url: oembedUrl,
7 format,
8 maxheight: maxHeight,
9 maxwidth: maxWidth
10 }
11
12 return request(url)
13 .get(path)
14 .query(query)
15 .set('Accept', 'application/json')
16 .expect(200)
17}
18
19// ---------------------------------------------------------------------------
20
21export {
22 getOEmbed
23}
diff --git a/server/tests/utils/videos/video-abuses.ts b/server/tests/utils/videos/video-abuses.ts
deleted file mode 100644
index 14907e6a0..000000000
--- a/server/tests/utils/videos/video-abuses.ts
+++ /dev/null
@@ -1,65 +0,0 @@
1import * as request from 'supertest'
2import { VideoAbuseUpdate } from '../../../../shared/models/videos/abuse/video-abuse-update.model'
3import { makeDeleteRequest, makePutBodyRequest } from '..'
4
5function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
6 const path = '/api/v1/videos/' + videoId + '/abuse'
7
8 return request(url)
9 .post(path)
10 .set('Accept', 'application/json')
11 .set('Authorization', 'Bearer ' + token)
12 .send({ reason })
13 .expect(specialStatus)
14}
15
16function getVideoAbusesList (url: string, token: string) {
17 const path = '/api/v1/videos/abuse'
18
19 return request(url)
20 .get(path)
21 .query({ sort: 'createdAt' })
22 .set('Accept', 'application/json')
23 .set('Authorization', 'Bearer ' + token)
24 .expect(200)
25 .expect('Content-Type', /json/)
26}
27
28function updateVideoAbuse (
29 url: string,
30 token: string,
31 videoId: string | number,
32 videoAbuseId: number,
33 body: VideoAbuseUpdate,
34 statusCodeExpected = 204
35) {
36 const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
37
38 return makePutBodyRequest({
39 url,
40 token,
41 path,
42 fields: body,
43 statusCodeExpected
44 })
45}
46
47function deleteVideoAbuse (url: string, token: string, videoId: string | number, videoAbuseId: number, statusCodeExpected = 204) {
48 const path = '/api/v1/videos/' + videoId + '/abuse/' + videoAbuseId
49
50 return makeDeleteRequest({
51 url,
52 token,
53 path,
54 statusCodeExpected
55 })
56}
57
58// ---------------------------------------------------------------------------
59
60export {
61 reportVideoAbuse,
62 getVideoAbusesList,
63 updateVideoAbuse,
64 deleteVideoAbuse
65}
diff --git a/server/tests/utils/videos/video-blacklist.ts b/server/tests/utils/videos/video-blacklist.ts
deleted file mode 100644
index 2c176fde0..000000000
--- a/server/tests/utils/videos/video-blacklist.ts
+++ /dev/null
@@ -1,67 +0,0 @@
1import * as request from 'supertest'
2
3function addVideoToBlacklist (url: string, token: string, videoId: number | string, reason?: string, specialStatus = 204) {
4 const path = '/api/v1/videos/' + videoId + '/blacklist'
5
6 return request(url)
7 .post(path)
8 .send({ reason })
9 .set('Accept', 'application/json')
10 .set('Authorization', 'Bearer ' + token)
11 .expect(specialStatus)
12}
13
14function updateVideoBlacklist (url: string, token: string, videoId: number, reason?: string, specialStatus = 204) {
15 const path = '/api/v1/videos/' + videoId + '/blacklist'
16
17 return request(url)
18 .put(path)
19 .send({ reason })
20 .set('Accept', 'application/json')
21 .set('Authorization', 'Bearer ' + token)
22 .expect(specialStatus)
23}
24
25function removeVideoFromBlacklist (url: string, token: string, videoId: number | string, specialStatus = 204) {
26 const path = '/api/v1/videos/' + videoId + '/blacklist'
27
28 return request(url)
29 .delete(path)
30 .set('Accept', 'application/json')
31 .set('Authorization', 'Bearer ' + token)
32 .expect(specialStatus)
33}
34
35function getBlacklistedVideosList (url: string, token: string, specialStatus = 200) {
36 const path = '/api/v1/videos/blacklist/'
37
38 return request(url)
39 .get(path)
40 .query({ sort: 'createdAt' })
41 .set('Accept', 'application/json')
42 .set('Authorization', 'Bearer ' + token)
43 .expect(specialStatus)
44 .expect('Content-Type', /json/)
45}
46
47function getSortedBlacklistedVideosList (url: string, token: string, sort: string, specialStatus = 200) {
48 const path = '/api/v1/videos/blacklist/'
49
50 return request(url)
51 .get(path)
52 .query({ sort: sort })
53 .set('Accept', 'application/json')
54 .set('Authorization', 'Bearer ' + token)
55 .expect(specialStatus)
56 .expect('Content-Type', /json/)
57}
58
59// ---------------------------------------------------------------------------
60
61export {
62 addVideoToBlacklist,
63 removeVideoFromBlacklist,
64 getBlacklistedVideosList,
65 getSortedBlacklistedVideosList,
66 updateVideoBlacklist
67}
diff --git a/server/tests/utils/videos/video-captions.ts b/server/tests/utils/videos/video-captions.ts
deleted file mode 100644
index 41e52be07..000000000
--- a/server/tests/utils/videos/video-captions.ts
+++ /dev/null
@@ -1,71 +0,0 @@
1import { makeDeleteRequest, makeGetRequest } from '../'
2import { buildAbsoluteFixturePath, makeUploadRequest } from '../index'
3import * as request from 'supertest'
4import * as chai from 'chai'
5
6const expect = chai.expect
7
8function createVideoCaption (args: {
9 url: string,
10 accessToken: string
11 videoId: string | number
12 language: string
13 fixture: string,
14 mimeType?: string,
15 statusCodeExpected?: number
16}) {
17 const path = '/api/v1/videos/' + args.videoId + '/captions/' + args.language
18
19 const captionfile = buildAbsoluteFixturePath(args.fixture)
20 const captionfileAttach = args.mimeType ? [ captionfile, { contentType: args.mimeType } ] : captionfile
21
22 return makeUploadRequest({
23 method: 'PUT',
24 url: args.url,
25 path,
26 token: args.accessToken,
27 fields: {},
28 attaches: {
29 captionfile: captionfileAttach
30 },
31 statusCodeExpected: args.statusCodeExpected || 204
32 })
33}
34
35function listVideoCaptions (url: string, videoId: string | number) {
36 const path = '/api/v1/videos/' + videoId + '/captions'
37
38 return makeGetRequest({
39 url,
40 path,
41 statusCodeExpected: 200
42 })
43}
44
45function deleteVideoCaption (url: string, token: string, videoId: string | number, language: string) {
46 const path = '/api/v1/videos/' + videoId + '/captions/' + language
47
48 return makeDeleteRequest({
49 url,
50 token,
51 path,
52 statusCodeExpected: 204
53 })
54}
55
56async function testCaptionFile (url: string, captionPath: string, containsString: string) {
57 const res = await request(url)
58 .get(captionPath)
59 .expect(200)
60
61 expect(res.text).to.contain(containsString)
62}
63
64// ---------------------------------------------------------------------------
65
66export {
67 createVideoCaption,
68 listVideoCaptions,
69 testCaptionFile,
70 deleteVideoCaption
71}
diff --git a/server/tests/utils/videos/video-change-ownership.ts b/server/tests/utils/videos/video-change-ownership.ts
deleted file mode 100644
index f288692ea..000000000
--- a/server/tests/utils/videos/video-change-ownership.ts
+++ /dev/null
@@ -1,54 +0,0 @@
1import * as request from 'supertest'
2
3function changeVideoOwnership (url: string, token: string, videoId: number | string, username) {
4 const path = '/api/v1/videos/' + videoId + '/give-ownership'
5
6 return request(url)
7 .post(path)
8 .set('Accept', 'application/json')
9 .set('Authorization', 'Bearer ' + token)
10 .send({ username })
11 .expect(204)
12}
13
14function getVideoChangeOwnershipList (url: string, token: string) {
15 const path = '/api/v1/videos/ownership'
16
17 return request(url)
18 .get(path)
19 .query({ sort: '-createdAt' })
20 .set('Accept', 'application/json')
21 .set('Authorization', 'Bearer ' + token)
22 .expect(200)
23 .expect('Content-Type', /json/)
24}
25
26function acceptChangeOwnership (url: string, token: string, ownershipId: string, channelId: number, expectedStatus = 204) {
27 const path = '/api/v1/videos/ownership/' + ownershipId + '/accept'
28
29 return request(url)
30 .post(path)
31 .set('Accept', 'application/json')
32 .set('Authorization', 'Bearer ' + token)
33 .send({ channelId })
34 .expect(expectedStatus)
35}
36
37function refuseChangeOwnership (url: string, token: string, ownershipId: string, expectedStatus = 204) {
38 const path = '/api/v1/videos/ownership/' + ownershipId + '/refuse'
39
40 return request(url)
41 .post(path)
42 .set('Accept', 'application/json')
43 .set('Authorization', 'Bearer ' + token)
44 .expect(expectedStatus)
45}
46
47// ---------------------------------------------------------------------------
48
49export {
50 changeVideoOwnership,
51 getVideoChangeOwnershipList,
52 acceptChangeOwnership,
53 refuseChangeOwnership
54}
diff --git a/server/tests/utils/videos/video-channels.ts b/server/tests/utils/videos/video-channels.ts
deleted file mode 100644
index 092985777..000000000
--- a/server/tests/utils/videos/video-channels.ts
+++ /dev/null
@@ -1,118 +0,0 @@
1import * as request from 'supertest'
2import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared/models/videos'
3import { updateAvatarRequest } from '../index'
4
5function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
6 const path = '/api/v1/video-channels'
7
8 const req = request(url)
9 .get(path)
10 .query({ start: start })
11 .query({ count: count })
12
13 if (sort) req.query({ sort })
14
15 return req.set('Accept', 'application/json')
16 .expect(200)
17 .expect('Content-Type', /json/)
18}
19
20function getAccountVideoChannelsList (url: string, accountName: string, specialStatus = 200) {
21 const path = '/api/v1/accounts/' + accountName + '/video-channels'
22
23 return request(url)
24 .get(path)
25 .set('Accept', 'application/json')
26 .expect(specialStatus)
27 .expect('Content-Type', /json/)
28}
29
30function addVideoChannel (
31 url: string,
32 token: string,
33 videoChannelAttributesArg: VideoChannelCreate,
34 expectedStatus = 200
35) {
36 const path = '/api/v1/video-channels/'
37
38 // Default attributes
39 let attributes = {
40 displayName: 'my super video channel',
41 description: 'my super channel description',
42 support: 'my super channel support'
43 }
44 attributes = Object.assign(attributes, videoChannelAttributesArg)
45
46 return request(url)
47 .post(path)
48 .send(attributes)
49 .set('Accept', 'application/json')
50 .set('Authorization', 'Bearer ' + token)
51 .expect(expectedStatus)
52}
53
54function updateVideoChannel (
55 url: string,
56 token: string,
57 channelName: string,
58 attributes: VideoChannelUpdate,
59 expectedStatus = 204
60) {
61 const body = {}
62 const path = '/api/v1/video-channels/' + channelName
63
64 if (attributes.displayName) body['displayName'] = attributes.displayName
65 if (attributes.description) body['description'] = attributes.description
66 if (attributes.support) body['support'] = attributes.support
67
68 return request(url)
69 .put(path)
70 .send(body)
71 .set('Accept', 'application/json')
72 .set('Authorization', 'Bearer ' + token)
73 .expect(expectedStatus)
74}
75
76function deleteVideoChannel (url: string, token: string, channelName: string, expectedStatus = 204) {
77 const path = '/api/v1/video-channels/' + channelName
78
79 return request(url)
80 .delete(path)
81 .set('Accept', 'application/json')
82 .set('Authorization', 'Bearer ' + token)
83 .expect(expectedStatus)
84}
85
86function getVideoChannel (url: string, channelName: string) {
87 const path = '/api/v1/video-channels/' + channelName
88
89 return request(url)
90 .get(path)
91 .set('Accept', 'application/json')
92 .expect(200)
93 .expect('Content-Type', /json/)
94}
95
96function updateVideoChannelAvatar (options: {
97 url: string,
98 accessToken: string,
99 fixture: string,
100 videoChannelName: string | number
101}) {
102
103 const path = '/api/v1/video-channels/' + options.videoChannelName + '/avatar/pick'
104
105 return updateAvatarRequest(Object.assign(options, { path }))
106}
107
108// ---------------------------------------------------------------------------
109
110export {
111 updateVideoChannelAvatar,
112 getVideoChannelsList,
113 getAccountVideoChannelsList,
114 addVideoChannel,
115 updateVideoChannel,
116 deleteVideoChannel,
117 getVideoChannel
118}
diff --git a/server/tests/utils/videos/video-comments.ts b/server/tests/utils/videos/video-comments.ts
deleted file mode 100644
index 1b9ee452e..000000000
--- a/server/tests/utils/videos/video-comments.ts
+++ /dev/null
@@ -1,83 +0,0 @@
1import * as request from 'supertest'
2import { makeDeleteRequest } from '../'
3
4function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string) {
5 const path = '/api/v1/videos/' + videoId + '/comment-threads'
6
7 const req = request(url)
8 .get(path)
9 .query({ start: start })
10 .query({ count: count })
11
12 if (sort) req.query({ sort })
13
14 return req.set('Accept', 'application/json')
15 .expect(200)
16 .expect('Content-Type', /json/)
17}
18
19function getVideoThreadComments (url: string, videoId: number | string, threadId: number) {
20 const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
21
22 return request(url)
23 .get(path)
24 .set('Accept', 'application/json')
25 .expect(200)
26 .expect('Content-Type', /json/)
27}
28
29function addVideoCommentThread (url: string, token: string, videoId: number | string, text: string, expectedStatus = 200) {
30 const path = '/api/v1/videos/' + videoId + '/comment-threads'
31
32 return request(url)
33 .post(path)
34 .send({ text })
35 .set('Accept', 'application/json')
36 .set('Authorization', 'Bearer ' + token)
37 .expect(expectedStatus)
38}
39
40function addVideoCommentReply (
41 url: string,
42 token: string,
43 videoId: number | string,
44 inReplyToCommentId: number,
45 text: string,
46 expectedStatus = 200
47) {
48 const path = '/api/v1/videos/' + videoId + '/comments/' + inReplyToCommentId
49
50 return request(url)
51 .post(path)
52 .send({ text })
53 .set('Accept', 'application/json')
54 .set('Authorization', 'Bearer ' + token)
55 .expect(expectedStatus)
56}
57
58function deleteVideoComment (
59 url: string,
60 token: string,
61 videoId: number | string,
62 commentId: number,
63 statusCodeExpected = 204
64) {
65 const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
66
67 return makeDeleteRequest({
68 url,
69 path,
70 token,
71 statusCodeExpected
72 })
73}
74
75// ---------------------------------------------------------------------------
76
77export {
78 getVideoCommentThreads,
79 getVideoThreadComments,
80 addVideoCommentThread,
81 addVideoCommentReply,
82 deleteVideoComment
83}
diff --git a/server/tests/utils/videos/video-history.ts b/server/tests/utils/videos/video-history.ts
deleted file mode 100644
index 7635478f7..000000000
--- a/server/tests/utils/videos/video-history.ts
+++ /dev/null
@@ -1,14 +0,0 @@
1import { makePutBodyRequest } from '../requests/requests'
2
3function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number) {
4 const path = '/api/v1/videos/' + videoId + '/watching'
5 const fields = { currentTime }
6
7 return makePutBodyRequest({ url, path, token, fields, statusCodeExpected: 204 })
8}
9
10// ---------------------------------------------------------------------------
11
12export {
13 userWatchVideo
14}
diff --git a/server/tests/utils/videos/video-imports.ts b/server/tests/utils/videos/video-imports.ts
deleted file mode 100644
index 59dfd481a..000000000
--- a/server/tests/utils/videos/video-imports.ts
+++ /dev/null
@@ -1,51 +0,0 @@
1import { VideoImportCreate } from '../../../../shared/models/videos'
2import { makeGetRequest, makeUploadRequest } from '..'
3
4function getYoutubeVideoUrl () {
5 return 'https://youtu.be/msX3jv1XdvM'
6}
7
8function getMagnetURI () {
9 // tslint:disable:max-line-length
10 return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4'
11}
12
13function importVideo (url: string, token: string, attributes: VideoImportCreate) {
14 const path = '/api/v1/videos/imports'
15
16 let attaches: any = {}
17 if (attributes.torrentfile) attaches = { torrentfile: attributes.torrentfile }
18
19 return makeUploadRequest({
20 url,
21 path,
22 token,
23 attaches,
24 fields: attributes,
25 statusCodeExpected: 200
26 })
27}
28
29function getMyVideoImports (url: string, token: string, sort?: string) {
30 const path = '/api/v1/users/me/videos/imports'
31
32 const query = {}
33 if (sort) query['sort'] = sort
34
35 return makeGetRequest({
36 url,
37 query,
38 path,
39 token,
40 statusCodeExpected: 200
41 })
42}
43
44// ---------------------------------------------------------------------------
45
46export {
47 getYoutubeVideoUrl,
48 importVideo,
49 getMagnetURI,
50 getMyVideoImports
51}
diff --git a/server/tests/utils/videos/videos.ts b/server/tests/utils/videos/videos.ts
deleted file mode 100644
index bc878b039..000000000
--- a/server/tests/utils/videos/videos.ts
+++ /dev/null
@@ -1,582 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import { expect } from 'chai'
4import { existsSync, readdir, readFile } from 'fs-extra'
5import * as parseTorrent from 'parse-torrent'
6import { extname, join } from 'path'
7import * as request from 'supertest'
8import {
9 buildAbsoluteFixturePath,
10 getMyUserInformation,
11 immutableAssign,
12 makeGetRequest,
13 makePutBodyRequest,
14 makeUploadRequest,
15 root,
16 ServerInfo,
17 testImage
18} from '../'
19import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos'
20import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers'
21import { dateIsValid, webtorrentAdd } from '../index'
22
23type VideoAttributes = {
24 name?: string
25 category?: number
26 licence?: number
27 language?: string
28 nsfw?: boolean
29 commentsEnabled?: boolean
30 downloadEnabled?: boolean
31 waitTranscoding?: boolean
32 description?: string
33 tags?: string[]
34 channelId?: number
35 privacy?: VideoPrivacy
36 fixture?: string
37 thumbnailfile?: string
38 previewfile?: string
39 scheduleUpdate?: {
40 updateAt: string
41 privacy?: VideoPrivacy
42 }
43}
44
45function getVideoCategories (url: string) {
46 const path = '/api/v1/videos/categories'
47
48 return makeGetRequest({
49 url,
50 path,
51 statusCodeExpected: 200
52 })
53}
54
55function getVideoLicences (url: string) {
56 const path = '/api/v1/videos/licences'
57
58 return makeGetRequest({
59 url,
60 path,
61 statusCodeExpected: 200
62 })
63}
64
65function getVideoLanguages (url: string) {
66 const path = '/api/v1/videos/languages'
67
68 return makeGetRequest({
69 url,
70 path,
71 statusCodeExpected: 200
72 })
73}
74
75function getVideoPrivacies (url: string) {
76 const path = '/api/v1/videos/privacies'
77
78 return makeGetRequest({
79 url,
80 path,
81 statusCodeExpected: 200
82 })
83}
84
85function getVideo (url: string, id: number | string, expectedStatus = 200) {
86 const path = '/api/v1/videos/' + id
87
88 return request(url)
89 .get(path)
90 .set('Accept', 'application/json')
91 .expect(expectedStatus)
92}
93
94function viewVideo (url: string, id: number | string, expectedStatus = 204, xForwardedFor?: string) {
95 const path = '/api/v1/videos/' + id + '/views'
96
97 const req = request(url)
98 .post(path)
99 .set('Accept', 'application/json')
100
101 if (xForwardedFor) {
102 req.set('X-Forwarded-For', xForwardedFor)
103 }
104
105 return req.expect(expectedStatus)
106}
107
108function getVideoWithToken (url: string, token: string, id: number | string, expectedStatus = 200) {
109 const path = '/api/v1/videos/' + id
110
111 return request(url)
112 .get(path)
113 .set('Authorization', 'Bearer ' + token)
114 .set('Accept', 'application/json')
115 .expect(expectedStatus)
116}
117
118function getVideoDescription (url: string, descriptionPath: string) {
119 return request(url)
120 .get(descriptionPath)
121 .set('Accept', 'application/json')
122 .expect(200)
123 .expect('Content-Type', /json/)
124}
125
126function getVideosList (url: string) {
127 const path = '/api/v1/videos'
128
129 return request(url)
130 .get(path)
131 .query({ sort: 'name' })
132 .set('Accept', 'application/json')
133 .expect(200)
134 .expect('Content-Type', /json/)
135}
136
137function getVideosListWithToken (url: string, token: string, query: { nsfw?: boolean } = {}) {
138 const path = '/api/v1/videos'
139
140 return request(url)
141 .get(path)
142 .set('Authorization', 'Bearer ' + token)
143 .query(immutableAssign(query, { sort: 'name' }))
144 .set('Accept', 'application/json')
145 .expect(200)
146 .expect('Content-Type', /json/)
147}
148
149function getLocalVideos (url: string) {
150 const path = '/api/v1/videos'
151
152 return request(url)
153 .get(path)
154 .query({ sort: 'name', filter: 'local' })
155 .set('Accept', 'application/json')
156 .expect(200)
157 .expect('Content-Type', /json/)
158}
159
160function getMyVideos (url: string, accessToken: string, start: number, count: number, sort?: string) {
161 const path = '/api/v1/users/me/videos'
162
163 const req = request(url)
164 .get(path)
165 .query({ start: start })
166 .query({ count: count })
167
168 if (sort) req.query({ sort })
169
170 return req.set('Accept', 'application/json')
171 .set('Authorization', 'Bearer ' + accessToken)
172 .expect(200)
173 .expect('Content-Type', /json/)
174}
175
176function getAccountVideos (
177 url: string,
178 accessToken: string,
179 accountName: string,
180 start: number,
181 count: number,
182 sort?: string,
183 query: { nsfw?: boolean } = {}
184) {
185 const path = '/api/v1/accounts/' + accountName + '/videos'
186
187 return makeGetRequest({
188 url,
189 path,
190 query: immutableAssign(query, {
191 start,
192 count,
193 sort
194 }),
195 token: accessToken,
196 statusCodeExpected: 200
197 })
198}
199
200function getVideoChannelVideos (
201 url: string,
202 accessToken: string,
203 videoChannelName: string,
204 start: number,
205 count: number,
206 sort?: string,
207 query: { nsfw?: boolean } = {}
208) {
209 const path = '/api/v1/video-channels/' + videoChannelName + '/videos'
210
211 return makeGetRequest({
212 url,
213 path,
214 query: immutableAssign(query, {
215 start,
216 count,
217 sort
218 }),
219 token: accessToken,
220 statusCodeExpected: 200
221 })
222}
223
224function getVideosListPagination (url: string, start: number, count: number, sort?: string) {
225 const path = '/api/v1/videos'
226
227 const req = request(url)
228 .get(path)
229 .query({ start: start })
230 .query({ count: count })
231
232 if (sort) req.query({ sort })
233
234 return req.set('Accept', 'application/json')
235 .expect(200)
236 .expect('Content-Type', /json/)
237}
238
239function getVideosListSort (url: string, sort: string) {
240 const path = '/api/v1/videos'
241
242 return request(url)
243 .get(path)
244 .query({ sort: sort })
245 .set('Accept', 'application/json')
246 .expect(200)
247 .expect('Content-Type', /json/)
248}
249
250function getVideosWithFilters (url: string, query: { tagsAllOf: string[], categoryOneOf: number[] | number }) {
251 const path = '/api/v1/videos'
252
253 return request(url)
254 .get(path)
255 .query(query)
256 .set('Accept', 'application/json')
257 .expect(200)
258 .expect('Content-Type', /json/)
259}
260
261function removeVideo (url: string, token: string, id: number | string, expectedStatus = 204) {
262 const path = '/api/v1/videos'
263
264 return request(url)
265 .delete(path + '/' + id)
266 .set('Accept', 'application/json')
267 .set('Authorization', 'Bearer ' + token)
268 .expect(expectedStatus)
269}
270
271async function checkVideoFilesWereRemoved (
272 videoUUID: string,
273 serverNumber: number,
274 directories = [ 'videos', 'thumbnails', 'torrents', 'previews', 'captions' ]
275) {
276 const testDirectory = 'test' + serverNumber
277
278 for (const directory of directories) {
279 const directoryPath = join(root(), testDirectory, directory)
280
281 const directoryExists = existsSync(directoryPath)
282 expect(directoryExists).to.be.true
283
284 const files = await readdir(directoryPath)
285 for (const file of files) {
286 expect(file).to.not.contain(videoUUID)
287 }
288 }
289}
290
291async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 200) {
292 const path = '/api/v1/videos/upload'
293 let defaultChannelId = '1'
294
295 try {
296 const res = await getMyUserInformation(url, accessToken)
297 defaultChannelId = res.body.videoChannels[0].id
298 } catch (e) { /* empty */ }
299
300 // Override default attributes
301 const attributes = Object.assign({
302 name: 'my super video',
303 category: 5,
304 licence: 4,
305 language: 'zh',
306 channelId: defaultChannelId,
307 nsfw: true,
308 waitTranscoding: false,
309 description: 'my super description',
310 support: 'my super support text',
311 tags: [ 'tag' ],
312 privacy: VideoPrivacy.PUBLIC,
313 commentsEnabled: true,
314 downloadEnabled: true,
315 fixture: 'video_short.webm'
316 }, videoAttributesArg)
317
318 const req = request(url)
319 .post(path)
320 .set('Accept', 'application/json')
321 .set('Authorization', 'Bearer ' + accessToken)
322 .field('name', attributes.name)
323 .field('nsfw', JSON.stringify(attributes.nsfw))
324 .field('commentsEnabled', JSON.stringify(attributes.commentsEnabled))
325 .field('downloadEnabled', JSON.stringify(attributes.downloadEnabled))
326 .field('waitTranscoding', JSON.stringify(attributes.waitTranscoding))
327 .field('privacy', attributes.privacy.toString())
328 .field('channelId', attributes.channelId)
329
330 if (attributes.description !== undefined) {
331 req.field('description', attributes.description)
332 }
333 if (attributes.language !== undefined) {
334 req.field('language', attributes.language.toString())
335 }
336 if (attributes.category !== undefined) {
337 req.field('category', attributes.category.toString())
338 }
339 if (attributes.licence !== undefined) {
340 req.field('licence', attributes.licence.toString())
341 }
342
343 for (let i = 0; i < attributes.tags.length; i++) {
344 req.field('tags[' + i + ']', attributes.tags[i])
345 }
346
347 if (attributes.thumbnailfile !== undefined) {
348 req.attach('thumbnailfile', buildAbsoluteFixturePath(attributes.thumbnailfile))
349 }
350 if (attributes.previewfile !== undefined) {
351 req.attach('previewfile', buildAbsoluteFixturePath(attributes.previewfile))
352 }
353
354 if (attributes.scheduleUpdate) {
355 req.field('scheduleUpdate[updateAt]', attributes.scheduleUpdate.updateAt)
356
357 if (attributes.scheduleUpdate.privacy) {
358 req.field('scheduleUpdate[privacy]', attributes.scheduleUpdate.privacy)
359 }
360 }
361
362 return req.attach('videofile', buildAbsoluteFixturePath(attributes.fixture))
363 .expect(specialStatus)
364}
365
366function updateVideo (url: string, accessToken: string, id: number | string, attributes: VideoAttributes, statusCodeExpected = 204) {
367 const path = '/api/v1/videos/' + id
368 const body = {}
369
370 if (attributes.name) body['name'] = attributes.name
371 if (attributes.category) body['category'] = attributes.category
372 if (attributes.licence) body['licence'] = attributes.licence
373 if (attributes.language) body['language'] = attributes.language
374 if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
375 if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
376 if (attributes.downloadEnabled !== undefined) body['downloadEnabled'] = JSON.stringify(attributes.downloadEnabled)
377 if (attributes.description) body['description'] = attributes.description
378 if (attributes.tags) body['tags'] = attributes.tags
379 if (attributes.privacy) body['privacy'] = attributes.privacy
380 if (attributes.channelId) body['channelId'] = attributes.channelId
381 if (attributes.scheduleUpdate) body['scheduleUpdate'] = attributes.scheduleUpdate
382
383 // Upload request
384 if (attributes.thumbnailfile || attributes.previewfile) {
385 const attaches: any = {}
386 if (attributes.thumbnailfile) attaches.thumbnailfile = attributes.thumbnailfile
387 if (attributes.previewfile) attaches.previewfile = attributes.previewfile
388
389 return makeUploadRequest({
390 url,
391 method: 'PUT',
392 path,
393 token: accessToken,
394 fields: body,
395 attaches,
396 statusCodeExpected
397 })
398 }
399
400 return makePutBodyRequest({
401 url,
402 path,
403 fields: body,
404 token: accessToken,
405 statusCodeExpected
406 })
407}
408
409function rateVideo (url: string, accessToken: string, id: number, rating: string, specialStatus = 204) {
410 const path = '/api/v1/videos/' + id + '/rate'
411
412 return request(url)
413 .put(path)
414 .set('Accept', 'application/json')
415 .set('Authorization', 'Bearer ' + accessToken)
416 .send({ rating })
417 .expect(specialStatus)
418}
419
420function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) {
421 return new Promise<any>((res, rej) => {
422 const torrentName = videoUUID + '-' + resolution + '.torrent'
423 const torrentPath = join(__dirname, '..', '..', '..', '..', 'test' + server.serverNumber, 'torrents', torrentName)
424 readFile(torrentPath, (err, data) => {
425 if (err) return rej(err)
426
427 return res(parseTorrent(data))
428 })
429 })
430}
431
432async function completeVideoCheck (
433 url: string,
434 video: any,
435 attributes: {
436 name: string
437 category: number
438 licence: number
439 language: string
440 nsfw: boolean
441 commentsEnabled: boolean
442 downloadEnabled: boolean
443 description: string
444 publishedAt?: string
445 support: string
446 account: {
447 name: string
448 host: string
449 }
450 isLocal: boolean
451 tags: string[]
452 privacy: number
453 likes?: number
454 dislikes?: number
455 duration: number
456 channel: {
457 displayName: string
458 name: string
459 description
460 isLocal: boolean
461 }
462 fixture: string
463 files: {
464 resolution: number
465 size: number
466 }[],
467 thumbnailfile?: string
468 previewfile?: string
469 }
470) {
471 if (!attributes.likes) attributes.likes = 0
472 if (!attributes.dislikes) attributes.dislikes = 0
473
474 expect(video.name).to.equal(attributes.name)
475 expect(video.category.id).to.equal(attributes.category)
476 expect(video.category.label).to.equal(attributes.category !== null ? VIDEO_CATEGORIES[attributes.category] : 'Misc')
477 expect(video.licence.id).to.equal(attributes.licence)
478 expect(video.licence.label).to.equal(attributes.licence !== null ? VIDEO_LICENCES[attributes.licence] : 'Unknown')
479 expect(video.language.id).to.equal(attributes.language)
480 expect(video.language.label).to.equal(attributes.language !== null ? VIDEO_LANGUAGES[attributes.language] : 'Unknown')
481 expect(video.privacy.id).to.deep.equal(attributes.privacy)
482 expect(video.privacy.label).to.deep.equal(VIDEO_PRIVACIES[attributes.privacy])
483 expect(video.nsfw).to.equal(attributes.nsfw)
484 expect(video.description).to.equal(attributes.description)
485 expect(video.account.id).to.be.a('number')
486 expect(video.account.uuid).to.be.a('string')
487 expect(video.account.host).to.equal(attributes.account.host)
488 expect(video.account.name).to.equal(attributes.account.name)
489 expect(video.channel.displayName).to.equal(attributes.channel.displayName)
490 expect(video.channel.name).to.equal(attributes.channel.name)
491 expect(video.likes).to.equal(attributes.likes)
492 expect(video.dislikes).to.equal(attributes.dislikes)
493 expect(video.isLocal).to.equal(attributes.isLocal)
494 expect(video.duration).to.equal(attributes.duration)
495 expect(dateIsValid(video.createdAt)).to.be.true
496 expect(dateIsValid(video.publishedAt)).to.be.true
497 expect(dateIsValid(video.updatedAt)).to.be.true
498
499 if (attributes.publishedAt) {
500 expect(video.publishedAt).to.equal(attributes.publishedAt)
501 }
502
503 const res = await getVideo(url, video.uuid)
504 const videoDetails: VideoDetails = res.body
505
506 expect(videoDetails.files).to.have.lengthOf(attributes.files.length)
507 expect(videoDetails.tags).to.deep.equal(attributes.tags)
508 expect(videoDetails.account.name).to.equal(attributes.account.name)
509 expect(videoDetails.account.host).to.equal(attributes.account.host)
510 expect(video.channel.displayName).to.equal(attributes.channel.displayName)
511 expect(video.channel.name).to.equal(attributes.channel.name)
512 expect(videoDetails.channel.host).to.equal(attributes.account.host)
513 expect(videoDetails.channel.isLocal).to.equal(attributes.channel.isLocal)
514 expect(dateIsValid(videoDetails.channel.createdAt.toString())).to.be.true
515 expect(dateIsValid(videoDetails.channel.updatedAt.toString())).to.be.true
516 expect(videoDetails.commentsEnabled).to.equal(attributes.commentsEnabled)
517 expect(videoDetails.downloadEnabled).to.equal(attributes.downloadEnabled)
518
519 for (const attributeFile of attributes.files) {
520 const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution)
521 expect(file).not.to.be.undefined
522
523 let extension = extname(attributes.fixture)
524 // Transcoding enabled on server 2, extension will always be .mp4
525 if (attributes.account.host === 'localhost:9002') extension = '.mp4'
526
527 const magnetUri = file.magnetUri
528 expect(file.magnetUri).to.have.lengthOf.above(2)
529 expect(file.torrentUrl).to.equal(`http://${attributes.account.host}/static/torrents/${videoDetails.uuid}-${file.resolution.id}.torrent`)
530 expect(file.fileUrl).to.equal(`http://${attributes.account.host}/static/webseed/${videoDetails.uuid}-${file.resolution.id}${extension}`)
531 expect(file.resolution.id).to.equal(attributeFile.resolution)
532 expect(file.resolution.label).to.equal(attributeFile.resolution + 'p')
533
534 const minSize = attributeFile.size - ((10 * attributeFile.size) / 100)
535 const maxSize = attributeFile.size + ((10 * attributeFile.size) / 100)
536 expect(file.size,
537 'File size for resolution ' + file.resolution.label + ' outside confidence interval (' + minSize + '> size <' + maxSize + ')')
538 .to.be.above(minSize).and.below(maxSize)
539
540 {
541 await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
542 }
543
544 if (attributes.previewfile) {
545 await testImage(url, attributes.previewfile, videoDetails.previewPath)
546 }
547
548 const torrent = await webtorrentAdd(magnetUri, true)
549 expect(torrent.files).to.be.an('array')
550 expect(torrent.files.length).to.equal(1)
551 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
552 }
553}
554
555// ---------------------------------------------------------------------------
556
557export {
558 getVideoDescription,
559 getVideoCategories,
560 getVideoLicences,
561 getVideoPrivacies,
562 getVideoLanguages,
563 getMyVideos,
564 getAccountVideos,
565 getVideoChannelVideos,
566 getVideo,
567 getVideoWithToken,
568 getVideosList,
569 getVideosListPagination,
570 getVideosListSort,
571 removeVideo,
572 getVideosListWithToken,
573 uploadVideo,
574 getVideosWithFilters,
575 updateVideo,
576 rateVideo,
577 viewVideo,
578 parseTorrentVideo,
579 getLocalVideos,
580 completeVideoCheck,
581 checkVideoFilesWereRemoved
582}