From 4fba51bcc89e22670d26b977bd9d894d389d88ad Mon Sep 17 00:00:00 2001 From: Ken Huang Date: Wed, 13 Mar 2024 09:45:52 +1100 Subject: [PATCH] chore: ken's tests --- src/entry-points/sensors-api.js | 3 ++ test/mission-basic-response-bay.test.js | 40 +++++++++++++++++- test/mission-database-bay.test.js | 56 +++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 5 deletions(-) diff --git a/src/entry-points/sensors-api.js b/src/entry-points/sensors-api.js index e442f4a..5d692f4 100644 --- a/src/entry-points/sensors-api.js +++ b/src/entry-points/sensors-api.js @@ -69,6 +69,9 @@ function defineAllRoutes(expressApp) { router.get('/sensor-events/:id', async (req, res, next) => { const sensorsService = new SensorsService(); const sensorToReturn = await sensorsService.getSensorById(req.params.id); + if(!sensorToReturn) { + return res.status(404).end(); + } res.json(sensorToReturn); }); diff --git a/test/mission-basic-response-bay.test.js b/test/mission-basic-response-bay.test.js index 6b5ed64..56ebe59 100644 --- a/test/mission-basic-response-bay.test.js +++ b/test/mission-basic-response-bay.test.js @@ -12,6 +12,7 @@ const { } = require('../src/entry-points/sensors-api'); const { getShortUnique, getSensorEvent } = require('./test-helper'); const sinon = require('sinon'); +const SensorsService = require('../src/domain/sensors-service'); let expressApp; @@ -34,6 +35,7 @@ afterEach(() => { }); describe('Sensors test', () => { + // ✅ TASK: Run the testing and ensure the the next simplistic test pass test('Just checking that testing works on your machine', () => { expect('Me boosting my testing knowledge in the workshop').toBeTruthy(); @@ -51,7 +53,7 @@ describe('Sensors test', () => { color: 'Green', weight: 80, status: 'active', - category: 'Kids-Room', + category: undefined, // 💡 TIP: Consider explicitly specify that category is undefined by assigning 'undefined' }; @@ -59,23 +61,33 @@ describe('Sensors test', () => { // 💡 TIP: use any http client lib like Axios OR supertest // 💡 TIP: This is how it is done with Supertest -> await request(expressApp).post("/sensor-events").send(eventToAdd); + const receivedResponse = await request(expressApp).post("/sensor-events").send(eventToAdd); // Assert // 💡 TIP: Check that the received response is indeed as stated in the test name // 💡 TIP: Use this syntax for example: expect(receivedResponse.status).toBe(...); + expect(receivedResponse.status).toBe(400); }); // ✅ TASK: Test that when a new valid event is posted to /sensor-events route, we get back a valid response // 💡 TIP: Consider checking both the HTTP status and the body test('When inserting a valid event, should get successful response', async () => { // Arrange + const eventToAdd = { + temperature: 20, + color: 'Green', + weight: 80, + status: 'active', + category: 'category', + }; // Act // 💡 TIP: use any http client lib like Axios OR supertest // 💡 TIP: This is how it is done with Supertest -> await request(expressApp).post("/sensor-events").send(eventToAdd); + const receivedResponse = await request(expressApp).post("/sensor-events").send(eventToAdd); // Assert // 💡 TIP: You may check the body and the status all together with the following syntax: - // expect(receivedResponse).toMatchObject({status: 200, body: {...}}); + expect(receivedResponse).toMatchObject({status: 200, body: {...eventToAdd}}); }); // ✅ TASK: Test that when a new valid event is posted to /sensor-events route, it's indeed retrievable from the DB @@ -84,6 +96,20 @@ describe('Sensors test', () => { // ✅ Keep the tests very short and readable, strive not to pass 7 statements per test // 💡 TIP: If it gets too long, extract obvious parts into an external helper + test('When a new valid event is posted to /sensor-events route, it\'s indeed retrievable from the DB', async () => { + const eventToAdd = { + temperature: 20, + color: 'Green', + weight: 80, + status: 'active', + category: 'category', + }; + const receivedResponse = await request(expressApp).post("/sensor-events").send(eventToAdd); + expect(receivedResponse).toMatchObject({status: 200, body: {...eventToAdd}}); + const getResponse =await request(expressApp).get(`/sensor-events/${receivedResponse.body.id}`); + expect(getResponse).toMatchObject({ status: 200, body: {...eventToAdd} }); + }); + // ✅🚀 TASK: Code the following test below test('When an internal unknown error occurs during request, Then get back 500 error', async () => { @@ -93,8 +119,18 @@ describe('Sensors test', () => { // 💡 TIP: Use the library sinon to alter the behaviour of existing function and make it throw error // https://sinonjs.org/releases/latest/stubs/ // 💡 TIP: Here is the syntax: sinon.stub(someClass.prototype, 'methodName').rejects(new Error("Error explanation")); + const eventToAdd = { + temperature: 20, + color: 'Green', + weight: 80, + status: 'active', + category: 'category', + }; + sinon.stub(SensorsService.prototype, 'addEvent').rejects(new Error("Error explanation")); + const receivedResponse = await request(expressApp).post("/sensor-events").send(eventToAdd); // Act // Assert + expect(receivedResponse.status).toBe(500); }); // ✅ Ensure that the webserver is closed when all the tests are completed diff --git a/test/mission-database-bay.test.js b/test/mission-database-bay.test.js index e68eef2..caf02ed 100644 --- a/test/mission-database-bay.test.js +++ b/test/mission-database-bay.test.js @@ -30,6 +30,8 @@ beforeEach(() => { }); describe('Sensors test', () => { + + let globalEventIdFromTest1; // ✅ TASK: Write the following test 👇 to ensure adding an event succeed // 💡 TIP: The event schema is already defined below test('When adding a valid event, Then should get successful confirmation', async () => { @@ -41,14 +43,20 @@ describe('Sensors test', () => { color: 'Green', weight: 80, status: 'active', + reason: `Thermostat ${getShortUnique()}`, }; // Act // 💡 TIP: use any http client lib like Axios OR supertest // 💡 TIP: This is how it is done with Supertest -> await request(expressApp).post("/sensor-events").send(eventToAdd); - + const receivedResponse = await request(expressApp).post("/sensor-events").send(eventToAdd); // Assert // 💡 TIP: Check not only the HTTP status bot also the body + expect(receivedResponse).toMatchObject({status: 200, body: { + ...eventToAdd, + id: expect.any(Number) + }}); + globalEventIdFromTest1 = receivedResponse.body.id; }); // ✅ TASK: Run the test above twice, it fails, ah? Let's fix! @@ -63,16 +71,58 @@ describe('Sensors test', () => { // ✅ TASK: Let's test that the system indeed enforces the 'reason' field uniqueness by writing this test below 👇 // 💡 TIP: This test probably demands two POST calls, you can use the same JSON payload twice - // test('When a record exist with a specific reason and trying to add a second one, then it fails with status 409'); + test('When a record exist with a specific reason and trying to add a second one, then it fails with status 409', async () => { + const eventToAdd = { + category: 'Home equipment', + temperature: 20, + reason: `Thermostat-failed`, // This must be unique + color: 'Green', + weight: 80, + status: 'active', + reason: `Thermostat ${getShortUnique()}`, + }; + const receivedResponse1 = await request(expressApp).post("/sensor-events").send(eventToAdd); + expect(receivedResponse1).toMatchObject({status: 200, body: { + ...eventToAdd, + id: expect.any(Number) + }}); + const receivedResponse2 = await request(expressApp).post("/sensor-events").send(eventToAdd); + expect(receivedResponse2).toMatchObject({status: 409}); + }); // ✅ TASK: Let's write the test below 👇 that checks that querying by ID works. For now, temporarily please query for the event that // was added using the first test above 👆. // 💡 TIP: This is not the recommended technique (reusing records from previous tests), we do this to understand // The consequences - test('When querying for event by id, Then the right event is being returned', () => { + test.only('When querying for event by id, Then the right event is being returned', async () => { // 💡 TIP: At first, query for the event that was added in the first test (In the first test above, store // the ID of the added event globally). In this test, query for that ID // 💡 TIP: This is the GET sensor URL: await request(expressApp).get(`/sensor-events/${id}`, + const eventToAdd = { + category: 'Home equipment', + temperature: 20, + reason: `Thermostat-failed`, // This must be unique + color: 'Green', + weight: 80, + status: 'active', + reason: `Thermostat ${getShortUnique()}`, + }; + const receivedResponse = await request(expressApp).post("/sensor-events").send(eventToAdd); + expect(receivedResponse).toMatchObject({status: 200, body: { + ...eventToAdd, + id: expect.any(Number) + }}); + const getResponse = await request(expressApp).get(`/sensor-events/${receivedResponse.body.id}`); + expect(getResponse).toMatchObject({status: 200, body: { + ...eventToAdd, + id: receivedResponse.body.id + }}); + + // const getResponse = await request(expressApp).get(`/sensor-events/${globalEventIdFromTest1}`); + // expect(getResponse).toMatchObject({status: 200, body: { + // id: globalEventIdFromTest1 + // }}); + }); // ✅ TASK: Run the last test 👆 alone (without running other tests). Does it pass now?