UNPKG

6.06 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 = await 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
58/**
59 * Sirv handles these now https://github.com/lukeed/sirv/tree/master/packages/sirv#optsextensions
60 */
61tap.test('createServerHandler - resolves a static index route', async (t) => {
62 let found = false
63
64 const config = await createConfig({ cli: { output: t.testdirName } })
65 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
66 './sendServerlessResponse': {
67 sendServerlessResponse() {
68 // should never hit this, picked up by sirv
69 found = true
70 },
71 },
72 })
73 const serverHandler = createServerHandler({ port: 4000, config })
74 const indexRouteFilepath = path.join(config.staticOutputDir, 'index.html')
75
76 fs.outputFileSync(indexRouteFilepath, '')
77
78 const server = http.createServer(async (req, res) => {
79 await serverHandler(req, res)
80 })
81
82 const fetch = makeFetch(server)
83
84 await fetch('/')
85
86 t.notOk(found)
87
88 fs.removeSync(indexRouteFilepath)
89})
90
91tap.test('createServerHandler - resolves a lambda', async (t) => {
92 let responses: boolean[] = []
93
94 const config = await createConfig({ cli: { output: t.testdirName } })
95 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
96 './sendServerlessResponse': {
97 sendServerlessResponse(_: http.ServerResponse, response: Partial<AWS['HandlerResponse']>) {
98 if (response.statusCode !== 404) {
99 responses.push(true)
100 } else {
101 responses.push(false)
102 }
103 },
104 },
105 })
106 const serverHandler = createServerHandler({ port: 4000, config })
107
108 const functionFilepath = path.join(config.functionsOutputDir, 'Route.js')
109 const functionsManifestFilepath = path.join(config.output, 'routes.json')
110 fs.outputFileSync(
111 functionsManifestFilepath,
112 JSON.stringify({
113 '/:slug?': functionFilepath,
114 })
115 )
116 fs.outputFileSync(functionFilepath, `module.exports = { handler () {} }`)
117
118 const server = http.createServer(async (req, res) => {
119 await serverHandler(req, res)
120 res.end()
121 })
122
123 const fetch = makeFetch(server)
124
125 await fetch('/') // found
126 await fetch('/foo/bar/baz') // not found
127
128 t.same(responses, [true, false])
129
130 fs.removeSync(functionFilepath)
131 fs.removeSync(functionsManifestFilepath)
132})
133
134tap.test('createServerHandler - wildcards can pick up extensions too', async (t) => {
135 let responses: boolean[] = []
136
137 const config = await createConfig({ cli: { output: t.testdirName } })
138 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
139 './sendServerlessResponse': {
140 sendServerlessResponse(_: http.ServerResponse, response: Partial<AWS['HandlerResponse']>) {
141 if (response.statusCode !== 404) {
142 responses.push(true)
143 } else {
144 responses.push(false)
145 }
146 },
147 },
148 })
149 const serverHandler = createServerHandler({ port: 4000, config })
150
151 const functionFilepath = path.join(config.functionsOutputDir, 'Wild.js')
152 const functionsManifestFilepath = path.join(config.output, 'routes.json')
153 fs.outputFileSync(
154 functionsManifestFilepath,
155 JSON.stringify({
156 '*': functionFilepath,
157 })
158 )
159 fs.outputFileSync(functionFilepath, `module.exports = { handler () {} }`)
160
161 const server = http.createServer(async (req, res) => {
162 await serverHandler(req, res)
163 res.end()
164 })
165
166 const fetch = makeFetch(server)
167
168 await fetch('/example.png')
169 await fetch('/example.json')
170
171 t.same(responses, [true, true])
172
173 fs.removeSync(functionFilepath)
174 fs.removeSync(functionsManifestFilepath)
175})
176
177tap.test('createServerHandler - throws 500', async (t) => {
178 let did500 = false
179
180 const config = await createConfig({ cli: { output: t.testdirName } })
181 const { createServerHandler }: CreateServerHandler = proxy('../lib/serve', {
182 './sendServerlessResponse': {
183 sendServerlessResponse(_: http.ServerResponse, response: Partial<AWS['HandlerResponse']>) {
184 if (response.statusCode === 500) {
185 did500 = true
186 }
187 },
188 },
189 })
190 const serverHandler = createServerHandler({ port: 4000, config })
191
192 const functionFilepath = path.join(config.functionsOutputDir, 'Route.js')
193 fs.outputFileSync(
194 path.join(config.output, 'routes.json'),
195 JSON.stringify({
196 '*': functionFilepath,
197 })
198 )
199 fs.outputFileSync(functionFilepath, `module.exports = { handler () { throw 'error' } }`)
200
201 const server = http.createServer(async (req, res) => {
202 await serverHandler(req, res)
203 res.end()
204 })
205
206 const fetch = makeFetch(server)
207
208 await fetch('/') // throws
209
210 t.ok(did500)
211
212 fs.removeSync(t.testdirName)
213})
214
\No newline at end of file