1 import { ChildProcess, fork } from 'child_process'
2 import { join } from 'path'
3 import { randomInt } from '../../core-utils/miscs/miscs'
4 import { parallelTests } from '../server/servers'
8 private static instance: MockSmtpServer
9 private started = false
10 private emailChildProcess: ChildProcess
11 private emails: object[]
13 private constructor () {
14 this.emailChildProcess = fork(join(__dirname, 'email-child-process'), [])
16 this.emailChildProcess.on('message', (msg: any) => {
18 return this.emails.push(msg.email)
22 process.on('exit', () => this.kill())
25 collectEmails (emailsCollection: object[]) {
26 return new Promise<number>((res, rej) => {
27 const port = parallelTests() ? randomInt(1000, 2000) : 1025
30 this.emails = emailsCollection
34 // ensure maildev isn't started until
35 // unexpected exit can be reported to test runner
36 this.emailChildProcess.send({ start: true, port })
37 this.emailChildProcess.on('exit', () => {
38 return rej(new Error('maildev exited unexpectedly, confirm port not in use'))
40 this.emailChildProcess.on('message', (msg: any) => {
41 if (msg.err) return rej(new Error(msg.err))
44 this.emails = emailsCollection
52 if (!this.emailChildProcess) return
54 process.kill(this.emailChildProcess.pid)
56 this.emailChildProcess = null
57 MockSmtpServer.instance = null
60 static get Instance () {
61 return this.instance || (this.instance = new this())
65 // ---------------------------------------------------------------------------