forked from oakserver/oak
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathetag_test.ts
172 lines (153 loc) · 4.18 KB
/
etag_test.ts
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright 2018-2023 the oak authors. All rights reserved. MIT license.
import { assert, assertEquals } from "./test_deps.ts";
import {
createMockApp,
createMockContext,
mockContextState,
} from "./testing.ts";
import type { Application } from "./application.ts";
import type { Context } from "./context.ts";
import type { RouteParams } from "./router.ts";
import { factory } from "./etag.ts";
const { test } = Deno;
function setup<
// deno-lint-ignore no-explicit-any
S extends Record<string | number | symbol, any> = Record<string, any>,
>(
path = "/",
method = "GET",
): {
app: Application<S>;
context: Context<S>;
} {
mockContextState.encodingsAccepted = "identity";
// deno-lint-ignore no-explicit-any
const app = createMockApp<any>();
const context = createMockContext<string, RouteParams<string>, S>({
app,
path,
method,
});
return { app, context };
}
const encoder = new TextEncoder();
test({
name: "etag - middleware - body string",
async fn() {
const { context } = setup();
function next() {
context.response.body = "hello deno";
return Promise.resolve();
}
const mw = factory();
await mw(context, next);
assertEquals(
context.response.headers.get("etag"),
`"a-YdfmHmj2RiwOVqJupcf3PLK9PuJ"`,
);
},
});
test({
name: "etag - middleware - body Uint8Array",
async fn() {
const { context } = setup();
function next() {
context.response.body = encoder.encode("hello deno");
return Promise.resolve();
}
const mw = factory();
await mw(context, next);
assertEquals(
context.response.headers.get("etag"),
`"a-YdfmHmj2RiwOVqJupcf3PLK9PuJ"`,
);
},
});
test({
name: "etag - middleware - body File",
async fn() {
const { context } = setup();
let file: Deno.FsFile;
async function next() {
file = await Deno.open("./fixtures/test.jpg", {
read: true,
});
context.response.body = file;
}
const mw = factory();
await mw(context, next);
// Deno.fstat is currently an unstable API in Deno, but the code is written
// to fail gracefully, so we sniff if the API is unavailable and change
// the assertions accordingly.
if ("fstat" in Deno) {
const actual = context.response.headers.get("etag");
// mtime will vary from system to system which makes up part of the hash
// we we only look at the part that is consistent.
assert(actual && actual.startsWith(`W/"4a3b7-`));
} else {
assertEquals(
context.response.headers.get("etag"),
null,
);
}
file!.close();
},
});
test({
name: "etag - middleware - body JSON-like",
async fn() {
const { context } = setup();
function next() {
context.response.body = { msg: "hello deno" };
return Promise.resolve();
}
const mw = factory();
await mw(context, next);
assertEquals(
context.response.headers.get("etag"),
`"14-JvQev/2QpYTuhshiKlzH0ZRXxAP"`,
);
},
});
test({
name: "etag - middleware - body function",
async fn() {
// if we call the body function in the middleware, we cause problems with
// the response, so we just have to ignore body functions
const { context } = setup();
function next() {
context.response.body = () => Promise.resolve("hello deno");
return Promise.resolve();
}
const mw = factory();
await mw(context, next);
assertEquals(
context.response.headers.get("etag"),
null,
);
},
});
test({
name: "etag - middleware - body async iterator",
async fn() {
// The only async readable we can really support is Deno.FsFile, because we
// know how to get the meta data in order to build a weak tag. Other async
// iterables should be ignored and not serialized as JSON.
const { context } = setup();
function next() {
context.response.body = new ReadableStream<string>({
start(controller) {
controller.enqueue("hello deno");
controller.close();
},
});
return Promise.resolve();
}
const mw = factory();
await mw(context, next);
assertEquals(
context.response.headers.get("etag"),
null,
);
},
});