Skip to content

Commit b962ab1

Browse files
authored
Refactoring unit test(middleware.spec.ts) (line#744)
## PR Context This PR is that we talked about in [line#699](line#699 (comment)) about improving Convention in Unit test. :) For time reasons, the unit test refactoring work will be carried out by file. If you see the refactoring of the test codes positively, please leave feedback and if not, you can close PR. ## Need Feedbacks ### 1. History with timeout function ```ts await http().post(`/webhook`, { events: [webhook], destination: DESTINATION, }); const req = getRecentReq(); deepEqual(req.body.destination, DESTINATION); deepEqual(req.body.events, [webhook]); }).timeout(6000); // ⛳️ ``` May I know why the code used `timeout` for that Unit test? :) Even if I remove timeout, all tests pass. If can I remove timeout, that test can move inside of the testCases. 😀
1 parent 8cffd97 commit b962ab1

File tree

1 file changed

+169
-144
lines changed

1 file changed

+169
-144
lines changed

test/middleware.spec.ts

Lines changed: 169 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ const m = middleware({ channelSecret: "test_channel_secret" });
1414
const getRecentReq = (): { body: Types.WebhookRequestBody } =>
1515
JSON.parse(readFileSync(join(__dirname, "helpers/request.json")).toString());
1616

17-
describe("middleware", () => {
17+
const DESTINATION = "Uaaaabbbbccccddddeeeeffff";
18+
19+
describe("middleware test", () => {
1820
const webhook: Types.MessageEvent = {
1921
message: {
2022
id: "test_event_message_id",
@@ -35,6 +37,7 @@ describe("middleware", () => {
3537
mode: "active",
3638
type: "message",
3739
};
40+
3841
const webhookSignature = {
3942
"X-Line-Signature": "eRdWYcVCzZV3MVZ3M9/rHJCl/a3oSbsRb04cLovpVwM=",
4043
};
@@ -48,155 +51,177 @@ describe("middleware", () => {
4851
before(() => listen(TEST_PORT, m));
4952
after(() => close());
5053

51-
it("succeed", async () => {
52-
await http().post(`/webhook`, {
53-
events: [webhook],
54-
destination: "Uaaaabbbbccccddddeeeeffff",
55-
});
56-
const req = getRecentReq();
57-
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
58-
deepEqual(req.body.events, [webhook]);
59-
}).timeout(6000);
60-
61-
it("succeed with pre-parsed string", async () => {
62-
await http().post(`/mid-text`, {
63-
events: [webhook],
64-
destination: "Uaaaabbbbccccddddeeeeffff",
65-
});
66-
const req = getRecentReq();
67-
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
68-
deepEqual(req.body.events, [webhook]);
69-
});
70-
71-
it("succeed with pre-parsed buffer", async () => {
72-
await http().post(`/mid-buffer`, {
73-
events: [webhook],
74-
destination: "Uaaaabbbbccccddddeeeeffff",
75-
});
76-
const req = getRecentReq();
77-
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
78-
deepEqual(req.body.events, [webhook]);
79-
});
80-
81-
it("succeed with pre-parsed buffer in rawBody", async () => {
82-
await http().post(`/mid-rawbody`, {
83-
events: [webhook],
84-
destination: "Uaaaabbbbccccddddeeeeffff",
85-
});
86-
const req = getRecentReq();
87-
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
88-
deepEqual(req.body.events, [webhook]);
89-
});
90-
91-
it("fails on parsing raw as it's a not valid request and should be catched", async () => {
92-
try {
93-
await http({
94-
"X-Line-Signature": "wqJD7WAIZhWcXThMCf8jZnwG3Hmn7EF36plkQGkj48w=",
95-
"Content-Encoding": 1,
96-
}).post(`/webhook`, {
97-
events: [webhook],
98-
destination: "Uaaaabbbbccccddddeeeeffff",
99-
});
100-
ok(false);
101-
} catch (err) {
102-
if (err instanceof HTTPError) {
103-
equal(err.statusCode, 401);
104-
} else {
105-
throw err;
106-
}
107-
}
108-
});
109-
110-
it("fails on pre-parsed json", async () => {
111-
try {
112-
await http().post(`/mid-json`, {
113-
events: [webhook],
114-
destination: "Uaaaabbbbccccddddeeeeffff",
54+
describe("Succeeds on parsing valid request", () => {
55+
const testCases = [
56+
{
57+
describe: "standard webhook request",
58+
path: `/webhook`,
59+
},
60+
61+
{
62+
describe: "pre-parsed string",
63+
path: `/mid-text`,
64+
},
65+
66+
{
67+
describe: "pre-parsed buffer",
68+
path: `/mid-buffer`,
69+
},
70+
71+
{
72+
describe: "pre-parsed buffer in rawBody",
73+
path: `/mid-rawbody`,
74+
},
75+
];
76+
77+
testCases.forEach(({ describe, path }) => {
78+
it(describe, async () => {
79+
await http().post(path, {
80+
events: [webhook],
81+
destination: DESTINATION,
82+
});
83+
84+
const req = getRecentReq();
85+
deepEqual(req.body.destination, DESTINATION);
86+
deepEqual(req.body.events, [webhook]);
11587
});
116-
ok(false);
117-
} catch (err) {
118-
if (err instanceof HTTPError) {
119-
equal(err.statusCode, 401);
120-
} else {
121-
throw err;
122-
}
123-
}
124-
});
125-
it("fails on construct with no channelSecret", () => {
126-
try {
127-
middleware({ channelSecret: null });
128-
ok(false);
129-
} catch (err) {
130-
equal(err.message, "no channel secret");
131-
}
88+
});
13289
});
13390

134-
it("fails on wrong signature", async () => {
135-
try {
136-
await http({
137-
"X-Line-Signature": "WqJD7WAIZhWcXThMCf8jZnwG3Hmn7EF36plkQGkj48w=",
138-
}).post(`/webhook`, {
139-
events: [webhook],
140-
destination: "Uaaaabbbbccccddddeeeeffff",
141-
});
142-
ok(false);
143-
} catch (err) {
144-
if (err instanceof HTTPError) {
145-
equal(err.statusCode, 401);
146-
} else {
147-
throw err;
91+
describe("Fails on parsing invalid request", () => {
92+
describe("invalid data request(test status)", () => {
93+
interface InvalidDataRequest {
94+
description: string;
95+
setup: () => Promise<any>;
96+
expectedError: any;
97+
expectedStatus: number;
14898
}
149-
}
150-
});
15199

152-
it("fails on wrong signature (length)", async () => {
153-
try {
154-
await http({
155-
"X-Line-Signature": "WqJD7WAIZ6plkQGkj48w=",
156-
}).post(`/webhook`, {
157-
events: [webhook],
158-
destination: "Uaaaabbbbccccddddeeeeffff",
159-
});
160-
ok(false);
161-
} catch (err) {
162-
if (err instanceof HTTPError) {
163-
equal(err.statusCode, 401);
164-
} else {
165-
throw err;
166-
}
167-
}
168-
});
169-
170-
it("fails on invalid JSON", async () => {
171-
try {
172-
await http({
173-
"X-Line-Signature": "Z8YlPpm0lQOqPipiCHVbiuwIDIzRzD7w5hvHgmwEuEs=",
174-
}).post(`/webhook`, "i am not jason", {
175-
headers: { "Content-Type": "text/plain" },
176-
});
177-
ok(false);
178-
} catch (err) {
179-
if (err instanceof HTTPError) {
180-
equal(err.statusCode, 400);
181-
} else {
182-
throw err;
183-
}
184-
}
185-
});
100+
const testCases: InvalidDataRequest[] = [
101+
{
102+
description:
103+
"parsing raw as it's not a valid request and should be catched",
104+
setup: async () => {
105+
return http({
106+
"X-Line-Signature":
107+
"wqJD7WAIZhWcXThMCf8jZnwG3Hmn7EF36plkQGkj48w=",
108+
"Content-Encoding": 1,
109+
}).post(`/webhook`, {
110+
events: [webhook],
111+
destination: DESTINATION,
112+
});
113+
},
114+
expectedError: HTTPError,
115+
expectedStatus: 401,
116+
},
117+
118+
{
119+
description: "pre-parsed json",
120+
setup: async () => {
121+
return http().post(`/mid-json`, {
122+
events: [webhook],
123+
destination: DESTINATION,
124+
});
125+
},
126+
expectedError: HTTPError,
127+
expectedStatus: 401,
128+
},
129+
130+
{
131+
description: "wrong signature",
132+
setup: async () => {
133+
return await http({
134+
"X-Line-Signature":
135+
"WqJD7WAIZhWcXThMCf8jZnwG3Hmn7EF36plkQGkj48w=",
136+
}).post(`/webhook`, {
137+
events: [webhook],
138+
destination: DESTINATION,
139+
});
140+
},
141+
expectedError: HTTPError,
142+
expectedStatus: 401,
143+
},
144+
145+
{
146+
description: "wrong signature (length)",
147+
setup: async () => {
148+
return http({
149+
"X-Line-Signature": "WqJD7WAIZ6plkQGkj48w=",
150+
}).post(`/webhook`, {
151+
events: [webhook],
152+
destination: DESTINATION,
153+
});
154+
},
155+
expectedError: HTTPError,
156+
expectedStatus: 401,
157+
},
158+
159+
{
160+
description: "invalid JSON",
161+
setup: async () => {
162+
return http({
163+
"X-Line-Signature":
164+
"Z8YlPpm0lQOqPipiCHVbiuwIDIzRzD7w5hvHgmwEuEs=",
165+
}).post(`/webhook`, "i am not jason", {
166+
headers: { "Content-Type": "text/plain" },
167+
});
168+
},
169+
expectedError: HTTPError,
170+
expectedStatus: 400,
171+
},
172+
173+
{
174+
description: "empty signature",
175+
setup: async () => {
176+
return http({}).post(`/webhook`, {
177+
events: [webhook],
178+
destination: DESTINATION,
179+
});
180+
},
181+
expectedError: HTTPError,
182+
expectedStatus: 401,
183+
},
184+
];
185+
186+
testCases.forEach(
187+
({ description, setup, expectedError, expectedStatus }) => {
188+
it(description, async () => {
189+
try {
190+
await setup();
191+
ok(false);
192+
} catch (err) {
193+
if (err instanceof expectedError) {
194+
equal(err.statusCode, expectedStatus);
195+
} else {
196+
throw err;
197+
}
198+
}
199+
});
200+
},
201+
);
202+
});
186203

187-
it("fails on empty signature", async () => {
188-
try {
189-
await http({}).post(`/webhook`, {
190-
events: [webhook],
191-
destination: "Uaaaabbbbccccddddeeeeffff",
204+
describe("Invalid data request(test message)", () => {
205+
const testCases = [
206+
{
207+
description: "construct with no channelSecret",
208+
setup: () => {
209+
middleware({ channelSecret: null });
210+
},
211+
expectedMessage: "no channel secret",
212+
},
213+
];
214+
215+
testCases.forEach(({ description, setup, expectedMessage }) => {
216+
it(description, () => {
217+
try {
218+
setup();
219+
ok(false);
220+
} catch (err) {
221+
equal(err.message, expectedMessage);
222+
}
223+
});
192224
});
193-
ok(false);
194-
} catch (err) {
195-
if (err instanceof HTTPError) {
196-
equal(err.statusCode, 401);
197-
} else {
198-
throw err;
199-
}
200-
}
225+
});
201226
});
202227
});

0 commit comments

Comments
 (0)