-
Notifications
You must be signed in to change notification settings - Fork 230
/
Copy pathbasic-tests.test.js
151 lines (128 loc) · 4.17 KB
/
basic-tests.test.js
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
const request = require("supertest");
const sinon = require("sinon");
const nock = require("nock");
const { initializeWebServer, stopWebServer } = require("../api-under-test");
const mailer = require("../libraries/mailer");
const OrderRepository = require("../data-access/order-repository");
let expressApp;
let sinonSandbox;
beforeAll(async (done) => {
// ️️️✅ Best Practice: Place the backend under test within the same process
expressApp = await initializeWebServer();
// ️️️✅ Best Practice: use a sandbox for test doubles for proper clean-up between tests
sinonSandbox = sinon.createSandbox();
// ️️️✅ Best Practice: Ensure that this component is isolated by preventing unknown calls
nock.disableNetConnect();
nock.enableNetConnect("127.0.0.1");
done();
});
afterAll(async (done) => {
// ️️️✅ Best Practice: Clean-up resources after each run
await stopWebServer();
done();
});
beforeEach(() => {
nock.cleanAll();
nock("http://localhost/user/").get(`/1`).reply(200, {
id: 1,
name: "John",
});
if (sinonSandbox) {
sinonSandbox.restore();
}
});
// ️️️✅ Best Practice: Structure tests
describe("/api", () => {
describe("POST /orders", () => {
test.todo("When adding order without product, return 400");
test("When adding an order without specifying product, stop and return 400", async () => {
//Arrange
nock("http://localhost/user/").get(`/1`).reply(200, {
id: 1,
name: "John",
});
const orderToAdd = {
userId: 1,
mode: "draft",
};
//Act
const orderAddResult = await request(expressApp).post("/order").send(orderToAdd);
//Assert
expect(orderAddResult.status).toBe(400);
});
test("When adding a new valid order , Then should get back 200 response", async () => {
//Arrange
const orderToAdd = {
userId: 1,
productId: 2,
mode: "approved",
};
nock("http://localhost/user/").get(`/1`).reply(200, {
id: 1,
name: "John",
});
//Act
const receivedAPIResponse = await request(expressApp).post("/order").send(orderToAdd);
//Assert
const { status, body } = receivedAPIResponse;
expect({
status,
body,
}).toMatchObject({
status: 200,
body: {
mode: "approved",
},
});
});
test("When order failed, send mail to admin", async () => {
//Arrange
process.env.SEND_MAILS = "true";
nock("http://localhost/user/").get(`/1`).reply(200, {
id: 1,
name: "John",
});
// ️️️✅ Best Practice: Intercept requests for 3rd party services to eliminate undesired side effects like emails or SMS
// ️️️✅ Best Practice: Specify the body when you need to make sure you call the 3rd party service as expected
const scope = nock("https://mailer.com")
.post("/send", {
subject: /^(?!\s*$).+/,
body: /^(?!\s*$).+/,
recipientAddress: /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/,
})
.reply(202);
sinonSandbox.stub(OrderRepository.prototype, "addOrder").throws(new Error("Unknown error"));
const orderToAdd = {
userId: 1,
productId: 2,
mode: "approved",
};
//Act
await request(expressApp).post("/order").send(orderToAdd);
//Assert
// ️️️✅ Best Practice: Assert that the app called the mailer service appropriately
expect(scope.isDone()).toBe(true);
});
test("When the user does not exist, return http 404", async () => {
//Arrange
nock("http://localhost/user/").get(`/7`).reply(404, {
message: "User does not exist",
code: "nonExisting",
});
const orderToAdd = {
userId: 7,
productId: 2,
mode: "draft",
};
//Act
const orderAddResult = await request(expressApp).post("/order").send(orderToAdd);
//Assert
expect(orderAddResult.status).toBe(404);
});
});
describe("GET /orders", () => {
test("When filtering for canceled orders, should show only relevant items", () => {
expect(true).toBe(true);
});
});
});