Skip to content

Commit d1d8175

Browse files
committed
test(context): cover append/delete edge cases and middleware use of preparedHeaders
Adds coverage for the append option, deleting a header (including one that was never set, which still allocates an empty Headers), and a real Hono app + middleware flow exercising the fast path.
1 parent bf29724 commit d1d8175

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

src/context.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Context } from './context'
22
import { setCookie } from './helper/cookie'
3+
import { Hono } from './hono'
34

45
const makeResponseHeaderImmutable = (res: Response) => {
56
Object.defineProperty(res, 'headers', {
@@ -555,6 +556,50 @@ describe('c.preparedHeaders', () => {
555556
expect(c.preparedHeaders?.get('X-Before')).toBe('a')
556557
expect(c.preparedHeaders?.get('X-After')).toBe('b')
557558
})
559+
560+
it('Should reflect the append option', () => {
561+
const c = new Context(req)
562+
c.header('Vary', 'Accept-Encoding', { append: true })
563+
c.header('Vary', 'User-Agent', { append: true })
564+
expect(c.preparedHeaders?.get('Vary')).toBe('Accept-Encoding, User-Agent')
565+
})
566+
567+
it('Should reflect a header removed with an undefined value', () => {
568+
const c = new Context(req)
569+
c.header('X-Temp', 'val')
570+
c.header('X-Temp', undefined)
571+
expect(c.preparedHeaders?.get('X-Temp')).toBeNull()
572+
})
573+
574+
it('Should create an empty Headers when deleting a header that was never set', () => {
575+
// header() unconditionally does #preparedHeaders ??= new Headers() before
576+
// the delete, even when there is nothing to delete
577+
const c = new Context(req)
578+
c.header('X-Never-Set', undefined)
579+
expect(c.preparedHeaders).toBeInstanceOf(Headers)
580+
expect(c.preparedHeaders?.get('X-Never-Set')).toBeNull()
581+
})
582+
583+
it('Should work from middleware without forcing finalized or breaking the fast path', async () => {
584+
let inspected: Headers | undefined
585+
let finalizedDuringMiddleware: boolean | undefined
586+
587+
const app = new Hono()
588+
app.use(async (ctx, next) => {
589+
ctx.header('X-From-Middleware', 'yes')
590+
inspected = ctx.preparedHeaders
591+
finalizedDuringMiddleware = ctx.finalized
592+
await next()
593+
})
594+
app.get('/', (ctx) => ctx.text('hi'))
595+
596+
const res = await app.request('/')
597+
598+
expect(finalizedDuringMiddleware).toBe(false)
599+
expect(inspected?.get('X-From-Middleware')).toBe('yes')
600+
expect(res.headers.get('X-From-Middleware')).toBe('yes')
601+
expect(await res.text()).toBe('hi')
602+
})
558603
})
559604

560605
describe('Pass a ResponseInit to respond methods', () => {

0 commit comments

Comments
 (0)