@server/next 0.21.2 → 0.21.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/auth/auth-cookie.test.js +4 -4
- package/src/auth/auth-token.test.js +9 -9
- package/src/auth/providers/email.js +1 -1
- package/src/context/node.js +13 -2
- package/src/context/winter.js +13 -1
- package/src/helpers/config.js +1 -1
- package/src/helpers/jsx.js +15 -4
- package/src/helpers/jsx.test.jsx +48 -0
- package/src/index.js +10 -6
- package/src/index.test.js +10 -12
- package/src/middle/assets.js +1 -1
- package/src/middle/assets.test.js +10 -0
- package/src/router.test.js +5 -5
- package/src/session.test.js +7 -7
- package/src/test/toSucceed.js +13 -13
- package/src/url.test.js +4 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@server/next",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.4",
|
|
4
4
|
"description": "A fully-fledged web server with routing, file uploads, sessions, static files, schema validation, websockets, testing, etc.",
|
|
5
5
|
"homepage": "https://server-js.com/",
|
|
6
6
|
"repository": "https://github.com/franciscop/server-next.git",
|
|
@@ -16,17 +16,17 @@ describe("user creation flow", () => {
|
|
|
16
16
|
.test();
|
|
17
17
|
|
|
18
18
|
// Bun's bug: https://github.com/oven-sh/bun/issues/6348
|
|
19
|
-
it
|
|
19
|
+
it("can create a new user", async () => {
|
|
20
20
|
const register = await api.post("/auth/register/email", CREDENTIALS);
|
|
21
21
|
expect(register).toSucceed();
|
|
22
22
|
expect(await store.keys()).toEqual([
|
|
23
23
|
"user:abc@test.com",
|
|
24
|
-
"auth:" + register.headers["set-cookie"].split("=")[1],
|
|
24
|
+
"auth:" + register.headers["set-cookie"].split(";")[0].split("=")[1],
|
|
25
25
|
]);
|
|
26
26
|
|
|
27
27
|
const me = await api.get("/me");
|
|
28
28
|
expect(me).toSucceed();
|
|
29
|
-
expect(me.
|
|
29
|
+
expect(me.body.email).toEqual(EMAIL);
|
|
30
30
|
|
|
31
31
|
const logout = await api.post("/auth/logout");
|
|
32
32
|
expect(logout).toSucceed();
|
|
@@ -36,7 +36,7 @@ describe("user creation flow", () => {
|
|
|
36
36
|
expect(login).toSucceed();
|
|
37
37
|
expect(await store.keys()).toEqual([
|
|
38
38
|
"user:abc@test.com",
|
|
39
|
-
"auth:" + login.headers["set-cookie"].split("=")[1],
|
|
39
|
+
"auth:" + login.headers["set-cookie"].split(";")[0].split("=")[1],
|
|
40
40
|
]);
|
|
41
41
|
});
|
|
42
42
|
});
|
|
@@ -18,7 +18,7 @@ describe("user creation flow", () => {
|
|
|
18
18
|
.test();
|
|
19
19
|
|
|
20
20
|
// Bun's bug: https://github.com/oven-sh/bun/issues/6348
|
|
21
|
-
it
|
|
21
|
+
it("tests a long user flow with tokens", async () => {
|
|
22
22
|
// The latest updated token
|
|
23
23
|
let token;
|
|
24
24
|
|
|
@@ -28,8 +28,8 @@ describe("user creation flow", () => {
|
|
|
28
28
|
expect(register).toSucceed();
|
|
29
29
|
|
|
30
30
|
expect(await users()).toEqual(["abc@test.com"]);
|
|
31
|
-
expect(await sessions()).toEqual([register.
|
|
32
|
-
return register.
|
|
31
|
+
expect(await sessions()).toEqual([register.body.token]);
|
|
32
|
+
return register.body.token;
|
|
33
33
|
})();
|
|
34
34
|
|
|
35
35
|
// CAN GET MY OWN INFO
|
|
@@ -37,7 +37,7 @@ describe("user creation flow", () => {
|
|
|
37
37
|
const headers = { authorization: "Bearer " + token };
|
|
38
38
|
const me = await api.get("/me", { headers });
|
|
39
39
|
expect(me).toSucceed();
|
|
40
|
-
expect(me.
|
|
40
|
+
expect(me.body.email).toEqual(EMAIL);
|
|
41
41
|
|
|
42
42
|
expect(await users()).toEqual(["abc@test.com"]);
|
|
43
43
|
expect(await sessions()).toEqual([token]);
|
|
@@ -57,8 +57,8 @@ describe("user creation flow", () => {
|
|
|
57
57
|
const login = await api.post("/auth/login/email", CREDENTIALS);
|
|
58
58
|
expect(login).toSucceed();
|
|
59
59
|
expect(await users()).toEqual(["abc@test.com"]);
|
|
60
|
-
expect(await sessions()).toEqual([login.
|
|
61
|
-
return login.
|
|
60
|
+
expect(await sessions()).toEqual([login.body.token]);
|
|
61
|
+
return login.body.token;
|
|
62
62
|
})();
|
|
63
63
|
|
|
64
64
|
// CAN GET MY OWN INFO
|
|
@@ -66,7 +66,7 @@ describe("user creation flow", () => {
|
|
|
66
66
|
const headers = { authorization: "Bearer " + token };
|
|
67
67
|
const me = await api.get("/me", { headers });
|
|
68
68
|
expect(me).toSucceed();
|
|
69
|
-
expect(me.
|
|
69
|
+
expect(me.body.email).toEqual(EMAIL);
|
|
70
70
|
})();
|
|
71
71
|
|
|
72
72
|
// UPDATE PASSWORD
|
|
@@ -103,8 +103,8 @@ describe("user creation flow", () => {
|
|
|
103
103
|
});
|
|
104
104
|
expect(login).toSucceed();
|
|
105
105
|
expect(await users()).toEqual(["abc@test.com"]);
|
|
106
|
-
expect(await sessions()).toEqual([login.
|
|
107
|
-
return login.
|
|
106
|
+
expect(await sessions()).toEqual([login.body.token]);
|
|
107
|
+
return login.body.token;
|
|
108
108
|
})();
|
|
109
109
|
});
|
|
110
110
|
});
|
package/src/context/node.js
CHANGED
|
@@ -17,6 +17,17 @@ export default async (request, options = {}, app) => {
|
|
|
17
17
|
ctx.res = { status: null, headers: {}, cookies: {} };
|
|
18
18
|
ctx.method = request.method.toLowerCase();
|
|
19
19
|
|
|
20
|
+
// Private
|
|
21
|
+
const events = {};
|
|
22
|
+
ctx.unstableOn = (name, callback) => {
|
|
23
|
+
events[name] = events[name] || [];
|
|
24
|
+
events[name].push(callback);
|
|
25
|
+
};
|
|
26
|
+
ctx.unstableFire = (name, data) => {
|
|
27
|
+
if (!events[name]) return;
|
|
28
|
+
events[name].forEach((cb) => cb(data));
|
|
29
|
+
};
|
|
30
|
+
|
|
20
31
|
ctx.headers = parseHeaders(new Headers(chunkArray(request.rawHeaders, 2)));
|
|
21
32
|
ctx.cookies = parseCookies(ctx.headers.cookie);
|
|
22
33
|
await auth.load(ctx);
|
|
@@ -26,7 +37,7 @@ export default async (request, options = {}, app) => {
|
|
|
26
37
|
const path = request.url.replace(/\/$/, "") || "/";
|
|
27
38
|
ctx.url = new URL(path, `${https}://${host}`);
|
|
28
39
|
define(ctx.url, "query", (url) =>
|
|
29
|
-
Object.fromEntries(url.searchParams.entries())
|
|
40
|
+
Object.fromEntries(url.searchParams.entries()),
|
|
30
41
|
);
|
|
31
42
|
|
|
32
43
|
await new Promise((resolve, reject) => {
|
|
@@ -40,7 +51,7 @@ export default async (request, options = {}, app) => {
|
|
|
40
51
|
ctx.body = await parseBody(
|
|
41
52
|
Buffer.concat(body).toString(),
|
|
42
53
|
type,
|
|
43
|
-
options.uploads
|
|
54
|
+
options.uploads,
|
|
44
55
|
);
|
|
45
56
|
resolve();
|
|
46
57
|
})
|
package/src/context/winter.js
CHANGED
|
@@ -5,18 +5,30 @@ import parseCookies from "./parseCookies.js";
|
|
|
5
5
|
|
|
6
6
|
export default async (request, options = {}, app) => {
|
|
7
7
|
const ctx = {};
|
|
8
|
+
ctx.init = performance.now();
|
|
8
9
|
ctx.options = options;
|
|
9
10
|
ctx.req = request;
|
|
10
11
|
ctx.res = { status: null, headers: {}, cookies: {} };
|
|
11
12
|
ctx.method = request.method.toLowerCase();
|
|
12
13
|
|
|
14
|
+
// Private
|
|
15
|
+
const events = {};
|
|
16
|
+
ctx.unstableOn = (name, callback) => {
|
|
17
|
+
events[name] = events[name] || [];
|
|
18
|
+
events[name].push(callback);
|
|
19
|
+
};
|
|
20
|
+
ctx.unstableFire = (name, data) => {
|
|
21
|
+
if (!events[name]) return;
|
|
22
|
+
events[name].forEach((cb) => cb(data));
|
|
23
|
+
};
|
|
24
|
+
|
|
13
25
|
ctx.headers = parseHeaders(request.headers);
|
|
14
26
|
ctx.cookies = parseCookies(ctx.headers.cookie);
|
|
15
27
|
await auth.load(ctx);
|
|
16
28
|
|
|
17
29
|
ctx.url = new URL(request.url.replace(/\/$/, ""));
|
|
18
30
|
define(ctx.url, "query", (url) =>
|
|
19
|
-
Object.fromEntries(url.searchParams.entries())
|
|
31
|
+
Object.fromEntries(url.searchParams.entries()),
|
|
20
32
|
);
|
|
21
33
|
|
|
22
34
|
if (request.body) {
|
package/src/helpers/config.js
CHANGED
|
@@ -3,7 +3,7 @@ import createId from "./createId.js";
|
|
|
3
3
|
|
|
4
4
|
// Big mess; parse all of the options for server, which can be at launch time
|
|
5
5
|
// or dynamically per-request for the functions (so have to read ENV inside)
|
|
6
|
-
export default function config(options) {
|
|
6
|
+
export default function config(options = {}) {
|
|
7
7
|
const env = globalThis.env;
|
|
8
8
|
|
|
9
9
|
// Basic options
|
package/src/helpers/jsx.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const entities = { "&": "&", "<": "<", ">": ">", '"': """ };
|
|
2
|
-
const encode = (str = "") =>
|
|
2
|
+
const encode = (str = "") => {
|
|
3
|
+
if (typeof str === "number") str = String(str);
|
|
4
|
+
if (typeof str !== "string") return ""; // nullify not-strings
|
|
5
|
+
return str.replace(/[&<>"]/g, (tag) => entities[tag]);
|
|
6
|
+
};
|
|
3
7
|
|
|
4
8
|
const SELFCLOSE = new Set(
|
|
5
9
|
"area,base,br,col,embed,hr,img,input,link,meta,source,track,wbr".split(","),
|
|
@@ -13,7 +17,7 @@ export const jsx = (tag, { children, ...props }) => {
|
|
|
13
17
|
if (typeof tag === "function") return tag({ children, ...props });
|
|
14
18
|
|
|
15
19
|
if (props.dangerouslySetInnerHTML)
|
|
16
|
-
children = props.dangerouslySetInnerHTML.__html;
|
|
20
|
+
children = () => props.dangerouslySetInnerHTML.__html;
|
|
17
21
|
if (!children) children = [];
|
|
18
22
|
if (typeof children === "string") children = [children];
|
|
19
23
|
children = (Array.isArray(children) ? children : [children])
|
|
@@ -22,12 +26,19 @@ export const jsx = (tag, { children, ...props }) => {
|
|
|
22
26
|
.join("");
|
|
23
27
|
if (!tag) return () => children;
|
|
24
28
|
let attrStr = Object.entries(props || {})
|
|
29
|
+
.filter(([k, v]) => k !== "dangerouslySetInnerHTML")
|
|
25
30
|
.filter(([k, v]) => !/on[A-Z]/.test(k) && typeof v !== "function")
|
|
26
|
-
.
|
|
31
|
+
.filter(([k, v]) => v !== false)
|
|
32
|
+
.map(([k, v]) =>
|
|
33
|
+
v === true
|
|
34
|
+
? altAttrs[k.toLowerCase()] || encode(k)
|
|
35
|
+
: `${altAttrs[k.toLowerCase()] || encode(k)}="${encode(v)}"`,
|
|
36
|
+
)
|
|
27
37
|
.join(" ");
|
|
28
38
|
if (attrStr) attrStr = " " + attrStr;
|
|
29
39
|
if (SELFCLOSE.has(tag)) return () => `<${tag}${attrStr} />`;
|
|
30
|
-
|
|
40
|
+
const doctype = tag === "html" ? "<!DOCTYPE html>" : "";
|
|
41
|
+
return () => `${doctype}<${tag}${attrStr}>${children}</${tag}>`;
|
|
31
42
|
};
|
|
32
43
|
export const jsxDEV = jsx;
|
|
33
44
|
export const Fragment = "";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx } from "./jsx.js";
|
|
2
|
+
|
|
3
|
+
const $ = (code) => code();
|
|
4
|
+
|
|
5
|
+
expect.extend({
|
|
6
|
+
toRender(fn, rendered) {
|
|
7
|
+
const html = fn();
|
|
8
|
+
if (this.isNot) {
|
|
9
|
+
const msg = `Expected "${html}" to render differently`;
|
|
10
|
+
return { pass: html === rendered, message: () => msg };
|
|
11
|
+
}
|
|
12
|
+
const msg = `Expected "${html}" to be rendered as "${rendered}"`;
|
|
13
|
+
return { pass: html === rendered, message: () => msg };
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe("jsx", () => {
|
|
18
|
+
it("can render a div", () => {
|
|
19
|
+
expect(<div>Hello</div>).toRender(`<div>Hello</div>`);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("can render an input with attributes", () => {
|
|
23
|
+
expect(<input name="hello" />).toRender(`<input name="hello" />`);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("will stringify an attribute", () => {
|
|
27
|
+
expect(<input value={5.2} />).toRender('<input value="5.2" />');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("will ignore a boolean attribute", () => {
|
|
31
|
+
expect(<input disabled />).toRender("<input disabled />");
|
|
32
|
+
expect(<input disabled={true} />).toRender("<input disabled />");
|
|
33
|
+
expect(<input disabled={false} />).toRender("<input />");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("will remove events", () => {
|
|
37
|
+
expect(<input onChange={() => console.log("hello")} />).toRender(
|
|
38
|
+
"<input />",
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("will inject the doctype for html", () => {
|
|
43
|
+
expect(<html>Hello</html>).toRender("<!DOCTYPE html><html>Hello</html>");
|
|
44
|
+
expect(<html lang="en">Hello</html>).toRender(
|
|
45
|
+
`<!DOCTYPE html><html lang="en">Hello</html>`,
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
});
|
package/src/index.js
CHANGED
|
@@ -116,7 +116,7 @@ server.prototype.node = async function () {
|
|
|
116
116
|
response.end();
|
|
117
117
|
}
|
|
118
118
|
})
|
|
119
|
-
.listen(
|
|
119
|
+
.listen(this.opts.port);
|
|
120
120
|
};
|
|
121
121
|
|
|
122
122
|
// Netlify
|
|
@@ -139,12 +139,16 @@ server.prototype.fetch = async function (request, env) {
|
|
|
139
139
|
if (env?.upgrade(request)) return;
|
|
140
140
|
Object.assign(globalThis.env, env); // Extend env with the passed vars
|
|
141
141
|
|
|
142
|
+
let ctx, res, error;
|
|
142
143
|
try {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
} catch (
|
|
146
|
-
|
|
144
|
+
ctx = await createWinterContext(request, this.opts, this);
|
|
145
|
+
res = await handleRequest(this.handlers, ctx);
|
|
146
|
+
} catch (err) {
|
|
147
|
+
error = err;
|
|
148
|
+
res = new Response(error.message, { status: error.status || 500 });
|
|
147
149
|
}
|
|
150
|
+
ctx?.unstableFire("finish", { ...ctx, error, res, end: performance.now() });
|
|
151
|
+
return res;
|
|
148
152
|
};
|
|
149
153
|
|
|
150
154
|
// #region HTTP methods
|
|
@@ -240,7 +244,7 @@ server.prototype.test = function () {
|
|
|
240
244
|
} else {
|
|
241
245
|
body = await res.text();
|
|
242
246
|
}
|
|
243
|
-
return { status: res.status, headers, body
|
|
247
|
+
return { status: res.status, headers, body };
|
|
244
248
|
};
|
|
245
249
|
return {
|
|
246
250
|
app: this,
|
package/src/index.test.js
CHANGED
|
@@ -45,13 +45,13 @@ describe("return different types", () => {
|
|
|
45
45
|
.test();
|
|
46
46
|
|
|
47
47
|
it("can get the plain text", async () => {
|
|
48
|
-
const {
|
|
49
|
-
expect(
|
|
48
|
+
const { body } = await api.get("/text");
|
|
49
|
+
expect(body).toBe("Hello world");
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
it("can get the array", async () => {
|
|
53
|
-
const {
|
|
54
|
-
expect(
|
|
53
|
+
const { body } = await api.get("/array");
|
|
54
|
+
expect(body).toEqual(["Hello world"]);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
it("can get the object", async () => {
|
|
@@ -71,19 +71,17 @@ describe("simple post works", () => {
|
|
|
71
71
|
.post("/", (ctx) => status(201).send(ctx.body))
|
|
72
72
|
.test();
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const { data, status, headers } = await api.post("/", "New Data");
|
|
74
|
+
it("can post new data", async () => {
|
|
75
|
+
const { body, status, headers } = await api.post("/", "New Data");
|
|
77
76
|
expect(status).toBe(201);
|
|
78
|
-
expect(
|
|
77
|
+
expect(body).toBe("New Data");
|
|
79
78
|
expect(headers["content-type"]).toBe("text/plain; charset=utf-8");
|
|
80
79
|
});
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const { data, status, headers } = await api.post("/", { hello: "world" });
|
|
81
|
+
it("will return JSON", async () => {
|
|
82
|
+
const { body, status, headers } = await api.post("/", { hello: "world" });
|
|
85
83
|
expect(status).toBe(201);
|
|
86
|
-
expect(
|
|
84
|
+
expect(body).toEqual({ hello: "world" });
|
|
87
85
|
expect(headers["content-type"]).toBe("application/json; charset=utf-8");
|
|
88
86
|
});
|
|
89
87
|
});
|
package/src/middle/assets.js
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import server from "../";
|
|
2
|
+
|
|
3
|
+
describe("static assets", () => {
|
|
4
|
+
it("can serve a simple file", async () => {
|
|
5
|
+
const app = server({ public: "./src/middle/" }).test();
|
|
6
|
+
const { body, headers } = await app.get("/assets.test.js");
|
|
7
|
+
expect(body).toInclude("describe");
|
|
8
|
+
expect(headers["content-type"]).toBe("text/javascript");
|
|
9
|
+
});
|
|
10
|
+
});
|
package/src/router.test.js
CHANGED
|
@@ -20,27 +20,27 @@ describe("can route properly", () => {
|
|
|
20
20
|
|
|
21
21
|
it("can get fallback when nothing matches", async () => {
|
|
22
22
|
const res = await api.get("/");
|
|
23
|
-
expect(res.
|
|
23
|
+
expect(res.body).toBe("Fallback");
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
it("can get the base get", async () => {
|
|
27
27
|
const res = await api.get("/hello");
|
|
28
|
-
expect(res.
|
|
28
|
+
expect(res.body).toBe("Hello /hello");
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
it("can get the nested get", async () => {
|
|
32
32
|
const res = await api.get("/api/hello");
|
|
33
|
-
expect(res.
|
|
33
|
+
expect(res.body).toBe("Hello /api/hello");
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("can post to the base get", async () => {
|
|
37
37
|
const res = await api.post("/hello");
|
|
38
|
-
expect(res.
|
|
38
|
+
expect(res.body).toBe("Hello /hello");
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
it("can post to the nested get", async () => {
|
|
42
42
|
const res = await api.post("/api/hello");
|
|
43
|
-
expect(res.
|
|
43
|
+
expect(res.body).toBe("Hello /api/hello");
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
it("no status reuse", async () => {
|
package/src/session.test.js
CHANGED
|
@@ -20,22 +20,22 @@ describe("session", () => {
|
|
|
20
20
|
await store.set("session:REqA2l022l8Q0tuIRtqLOPUy", { a: 0 });
|
|
21
21
|
|
|
22
22
|
const res = await api.get("/hello", options);
|
|
23
|
-
expect(res.
|
|
23
|
+
expect(res.body).toBe("Hello 0");
|
|
24
24
|
|
|
25
25
|
const res2 = await api.post("/hello", {}, options);
|
|
26
|
-
expect(res2.
|
|
26
|
+
expect(res2.body).toBe("Bye 1");
|
|
27
27
|
|
|
28
28
|
const res3 = await api.get("/hello", options);
|
|
29
|
-
expect(res3.
|
|
29
|
+
expect(res3.body).toBe("Hello 1");
|
|
30
30
|
expect(await store.get("session:REqA2l022l8Q0tuIRtqLOPUy")).toEqual({
|
|
31
31
|
a: 1,
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
const res4 = await api.post("/hello", {}, options);
|
|
35
|
-
expect(res4.
|
|
35
|
+
expect(res4.body).toBe("Bye 2");
|
|
36
36
|
|
|
37
37
|
const res5 = await api.get("/hello", options);
|
|
38
|
-
expect(res5.
|
|
38
|
+
expect(res5.body).toBe("Hello 2");
|
|
39
39
|
expect(await store.get("session:REqA2l022l8Q0tuIRtqLOPUy")).toEqual({
|
|
40
40
|
a: 2,
|
|
41
41
|
});
|
|
@@ -54,12 +54,12 @@ describe("missing store", () => {
|
|
|
54
54
|
it("cannot read a session without a store", async () => {
|
|
55
55
|
const res = await api.get("/read");
|
|
56
56
|
expect(res.status).toBe(500);
|
|
57
|
-
expect(res.
|
|
57
|
+
expect(res.body).toBe("You need a 'store' to read 'ctx.session.a'");
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
it("cannot write a session without a store", async () => {
|
|
61
61
|
const res = await api.get("/write");
|
|
62
62
|
expect(res.status).toBe(500);
|
|
63
|
-
expect(res.
|
|
63
|
+
expect(res.body).toBe("You need a 'store' to write 'ctx.session.a'");
|
|
64
64
|
});
|
|
65
65
|
});
|
package/src/test/toSucceed.js
CHANGED
|
@@ -10,17 +10,17 @@ const spaceOrEnter = (msg) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
export default function toSucceed(request, message) {
|
|
13
|
-
const pass = request.status >= 200 && request.status <
|
|
13
|
+
const pass = request.status >= 200 && request.status < 400;
|
|
14
14
|
|
|
15
|
-
if (message && JSON.stringify(request.
|
|
15
|
+
if (message && JSON.stringify(request.body) !== JSON.stringify(message)) {
|
|
16
16
|
if (pass) {
|
|
17
17
|
return {
|
|
18
18
|
message: () =>
|
|
19
19
|
`${reset}Expected body:${spaceOrEnter(
|
|
20
|
-
message
|
|
20
|
+
message,
|
|
21
21
|
)}${this.utils.printExpected(message)}\nReceived body:${spaceOrEnter(
|
|
22
|
-
request.
|
|
23
|
-
)}${this.utils.printReceived(request.
|
|
22
|
+
request.body,
|
|
23
|
+
)}${this.utils.printReceived(request.body)}`,
|
|
24
24
|
pass,
|
|
25
25
|
};
|
|
26
26
|
}
|
|
@@ -28,10 +28,10 @@ export default function toSucceed(request, message) {
|
|
|
28
28
|
return {
|
|
29
29
|
message: () =>
|
|
30
30
|
`${reset}Expected error:${spaceOrEnter(
|
|
31
|
-
message
|
|
31
|
+
message,
|
|
32
32
|
)}${this.utils.printExpected(message)}\nReceived error:${spaceOrEnter(
|
|
33
|
-
request.
|
|
34
|
-
)}${this.utils.printReceived(request.
|
|
33
|
+
request.body,
|
|
34
|
+
)}${this.utils.printReceived(request.body)}`,
|
|
35
35
|
pass: !pass,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
@@ -40,9 +40,9 @@ export default function toSucceed(request, message) {
|
|
|
40
40
|
return {
|
|
41
41
|
message: () =>
|
|
42
42
|
`${reset}Expected ${this.utils.printExpected(
|
|
43
|
-
request.status
|
|
43
|
+
request.status,
|
|
44
44
|
)} to be an error code, received body:\n${this.utils.printExpected(
|
|
45
|
-
request.
|
|
45
|
+
request.body,
|
|
46
46
|
)}`,
|
|
47
47
|
pass: true,
|
|
48
48
|
};
|
|
@@ -51,11 +51,11 @@ export default function toSucceed(request, message) {
|
|
|
51
51
|
return {
|
|
52
52
|
message: () =>
|
|
53
53
|
`${reset}Expected ${this.utils.printReceived(
|
|
54
|
-
request.status
|
|
54
|
+
request.status,
|
|
55
55
|
)} to succeed, received body:\n${this.utils.printReceived(
|
|
56
|
-
request.
|
|
56
|
+
request.body,
|
|
57
57
|
null,
|
|
58
|
-
2
|
|
58
|
+
2,
|
|
59
59
|
)}`,
|
|
60
60
|
pass: false,
|
|
61
61
|
};
|
package/src/url.test.js
CHANGED
|
@@ -7,8 +7,8 @@ describe("can match the url", () => {
|
|
|
7
7
|
.get("/*", (ctx) => ctx.url.params)
|
|
8
8
|
.test();
|
|
9
9
|
|
|
10
|
-
const {
|
|
11
|
-
expect(
|
|
10
|
+
const { body, headers } = await api.get("/hello");
|
|
11
|
+
expect(body).toEqual({ id: "hello" });
|
|
12
12
|
expect(headers["content-type"]).toEqual("application/json; charset=utf-8");
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -19,8 +19,8 @@ describe("can match the url", () => {
|
|
|
19
19
|
.get("/*", (ctx) => ctx.url.params)
|
|
20
20
|
.test();
|
|
21
21
|
|
|
22
|
-
const {
|
|
23
|
-
expect(
|
|
22
|
+
const { body, headers, ...rest } = await api.get("/hello");
|
|
23
|
+
expect(body).toEqual({ id: "hello" });
|
|
24
24
|
expect(headers["content-type"]).toEqual("application/json; charset=utf-8");
|
|
25
25
|
});
|
|
26
26
|
});
|