throw error if MailDev doesn't run
authorJosh Morel <morel.josh@hotmail.com>
Sat, 15 Dec 2018 13:51:51 +0000 (08:51 -0500)
committerChocobozzz <me@florianbigard.com>
Mon, 17 Dec 2018 09:59:07 +0000 (10:59 +0100)
also allow calling in multiple file

server/tests/api/server/email.ts
server/tests/api/users/users-verification.ts
shared/utils/miscs/email-child-process.js [new file with mode: 0644]
shared/utils/miscs/email.ts

index 13df772c686c55a01bca983ef6af65d8e3571ddc..b8d29ef81dc5c4b9fd526c8db7039f8af0c5f3bc 100644 (file)
@@ -20,7 +20,7 @@ import {
   ServerInfo,
   setAccessTokensToServers
 } from '../../../../shared/utils'
-import { mockSmtpServer } from '../../../../shared/utils/miscs/email'
+import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
 import { waitJobs } from '../../../../shared/utils/server/jobs'
 
 const expect = chai.expect
@@ -41,7 +41,7 @@ describe('Test emails', function () {
   before(async function () {
     this.timeout(30000)
 
-    await mockSmtpServer(emails)
+    await MockSmtpServer.Instance.collectEmails(emails)
 
     await flushTests()
 
index b1733e45e95bc09d413d9001470b6594385e09a2..afc8a00598a035b2f74d8d7d41c4c262d5f1b6ad 100644 (file)
@@ -7,7 +7,7 @@ import {
   userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig
 } from '../../../../shared/utils'
 import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
-import { mockSmtpServer } from '../../../../shared/utils/miscs/email'
+import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
 import { waitJobs } from '../../../../shared/utils/server/jobs'
 
 const expect = chai.expect
@@ -30,7 +30,7 @@ describe('Test users account verification', function () {
   before(async function () {
     this.timeout(30000)
 
-    await mockSmtpServer(emails)
+    await MockSmtpServer.Instance.collectEmails(emails)
 
     await flushTests()
 
diff --git a/shared/utils/miscs/email-child-process.js b/shared/utils/miscs/email-child-process.js
new file mode 100644 (file)
index 0000000..40ae37d
--- /dev/null
@@ -0,0 +1,27 @@
+const MailDev = require('maildev')
+
+// must run maildev as forked ChildProcess
+// failed instantiation stops main process with exit code 0
+process.on('message', (msg) => {
+  if (msg.start) {
+    const maildev = new MailDev({
+      ip: '127.0.0.1',
+      smtp: 1025,
+      disableWeb: true,
+      silent: true
+    })
+
+    maildev.on('new', email => {
+      process.send({ email })
+    })
+
+    maildev.listen(err => {
+      if (err) {
+        // cannot send as Error object
+        return process.send({ err: err.message })
+      }
+
+      return process.send({ err: null })
+    })
+  }
+})
index 21accd09d0df0d1c506f5a0a81a92b7c2b271405..108f7d3d93b8bb1c2f2f91e0bd33456d5e19504a 100644 (file)
@@ -1,25 +1,55 @@
-import * as MailDev from 'maildev'
-
-function mockSmtpServer (emailsCollection: object[]) {
-  const maildev = new MailDev({
-    ip: '127.0.0.1',
-    smtp: 1025,
-    disableWeb: true,
-    silent: true
-  })
-  maildev.on('new', email => emailsCollection.push(email))
-
-  return new Promise((res, rej) => {
-    maildev.listen(err => {
-      if (err) return rej(err)
-
-      return res()
+import * as child from 'child_process'
+
+class MockSmtpServer {
+
+  private static instance: MockSmtpServer
+  private started = false
+  private emailChildProcess: child.ChildProcess
+  private emails: object[]
+
+  private constructor () {
+    this.emailChildProcess = child.fork(`${__dirname}/email-child-process`, [], { silent: true })
+    this.emailChildProcess.on('message', (msg) => {
+      if (msg.email) {
+        return this.emails.push(msg.email)
+      }
+    })
+    process.on('exit', () => {
+      this.emailChildProcess.kill()
     })
-  })
+  }
+
+  collectEmails (emailsCollection: object[]) {
+    return new Promise((res, rej) => {
+      if (this.started) {
+        this.emails = emailsCollection
+        return res()
+      }
+
+      // ensure maildev isn't started until
+      // unexpected exit can be reported to test runner
+      this.emailChildProcess.send({ start: true })
+      this.emailChildProcess.on('exit', () => {
+        return rej(new Error('maildev exited unexpectedly, confirm port not in use'))
+      })
+      this.emailChildProcess.on('message', (msg) => {
+        if (msg.err) {
+          return rej(new Error(msg.err))
+        }
+        this.started = true
+        this.emails = emailsCollection
+        return res()
+      })
+    })
+  }
+
+  static get Instance () {
+    return this.instance || (this.instance = new this())
+  }
 }
 
 // ---------------------------------------------------------------------------
 
 export {
-  mockSmtpServer
+  MockSmtpServer
 }