aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared/extra-utils
diff options
context:
space:
mode:
Diffstat (limited to 'shared/extra-utils')
-rw-r--r--shared/extra-utils/custom-pages/custom-pages.ts31
-rw-r--r--shared/extra-utils/index.ts20
-rw-r--r--shared/extra-utils/miscs/email-child-process.js27
-rw-r--r--shared/extra-utils/miscs/email.ts39
-rw-r--r--shared/extra-utils/miscs/miscs.ts11
-rw-r--r--shared/extra-utils/plugins/mock-blocklist.ts6
-rw-r--r--shared/extra-utils/requests/requests.ts2
-rw-r--r--shared/extra-utils/search/video-playlists.ts36
-rw-r--r--shared/extra-utils/server/config.ts3
-rw-r--r--shared/extra-utils/server/plugins.ts4
-rw-r--r--shared/extra-utils/server/servers.ts4
-rw-r--r--shared/extra-utils/users/user-notifications.ts2
-rw-r--r--shared/extra-utils/videos/live.ts7
-rw-r--r--shared/extra-utils/videos/videos.ts13
14 files changed, 142 insertions, 63 deletions
diff --git a/shared/extra-utils/custom-pages/custom-pages.ts b/shared/extra-utils/custom-pages/custom-pages.ts
new file mode 100644
index 000000000..bf2d16c70
--- /dev/null
+++ b/shared/extra-utils/custom-pages/custom-pages.ts
@@ -0,0 +1,31 @@
1import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
2import { makeGetRequest, makePutBodyRequest } from '../requests/requests'
3
4function getInstanceHomepage (url: string, statusCodeExpected = HttpStatusCode.OK_200) {
5 const path = '/api/v1/custom-pages/homepage/instance'
6
7 return makeGetRequest({
8 url,
9 path,
10 statusCodeExpected
11 })
12}
13
14function updateInstanceHomepage (url: string, token: string, content: string) {
15 const path = '/api/v1/custom-pages/homepage/instance'
16
17 return makePutBodyRequest({
18 url,
19 path,
20 token,
21 fields: { content },
22 statusCodeExpected: HttpStatusCode.NO_CONTENT_204
23 })
24}
25
26// ---------------------------------------------------------------------------
27
28export {
29 getInstanceHomepage,
30 updateInstanceHomepage
31}
diff --git a/shared/extra-utils/index.ts b/shared/extra-utils/index.ts
index 898a92d43..87ee8abba 100644
--- a/shared/extra-utils/index.ts
+++ b/shared/extra-utils/index.ts
@@ -1,15 +1,28 @@
1export * from './bulk/bulk' 1export * from './bulk/bulk'
2
2export * from './cli/cli' 3export * from './cli/cli'
4
5export * from './custom-pages/custom-pages'
6
3export * from './feeds/feeds' 7export * from './feeds/feeds'
8
4export * from './mock-servers/mock-instances-index' 9export * from './mock-servers/mock-instances-index'
5export * from './miscs/miscs' 10
11export * from './miscs/email'
6export * from './miscs/sql' 12export * from './miscs/sql'
13export * from './miscs/miscs'
7export * from './miscs/stubs' 14export * from './miscs/stubs'
15
8export * from './moderation/abuses' 16export * from './moderation/abuses'
9export * from './plugins/mock-blocklist' 17export * from './plugins/mock-blocklist'
18
10export * from './requests/check-api-params' 19export * from './requests/check-api-params'
11export * from './requests/requests' 20export * from './requests/requests'
21
22export * from './search/video-channels'
23export * from './search/video-playlists'
12export * from './search/videos' 24export * from './search/videos'
25
13export * from './server/activitypub' 26export * from './server/activitypub'
14export * from './server/clients' 27export * from './server/clients'
15export * from './server/config' 28export * from './server/config'
@@ -18,9 +31,14 @@ export * from './server/follows'
18export * from './server/jobs' 31export * from './server/jobs'
19export * from './server/plugins' 32export * from './server/plugins'
20export * from './server/servers' 33export * from './server/servers'
34
21export * from './users/accounts' 35export * from './users/accounts'
36export * from './users/blocklist'
22export * from './users/login' 37export * from './users/login'
38export * from './users/user-notifications'
39export * from './users/user-subscriptions'
23export * from './users/users' 40export * from './users/users'
41
24export * from './videos/live' 42export * from './videos/live'
25export * from './videos/services' 43export * from './videos/services'
26export * from './videos/video-blacklist' 44export * from './videos/video-blacklist'
diff --git a/shared/extra-utils/miscs/email-child-process.js b/shared/extra-utils/miscs/email-child-process.js
deleted file mode 100644
index 088a5a08c..000000000
--- a/shared/extra-utils/miscs/email-child-process.js
+++ /dev/null
@@ -1,27 +0,0 @@
1const MailDev = require('maildev')
2
3// must run maildev as forked ChildProcess
4// failed instantiation stops main process with exit code 0
5process.on('message', (msg) => {
6 if (msg.start) {
7 const maildev = new MailDev({
8 ip: '127.0.0.1',
9 smtp: msg.port,
10 disableWeb: true,
11 silent: true
12 })
13
14 maildev.on('new', email => {
15 process.send({ email })
16 })
17
18 maildev.listen(err => {
19 if (err) {
20 // cannot send as Error object
21 return process.send({ err: err.message })
22 }
23
24 return process.send({ err: null })
25 })
26 }
27})
diff --git a/shared/extra-utils/miscs/email.ts b/shared/extra-utils/miscs/email.ts
index 758b15b58..9fc9a5ad0 100644
--- a/shared/extra-utils/miscs/email.ts
+++ b/shared/extra-utils/miscs/email.ts
@@ -1,8 +1,9 @@
1import { ChildProcess, fork } from 'child_process' 1import { ChildProcess } from 'child_process'
2import { join } from 'path'
3import { randomInt } from '../../core-utils/miscs/miscs' 2import { randomInt } from '../../core-utils/miscs/miscs'
4import { parallelTests } from '../server/servers' 3import { parallelTests } from '../server/servers'
5 4
5const MailDev = require('maildev')
6
6class MockSmtpServer { 7class MockSmtpServer {
7 8
8 private static instance: MockSmtpServer 9 private static instance: MockSmtpServer
@@ -10,38 +11,32 @@ class MockSmtpServer {
10 private emailChildProcess: ChildProcess 11 private emailChildProcess: ChildProcess
11 private emails: object[] 12 private emails: object[]
12 13
13 private constructor () { 14 private constructor () { }
14 this.emailChildProcess = fork(join(__dirname, 'email-child-process'), [])
15
16 this.emailChildProcess.on('message', (msg: any) => {
17 if (msg.email) {
18 return this.emails.push(msg.email)
19 }
20 })
21
22 process.on('exit', () => this.kill())
23 }
24 15
25 collectEmails (emailsCollection: object[]) { 16 collectEmails (emailsCollection: object[]) {
26 return new Promise<number>((res, rej) => { 17 return new Promise<number>((res, rej) => {
27 const port = parallelTests() ? randomInt(1000, 2000) : 1025 18 const port = parallelTests() ? randomInt(1000, 2000) : 1025
19 this.emails = emailsCollection
28 20
29 if (this.started) { 21 if (this.started) {
30 this.emails = emailsCollection
31 return res(undefined) 22 return res(undefined)
32 } 23 }
33 24
34 // ensure maildev isn't started until 25 const maildev = new MailDev({
35 // unexpected exit can be reported to test runner 26 ip: '127.0.0.1',
36 this.emailChildProcess.send({ start: true, port }) 27 smtp: port,
37 this.emailChildProcess.on('exit', () => { 28 disableWeb: true,
38 return rej(new Error('maildev exited unexpectedly, confirm port not in use')) 29 silent: true
30 })
31
32 maildev.on('new', email => {
33 this.emails.push(email)
39 }) 34 })
40 this.emailChildProcess.on('message', (msg: any) => { 35
41 if (msg.err) return rej(new Error(msg.err)) 36 maildev.listen(err => {
37 if (err) return rej(err)
42 38
43 this.started = true 39 this.started = true
44 this.emails = emailsCollection
45 40
46 return res(port) 41 return res(port)
47 }) 42 })
diff --git a/shared/extra-utils/miscs/miscs.ts b/shared/extra-utils/miscs/miscs.ts
index 1cb1cf440..462b914d4 100644
--- a/shared/extra-utils/miscs/miscs.ts
+++ b/shared/extra-utils/miscs/miscs.ts
@@ -60,8 +60,14 @@ async function testImage (url: string, imageName: string, imagePath: string, ext
60 const minLength = body.length - ((30 * body.length) / 100) 60 const minLength = body.length - ((30 * body.length) / 100)
61 const maxLength = body.length + ((30 * body.length) / 100) 61 const maxLength = body.length + ((30 * body.length) / 100)
62 62
63 expect(data.length).to.be.above(minLength, "the generated image is way smaller than the recorded fixture") 63 expect(data.length).to.be.above(minLength, 'the generated image is way smaller than the recorded fixture')
64 expect(data.length).to.be.below(maxLength, "the generated image is way larger than the recorded fixture") 64 expect(data.length).to.be.below(maxLength, 'the generated image is way larger than the recorded fixture')
65}
66
67async function testFileExistsOrNot (server: { internalServerNumber: number }, directory: string, filePath: string, exist: boolean) {
68 const base = buildServerDirectory(server, directory)
69
70 expect(await pathExists(join(base, filePath))).to.equal(exist)
65} 71}
66 72
67function isGithubCI () { 73function isGithubCI () {
@@ -157,6 +163,7 @@ export {
157 testImage, 163 testImage,
158 isGithubCI, 164 isGithubCI,
159 buildAbsoluteFixturePath, 165 buildAbsoluteFixturePath,
166 testFileExistsOrNot,
160 root, 167 root,
161 generateHighBitrateVideo, 168 generateHighBitrateVideo,
162 generateVideoWithFramerate 169 generateVideoWithFramerate
diff --git a/shared/extra-utils/plugins/mock-blocklist.ts b/shared/extra-utils/plugins/mock-blocklist.ts
index 50e2289f1..d18f8224f 100644
--- a/shared/extra-utils/plugins/mock-blocklist.ts
+++ b/shared/extra-utils/plugins/mock-blocklist.ts
@@ -1,5 +1,6 @@
1import * as express from 'express' 1import * as express from 'express'
2import { Server } from 'http' 2import { Server } from 'http'
3import { randomInt } from '@shared/core-utils'
3 4
4type BlocklistResponse = { 5type BlocklistResponse = {
5 data: { 6 data: {
@@ -14,14 +15,15 @@ export class MockBlocklist {
14 private server: Server 15 private server: Server
15 16
16 initialize () { 17 initialize () {
17 return new Promise<void>(res => { 18 return new Promise<number>(res => {
18 const app = express() 19 const app = express()
19 20
20 app.get('/blocklist', (req: express.Request, res: express.Response) => { 21 app.get('/blocklist', (req: express.Request, res: express.Response) => {
21 return res.json(this.body) 22 return res.json(this.body)
22 }) 23 })
23 24
24 this.server = app.listen(42100, () => res()) 25 const port = 42201 + randomInt(1, 100)
26 this.server = app.listen(port, () => res(port))
25 }) 27 })
26 } 28 }
27 29
diff --git a/shared/extra-utils/requests/requests.ts b/shared/extra-utils/requests/requests.ts
index 8b5cddf4a..38e24d897 100644
--- a/shared/extra-utils/requests/requests.ts
+++ b/shared/extra-utils/requests/requests.ts
@@ -26,6 +26,7 @@ function makeGetRequest (options: {
26 contentType?: string 26 contentType?: string
27 range?: string 27 range?: string
28 redirects?: number 28 redirects?: number
29 accept?: string
29}) { 30}) {
30 if (!options.statusCodeExpected) options.statusCodeExpected = HttpStatusCode.BAD_REQUEST_400 31 if (!options.statusCodeExpected) options.statusCodeExpected = HttpStatusCode.BAD_REQUEST_400
31 if (options.contentType === undefined) options.contentType = 'application/json' 32 if (options.contentType === undefined) options.contentType = 'application/json'
@@ -36,6 +37,7 @@ function makeGetRequest (options: {
36 if (options.token) req.set('Authorization', 'Bearer ' + options.token) 37 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
37 if (options.query) req.query(options.query) 38 if (options.query) req.query(options.query)
38 if (options.range) req.set('Range', options.range) 39 if (options.range) req.set('Range', options.range)
40 if (options.accept) req.set('Accept', options.accept)
39 if (options.redirects) req.redirects(options.redirects) 41 if (options.redirects) req.redirects(options.redirects)
40 42
41 return req.expect(options.statusCodeExpected) 43 return req.expect(options.statusCodeExpected)
diff --git a/shared/extra-utils/search/video-playlists.ts b/shared/extra-utils/search/video-playlists.ts
new file mode 100644
index 000000000..c22831df7
--- /dev/null
+++ b/shared/extra-utils/search/video-playlists.ts
@@ -0,0 +1,36 @@
1import { VideoPlaylistsSearchQuery } from '@shared/models'
2import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes'
3import { makeGetRequest } from '../requests/requests'
4
5function searchVideoPlaylists (url: string, search: string, token?: string, statusCodeExpected = HttpStatusCode.OK_200) {
6 const path = '/api/v1/search/video-playlists'
7
8 return makeGetRequest({
9 url,
10 path,
11 query: {
12 sort: '-createdAt',
13 search
14 },
15 token,
16 statusCodeExpected
17 })
18}
19
20function advancedVideoPlaylistSearch (url: string, search: VideoPlaylistsSearchQuery) {
21 const path = '/api/v1/search/video-playlists'
22
23 return makeGetRequest({
24 url,
25 path,
26 query: search,
27 statusCodeExpected: HttpStatusCode.OK_200
28 })
29}
30
31// ---------------------------------------------------------------------------
32
33export {
34 searchVideoPlaylists,
35 advancedVideoPlaylistSearch
36}
diff --git a/shared/extra-utils/server/config.ts b/shared/extra-utils/server/config.ts
index b70110852..9fcfb31fd 100644
--- a/shared/extra-utils/server/config.ts
+++ b/shared/extra-utils/server/config.ts
@@ -98,7 +98,8 @@ function updateCustomSubConfig (url: string, token: string, newConfig: DeepParti
98 signup: { 98 signup: {
99 enabled: false, 99 enabled: false,
100 limit: 5, 100 limit: 5,
101 requiresEmailVerification: false 101 requiresEmailVerification: false,
102 minimumAge: 16
102 }, 103 },
103 admin: { 104 admin: {
104 email: 'superadmin1@example.com' 105 email: 'superadmin1@example.com'
diff --git a/shared/extra-utils/server/plugins.ts b/shared/extra-utils/server/plugins.ts
index 864954ee7..d53e5b382 100644
--- a/shared/extra-utils/server/plugins.ts
+++ b/shared/extra-utils/server/plugins.ts
@@ -4,12 +4,12 @@ import { expect } from 'chai'
4import { readJSON, writeJSON } from 'fs-extra' 4import { readJSON, writeJSON } from 'fs-extra'
5import { join } from 'path' 5import { join } from 'path'
6import { RegisteredServerSettings } from '@shared/models' 6import { RegisteredServerSettings } from '@shared/models'
7import { PeertubePluginIndexList } from '../../models/plugins/peertube-plugin-index-list.model' 7import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
8import { PeertubePluginIndexList } from '../../models/plugins/plugin-index/peertube-plugin-index-list.model'
8import { PluginType } from '../../models/plugins/plugin.type' 9import { PluginType } from '../../models/plugins/plugin.type'
9import { buildServerDirectory, root } from '../miscs/miscs' 10import { buildServerDirectory, root } from '../miscs/miscs'
10import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests' 11import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
11import { ServerInfo } from './servers' 12import { ServerInfo } from './servers'
12import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
13 13
14function listPlugins (parameters: { 14function listPlugins (parameters: {
15 url: string 15 url: string
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index 479f08e12..28e431e94 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -43,11 +43,15 @@ interface ServerInfo {
43 video?: { 43 video?: {
44 id: number 44 id: number
45 uuid: string 45 uuid: string
46 shortUUID: string
46 name?: string 47 name?: string
47 url?: string 48 url?: string
49
48 account?: { 50 account?: {
49 name: string 51 name: string
50 } 52 }
53
54 embedPath?: string
51 } 55 }
52 56
53 remoteVideo?: { 57 remoteVideo?: {
diff --git a/shared/extra-utils/users/user-notifications.ts b/shared/extra-utils/users/user-notifications.ts
index 249e82925..844f4442d 100644
--- a/shared/extra-utils/users/user-notifications.ts
+++ b/shared/extra-utils/users/user-notifications.ts
@@ -431,7 +431,7 @@ async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string,
431 } 431 }
432 } 432 }
433 433
434 const commentUrl = `http://localhost:${base.server.port}/videos/watch/${uuid};threadId=${threadId}` 434 const commentUrl = `http://localhost:${base.server.port}/w/${uuid};threadId=${threadId}`
435 435
436 function emailNotificationFinder (email: object) { 436 function emailNotificationFinder (email: object) {
437 return email['text'].indexOf(commentUrl) !== -1 437 return email['text'].indexOf(commentUrl) !== -1
diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts
index d3cd974de..c0384769b 100644
--- a/shared/extra-utils/videos/live.ts
+++ b/shared/extra-utils/videos/live.ts
@@ -175,6 +175,12 @@ async function waitUntilLiveSaved (url: string, token: string, videoId: number |
175 } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) 175 } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED)
176} 176}
177 177
178async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoId: string) {
179 for (const server of servers) {
180 await waitUntilLivePublished(server.url, server.accessToken, videoId)
181 }
182}
183
178async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) { 184async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) {
179 const basePath = buildServerDirectory(server, 'streaming-playlists') 185 const basePath = buildServerDirectory(server, 'streaming-playlists')
180 const hlsPath = join(basePath, 'hls', videoUUID) 186 const hlsPath = join(basePath, 'hls', videoUUID)
@@ -226,6 +232,7 @@ export {
226 sendRTMPStreamInVideo, 232 sendRTMPStreamInVideo,
227 waitUntilLiveEnded, 233 waitUntilLiveEnded,
228 waitFfmpegUntilError, 234 waitFfmpegUntilError,
235 waitUntilLivePublishedOnAllServers,
229 sendRTMPStream, 236 sendRTMPStream,
230 testFfmpegStreamError 237 testFfmpegStreamError
231} 238}
diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts
index e88256ac0..469ea4d63 100644
--- a/shared/extra-utils/videos/videos.ts
+++ b/shared/extra-utils/videos/videos.ts
@@ -4,10 +4,11 @@ import { expect } from 'chai'
4import { createReadStream, pathExists, readdir, readFile, stat } from 'fs-extra' 4import { createReadStream, pathExists, readdir, readFile, stat } from 'fs-extra'
5import got, { Response as GotResponse } from 'got/dist/source' 5import got, { Response as GotResponse } from 'got/dist/source'
6import * as parseTorrent from 'parse-torrent' 6import * as parseTorrent from 'parse-torrent'
7import { extname, join } from 'path' 7import { join } from 'path'
8import * as request from 'supertest' 8import * as request from 'supertest'
9import { v4 as uuidv4 } from 'uuid'
10import validator from 'validator' 9import validator from 'validator'
10import { getLowercaseExtension } from '@server/helpers/core-utils'
11import { buildUUID } from '@server/helpers/uuid'
11import { HttpStatusCode } from '@shared/core-utils' 12import { HttpStatusCode } from '@shared/core-utils'
12import { VideosCommonQuery } from '@shared/models' 13import { VideosCommonQuery } from '@shared/models'
13import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' 14import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants'
@@ -738,7 +739,7 @@ async function completeVideoCheck (
738 const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution) 739 const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution)
739 expect(file).not.to.be.undefined 740 expect(file).not.to.be.undefined
740 741
741 let extension = extname(attributes.fixture) 742 let extension = getLowercaseExtension(attributes.fixture)
742 // Transcoding enabled: extension will always be .mp4 743 // Transcoding enabled: extension will always be .mp4
743 if (attributes.files.length > 1) extension = '.mp4' 744 if (attributes.files.length > 1) extension = '.mp4'
744 745
@@ -774,9 +775,11 @@ async function completeVideoCheck (
774 expect(torrent.files[0].path).to.exist.and.to.not.equal('') 775 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
775 } 776 }
776 777
778 expect(videoDetails.thumbnailPath).to.exist
777 await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath) 779 await testImage(url, attributes.thumbnailfile || attributes.fixture, videoDetails.thumbnailPath)
778 780
779 if (attributes.previewfile) { 781 if (attributes.previewfile) {
782 expect(videoDetails.previewPath).to.exist
780 await testImage(url, attributes.previewfile, videoDetails.previewPath) 783 await testImage(url, attributes.previewfile, videoDetails.previewPath)
781 } 784 }
782} 785}
@@ -803,7 +806,7 @@ async function uploadVideoAndGetId (options: {
803 806
804 const res = await uploadVideo(options.server.url, options.token || options.server.accessToken, videoAttrs) 807 const res = await uploadVideo(options.server.url, options.token || options.server.accessToken, videoAttrs)
805 808
806 return { id: res.body.video.id, uuid: res.body.video.uuid } 809 return res.body.video as { id: number, uuid: string, shortUUID: string }
807} 810}
808 811
809async function getLocalIdByUUID (url: string, uuid: string) { 812async function getLocalIdByUUID (url: string, uuid: string) {
@@ -824,7 +827,7 @@ async function uploadRandomVideoOnServers (servers: ServerInfo[], serverNumber:
824 827
825async function uploadRandomVideo (server: ServerInfo, wait = true, additionalParams: any = {}) { 828async function uploadRandomVideo (server: ServerInfo, wait = true, additionalParams: any = {}) {
826 const prefixName = additionalParams.prefixName || '' 829 const prefixName = additionalParams.prefixName || ''
827 const name = prefixName + uuidv4() 830 const name = prefixName + buildUUID()
828 831
829 const data = Object.assign({ name }, additionalParams) 832 const data = Object.assign({ name }, additionalParams)
830 const res = await uploadVideo(server.url, server.accessToken, data) 833 const res = await uploadVideo(server.url, server.accessToken, data)