aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/tests/src/shared/mock-servers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-07-31 14:34:36 +0200
committerChocobozzz <me@florianbigard.com>2023-08-11 15:02:33 +0200
commit3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch)
treee4510b39bdac9c318fdb4b47018d08f15368b8f0 /packages/tests/src/shared/mock-servers
parent04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff)
downloadPeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip
Migrate server to ESM
Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports)
Diffstat (limited to 'packages/tests/src/shared/mock-servers')
-rw-r--r--packages/tests/src/shared/mock-servers/index.ts8
-rw-r--r--packages/tests/src/shared/mock-servers/mock-429.ts33
-rw-r--r--packages/tests/src/shared/mock-servers/mock-email.ts62
-rw-r--r--packages/tests/src/shared/mock-servers/mock-http.ts23
-rw-r--r--packages/tests/src/shared/mock-servers/mock-instances-index.ts46
-rw-r--r--packages/tests/src/shared/mock-servers/mock-joinpeertube-versions.ts34
-rw-r--r--packages/tests/src/shared/mock-servers/mock-object-storage.ts41
-rw-r--r--packages/tests/src/shared/mock-servers/mock-plugin-blocklist.ts36
-rw-r--r--packages/tests/src/shared/mock-servers/mock-proxy.ts24
-rw-r--r--packages/tests/src/shared/mock-servers/shared.ts33
10 files changed, 340 insertions, 0 deletions
diff --git a/packages/tests/src/shared/mock-servers/index.ts b/packages/tests/src/shared/mock-servers/index.ts
new file mode 100644
index 000000000..9d1c63c67
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/index.ts
@@ -0,0 +1,8 @@
1export * from './mock-429.js'
2export * from './mock-email.js'
3export * from './mock-http.js'
4export * from './mock-instances-index.js'
5export * from './mock-joinpeertube-versions.js'
6export * from './mock-object-storage.js'
7export * from './mock-plugin-blocklist.js'
8export * from './mock-proxy.js'
diff --git a/packages/tests/src/shared/mock-servers/mock-429.ts b/packages/tests/src/shared/mock-servers/mock-429.ts
new file mode 100644
index 000000000..5fcb1447d
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-429.ts
@@ -0,0 +1,33 @@
1import express from 'express'
2import { Server } from 'http'
3import { getPort, randomListen, terminateServer } from './shared.js'
4
5export class Mock429 {
6 private server: Server
7 private responseSent = false
8
9 async initialize () {
10 const app = express()
11
12 app.get('/', (req: express.Request, res: express.Response, next: express.NextFunction) => {
13
14 if (!this.responseSent) {
15 this.responseSent = true
16
17 // Retry after 5 seconds
18 res.header('retry-after', '2')
19 return res.sendStatus(429)
20 }
21
22 return res.sendStatus(200)
23 })
24
25 this.server = await randomListen(app)
26
27 return getPort(this.server)
28 }
29
30 terminate () {
31 return terminateServer(this.server)
32 }
33}
diff --git a/packages/tests/src/shared/mock-servers/mock-email.ts b/packages/tests/src/shared/mock-servers/mock-email.ts
new file mode 100644
index 000000000..7c618e57f
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-email.ts
@@ -0,0 +1,62 @@
1import MailDev from '@peertube/maildev'
2import { randomInt } from '@peertube/peertube-core-utils'
3import { parallelTests } from '@peertube/peertube-node-utils'
4
5class MockSmtpServer {
6
7 private static instance: MockSmtpServer
8 private started = false
9 private maildev: any
10 private emails: object[]
11
12 private constructor () { }
13
14 collectEmails (emailsCollection: object[]) {
15 return new Promise<number>((res, rej) => {
16 const port = parallelTests() ? randomInt(1025, 2000) : 1025
17 this.emails = emailsCollection
18
19 if (this.started) {
20 return res(undefined)
21 }
22
23 this.maildev = new MailDev({
24 ip: '127.0.0.1',
25 smtp: port,
26 disableWeb: true,
27 silent: true
28 })
29
30 this.maildev.on('new', email => {
31 this.emails.push(email)
32 })
33
34 this.maildev.listen(err => {
35 if (err) return rej(err)
36
37 this.started = true
38
39 return res(port)
40 })
41 })
42 }
43
44 kill () {
45 if (!this.maildev) return
46
47 this.maildev.close()
48
49 this.maildev = null
50 MockSmtpServer.instance = null
51 }
52
53 static get Instance () {
54 return this.instance || (this.instance = new this())
55 }
56}
57
58// ---------------------------------------------------------------------------
59
60export {
61 MockSmtpServer
62}
diff --git a/packages/tests/src/shared/mock-servers/mock-http.ts b/packages/tests/src/shared/mock-servers/mock-http.ts
new file mode 100644
index 000000000..bc1a9ce91
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-http.ts
@@ -0,0 +1,23 @@
1import express from 'express'
2import { Server } from 'http'
3import { getPort, randomListen, terminateServer } from './shared.js'
4
5export class MockHTTP {
6 private server: Server
7
8 async initialize () {
9 const app = express()
10
11 app.get('/*', (req: express.Request, res: express.Response, next: express.NextFunction) => {
12 return res.sendStatus(200)
13 })
14
15 this.server = await randomListen(app)
16
17 return getPort(this.server)
18 }
19
20 terminate () {
21 return terminateServer(this.server)
22 }
23}
diff --git a/packages/tests/src/shared/mock-servers/mock-instances-index.ts b/packages/tests/src/shared/mock-servers/mock-instances-index.ts
new file mode 100644
index 000000000..a21367358
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-instances-index.ts
@@ -0,0 +1,46 @@
1import express from 'express'
2import { Server } from 'http'
3import { getPort, randomListen, terminateServer } from './shared.js'
4
5export class MockInstancesIndex {
6 private server: Server
7
8 private readonly indexInstances: { host: string, createdAt: string }[] = []
9
10 async initialize () {
11 const app = express()
12
13 app.use('/', (req: express.Request, res: express.Response, next: express.NextFunction) => {
14 if (process.env.DEBUG) console.log('Receiving request on mocked server %s.', req.url)
15
16 return next()
17 })
18
19 app.get('/api/v1/instances/hosts', (req: express.Request, res: express.Response) => {
20 const since = req.query.since
21
22 const filtered = this.indexInstances.filter(i => {
23 if (!since) return true
24
25 return i.createdAt > since
26 })
27
28 return res.json({
29 total: filtered.length,
30 data: filtered
31 })
32 })
33
34 this.server = await randomListen(app)
35
36 return getPort(this.server)
37 }
38
39 addInstance (host: string) {
40 this.indexInstances.push({ host, createdAt: new Date().toISOString() })
41 }
42
43 terminate () {
44 return terminateServer(this.server)
45 }
46}
diff --git a/packages/tests/src/shared/mock-servers/mock-joinpeertube-versions.ts b/packages/tests/src/shared/mock-servers/mock-joinpeertube-versions.ts
new file mode 100644
index 000000000..0783165e4
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-joinpeertube-versions.ts
@@ -0,0 +1,34 @@
1import express from 'express'
2import { Server } from 'http'
3import { getPort, randomListen } from './shared.js'
4
5export class MockJoinPeerTubeVersions {
6 private server: Server
7 private latestVersion: string
8
9 async initialize () {
10 const app = express()
11
12 app.use('/', (req: express.Request, res: express.Response, next: express.NextFunction) => {
13 if (process.env.DEBUG) console.log('Receiving request on mocked server %s.', req.url)
14
15 return next()
16 })
17
18 app.get('/versions.json', (req: express.Request, res: express.Response) => {
19 return res.json({
20 peertube: {
21 latestVersion: this.latestVersion
22 }
23 })
24 })
25
26 this.server = await randomListen(app)
27
28 return getPort(this.server)
29 }
30
31 setLatestVersion (latestVersion: string) {
32 this.latestVersion = latestVersion
33 }
34}
diff --git a/packages/tests/src/shared/mock-servers/mock-object-storage.ts b/packages/tests/src/shared/mock-servers/mock-object-storage.ts
new file mode 100644
index 000000000..f97c57fd7
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-object-storage.ts
@@ -0,0 +1,41 @@
1import express from 'express'
2import got, { RequestError } from 'got'
3import { Server } from 'http'
4import { pipeline } from 'stream'
5import { ObjectStorageCommand } from '@peertube/peertube-server-commands'
6import { getPort, randomListen, terminateServer } from './shared.js'
7
8export class MockObjectStorageProxy {
9 private server: Server
10
11 async initialize () {
12 const app = express()
13
14 app.get('/:bucketName/:path(*)', (req: express.Request, res: express.Response, next: express.NextFunction) => {
15 const url = `http://${req.params.bucketName}.${ObjectStorageCommand.getMockEndpointHost()}/${req.params.path}`
16
17 if (process.env.DEBUG) {
18 console.log('Receiving request on mocked server %s.', req.url)
19 console.log('Proxifying request to %s', url)
20 }
21
22 return pipeline(
23 got.stream(url, { throwHttpErrors: false }),
24 res,
25 (err: RequestError) => {
26 if (!err) return
27
28 console.error('Pipeline failed.', err)
29 }
30 )
31 })
32
33 this.server = await randomListen(app)
34
35 return getPort(this.server)
36 }
37
38 terminate () {
39 return terminateServer(this.server)
40 }
41}
diff --git a/packages/tests/src/shared/mock-servers/mock-plugin-blocklist.ts b/packages/tests/src/shared/mock-servers/mock-plugin-blocklist.ts
new file mode 100644
index 000000000..c0b6518ba
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-plugin-blocklist.ts
@@ -0,0 +1,36 @@
1import express, { Request, Response } from 'express'
2import { Server } from 'http'
3import { getPort, randomListen, terminateServer } from './shared.js'
4
5type BlocklistResponse = {
6 data: {
7 value: string
8 action?: 'add' | 'remove'
9 updatedAt?: string
10 }[]
11}
12
13export class MockBlocklist {
14 private body: BlocklistResponse
15 private server: Server
16
17 async initialize () {
18 const app = express()
19
20 app.get('/blocklist', (req: Request, res: Response) => {
21 return res.json(this.body)
22 })
23
24 this.server = await randomListen(app)
25
26 return getPort(this.server)
27 }
28
29 replace (body: BlocklistResponse) {
30 this.body = body
31 }
32
33 terminate () {
34 return terminateServer(this.server)
35 }
36}
diff --git a/packages/tests/src/shared/mock-servers/mock-proxy.ts b/packages/tests/src/shared/mock-servers/mock-proxy.ts
new file mode 100644
index 000000000..e731670d8
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/mock-proxy.ts
@@ -0,0 +1,24 @@
1import { createServer, Server } from 'http'
2import { createProxy } from 'proxy'
3import { getPort, terminateServer } from './shared.js'
4
5class MockProxy {
6 private server: Server
7
8 initialize () {
9 return new Promise<number>(res => {
10 this.server = createProxy(createServer())
11 this.server.listen(0, () => res(getPort(this.server)))
12 })
13 }
14
15 terminate () {
16 return terminateServer(this.server)
17 }
18}
19
20// ---------------------------------------------------------------------------
21
22export {
23 MockProxy
24}
diff --git a/packages/tests/src/shared/mock-servers/shared.ts b/packages/tests/src/shared/mock-servers/shared.ts
new file mode 100644
index 000000000..235642439
--- /dev/null
+++ b/packages/tests/src/shared/mock-servers/shared.ts
@@ -0,0 +1,33 @@
1import { Express } from 'express'
2import { Server } from 'http'
3import { AddressInfo } from 'net'
4
5function randomListen (app: Express) {
6 return new Promise<Server>(res => {
7 const server = app.listen(0, () => res(server))
8 })
9}
10
11function getPort (server: Server) {
12 const address = server.address() as AddressInfo
13
14 return address.port
15}
16
17function terminateServer (server: Server) {
18 if (!server) return Promise.resolve()
19
20 return new Promise<void>((res, rej) => {
21 server.close(err => {
22 if (err) return rej(err)
23
24 return res()
25 })
26 })
27}
28
29export {
30 randomListen,
31 getPort,
32 terminateServer
33}