@server/next 0.21.1 → 0.21.3
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/auth.js +2 -2
- package/src/auth/index.js +2 -2
- package/src/auth/index.test.js +4 -2
- package/src/auth/logout.js +1 -1
- package/src/auth/providers/email.js +1 -1
- package/src/helpers/jsx.js +15 -4
- package/src/helpers/jsx.test.jsx +48 -0
- package/src/index.js +10 -10
- package/src/index.test.js +10 -12
- package/src/middle/assets.js +1 -1
- package/src/middle/assets.test.js +10 -0
- package/src/middle/index.js +3 -2
- 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.3",
|
|
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/auth/auth.js
CHANGED
|
@@ -48,8 +48,8 @@ export default async function auth(ctx) {
|
|
|
48
48
|
|
|
49
49
|
const auth = await options.session.get(sessionId);
|
|
50
50
|
// Mmh, which one to do...
|
|
51
|
-
if (!auth) throw ServerError.AUTH_NO_SESSION();
|
|
52
|
-
|
|
51
|
+
// if (!auth) throw ServerError.AUTH_NO_SESSION();
|
|
52
|
+
if (!auth) return; // SESSION ALREADY INVALID; no auth
|
|
53
53
|
|
|
54
54
|
if (!auth.provider) throw ServerError.AUTH_NO_PROVIDER();
|
|
55
55
|
if (!options.provider.includes(auth.provider)) {
|
package/src/auth/index.js
CHANGED
|
@@ -12,16 +12,16 @@ const load = async (ctx) => {
|
|
|
12
12
|
|
|
13
13
|
const middle = async (ctx) => {
|
|
14
14
|
if (ctx.options.auth) {
|
|
15
|
-
ctx.app.post("/auth/logout", logout);
|
|
16
|
-
|
|
17
15
|
if (ctx.options.auth.provider.includes("github")) {
|
|
18
16
|
if (!env.GITHUB_ID) throw new Error("GITHUB_ID not defined");
|
|
19
17
|
if (!env.GITHUB_SECRET) throw new Error("GITHUB_SECRET not defined");
|
|
18
|
+
ctx.app.get("/auth/logout", logout);
|
|
20
19
|
ctx.app.get("/auth/login/github", providers.github.login);
|
|
21
20
|
ctx.app.get("/auth/callback/github", providers.github.callback);
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
if (ctx.options.auth.provider.includes("email")) {
|
|
24
|
+
ctx.app.post("/auth/logout", logout);
|
|
25
25
|
ctx.app.post("/auth/register/email", providers.email.register);
|
|
26
26
|
ctx.app.post("/auth/login/email", providers.email.login);
|
|
27
27
|
ctx.app.put("/auth/password/email", providers.email.password);
|
package/src/auth/index.test.js
CHANGED
|
@@ -61,7 +61,8 @@ describe("token", () => {
|
|
|
61
61
|
it("cannot get the session", async () => {
|
|
62
62
|
const authorization = "Bearer REqA2l022l8Q0tuI";
|
|
63
63
|
const req = await api.get("/", { headers: { authorization } });
|
|
64
|
-
expect(req).
|
|
64
|
+
expect(req.status).toBe(404);
|
|
65
|
+
// expect(req).not.toSucceed("Invalid session");
|
|
65
66
|
});
|
|
66
67
|
|
|
67
68
|
it("cannot get the user", async () => {
|
|
@@ -112,7 +113,8 @@ describe("cookie", () => {
|
|
|
112
113
|
it("can get the proper session", async () => {
|
|
113
114
|
const cookie = "authentication=REqA2l022l8Q0tuI";
|
|
114
115
|
const req = await api.get("/", { headers: { cookie } });
|
|
115
|
-
expect(req).
|
|
116
|
+
expect(req.status).toBe(404);
|
|
117
|
+
// expect(req).not.toSucceed("Invalid session");
|
|
116
118
|
});
|
|
117
119
|
|
|
118
120
|
it("can get the proper session", async () => {
|
package/src/auth/logout.js
CHANGED
|
@@ -7,7 +7,7 @@ export default async function logout(ctx) {
|
|
|
7
7
|
if (type === "token") {
|
|
8
8
|
return { token: null };
|
|
9
9
|
} else if (type === "cookie") {
|
|
10
|
-
return cookies({ authorization: null }).
|
|
10
|
+
return cookies({ authorization: null }).redirect("/");
|
|
11
11
|
} else if (type === "jwt") {
|
|
12
12
|
throw new Error("JWT auth not supported yet");
|
|
13
13
|
} else if (type === "key") {
|
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
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
parseHeaders,
|
|
12
12
|
} from "./helpers/index.js";
|
|
13
13
|
|
|
14
|
-
import
|
|
14
|
+
import { assets, auth } from "./middle/index.js";
|
|
15
15
|
|
|
16
16
|
// Export the reply helpers
|
|
17
17
|
export * from "./reply.js";
|
|
@@ -29,7 +29,7 @@ export default function server(options = {}) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Keep a copy of the options in the instance
|
|
32
|
-
this.opts = options;
|
|
32
|
+
this.opts = config(options);
|
|
33
33
|
this.platform = getMachine();
|
|
34
34
|
|
|
35
35
|
// TODO: find a way to remove this hack
|
|
@@ -74,7 +74,10 @@ export default function server(options = {}) {
|
|
|
74
74
|
this.node();
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
this.use(
|
|
77
|
+
this.use(assets);
|
|
78
|
+
if (this.opts.auth) {
|
|
79
|
+
this.use(auth({ options: this.opts, app: this }));
|
|
80
|
+
}
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
server.prototype.self = function () {
|
|
@@ -93,12 +96,11 @@ server.prototype.self = function () {
|
|
|
93
96
|
// #region Runtimes
|
|
94
97
|
// Node.js
|
|
95
98
|
server.prototype.node = async function () {
|
|
96
|
-
const options = config(this.opts);
|
|
97
99
|
const http = await import("http");
|
|
98
100
|
http
|
|
99
101
|
.createServer(async (request, response) => {
|
|
100
102
|
try {
|
|
101
|
-
const ctx = await createNodeContext(request,
|
|
103
|
+
const ctx = await createNodeContext(request, this.opts, this);
|
|
102
104
|
const out = await handleRequest(this.handlers, ctx);
|
|
103
105
|
|
|
104
106
|
response.writeHead(out.status || 200, parseHeaders(out.headers));
|
|
@@ -125,8 +127,7 @@ server.prototype.callback = async function (request, context) {
|
|
|
125
127
|
if (typeof Netlify === "undefined") {
|
|
126
128
|
throw new Error("Netlify doesn't exist");
|
|
127
129
|
}
|
|
128
|
-
const
|
|
129
|
-
const ctx = await createWinterContext(request, options, this);
|
|
130
|
+
const ctx = await createWinterContext(request, this.opts, this);
|
|
130
131
|
return await handleRequest(this.handlers, ctx);
|
|
131
132
|
} catch (error) {
|
|
132
133
|
return new Response(error.message, { status: error.status || 500 });
|
|
@@ -139,8 +140,7 @@ server.prototype.fetch = async function (request, env) {
|
|
|
139
140
|
Object.assign(globalThis.env, env); // Extend env with the passed vars
|
|
140
141
|
|
|
141
142
|
try {
|
|
142
|
-
const
|
|
143
|
-
const ctx = await createWinterContext(request, options, this);
|
|
143
|
+
const ctx = await createWinterContext(request, this.opts, this);
|
|
144
144
|
return await handleRequest(this.handlers, ctx);
|
|
145
145
|
} catch (error) {
|
|
146
146
|
return new Response(error.message, { status: error.status || 500 });
|
|
@@ -240,7 +240,7 @@ server.prototype.test = function () {
|
|
|
240
240
|
} else {
|
|
241
241
|
body = await res.text();
|
|
242
242
|
}
|
|
243
|
-
return { status: res.status, headers, body
|
|
243
|
+
return { status: res.status, headers, body };
|
|
244
244
|
};
|
|
245
245
|
return {
|
|
246
246
|
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/middle/index.js
CHANGED
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
|
});
|