All files / src/test-helpers TestmailInbox.ts

100% Statements 23/23
100% Branches 2/2
100% Functions 3/3
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 651x   1x 1x             1x 1x 1x 1x                           1x           44x 44x 44x     44x       71x 71x 71x 71x 71x 71x   71x 71x   71x   71x             100x      
import cryptoRandomString from 'crypto-random-string'
 
let fetch = global.fetch
let URL = global.URL
 
/* istanbul ignore next */
if (!fetch) fetch = require('node-fetch')
/* istanbul ignore next */
if (!URL) URL = require('url').URL
 
const TESTMAIL_API_URL = 'https://api.testmail.app/api/json'
const TESTMAIL_INBOX_DOMAIN = 'inbox.testmail.app'
const TESTMAIL_API_KEY = process.env.TESTMAIL_API_KEY
const TESTMAIL_NAMESPACE = process.env.TESTMAIL_NS
 
interface InboxOptions {
  prefix: string
  suffix: string
}
 
interface Email {
  subject: string
  body: string
}
 
// NOTE: Only use this helper when you need to read inbox contents
//       For email generation use generateEmail() helper instead
export class TestmailInbox {
  private _tag: string
  private _email: string
  private _lastEmailTimestamp: number
 
  constructor({ prefix, suffix }: InboxOptions) {
    const inboxId = cryptoRandomString({ length: 12 }) // arbitrary length
    this._tag = `${prefix}.${inboxId}.${suffix}`
    this._email = `${TESTMAIL_NAMESPACE}.${this._tag}@${TESTMAIL_INBOX_DOMAIN}`
 
    // if inbox has already been used, ignore its old emails (1 minute is arbitrary)
    this._lastEmailTimestamp = Date.now() - 60_000
  }
 
  public async waitForNewEmail(): Promise<Email> {
    const url = new URL(TESTMAIL_API_URL)
    url.searchParams.append('apikey', TESTMAIL_API_KEY)
    url.searchParams.append('namespace', TESTMAIL_NAMESPACE)
    url.searchParams.append('tag', this._tag)
    url.searchParams.append('timestamp_from', String(this._lastEmailTimestamp + 1))
    url.searchParams.append('livequery', 'true')
 
    const response = await (await fetch(url.toString())).json()
    const { subject, html, text, timestamp } = response.emails[0]
 
    this._lastEmailTimestamp = timestamp
 
    return {
      subject,
      body: text || html,
    }
  }
 
  public get email(): string {
    return this._email
  }
}