UNPKG

4.59 kBPlain TextView Raw
1import tap from 'tap'
2import fs from 'fs-extra'
3import path from 'path'
4import http from 'http'
5import { makeFetch } from 'supertest-fetch'
6// @ts-ignore
7import proxy from 'proxyquire'
8
9import { createConfig } from '../lib/config'
10import { createServerHandler as base } from '../lib/serve'
11import type { AWS } from '../lib/types'
12
13type CreateServerHandler = {
14 createServerHandler: typeof base
15}
16
17tap.test('createServerHandler - searches for static assets', async (t) => {
18 const assets = './assets'
19
20 const dirs: string[] = []
21 let called = false
22
23 const config = createConfig({
24 cli: { assets, output: t.testdirName },
25 })
26 const expectedDirs = [path.join(process.cwd(), assets), config.staticOutputDir]
27 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
28 sirv: (dir: string) => (req: http.ClientRequest, res: http.ServerResponse, cb: () => {}) => {
29 dirs.push(dir)
30 cb()
31 },
32 './sendServerlessResponse': {
33 sendServerlessResponse() {
34 called = true
35 },
36 },
37 })
38 const serverHandler = createServerHandler({ port: 4000, config })
39 const imageFilepath = path.join(config.staticOutputDir, 'image.png')
40
41 fs.outputFileSync(imageFilepath, '')
42
43 const server = http.createServer(async (req, res) => {
44 await serverHandler(req, res)
45 res.end()
46 })
47
48 const fetch = makeFetch(server)
49
50 await fetch('/image.png') // would normally match
51
52 t.same(dirs, expectedDirs)
53 t.ok(called)
54
55 fs.removeSync(imageFilepath)
56})
57
58tap.test('createServerHandler - resolves a static route', async (t) => {
59 let found = false
60
61 const config = createConfig({ cli: { output: t.testdirName } })
62 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
63 './sendServerlessResponse': {
64 sendServerlessResponse() {
65 found = true
66 },
67 },
68 })
69 const serverHandler = createServerHandler({ port: 4000, config })
70 const indexRouteFilepath = path.join(config.staticOutputDir, 'index.html')
71
72 fs.outputFileSync(indexRouteFilepath, '')
73
74 const server = http.createServer(async (req, res) => {
75 await serverHandler(req, res)
76 res.end()
77 })
78
79 const fetch = makeFetch(server)
80
81 await fetch('/')
82
83 t.ok(found)
84
85 fs.removeSync(indexRouteFilepath)
86})
87
88tap.test('createServerHandler - resolves a lambda', async (t) => {
89 let responses: boolean[] = []
90
91 const config = createConfig({ cli: { output: t.testdirName } })
92 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
93 './sendServerlessResponse': {
94 sendServerlessResponse(_: http.ServerResponse, response: Partial<AWS['HandlerResponse']>) {
95 if (response.statusCode !== 404) {
96 responses.push(true)
97 } else {
98 responses.push(false)
99 }
100 },
101 },
102 })
103 const serverHandler = createServerHandler({ port: 4000, config })
104
105 const functionFilepath = path.join(config.functionsOutputDir, 'Route.js')
106 const functionsManifestFilepath = path.join(config.output, 'routes.json')
107 fs.outputFileSync(
108 functionsManifestFilepath,
109 JSON.stringify({
110 '/:slug?': functionFilepath,
111 })
112 )
113 fs.outputFileSync(functionFilepath, `module.exports = { handler () {} }`)
114
115 const server = http.createServer(async (req, res) => {
116 await serverHandler(req, res)
117 res.end()
118 })
119
120 const fetch = makeFetch(server)
121
122 await fetch('/') // found
123 await fetch('/foo/bar/baz') // not found
124
125 t.same(responses, [true, false])
126
127 fs.removeSync(functionFilepath)
128 fs.removeSync(functionsManifestFilepath)
129})
130
131tap.test('createServerHandler - throws 500', async (t) => {
132 let did500 = false
133
134 const config = createConfig({ cli: { output: t.testdirName } })
135 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
136 './sendServerlessResponse': {
137 sendServerlessResponse(_: http.ServerResponse, response: Partial<AWS['HandlerResponse']>) {
138 if (response.statusCode === 500) {
139 did500 = true
140 }
141 },
142 },
143 })
144 const serverHandler = createServerHandler({ port: 4000, config })
145
146 const functionFilepath = path.join(config.functionsOutputDir, 'Route.js')
147 fs.outputFileSync(
148 path.join(config.output, 'routes.json'),
149 JSON.stringify({
150 '*': functionFilepath,
151 })
152 )
153 fs.outputFileSync(functionFilepath, `module.exports = { handler () { throw 'error' } }`)
154
155 const server = http.createServer(async (req, res) => {
156 await serverHandler(req, res)
157 res.end()
158 })
159
160 const fetch = makeFetch(server)
161
162 await fetch('/') // throws
163
164 t.ok(did500)
165
166 fs.removeSync(t.testdirName)
167})
168
\No newline at end of file