Update server dependencies
[oweals/peertube.git] / shared / extra-utils / miscs / email.ts
1 import { ChildProcess, fork } from 'child_process'
2 import { randomInt } from '../../core-utils/miscs/miscs'
3 import { parallelTests } from '../server/servers'
4
5 class MockSmtpServer {
6
7   private static instance: MockSmtpServer
8   private started = false
9   private emailChildProcess: ChildProcess
10   private emails: object[]
11
12   private constructor () {
13     this.emailChildProcess = fork(`${__dirname}/email-child-process`, [])
14
15     this.emailChildProcess.on('message', (msg: any) => {
16       if (msg.email) {
17         return this.emails.push(msg.email)
18       }
19     })
20
21     process.on('exit', () => this.kill())
22   }
23
24   collectEmails (emailsCollection: object[]) {
25     return new Promise<number>((res, rej) => {
26       const port = parallelTests() ? randomInt(1000, 2000) : 1025
27
28       if (this.started) {
29         this.emails = emailsCollection
30         return res()
31       }
32
33       // ensure maildev isn't started until
34       // unexpected exit can be reported to test runner
35       this.emailChildProcess.send({ start: true, port })
36       this.emailChildProcess.on('exit', () => {
37         return rej(new Error('maildev exited unexpectedly, confirm port not in use'))
38       })
39       this.emailChildProcess.on('message', (msg: any) => {
40         if (msg.err) return rej(new Error(msg.err))
41
42         this.started = true
43         this.emails = emailsCollection
44
45         return res(port)
46       })
47     })
48   }
49
50   kill () {
51     if (!this.emailChildProcess) return
52
53     process.kill(this.emailChildProcess.pid)
54
55     this.emailChildProcess = null
56     MockSmtpServer.instance = null
57   }
58
59   static get Instance () {
60     return this.instance || (this.instance = new this())
61   }
62 }
63
64 // ---------------------------------------------------------------------------
65
66 export {
67   MockSmtpServer
68 }