From bf58adfdde2a9c66f169964738fb131953c69094 Mon Sep 17 00:00:00 2001 From: Matthew Petro Date: Fri, 9 Feb 2024 09:44:54 -0700 Subject: [PATCH] Got unit tests working for Maker API --- .env.testing | 7 + .gitignore | 2 +- .../irrigation-events.controller.ts | 4 +- .../maker-api.service.spec.ts | 27 +++- .../mocks/maker-api.mocks.json | 150 ++++++++++++++++++ tsconfig.json | 1 + 6 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 .env.testing create mode 100644 src/irrigation-events/mocks/maker-api.mocks.json diff --git a/.env.testing b/.env.testing new file mode 100644 index 0000000..c674fd9 --- /dev/null +++ b/.env.testing @@ -0,0 +1,7 @@ +COUCHDB_URL=http://localhost +DB_NAME=irrigation-events +DB_USERNAME=username +DB_PASSWORD=passowrd +DB_AUTH_REFRESH_MINUTES=9 +MAKER_API_URL=http://localhost +MAKER_API_ACCESS_TOKEN=fake-token \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3b29c8c..422e43f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,4 @@ lerna-debug.log* !.vscode/launch.json !.vscode/extensions.json -.env* \ No newline at end of file +.env.local \ No newline at end of file diff --git a/src/irrigation-events/irrigation-events.controller.ts b/src/irrigation-events/irrigation-events.controller.ts index 130ed27..6e145e5 100644 --- a/src/irrigation-events/irrigation-events.controller.ts +++ b/src/irrigation-events/irrigation-events.controller.ts @@ -101,9 +101,9 @@ export class IrrigationEventsController { } private async addCurrentDeviceStates(deviceEventsList: DeviceEvents[]): Promise { - const makerEvents = await this.makerApiService.getAllDeviceStates() + const deviceDetails = await this.makerApiService.getAllDeviceDetails() deviceEventsList.forEach((device) => { - const currentDeviceState = makerEvents[device.getDeviceId()] + const currentDeviceState = deviceDetails[device.getDeviceId()] device.setCurrentDeviceState(currentDeviceState) }) } diff --git a/src/irrigation-events/maker-api.service.spec.ts b/src/irrigation-events/maker-api.service.spec.ts index 774cd67..ff42b9f 100644 --- a/src/irrigation-events/maker-api.service.spec.ts +++ b/src/irrigation-events/maker-api.service.spec.ts @@ -1,13 +1,17 @@ import { Test, TestingModule } from '@nestjs/testing' import { MakerApiService } from '@/irrigation-events/maker-api.service' import { ConfigModule } from '@nestjs/config' +import axios from 'axios' +import mockData from './mocks/maker-api.mocks.json' + +jest.mock('axios') describe('MakerApiService', () => { let service: MakerApiService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - imports: [ConfigModule.forRoot({ envFilePath: '.env.local' })], + imports: [ConfigModule.forRoot({ envFilePath: '.env.testing' })], providers: [MakerApiService], }).compile() @@ -17,4 +21,25 @@ describe('MakerApiService', () => { it('should be defined', () => { expect(service).toBeDefined() }) + + it('should return data correctly', async () => { + const mockedGet = axios.get as jest.MockedFunction + mockedGet.mockResolvedValue({ data: mockData.input }) + const deviceDetails = await service.getAllDeviceDetails() + expect(deviceDetails).toEqual(mockData.output) + }) + + it('should return empty object if no data is returned', async () => { + const mockedGet = axios.get as jest.MockedFunction + mockedGet.mockResolvedValue({ data: undefined }) + const deviceDetails = await service.getAllDeviceDetails() + expect(deviceDetails).toEqual({}) + }) + + it('should return empty object if an empty array is returned', async () => { + const mockedGet = axios.get as jest.MockedFunction + mockedGet.mockResolvedValue({ data: [] }) + const deviceDetails = await service.getAllDeviceDetails() + expect(deviceDetails).toEqual({}) + }) }) diff --git a/src/irrigation-events/mocks/maker-api.mocks.json b/src/irrigation-events/mocks/maker-api.mocks.json new file mode 100644 index 0000000..95a3202 --- /dev/null +++ b/src/irrigation-events/mocks/maker-api.mocks.json @@ -0,0 +1,150 @@ +{ + "input": [ + { + "name": "Generic Component Switch", + "label": "North lawn", + "type": "Generic Component Switch", + "id": "768", + "date": "2024-01-16T18:58:54+0000", + "model": null, + "manufacturer": null, + "room": "Irrigation", + "capabilities": ["Actuator", "Switch", "Refresh"], + "attributes": { "switch": "on", "dataType": "ENUM", "values": ["on", "off"] }, + "commands": [{ "command": "off" }, { "command": "on" }, { "command": "refresh" }] + }, + { + "name": "Generic Component Switch", + "label": "Back plants", + "type": "Generic Component Switch", + "id": "769", + "date": "2024-02-01T15:16:01+0000", + "model": null, + "manufacturer": null, + "room": "Irrigation", + "capabilities": ["Actuator", "Switch", "Refresh"], + "attributes": { "switch": "off", "dataType": "ENUM", "values": ["on", "off"] }, + "commands": [{ "command": "off" }, { "command": "on" }, { "command": "refresh" }] + }, + { + "name": "Generic Component Switch", + "label": "Front trees", + "type": "Generic Component Switch", + "id": "675", + "date": "2024-01-17T14:07:24+0000", + "model": null, + "manufacturer": null, + "room": "Irrigation", + "capabilities": ["Actuator", "Switch", "Refresh"], + "attributes": { "switch": "off", "dataType": "ENUM", "values": ["on", "off"] }, + "commands": [{ "command": "off" }, { "command": "on" }, { "command": "refresh" }] + }, + { + "name": "Generic Component Switch", + "label": "Front plants", + "type": "Generic Component Switch", + "id": "676", + "date": "2024-01-29T15:18:01+0000", + "model": null, + "manufacturer": null, + "room": "Irrigation", + "capabilities": ["Actuator", "Switch", "Refresh"], + "attributes": { "switch": "off", "dataType": "ENUM", "values": ["on", "off"] }, + "commands": [{ "command": "off" }, { "command": "on" }, { "command": "refresh" }] + }, + { + "name": "Virtual irrigation relay", + "label": "Virtual irrigation relay", + "type": "Virtual Switch", + "id": "852", + "date": null, + "model": null, + "manufacturer": null, + "room": null, + "capabilities": ["Switch", "Refresh"], + "attributes": { "switch": "off", "dataType": "ENUM", "values": ["on", "off"] }, + "commands": [{ "command": "off" }, { "command": "on" }, { "command": "refresh" }] + }, + { + "name": "Generic Component Switch", + "label": "Back trees", + "type": "Generic Component Switch", + "id": "677", + "date": "2024-01-13T13:34:01+0000", + "model": null, + "manufacturer": null, + "room": "Irrigation", + "capabilities": ["Actuator", "Switch", "Refresh"], + "attributes": { "switch": "off", "dataType": "ENUM", "values": ["on", "off"] }, + "commands": [{ "command": "off" }, { "command": "on" }, { "command": "refresh" }] + }, + { + "name": "Bhyve Hose Timer", + "label": "Tangelo tree", + "type": "Orbit Bhyve Sprinkler Timer", + "id": "813", + "date": "2024-01-24T14:41:16+0000", + "model": null, + "manufacturer": null, + "room": "Irrigation", + "capabilities": ["Refresh", "Battery", "Initialize", "Valve", "Switch", "Sensor"], + "attributes": { + "battery": "60", + "dataType": "NUMBER", + "values": null, + "last_watering_volume": "0", + "programs": "Tangelo Programs\nSmart Hose Timer: None", + "scheduled_auto_on": "true", + "water_flow_rate": null, + "valve": "closed", + "next_start_time": "1693917000000", + "start_times": "5:30 am", + "switch": "off", + "sprinkler_type": "Unknown ", + "station": "1", + "next_start_programs": "Station 1: A", + "run_mode": "auto", + "stop_time": "1705678385556", + "is_connected": "true", + "rain_icon": "sun", + "start_time": "1705672984235", + "preset_runtime": "10", + "rain_delay": "0", + "manual_preset_runtime_min": "10" + }, + "commands": [ + { "command": "close" }, + { "command": "initialize" }, + { "command": "off" }, + { "command": "on" }, + { "command": "open" }, + { "command": "open" }, + { "command": "refresh" }, + { "command": "setRainDelay" } + ] + }, + { + "name": "Generic Component Switch", + "label": "South lawn", + "type": "Generic Component Switch", + "id": "767", + "date": "2024-01-16T19:14:12+0000", + "model": null, + "manufacturer": null, + "room": "Irrigation", + "capabilities": ["Actuator", "Switch", "Refresh"], + "attributes": { "switch": "off", "dataType": "ENUM", "values": ["on", "off"] }, + "commands": [{ "command": "off" }, { "command": "on" }, { "command": "refresh" }] + } + ], + "output": { + "768": "on", + "769": "off", + "675": "off", + "676": "off", + "852": "off", + "677": "off", + "813": "off", + "767": "off" + } +} diff --git a/tsconfig.json b/tsconfig.json index e86ef30..5054de8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,7 @@ "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false, "esModuleInterop": true, + "resolveJsonModule": true, "paths": { "@/*": [ "src/*"