1 | import tap from 'tap'
|
2 | import fs from 'fs-extra'
|
3 | import path from 'path'
|
4 | import http from 'http'
|
5 | import { makeFetch } from 'supertest-fetch'
|
6 |
|
7 | import proxy from 'proxyquire'
|
8 |
|
9 | import { createConfig } from '../lib/config'
|
10 | import { createServerHandler as base } from '../lib/serve'
|
11 | import type { AWS } from '../lib/types'
|
12 |
|
13 | type CreateServerHandler = {
|
14 | createServerHandler: typeof base
|
15 | }
|
16 |
|
17 | tap.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')
|
51 |
|
52 | t.same(dirs, expectedDirs)
|
53 | t.ok(called)
|
54 |
|
55 | fs.removeSync(imageFilepath)
|
56 | })
|
57 |
|
58 |
|
59 |
|
60 |
|
61 | tap.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 |
|
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 |
|
91 | tap.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 |
|
134 | tap.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 |
|
177 | tap.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('/')
|
209 |
|
210 | t.ok(did500)
|
211 |
|
212 | fs.removeSync(t.testdirName)
|
213 | })
|
214 |
|
\ | No newline at end of file |