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/search.test.js

70 lines · 2.7 KB · JavaScript
Raw
import assert from 'node:assert/strict'
import { afterEach, beforeEach, test } from 'node:test'

import search from '../src/search.js'
import { HEY, installFetch, jsonResponse, resetKodySecrets } from './helpers.mjs'

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 matches(count, start = 1) {
  return Array.from({ length: count }, (_, i) => ({ topic: { id: start + i } }))
}

function searchUrl(query) {
  const url = new URL('/advanced_search.json', HEY)
  for (const [key, value] of Object.entries(query)) url.searchParams.set(key, value)
  return url.toString()
}

test('search requests only the first page when the caller wants at most 10 matches', async () => {
  on('GET', searchUrl({ q: 'receipt' }), () => jsonResponse(200, { matches: matches(10) }))
  const result = await search({ q: 'receipt' })
  assert.equal(result.matches.length, 10)
  assert.equal(fixture.requests.length, 1)
  const url = new URL(fixture.requests[0].url)
  assert.equal(fixture.requests[0].method, 'GET')
  assert.equal(url.origin, HEY)
  assert.equal(url.pathname, '/advanced_search.json')
  assert.equal(url.searchParams.get('q'), 'receipt')
  assert.equal(url.searchParams.has('page'), false)
  assert.equal(url.searchParams.has('limit'), false)
})

test('search requests a second page when the caller asks for more than the first 10', async () => {
  on('GET', searchUrl({ q: 'receipt' }), () => jsonResponse(200, { matches: matches(10) }))
  on('GET', searchUrl({ q: 'receipt', page: '2' }), () => jsonResponse(200, { matches: matches(5, 11) }))
  const result = await search({ q: 'receipt', limit: 11 })
  assert.equal(result.matches.length, 15)
  assert.equal(fixture.requests.length, 2)
  assert.equal(fixture.requests[0].method, 'GET')
  assert.equal(fixture.requests[1].method, 'GET')
  const first = new URL(fixture.requests[0].url)
  const second = new URL(fixture.requests[1].url)
  assert.equal(first.pathname, '/advanced_search.json')
  assert.equal(second.pathname, '/advanced_search.json')
  assert.equal(first.searchParams.get('q'), 'receipt')
  assert.equal(second.searchParams.get('q'), 'receipt')
  assert.equal(first.searchParams.has('page'), false)
  assert.equal(second.searchParams.get('page'), '2')
  assert.equal(first.searchParams.has('limit'), false)
  assert.equal(second.searchParams.has('limit'), false)
})