1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/**
* A throwaway HTTP server on a random loopback port.
*
* The suite points a real {@link Client} at a real socket: no test touches the
* network, and no test stubs `fetch`. The code path exercised is the one that
* runs in production, request construction and error body reading included.
*
* It doubles as the test that `baseUrl` works — if it did not, none of this
* would run.
*
* @module
*/
/** What the fake server should answer for one request. */
export interface Reply {
status: number;
body: string;
headers?: Record<string, string>;
}
/** Per-test programmable routes, plus a request counter. */
export class Router {
private readonly routes = new Map<string, Reply | Reply[]>();
/** Every path requested so far, in order. */
readonly calls: string[] = [];
/** Answers any path with no registered route. */
fallback?: (path: string) => Reply;
/**
* Register the answer for a path.
*
* An array makes each request consume the next entry, which is how retrying
* is tested. The last entry repeats once the array runs out.
*/
respond(path: string, reply: Reply | Reply[]): void {
this.routes.set(path, reply);
}
/** Record the call and return the answer registered for `path`. */
next(path: string): Reply {
this.calls.push(path);
const reply = this.routes.get(path);
if (reply === undefined) {
if (this.fallback !== undefined) {
return this.fallback(path);
}
return {
status: 404,
body: JSON.stringify({ erro: "cep_nao_encontrado" }),
};
}
if (Array.isArray(reply)) {
return (reply.length > 1 ? reply.shift() : reply[0]) as Reply;
}
return reply;
}
/** How many requests so far began with `prefix`. */
count(prefix: string): number {
return this.calls.filter((call) => call.startsWith(prefix)).length;
}
}
/** A running fake API, with its router. */
export interface FakeServer {
url: string;
routes: Router;
stop: () => void;
}
/** Start a fake API on `127.0.0.1` and a port the kernel picks. */
export function startServer(): FakeServer {
const routes = new Router();
const server = Bun.serve({
hostname: "127.0.0.1",
port: 0,
fetch(request) {
const url = new URL(request.url);
const reply = routes.next(`${url.pathname}${url.search}`);
return new Response(reply.body, {
status: reply.status,
headers: {
"Content-Type": "application/json; charset=utf-8",
...reply.headers,
},
});
},
});
return {
url: `http://127.0.0.1:${server.port}`,
routes,
stop: () => {
server.stop(true);
},
};
}
|