aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/tests/api/server/email.ts4
-rw-r--r--server/tests/api/users/users-verification.ts4
-rw-r--r--shared/utils/miscs/email-child-process.js27
-rw-r--r--shared/utils/miscs/email.ts66
4 files changed, 79 insertions, 22 deletions
diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts
index 13df772c6..b8d29ef81 100644
--- a/server/tests/api/server/email.ts
+++ b/server/tests/api/server/email.ts
@@ -20,7 +20,7 @@ import {
20 ServerInfo, 20 ServerInfo,
21 setAccessTokensToServers 21 setAccessTokensToServers
22} from '../../../../shared/utils' 22} from '../../../../shared/utils'
23import { mockSmtpServer } from '../../../../shared/utils/miscs/email' 23import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
24import { waitJobs } from '../../../../shared/utils/server/jobs' 24import { waitJobs } from '../../../../shared/utils/server/jobs'
25 25
26const expect = chai.expect 26const expect = chai.expect
@@ -41,7 +41,7 @@ describe('Test emails', function () {
41 before(async function () { 41 before(async function () {
42 this.timeout(30000) 42 this.timeout(30000)
43 43
44 await mockSmtpServer(emails) 44 await MockSmtpServer.Instance.collectEmails(emails)
45 45
46 await flushTests() 46 await flushTests()
47 47
diff --git a/server/tests/api/users/users-verification.ts b/server/tests/api/users/users-verification.ts
index b1733e45e..afc8a0059 100644
--- a/server/tests/api/users/users-verification.ts
+++ b/server/tests/api/users/users-verification.ts
@@ -7,7 +7,7 @@ import {
7 userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig 7 userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig
8} from '../../../../shared/utils' 8} from '../../../../shared/utils'
9import { setAccessTokensToServers } from '../../../../shared/utils/users/login' 9import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
10import { mockSmtpServer } from '../../../../shared/utils/miscs/email' 10import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
11import { waitJobs } from '../../../../shared/utils/server/jobs' 11import { waitJobs } from '../../../../shared/utils/server/jobs'
12 12
13const expect = chai.expect 13const expect = chai.expect
@@ -30,7 +30,7 @@ describe('Test users account verification', function () {
30 before(async function () { 30 before(async function () {
31 this.timeout(30000) 31 this.timeout(30000)
32 32
33 await mockSmtpServer(emails) 33 await MockSmtpServer.Instance.collectEmails(emails)
34 34
35 await flushTests() 35 await flushTests()
36 36
diff --git a/shared/utils/miscs/email-child-process.js b/shared/utils/miscs/email-child-process.js
new file mode 100644
index 000000000..40ae37d70
--- /dev/null
+++ b/shared/utils/miscs/email-child-process.js
@@ -0,0 +1,27 @@
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: 1025,
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/utils/miscs/email.ts b/shared/utils/miscs/email.ts
index 21accd09d..108f7d3d9 100644
--- a/shared/utils/miscs/email.ts
+++ b/shared/utils/miscs/email.ts
@@ -1,25 +1,55 @@
1import * as MailDev from 'maildev' 1import * as child from 'child_process'
2 2
3function mockSmtpServer (emailsCollection: object[]) { 3class MockSmtpServer {
4 const maildev = new MailDev({ 4
5 ip: '127.0.0.1', 5 private static instance: MockSmtpServer
6 smtp: 1025, 6 private started = false
7 disableWeb: true, 7 private emailChildProcess: child.ChildProcess
8 silent: true 8 private emails: object[]
9 }) 9
10 maildev.on('new', email => emailsCollection.push(email)) 10 private constructor () {
11 11 this.emailChildProcess = child.fork(`${__dirname}/email-child-process`, [], { silent: true })
12 return new Promise((res, rej) => { 12 this.emailChildProcess.on('message', (msg) => {
13 maildev.listen(err => { 13 if (msg.email) {
14 if (err) return rej(err) 14 return this.emails.push(msg.email)
15 15 }
16 return res() 16 })
17 process.on('exit', () => {
18 this.emailChildProcess.kill()
17 }) 19 })
18 }) 20 }
21
22 collectEmails (emailsCollection: object[]) {
23 return new Promise((res, rej) => {
24 if (this.started) {
25 this.emails = emailsCollection
26 return res()
27 }
28
29 // ensure maildev isn't started until
30 // unexpected exit can be reported to test runner
31 this.emailChildProcess.send({ start: true })
32 this.emailChildProcess.on('exit', () => {
33 return rej(new Error('maildev exited unexpectedly, confirm port not in use'))
34 })
35 this.emailChildProcess.on('message', (msg) => {
36 if (msg.err) {
37 return rej(new Error(msg.err))
38 }
39 this.started = true
40 this.emails = emailsCollection
41 return res()
42 })
43 })
44 }
45
46 static get Instance () {
47 return this.instance || (this.instance = new this())
48 }
19} 49}
20 50
21// --------------------------------------------------------------------------- 51// ---------------------------------------------------------------------------
22 52
23export { 53export {
24 mockSmtpServer 54 MockSmtpServer
25} 55}