← 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/paper-trail.test.js
91 lines · 3.0 KB · JavaScriptimport assert from 'node:assert/strict'
import { afterEach, beforeEach, test } from 'node:test'
import moveToPaperTrail from '../src/paper-trail.js'
import { HEY, installFetch, jsonResponse, resetKodySecrets } from './helpers.mjs'
// Fixture only: the Logos weekly newsletter thread. Never a live app.hey.com call.
const LOGOS_TOPIC_ID = 2153822589
const TRAILBOX_ID = 33
const ENTRY_ID = 8001
const BOXES = [
{ id: 11, kind: 'imbox', name: 'Imbox' },
{ id: 22, kind: 'feedbox', name: 'The Feed' },
{ id: TRAILBOX_ID, kind: 'trailbox', name: 'Paper Trail' },
]
let fixture
beforeEach(() => {
resetKodySecrets()
fixture = installFetch(async (url, init) => {
const method = String(init.method || 'GET').toUpperCase()
const handler = fixture.routes.get(`${method} ${url}`)
if (handler) return handler(url, init)
throw new Error(`unexpected ${method} ${url}`)
})
fixture.routes = new Map()
})
afterEach(() => {
fixture?.restore()
})
function on(method, url, handler) {
fixture.routes.set(`${method} ${url}`, handler)
}
function writes() {
return fixture.requests.filter((row) => row.method !== 'GET')
}
function routeBoxes(boxes = BOXES) {
on('GET', `${HEY}/boxes.json`, () => jsonResponse(200, boxes))
}
function routeMove(topicId = LOGOS_TOPIC_ID) {
on('POST', `${HEY}/topics/${topicId}/moves.json`, () => new Response(null, { status: 204 }))
}
test('moveToPaperTrail posts the single-topic MoveTopic body to the Paper Trail box', async () => {
routeBoxes()
routeMove()
const moved = await moveToPaperTrail({ topicId: LOGOS_TOPIC_ID })
const [post] = writes()
assert.equal(post.method, 'POST')
assert.equal(post.url, `${HEY}/topics/${LOGOS_TOPIC_ID}/moves.json`)
assert.equal(post.headers['content-type'], 'application/json')
assert.deepEqual(JSON.parse(post.body), { box_id: TRAILBOX_ID })
assert.equal(moved.topicId, LOGOS_TOPIC_ID)
assert.equal(moved.boxId, TRAILBOX_ID)
assert.equal(moved.status, 204)
assert.equal(moved.url, `${HEY}/topics/${LOGOS_TOPIC_ID}`)
assert.equal(writes().length, 1)
assert.equal(
fixture.requests.some((row) => /clearance|contacts|postings\/moves|designation/i.test(row.url)),
false,
)
})
test('moveToPaperTrail with entryId reads the message topic then posts the same single-topic move', async () => {
on('GET', `${HEY}/messages/${ENTRY_ID}.json`, () =>
jsonResponse(200, { id: ENTRY_ID, topic_id: LOGOS_TOPIC_ID, subject: 'New resources are coming soon to Logos' }),
)
routeBoxes()
routeMove()
await moveToPaperTrail({ entryId: ENTRY_ID })
const [post] = writes()
assert.equal(post.method, 'POST')
assert.equal(post.url, `${HEY}/topics/${LOGOS_TOPIC_ID}/moves.json`)
assert.deepEqual(JSON.parse(post.body), { box_id: TRAILBOX_ID })
assert.equal(
fixture.requests.some((row) => /clearance|contacts|postings\/moves/i.test(row.url)),
false,
)
})
test('moveToPaperTrail throws before any request without topicId or entryId', async () => {
await assert.rejects(() => moveToPaperTrail({}), /topicId or entryId is required/)
assert.equal(fixture.requests.length, 0)
})