2022-07-17 00:51:42 +00:00
|
|
|
import { describe, expect, it } from 'bun:test'
|
2023-03-06 12:12:22 +00:00
|
|
|
import { env } from '../src/adapter'
|
2023-01-17 08:40:54 +00:00
|
|
|
import { serveStatic } from '../src/adapter/bun'
|
2022-11-03 06:53:41 +00:00
|
|
|
import { Context } from '../src/context'
|
2022-07-13 00:50:31 +00:00
|
|
|
import { Hono } from '../src/index'
|
2022-07-16 00:35:51 +00:00
|
|
|
import { basicAuth } from '../src/middleware/basic-auth'
|
2022-07-16 00:59:10 +00:00
|
|
|
import { jwt } from '../src/middleware/jwt'
|
2022-07-13 00:50:31 +00:00
|
|
|
|
|
|
|
// Test just only minimal patterns.
|
|
|
|
// Because others are tested well in Cloudflare Workers environment already.
|
|
|
|
|
2022-07-17 00:51:42 +00:00
|
|
|
describe('Basic', () => {
|
|
|
|
const app = new Hono()
|
|
|
|
app.get('/a/:foo', (c) => {
|
|
|
|
c.header('x-param', c.req.param('foo'))
|
|
|
|
c.header('x-query', c.req.query('q'))
|
2023-03-06 12:12:22 +00:00
|
|
|
return c.text('Hello Bun!')
|
2022-07-17 00:51:42 +00:00
|
|
|
})
|
2022-07-13 00:50:31 +00:00
|
|
|
|
2022-07-17 00:51:42 +00:00
|
|
|
it('Should return 200 Response', async () => {
|
|
|
|
const req = new Request('http://localhost/a/foo?q=bar')
|
|
|
|
const res = await app.request(req)
|
|
|
|
expect(res.status).toBe(200)
|
2023-03-06 12:12:22 +00:00
|
|
|
expect(await res.text()).toBe('Hello Bun!')
|
2022-07-17 00:51:42 +00:00
|
|
|
expect(res.headers.get('x-param')).toBe('foo')
|
|
|
|
expect(res.headers.get('x-query')).toBe('bar')
|
2022-07-13 00:50:31 +00:00
|
|
|
})
|
2022-11-03 06:35:23 +00:00
|
|
|
|
|
|
|
it('returns current runtime (bun)', async () => {
|
2022-11-03 06:53:41 +00:00
|
|
|
const c = new Context(new Request('http://localhost/'))
|
2022-11-03 06:35:23 +00:00
|
|
|
expect(c.runtime).toBe('bun')
|
|
|
|
})
|
2022-07-17 00:51:42 +00:00
|
|
|
})
|
2022-07-13 00:50:31 +00:00
|
|
|
|
2023-03-06 12:12:22 +00:00
|
|
|
describe('Environment Variables', () => {
|
|
|
|
it('Should return the environment variable', async () => {
|
|
|
|
const c = new Context(new Request('http://localhost/'))
|
|
|
|
const { NAME } = env<{ NAME: string }>(c)
|
|
|
|
expect(NAME).toBe('Bun')
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2022-07-17 00:51:42 +00:00
|
|
|
describe('Basic Auth Middleware', () => {
|
|
|
|
const app = new Hono()
|
2022-07-13 00:50:31 +00:00
|
|
|
|
2022-07-17 00:51:42 +00:00
|
|
|
const username = 'hono-user-a'
|
|
|
|
const password = 'hono-password-a'
|
|
|
|
app.use(
|
|
|
|
'/auth/*',
|
|
|
|
basicAuth({
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
})
|
|
|
|
)
|
2022-07-13 00:50:31 +00:00
|
|
|
|
2022-07-17 00:51:42 +00:00
|
|
|
app.get('/auth/*', () => new Response('auth'))
|
2022-07-13 00:50:31 +00:00
|
|
|
|
2022-07-17 00:51:42 +00:00
|
|
|
it('Should not authorize, return 401 Response', async () => {
|
|
|
|
const req = new Request('http://localhost/auth/a')
|
|
|
|
const res = await app.request(req)
|
|
|
|
expect(res.status).toBe(401)
|
|
|
|
expect(await res.text()).toBe('Unauthorized')
|
|
|
|
})
|
2022-07-13 00:50:31 +00:00
|
|
|
|
2022-07-17 00:51:42 +00:00
|
|
|
it('Should authorize, return 200 Response', async () => {
|
|
|
|
const credential = 'aG9uby11c2VyLWE6aG9uby1wYXNzd29yZC1h'
|
|
|
|
const req = new Request('http://localhost/auth/a')
|
|
|
|
req.headers.set('Authorization', `Basic ${credential}`)
|
|
|
|
const res = await app.request(req)
|
|
|
|
expect(res.status).toBe(200)
|
|
|
|
expect(await res.text()).toBe('auth')
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('Serve Static Middleware', () => {
|
|
|
|
const app = new Hono()
|
2023-01-07 00:55:42 +00:00
|
|
|
app.all('/favicon.ico', serveStatic({ path: './test_bun/favicon.ico' }))
|
|
|
|
app.all('/favicon-notfound.ico', serveStatic({ path: './test_bun/favicon-notfound.ico' }))
|
2022-10-09 15:24:14 +00:00
|
|
|
app.use('/favicon-notfound.ico', async (c, next) => {
|
|
|
|
await next()
|
|
|
|
c.header('X-Custom', 'Bun')
|
|
|
|
})
|
2022-07-17 00:51:42 +00:00
|
|
|
|
|
|
|
it('Should return static file correctly', async () => {
|
|
|
|
const res = await app.request(new Request('http://localhost/favicon.ico'))
|
|
|
|
await res.arrayBuffer()
|
|
|
|
expect(res.status).toBe(200)
|
2022-08-09 01:51:08 +00:00
|
|
|
expect(res.headers.get('Content-Type')).toBe('image/x-icon')
|
2022-07-17 00:51:42 +00:00
|
|
|
})
|
2022-09-19 03:25:04 +00:00
|
|
|
|
|
|
|
it('Should return 404 response', async () => {
|
|
|
|
const res = await app.request(new Request('http://localhost/favicon-notfound.ico'))
|
|
|
|
expect(res.status).toBe(404)
|
2022-10-09 15:24:14 +00:00
|
|
|
expect(res.headers.get('X-Custom')).toBe('Bun')
|
2022-09-19 03:25:04 +00:00
|
|
|
})
|
2022-07-17 00:51:42 +00:00
|
|
|
})
|
2022-07-16 00:59:10 +00:00
|
|
|
|
2022-10-28 15:09:09 +00:00
|
|
|
// Bun support WebCrypto since v0.2.2
|
|
|
|
// So, JWT middleware works well.
|
|
|
|
describe('JWT Auth Middleware', () => {
|
2022-07-17 00:51:42 +00:00
|
|
|
const app = new Hono()
|
2022-10-28 15:09:09 +00:00
|
|
|
app.use('/jwt/*', jwt({ secret: 'a-secret' }))
|
|
|
|
app.get('/jwt/a', (c) => c.text('auth'))
|
|
|
|
|
|
|
|
it('Should not authorize, return 401 Response', async () => {
|
|
|
|
const req = new Request('http://localhost/jwt/a')
|
|
|
|
const res = await app.request(req)
|
|
|
|
expect(res.status).toBe(401)
|
|
|
|
expect(await res.text()).toBe('Unauthorized')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should authorize, return 200 Response', async () => {
|
|
|
|
const credential =
|
|
|
|
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXNzYWdlIjoiaGVsbG8gd29ybGQifQ.B54pAqIiLbu170tGQ1rY06Twv__0qSHTA0ioQPIOvFE'
|
|
|
|
const req = new Request('http://localhost/jwt/a')
|
|
|
|
req.headers.set('Authorization', `Bearer ${credential}`)
|
|
|
|
const res = await app.request(req)
|
|
|
|
expect(res.status).toBe(200)
|
|
|
|
expect(await res.text()).toBe('auth')
|
2022-07-17 00:51:42 +00:00
|
|
|
})
|
2022-07-16 00:59:10 +00:00
|
|
|
})
|
2022-07-24 08:36:37 +00:00
|
|
|
|
|
|
|
// To enable JSX middleware,
|
|
|
|
// set "jsxImportSource": "hono/jsx" in the tsconfig.json
|
|
|
|
describe('JSX Middleware', () => {
|
|
|
|
const app = new Hono()
|
2022-07-24 11:39:41 +00:00
|
|
|
|
|
|
|
const Layout = (props: { children?: string }) => {
|
|
|
|
return <html>{props.children}</html>
|
|
|
|
}
|
|
|
|
|
2022-07-24 08:36:37 +00:00
|
|
|
app.get('/', (c) => {
|
|
|
|
return c.html(<h1>Hello</h1>)
|
|
|
|
})
|
2022-07-24 11:39:41 +00:00
|
|
|
app.get('/nest', (c) => {
|
|
|
|
return c.html(
|
|
|
|
<h1>
|
|
|
|
<a href='/top'>Hello</a>
|
|
|
|
</h1>
|
|
|
|
)
|
|
|
|
})
|
|
|
|
app.get('/layout', (c) => {
|
|
|
|
return c.html(
|
|
|
|
<Layout>
|
|
|
|
<p>hello</p>
|
|
|
|
</Layout>
|
|
|
|
)
|
|
|
|
})
|
2022-07-24 08:36:37 +00:00
|
|
|
|
|
|
|
it('Should return rendered HTML', async () => {
|
|
|
|
const res = await app.request(new Request('http://localhost/'))
|
|
|
|
expect(res.status).toBe(200)
|
|
|
|
expect(res.headers.get('Content-Type')).toBe('text/html; charset=UTF-8')
|
|
|
|
expect(await res.text()).toBe('<h1>Hello</h1>')
|
|
|
|
})
|
2022-07-24 11:39:41 +00:00
|
|
|
|
|
|
|
it('Should return rendered HTML with nest', async () => {
|
|
|
|
const res = await app.request(new Request('http://localhost/nest'))
|
|
|
|
expect(res.status).toBe(200)
|
|
|
|
expect(res.headers.get('Content-Type')).toBe('text/html; charset=UTF-8')
|
|
|
|
expect(await res.text()).toBe('<h1><a href="/top">Hello</a></h1>')
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should return rendered HTML with Layout', async () => {
|
|
|
|
const res = await app.request(new Request('http://localhost/layout'))
|
|
|
|
expect(res.status).toBe(200)
|
|
|
|
expect(res.headers.get('Content-Type')).toBe('text/html; charset=UTF-8')
|
|
|
|
expect(await res.text()).toBe('<html><p>hello</p></html>')
|
|
|
|
})
|
2022-07-24 08:36:37 +00:00
|
|
|
})
|