email.ts 1.7 KB

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