Skip to content
← Public packages

@danj/hey-email

HEY.com email for Kody: search threads, read messages, download PDF attachments, and write drafts. Sending is barred until you allow it.

test/sending-gate.test.js

94 lines · 3.1 KB · JavaScript
Raw
import assert from 'node:assert/strict'
import { test } from 'node:test'

import { SENDING } from '../src/config.js'
import { sendDraft, sendMessage, sendReply } from '../src/send.js'
import { HEY, installFetch, resetKodySecrets } from './helpers.mjs'

const CONFIRM_CASES = [
  { label: 'confirm true', confirm: true },
  { label: "confirm 'true'", confirm: 'true' },
  { label: 'confirm 1', confirm: 1 },
  { label: 'confirm omitted' },
]

function withConfirm(base, confirmCase) {
  if (!Object.hasOwn(confirmCase, 'confirm')) return base
  return { ...base, confirm: confirmCase.confirm }
}

test('sending gate: barred sendMessage, sendReply, and sendDraft make zero app.hey.com requests', async () => {
  assert.equal(SENDING, 'barred')
  resetKodySecrets()
  const fixture = installFetch(async () => {
    throw new Error('fetch should not be called')
  })
  try {
    for (const confirmCase of CONFIRM_CASES) {
      const sent = await sendMessage(withConfirm({
        to: 'ada@example.com',
        subject: 'Notes',
        text: 'See you Thursday.',
      }, confirmCase))
      assert.equal(sent.barred, true, confirmCase.label)
      assert.equal(sent.dryRun, true)
      assert.equal(sent.wouldSend, false)
      assert.equal(sent.sent, false)
      assert.equal(sent.reason, 'sending-barred')
      assert.equal(typeof sent.message, 'string')
      assert.deepEqual(sent.to, ['ada@example.com'])
      assert.equal(sent.subject, 'Notes')
      assert.equal(sent.content, '<div>See you Thursday.</div>')

      const reply = await sendReply(withConfirm({
        entryId: 42,
        text: 'Thanks',
      }, confirmCase))
      assert.equal(reply.barred, true, confirmCase.label)
      assert.equal(reply.dryRun, true)
      assert.equal(reply.wouldSend, false)
      assert.equal(reply.sent, false)
      assert.equal(reply.reason, 'sending-barred')
      assert.equal(reply.to, undefined)
      assert.equal(reply.subject, undefined)
      assert.equal(reply.content, undefined)

      const draft = await sendDraft(withConfirm({
        id: 9,
        to: ['ada@example.com'],
      }, confirmCase))
      assert.equal(draft.barred, true, confirmCase.label)
      assert.equal(draft.dryRun, true)
      assert.equal(draft.wouldSend, false)
      assert.equal(draft.sent, false)
      assert.equal(draft.reason, 'sending-barred')
      assert.equal(draft.to, undefined)
      assert.equal(draft.draft, undefined)
    }

    await assert.rejects(
      () => sendMessage({ subject: 'Notes', text: 'See you Thursday.', confirm: true }),
      /to is required/,
    )
    await assert.rejects(
      () => sendMessage({ to: 'ada@example.com', text: 'See you Thursday.', confirm: true }),
      /subject is required/,
    )
    await assert.rejects(
      () => sendDraft({ confirm: true }),
      /id is required/,
    )

    const heyRequests = fixture.requests.filter((row) => {
      try {
        return new URL(row.url).origin === HEY
      } catch {
        return false
      }
    })
    assert.equal(heyRequests.length, 0)
    assert.equal(fixture.requests.length, 0)
  } finally {
    fixture.restore()
  }
})