From f5bfca630923337c40f07e5209c54be4bb26d286 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 27 Feb 2026 22:14:24 +0100 Subject: [PATCH] refactor(tests): harmonize test naming and consolidate utilities - Standardize test names to 'should [verb]' lowercase pattern - Extract createConnectorStatus() as shared utility - Remove duplicate MockWebSocket and waitForCondition() - Update TEST_STYLE_GUIDE.md with shared utilities table --- tests/ChargingStationFactory.test.ts | 128 ++++++++-------- tests/ChargingStationFactory.ts | 31 +--- tests/TEST_STYLE_GUIDE.md | 54 ++++++- .../ChargingStation-Resilience.test.ts | 4 +- .../ChargingStationTestUtils.ts | 2 + tests/charging-station/Helpers.test.ts | 86 +++++------ .../helpers/StationHelpers.ts | 73 ++++++--- tests/charging-station/mocks/MockWebSocket.ts | 16 ++ .../ocpp/2.0/OCPP20CertificateManager.test.ts | 60 ++++---- ...ngRequestService-CertificateSigned.test.ts | 20 +-- ...0IncomingRequestService-ClearCache.test.ts | 18 +-- ...ngRequestService-DeleteCertificate.test.ts | 16 +- ...comingRequestService-GetBaseReport.test.ts | 24 +-- ...Service-GetInstalledCertificateIds.test.ts | 16 +- ...ncomingRequestService-GetVariables.test.ts | 44 +++--- ...gRequestService-InstallCertificate.test.ts | 18 +-- ...estService-RequestStartTransaction.test.ts | 18 +-- ...uestService-RequestStopTransaction.test.ts | 22 +-- ...OCPP20IncomingRequestService-Reset.test.ts | 44 +++--- ...ncomingRequestService-SetVariables.test.ts | 40 ++--- ...P20RequestService-BootNotification.test.ts | 10 +- .../OCPP20RequestService-HeartBeat.test.ts | 12 +- .../2.0/OCPP20RequestService-ISO15118.test.ts | 24 +-- .../OCPP20RequestService-NotifyReport.test.ts | 20 +-- ...PP20RequestService-SignCertificate.test.ts | 20 +-- ...0RequestService-StatusNotification.test.ts | 14 +- ...eUtils-TransactionEvent-CableFirst.test.ts | 24 +-- ...tils-TransactionEvent-IdTokenFirst.test.ts | 32 ++-- ...viceUtils-TransactionEvent-Offline.test.ts | 26 ++-- ...iceUtils-TransactionEvent-Periodic.test.ts | 24 +-- ...CPP20ServiceUtils-TransactionEvent.test.ts | 78 +++++----- .../ocpp/2.0/OCPP20VariableManager.test.ts | 142 +++++++++--------- .../ocpp/auth/helpers/MockFactories.ts | 7 +- .../ui-server/UIHttpServer.test.ts | 36 ++--- .../ui-server/UIServerSecurity.test.ts | 36 ++--- .../ui-server/UIServerTestUtils.ts | 62 +++----- .../ui-server/UIWebSocketServer.test.ts | 22 +-- .../ui-services/AbstractUIService.test.ts | 18 +-- tests/exception/BaseError.test.ts | 4 +- tests/exception/OCPPError.test.ts | 2 +- tests/types/ConfigurationData.test.ts | 6 +- tests/utils/AsyncLock.test.ts | 4 +- tests/utils/ConfigurationUtils.test.ts | 10 +- tests/utils/ElectricUtils.test.ts | 14 +- tests/utils/ErrorUtils.test.ts | 6 +- tests/utils/StatisticUtils.test.ts | 12 +- tests/utils/Utils.test.ts | 64 ++++---- tests/worker/WorkerUtils.test.ts | 10 +- 48 files changed, 770 insertions(+), 703 deletions(-) diff --git a/tests/ChargingStationFactory.test.ts b/tests/ChargingStationFactory.test.ts index a842c4e8..a5ba713a 100644 --- a/tests/ChargingStationFactory.test.ts +++ b/tests/ChargingStationFactory.test.ts @@ -11,7 +11,7 @@ import { createChargingStation, createChargingStationTemplate } from './Charging await describe('ChargingStationFactory', async () => { await describe('OCPP Service Mocking', async () => { - await it('Should throw error when OCPPRequestService.requestHandler is not mocked', async () => { + await it('should throw error when OCPPRequestService.requestHandler is not mocked', async () => { const station = createChargingStation({ connectorsCount: 1 }) await expect(station.ocppRequestService.requestHandler()).rejects.toThrow( @@ -19,7 +19,7 @@ await describe('ChargingStationFactory', async () => { ) }) - await it('Should throw error when OCPPIncomingRequestService.stop is not mocked', () => { + await it('should throw error when OCPPIncomingRequestService.stop is not mocked', () => { const station = createChargingStation({ connectorsCount: 1 }) expect(() => { @@ -29,7 +29,7 @@ await describe('ChargingStationFactory', async () => { ) }) - await it('Should allow custom OCPPRequestService.requestHandler mock', async () => { + await it('should allow custom OCPPRequestService.requestHandler mock', async () => { const mockRequestHandler = async () => { return Promise.resolve({ success: true }) } @@ -45,7 +45,7 @@ await describe('ChargingStationFactory', async () => { expect(result.success).toBe(true) }) - await it('Should allow custom OCPPIncomingRequestService.stop mock', () => { + await it('should allow custom OCPPIncomingRequestService.stop mock', () => { let stopCalled = false const station = createChargingStation({ connectorsCount: 1, @@ -60,7 +60,7 @@ await describe('ChargingStationFactory', async () => { expect(stopCalled).toBe(true) }) - await it('Should throw error when OCPPRequestService.sendError is not mocked', async () => { + await it('should throw error when OCPPRequestService.sendError is not mocked', async () => { const station = createChargingStation({ connectorsCount: 1 }) await expect(station.ocppRequestService.sendError()).rejects.toThrow( @@ -68,7 +68,7 @@ await describe('ChargingStationFactory', async () => { ) }) - await it('Should throw error when OCPPRequestService.sendResponse is not mocked', async () => { + await it('should throw error when OCPPRequestService.sendResponse is not mocked', async () => { const station = createChargingStation({ connectorsCount: 1 }) await expect(station.ocppRequestService.sendResponse()).rejects.toThrow( @@ -76,7 +76,7 @@ await describe('ChargingStationFactory', async () => { ) }) - await it('Should allow custom OCPPRequestService.sendError mock', async () => { + await it('should allow custom OCPPRequestService.sendError mock', async () => { const mockSendError = async () => { return Promise.resolve({ error: 'test-error' }) } @@ -92,7 +92,7 @@ await describe('ChargingStationFactory', async () => { expect(result.error).toBe('test-error') }) - await it('Should allow custom OCPPRequestService.sendResponse mock', async () => { + await it('should allow custom OCPPRequestService.sendResponse mock', async () => { const mockSendResponse = async () => { return Promise.resolve({ response: 'test-response' }) } @@ -108,7 +108,7 @@ await describe('ChargingStationFactory', async () => { expect(result.response).toBe('test-response') }) - await it('Should throw error when OCPPIncomingRequestService.incomingRequestHandler is not mocked', async () => { + await it('should throw error when OCPPIncomingRequestService.incomingRequestHandler is not mocked', async () => { const station = createChargingStation({ connectorsCount: 1 }) await expect(station.ocppIncomingRequestService.incomingRequestHandler()).rejects.toThrow( @@ -116,7 +116,7 @@ await describe('ChargingStationFactory', async () => { ) }) - await it('Should allow custom OCPPIncomingRequestService.incomingRequestHandler mock', async () => { + await it('should allow custom OCPPIncomingRequestService.incomingRequestHandler mock', async () => { const mockIncomingRequestHandler = async () => { return Promise.resolve({ handled: true }) } @@ -137,7 +137,7 @@ await describe('ChargingStationFactory', async () => { await describe('Configuration Validation', async () => { await describe('StationInfo Properties', async () => { - await it('Should create station with valid stationInfo', () => { + await it('should create station with valid stationInfo', () => { const station = createChargingStation({ connectorsCount: 1, stationInfo: { @@ -158,7 +158,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('Connector Configuration', async () => { - await it('Should create station with no connectors when connectorsCount is 0', () => { + await it('should create station with no connectors when connectorsCount is 0', () => { const station = createChargingStation({ connectorsCount: 0, }) @@ -167,7 +167,7 @@ await describe('ChargingStationFactory', async () => { expect(station.connectors.size).toBe(0) }) - await it('Should create station with specified number of connectors', () => { + await it('should create station with specified number of connectors', () => { const station = createChargingStation({ connectorsCount: 3, }) @@ -176,7 +176,7 @@ await describe('ChargingStationFactory', async () => { expect(station.connectors.size).toBe(4) }) - await it('Should handle connector status properly', () => { + await it('should handle connector status properly', () => { const station = createChargingStation({ connectorsCount: 2, }) @@ -186,7 +186,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectorStatus(2)).toBeDefined() }) - await it('Should create station with custom connector defaults', () => { + await it('should create station with custom connector defaults', () => { const station = createChargingStation({ connectorDefaults: { availability: AvailabilityType.Inoperative, @@ -202,7 +202,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('OCPP Version-Specific Configuration', async () => { - await it('Should configure OCPP 1.6 station correctly', () => { + await it('should configure OCPP 1.6 station correctly', () => { const station = createChargingStation({ connectorsCount: 2, stationInfo: { @@ -215,7 +215,7 @@ await describe('ChargingStationFactory', async () => { expect(station.hasEvses).toBe(false) }) - await it('Should configure OCPP 2.0 station with EVSEs', () => { + await it('should configure OCPP 2.0 station with EVSEs', () => { const station = createChargingStation({ connectorsCount: 0, // OCPP 2.0 uses EVSEs instead of connectors stationInfo: { @@ -228,7 +228,7 @@ await describe('ChargingStationFactory', async () => { expect(station.hasEvses).toBe(true) }) - await it('Should configure OCPP 2.0.1 station with EVSEs', () => { + await it('should configure OCPP 2.0.1 station with EVSEs', () => { const station = createChargingStation({ connectorsCount: 0, // OCPP 2.0.1 uses EVSEs instead of connectors stationInfo: { @@ -243,7 +243,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('EVSE Configuration', async () => { - await it('Should create station with EVSEs when configuration is provided', () => { + await it('should create station with EVSEs when configuration is provided', () => { const station = createChargingStation({ connectorsCount: 6, evseConfiguration: { @@ -256,7 +256,7 @@ await describe('ChargingStationFactory', async () => { expect(station.connectors.size).toBe(7) // 0 + 6 connectors }) - await it('Should automatically enable EVSEs for OCPP 2.0+ versions', () => { + await it('should automatically enable EVSEs for OCPP 2.0+ versions', () => { const station = createChargingStation({ connectorsCount: 3, stationInfo: { @@ -270,7 +270,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('Factory Default Values', async () => { - await it('Should provide sensible defaults for all required properties', () => { + await it('should provide sensible defaults for all required properties', () => { const station = createChargingStation({ connectorsCount: 1, }) @@ -283,7 +283,7 @@ await describe('ChargingStationFactory', async () => { expect(station.stationInfo?.templateHash).toBeUndefined() // Factory doesn't set templateHash by default }) - await it('Should allow overriding factory defaults', () => { + await it('should allow overriding factory defaults', () => { const customStationId = 'custom-station-123' const customHashId = 'custom-hash-456' @@ -302,7 +302,7 @@ await describe('ChargingStationFactory', async () => { expect(station.stationInfo?.ocppVersion).toBeDefined() }) - await it('Should use default base name when not provided', () => { + await it('should use default base name when not provided', () => { const station = createChargingStation({ connectorsCount: 1, }) @@ -311,7 +311,7 @@ await describe('ChargingStationFactory', async () => { expect(station.stationInfo?.chargingStationId).toBe('CS-TEST-00001') }) - await it('Should use custom base name when provided', () => { + await it('should use custom base name when provided', () => { const customBaseName = 'CUSTOM-STATION' const station = createChargingStation({ baseName: customBaseName, @@ -324,7 +324,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('Configuration Options', async () => { - await it('Should respect connection timeout setting', () => { + await it('should respect connection timeout setting', () => { const customTimeout = 45000 const station = createChargingStation({ connectionTimeout: customTimeout, @@ -334,7 +334,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectionTimeout()).toBe(customTimeout) }) - await it('Should respect heartbeat interval setting', () => { + await it('should respect heartbeat interval setting', () => { const customInterval = 120000 const station = createChargingStation({ connectorsCount: 1, @@ -344,7 +344,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getHeartbeatInterval()).toBe(customInterval) }) - await it('Should respect websocket ping interval setting', () => { + await it('should respect websocket ping interval setting', () => { const customPingInterval = 90000 const station = createChargingStation({ connectorsCount: 1, @@ -354,7 +354,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getWebSocketPingInterval()).toBe(customPingInterval) }) - await it('Should respect started and starting flags', () => { + await it('should respect started and starting flags', () => { const station = createChargingStation({ connectorsCount: 1, started: true, @@ -367,7 +367,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('Integration with Helpers', async () => { - await it('Should properly integrate with helper functions', () => { + await it('should properly integrate with helper functions', () => { const station = createChargingStation({ connectorsCount: 1, stationInfo: { @@ -390,21 +390,21 @@ await describe('ChargingStationFactory', async () => { await describe('Mock Behavioral Parity', async () => { await describe('getConnectorIdByTransactionId', async () => { - await it('Should return undefined for null transaction ID', () => { + await it('should return undefined for null transaction ID', () => { const station = createChargingStation({ connectorsCount: 2 }) // Test null handling (matches real class behavior) expect(station.getConnectorIdByTransactionId(null)).toBeUndefined() }) - await it('Should return undefined for undefined transaction ID', () => { + await it('should return undefined for undefined transaction ID', () => { const station = createChargingStation({ connectorsCount: 2 }) // Test undefined handling (matches real class behavior) expect(station.getConnectorIdByTransactionId(undefined)).toBeUndefined() }) - await it('Should return connector ID when transaction ID matches (standard connectors)', () => { + await it('should return connector ID when transaction ID matches (standard connectors)', () => { const station = createChargingStation({ connectorsCount: 2, stationInfo: { ocppVersion: OCPPVersion.VERSION_16 }, // Force non-EVSE mode @@ -419,7 +419,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectorIdByTransactionId('test-transaction-123')).toBe(1) }) - await it('Should return connector ID when transaction ID matches (EVSE mode)', () => { + await it('should return connector ID when transaction ID matches (EVSE mode)', () => { const station = createChargingStation({ connectorsCount: 2, stationInfo: { ocppVersion: OCPPVersion.VERSION_201 }, // Force EVSE mode @@ -434,13 +434,13 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectorIdByTransactionId('test-evse-transaction-456')).toBe(1) }) - await it('Should return undefined when transaction ID does not match any connector', () => { + await it('should return undefined when transaction ID does not match any connector', () => { const station = createChargingStation({ connectorsCount: 2 }) expect(station.getConnectorIdByTransactionId('non-existent-transaction')).toBeUndefined() }) - await it('Should handle numeric transaction IDs', () => { + await it('should handle numeric transaction IDs', () => { const station = createChargingStation({ connectorsCount: 2 }) // Set up a transaction with numeric ID on connector 2 @@ -454,7 +454,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('getEvseIdByConnectorId', async () => { - await it('Should return undefined for stations without EVSEs', () => { + await it('should return undefined for stations without EVSEs', () => { const station = createChargingStation({ connectorsCount: 3, stationInfo: { ocppVersion: OCPPVersion.VERSION_16 }, // OCPP 1.6 doesn't use EVSEs @@ -464,7 +464,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByConnectorId(2)).toBeUndefined() }) - await it('Should return correct EVSE ID for connectors in EVSE mode', () => { + await it('should return correct EVSE ID for connectors in EVSE mode', () => { const station = createChargingStation({ connectorsCount: 6, evseConfiguration: { evsesCount: 2 }, // 2 EVSEs with 3 connectors each @@ -482,7 +482,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByConnectorId(6)).toBe(2) }) - await it('Should return undefined for non-existent connector IDs', () => { + await it('should return undefined for non-existent connector IDs', () => { const station = createChargingStation({ connectorsCount: 4, evseConfiguration: { evsesCount: 2 }, @@ -494,7 +494,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByConnectorId(-1)).toBeUndefined() // Invalid connector ID }) - await it('Should handle single EVSE with multiple connectors', () => { + await it('should handle single EVSE with multiple connectors', () => { const station = createChargingStation({ connectorsCount: 3, evseConfiguration: { evsesCount: 1 }, // Single EVSE with all connectors @@ -509,7 +509,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('getEvseIdByTransactionId', async () => { - await it('Should return undefined for null transaction ID', () => { + await it('should return undefined for null transaction ID', () => { const station = createChargingStation({ connectorsCount: 2, stationInfo: { ocppVersion: OCPPVersion.VERSION_201 }, @@ -519,7 +519,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId(null)).toBeUndefined() }) - await it('Should return undefined for undefined transaction ID', () => { + await it('should return undefined for undefined transaction ID', () => { const station = createChargingStation({ connectorsCount: 2, stationInfo: { ocppVersion: OCPPVersion.VERSION_201 }, @@ -529,7 +529,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId(undefined)).toBeUndefined() }) - await it('Should return undefined for stations without EVSEs', () => { + await it('should return undefined for stations without EVSEs', () => { const station = createChargingStation({ connectorsCount: 3, stationInfo: { ocppVersion: OCPPVersion.VERSION_16 }, // OCPP 1.6 doesn't use EVSEs @@ -544,7 +544,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId('test-transaction-123')).toBeUndefined() }) - await it('Should return correct EVSE ID when transaction ID matches (single EVSE)', () => { + await it('should return correct EVSE ID when transaction ID matches (single EVSE)', () => { const station = createChargingStation({ connectorsCount: 3, evseConfiguration: { evsesCount: 1 }, // Single EVSE with all connectors @@ -566,7 +566,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId(456)).toBe(1) }) - await it('Should return correct EVSE ID when transaction ID matches (multiple EVSEs)', () => { + await it('should return correct EVSE ID when transaction ID matches (multiple EVSEs)', () => { const station = createChargingStation({ connectorsCount: 6, evseConfiguration: { evsesCount: 2 }, // 2 EVSEs with 3 connectors each @@ -594,7 +594,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId(999)).toBe(2) }) - await it('Should return undefined when transaction ID does not match any connector', () => { + await it('should return undefined when transaction ID does not match any connector', () => { const station = createChargingStation({ connectorsCount: 4, evseConfiguration: { evsesCount: 2 }, @@ -611,7 +611,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId(12345)).toBeUndefined() }) - await it('Should handle numeric transaction IDs', () => { + await it('should handle numeric transaction IDs', () => { const station = createChargingStation({ connectorsCount: 4, evseConfiguration: { evsesCount: 2 }, @@ -627,7 +627,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId(789)).toBe(2) }) - await it('Should handle string transaction IDs', () => { + await it('should handle string transaction IDs', () => { const station = createChargingStation({ connectorsCount: 4, evseConfiguration: { evsesCount: 2 }, @@ -643,7 +643,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getEvseIdByTransactionId('string-transaction-id-abc123')).toBe(1) }) - await it('Should maintain consistency with getConnectorIdByTransactionId', () => { + await it('should maintain consistency with getConnectorIdByTransactionId', () => { const station = createChargingStation({ connectorsCount: 6, evseConfiguration: { evsesCount: 3 }, @@ -671,7 +671,7 @@ await describe('ChargingStationFactory', async () => { } }) - await it('Should handle mixed transaction ID types correctly', () => { + await it('should handle mixed transaction ID types correctly', () => { const station = createChargingStation({ connectorsCount: 4, evseConfiguration: { evsesCount: 2 }, @@ -700,21 +700,21 @@ await describe('ChargingStationFactory', async () => { }) await describe('isConnectorAvailable', async () => { - await it('Should return false for connector ID 0', () => { + await it('should return false for connector ID 0', () => { const station = createChargingStation({ connectorsCount: 2 }) // Connector 0 should never be available (matches real class behavior) expect(station.isConnectorAvailable(0)).toBe(false) }) - await it('Should return false for negative connector ID', () => { + await it('should return false for negative connector ID', () => { const station = createChargingStation({ connectorsCount: 2 }) // Negative connectorId should return false (matches real class behavior) expect(station.isConnectorAvailable(-1)).toBe(false) }) - await it('Should return true for available operative connector', () => { + await it('should return true for available operative connector', () => { const station = createChargingStation({ connectorDefaults: { availability: AvailabilityType.Operative, @@ -727,7 +727,7 @@ await describe('ChargingStationFactory', async () => { expect(station.isConnectorAvailable(2)).toBe(true) }) - await it('Should return false for inoperative connector', () => { + await it('should return false for inoperative connector', () => { const station = createChargingStation({ connectorDefaults: { availability: AvailabilityType.Inoperative, @@ -740,7 +740,7 @@ await describe('ChargingStationFactory', async () => { expect(station.isConnectorAvailable(2)).toBe(false) }) - await it('Should check availability regardless of status (matches real class)', () => { + await it('should check availability regardless of status (matches real class)', () => { const station = createChargingStation({ connectorDefaults: { availability: AvailabilityType.Operative, @@ -754,14 +754,14 @@ await describe('ChargingStationFactory', async () => { expect(station.isConnectorAvailable(2)).toBe(true) }) - await it('Should return false for non-existent connector', () => { + await it('should return false for non-existent connector', () => { const station = createChargingStation({ connectorsCount: 2 }) // Connector 3 doesn't exist expect(station.isConnectorAvailable(3)).toBe(false) }) - await it('Should work correctly in EVSE mode', () => { + await it('should work correctly in EVSE mode', () => { const station = createChargingStation({ connectorDefaults: { availability: AvailabilityType.Operative, @@ -777,7 +777,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('getConnectorStatus behavioral parity', async () => { - await it('Should return undefined for non-existent connector in standard mode', () => { + await it('should return undefined for non-existent connector in standard mode', () => { const station = createChargingStation({ connectorsCount: 2, stationInfo: { ocppVersion: OCPPVersion.VERSION_16 }, @@ -786,7 +786,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectorStatus(999)).toBeUndefined() }) - await it('Should return undefined for non-existent connector in EVSE mode', () => { + await it('should return undefined for non-existent connector in EVSE mode', () => { const station = createChargingStation({ connectorsCount: 2, stationInfo: { ocppVersion: OCPPVersion.VERSION_201 }, @@ -795,7 +795,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectorStatus(999)).toBeUndefined() }) - await it('Should return connector status for valid connector in both modes', () => { + await it('should return connector status for valid connector in both modes', () => { const stationStandard = createChargingStation({ connectorsCount: 2, stationInfo: { ocppVersion: OCPPVersion.VERSION_16 }, @@ -811,7 +811,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('Method interaction behavioral parity', async () => { - await it('Should maintain consistency between getConnectorStatus and isConnectorAvailable', () => { + await it('should maintain consistency between getConnectorStatus and isConnectorAvailable', () => { const station = createChargingStation({ connectorsCount: 2 }) // Test consistency - if connector status exists and is operative, should be available @@ -826,7 +826,7 @@ await describe('ChargingStationFactory', async () => { expect(station.isConnectorAvailable(1)).toBe(false) }) - await it('Should maintain consistency between getConnectorIdByTransactionId and getConnectorStatus', () => { + await it('should maintain consistency between getConnectorIdByTransactionId and getConnectorStatus', () => { const station = createChargingStation({ connectorsCount: 2 }) // Set up transaction @@ -846,7 +846,7 @@ await describe('ChargingStationFactory', async () => { }) await describe('Edge Cases and Error Handling', async () => { - await it('Should handle empty station (no connectors)', () => { + await it('should handle empty station (no connectors)', () => { const station = createChargingStation({ connectorsCount: 0 }) expect(station.getConnectorIdByTransactionId('any-transaction')).toBeUndefined() @@ -854,7 +854,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectorStatus(1)).toBeUndefined() }) - await it('Should handle mixed transaction ID types in search', () => { + await it('should handle mixed transaction ID types in search', () => { const station = createChargingStation({ connectorsCount: 3 }) // Set up mixed transaction types @@ -870,7 +870,7 @@ await describe('ChargingStationFactory', async () => { expect(station.getConnectorIdByTransactionId('999')).toBeUndefined() // String vs number }) - await it('Should handle partially configured connectors', () => { + await it('should handle partially configured connectors', () => { const station = createChargingStation({ connectorsCount: 2 }) // Manually modify one connector to test resilience diff --git a/tests/ChargingStationFactory.ts b/tests/ChargingStationFactory.ts index 4b3f3038..1ac8b869 100644 --- a/tests/ChargingStationFactory.ts +++ b/tests/ChargingStationFactory.ts @@ -7,7 +7,6 @@ import { IdTagsCache } from '../src/charging-station/IdTagsCache.js' import { AvailabilityType, type BootNotificationResponse, - type ChargingProfile, type ChargingStationConfiguration, type ChargingStationInfo, type ChargingStationTemplate, @@ -17,10 +16,10 @@ import { OCPP20OptionalVariableName, OCPPVersion, RegistrationStatusEnumType, - type SampledValueTemplate, StandardParametersKey, } from '../src/types/index.js' import { clone, Constants, convertToBoolean } from '../src/utils/index.js' +import { createConnectorStatus } from './charging-station/helpers/StationHelpers.js' /** * Options to customize the construction of a ChargingStation test instance @@ -337,31 +336,17 @@ function createConnectorsConfiguration ( return { connectors, evses } } - const createConnectorStatus = (connectorId: number) => { - const baseStatus = { - availability: options.connectorDefaults?.availability ?? AvailabilityType.Operative, - chargingProfiles: [] as ChargingProfile[], - energyActiveImportRegisterValue: 0, - idTagAuthorized: false, - idTagLocalAuthorized: false, - MeterValues: [] as SampledValueTemplate[], - status: options.connectorDefaults?.status ?? ConnectorStatusEnum.Available, - transactionEnergyActiveImportRegisterValue: 0, - transactionId: undefined, - transactionIdTag: undefined, - transactionRemoteStarted: false, - transactionStart: undefined, - transactionStarted: false, - } - - return clone(baseStatus) + // Helper to create connector status with options defaults + const connectorStatusOptions = { + availability: options.connectorDefaults?.availability, + status: options.connectorDefaults?.status, } if (useEvses) { const evsesCount = options.evseConfiguration?.evsesCount ?? connectorsCount const connectorsCountPerEvse = Math.ceil(connectorsCount / evsesCount) - const connector0 = createConnectorStatus(0) + const connector0 = createConnectorStatus(0, connectorStatusOptions) connectors.set(0, connector0) for (let evseId = 1; evseId <= evsesCount; evseId++) { @@ -373,7 +358,7 @@ function createConnectorsConfiguration ( ) for (let connectorId = startConnectorId; connectorId <= endConnectorId; connectorId++) { - const connectorStatus = createConnectorStatus(connectorId) + const connectorStatus = createConnectorStatus(connectorId, connectorStatusOptions) connectors.set(connectorId, connectorStatus) evseConnectors.set(connectorId, clone(connectorStatus)) } @@ -385,7 +370,7 @@ function createConnectorsConfiguration ( } } else { for (let connectorId = 0; connectorId <= connectorsCount; connectorId++) { - connectors.set(connectorId, createConnectorStatus(connectorId)) + connectors.set(connectorId, createConnectorStatus(connectorId, connectorStatusOptions)) } } diff --git a/tests/TEST_STYLE_GUIDE.md b/tests/TEST_STYLE_GUIDE.md index 9a0cfa34..a26b3757 100644 --- a/tests/TEST_STYLE_GUIDE.md +++ b/tests/TEST_STYLE_GUIDE.md @@ -4,9 +4,37 @@ This document establishes conventions for writing maintainable, consistent tests ## Naming Conventions +### Test Case Naming (MANDATORY) + +Use consistent `should [verb]` pattern in **lowercase**: + +✅ **Good:** + +```typescript +it('should start successfully with valid configuration', async () => {}) +it('should reject invalid identifier', () => {}) +it('should handle Reset request with Immediate type', async () => {}) +``` + +❌ **Bad:** + +```typescript +// Inconsistent capitalization +it('Should start successfully', () => {}) // Capital 'S' + +// Imperative style +it('Verify generateUUID()', () => {}) // Not declarative + +// Missing 'should' +it('starts successfully', () => {}) // No 'should' +``` + +### Files & Suites + - **Files**: Use descriptive names matching the module under test: `ModuleName.test.ts` - **Test suites**: Use `describe()` with clear, specific descriptions -- **Test cases**: Use `it()` or `test()` with descriptive names starting with action verbs +- **OCPP tests**: Use requirement codes: `describe('B11 & B12 - Reset', () => {})` +- **Auth tests**: Reference spec sections: `describe('G03.FR.01 - AuthCache Conformance', () => {})` - **Variables**: Use camelCase for variables, functions, and test helpers - **Constants**: Use SCREAMING_SNAKE_CASE for test constants @@ -105,6 +133,30 @@ const station = await createChargingStation({ }) ``` +### Shared Test Utilities + +The following utilities are available for reuse across test files: + +| Utility | Location | Purpose | +| ----------------------------- | ------------------------------------ | ----------------------------------------- | +| `createMockChargingStation()` | `ChargingStationTestUtils.ts` | Lightweight mock station stub | +| `createChargingStation()` | `ChargingStationFactory.ts` | Full test station with OCPP services | +| `createConnectorStatus()` | `helpers/StationHelpers.ts` | ConnectorStatus factory with defaults | +| `MockWebSocket` | `mocks/MockWebSocket.ts` | WebSocket simulation with message capture | +| `MockIdTagsCache` | `mocks/MockCaches.ts` | In-memory IdTags cache mock | +| `MockSharedLRUCache` | `mocks/MockCaches.ts` | In-memory LRU cache mock | +| `waitForCondition()` | `helpers/StationHelpers.ts` | Async condition waiting with timeout | +| `cleanupChargingStation()` | `helpers/StationHelpers.ts` | Proper station cleanup for afterEach | +| Auth factories | `ocpp/auth/helpers/MockFactories.ts` | Auth-specific mock creation | + +**DO NOT duplicate these utilities.** Import and reuse them. + +```typescript +// Good: Import shared utilities +import { createMockChargingStation, cleanupChargingStation } from './ChargingStationTestUtils.js' +import { waitForCondition } from './helpers/StationHelpers.js' +``` + ### Mocking Best Practices - Use `mock.method()` for function mocking (Node.js native) diff --git a/tests/charging-station/ChargingStation-Resilience.test.ts b/tests/charging-station/ChargingStation-Resilience.test.ts index 2dd721b4..b9e447e8 100644 --- a/tests/charging-station/ChargingStation-Resilience.test.ts +++ b/tests/charging-station/ChargingStation-Resilience.test.ts @@ -396,9 +396,7 @@ await describe('ChargingStation Message Buffering', async () => { // Verify first and last message are in correct positions expect(station.messageQueue[0]).toContain('msg-0') - expect(station.messageQueue[messageCount - 1]).toContain( - `msg-${(messageCount - 1).toString()}` - ) + expect(station.messageQueue[messageCount - 1]).toContain(`msg-${(messageCount - 1).toString()}`) }) // ------------------------------------------------------------------------- diff --git a/tests/charging-station/ChargingStationTestUtils.ts b/tests/charging-station/ChargingStationTestUtils.ts index df1ece2e..c23bb1a6 100644 --- a/tests/charging-station/ChargingStationTestUtils.ts +++ b/tests/charging-station/ChargingStationTestUtils.ts @@ -15,11 +15,13 @@ // Re-export all helper functions and types export type { ChargingStationMocks, + CreateConnectorStatusOptions, MockChargingStationOptions, MockChargingStationResult, } from './helpers/StationHelpers.js' export { cleanupChargingStation, + createConnectorStatus, createMockChargingStation, createMockTemplate, resetChargingStationState, diff --git a/tests/charging-station/Helpers.test.ts b/tests/charging-station/Helpers.test.ts index f76e1c36..271028f8 100644 --- a/tests/charging-station/Helpers.test.ts +++ b/tests/charging-station/Helpers.test.ts @@ -49,17 +49,17 @@ await describe('Helpers test suite', async () => { reservationId: 1, }) as Reservation - await it('Verify getChargingStationId()', () => { + await it('should verify getChargingStationId()', () => { expect(getChargingStationId(1, chargingStationTemplate)).toBe(`${baseName}-00001`) }) - await it('Verify getHashId()', () => { + await it('should verify getHashId()', () => { expect(getHashId(1, chargingStationTemplate)).toBe( 'b4b1e8ec4fca79091d99ea9a7ea5901548010e6c0e98be9296f604b9d68734444dfdae73d7d406b6124b42815214d088' ) }) - await it('Verify validateStationInfo() - Missing stationInfo', () => { + await it('should verify validateStationInfo() - Missing stationInfo', () => { // For validation edge cases, we need to manually create invalid states // since the factory is designed to create valid configurations const stationNoInfo = createChargingStation({ baseName }) @@ -70,7 +70,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError('Missing charging station information')) }) - await it('Verify validateStationInfo() - Empty stationInfo', () => { + await it('should verify validateStationInfo() - Empty stationInfo', () => { // For validation edge cases, manually create empty stationInfo const stationEmptyInfo = createChargingStation({ baseName }) stationEmptyInfo.stationInfo = {} as ChargingStationInfo @@ -79,7 +79,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError('Missing charging station information')) }) - await it('Verify validateStationInfo() - Missing chargingStationId', () => { + await it('should verify validateStationInfo() - Missing chargingStationId', () => { const stationMissingId = createChargingStation({ baseName, stationInfo: { baseName, chargingStationId: undefined }, @@ -89,7 +89,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError('Missing chargingStationId in stationInfo properties')) }) - await it('Verify validateStationInfo() - Empty chargingStationId', () => { + await it('should verify validateStationInfo() - Empty chargingStationId', () => { const stationEmptyId = createChargingStation({ baseName, stationInfo: { baseName, chargingStationId: '' }, @@ -99,7 +99,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError('Missing chargingStationId in stationInfo properties')) }) - await it('Verify validateStationInfo() - Missing hashId', () => { + await it('should verify validateStationInfo() - Missing hashId', () => { const stationMissingHash = createChargingStation({ baseName, stationInfo: { @@ -113,7 +113,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError(`${baseName}-00001: Missing hashId in stationInfo properties`)) }) - await it('Verify validateStationInfo() - Empty hashId', () => { + await it('should verify validateStationInfo() - Empty hashId', () => { const stationEmptyHash = createChargingStation({ baseName, stationInfo: { @@ -127,7 +127,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError(`${baseName}-00001: Missing hashId in stationInfo properties`)) }) - await it('Verify validateStationInfo() - Missing templateIndex', () => { + await it('should verify validateStationInfo() - Missing templateIndex', () => { const stationMissingTemplate = createChargingStation({ baseName, stationInfo: { @@ -142,7 +142,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError(`${baseName}-00001: Missing templateIndex in stationInfo properties`)) }) - await it('Verify validateStationInfo() - Invalid templateIndex (zero)', () => { + await it('should verify validateStationInfo() - Invalid templateIndex (zero)', () => { const stationInvalidTemplate = createChargingStation({ baseName, stationInfo: { @@ -159,7 +159,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify validateStationInfo() - Missing templateName', () => { + await it('should verify validateStationInfo() - Missing templateName', () => { const stationMissingName = createChargingStation({ baseName, stationInfo: { @@ -175,7 +175,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError(`${baseName}-00001: Missing templateName in stationInfo properties`)) }) - await it('Verify validateStationInfo() - Empty templateName', () => { + await it('should verify validateStationInfo() - Empty templateName', () => { const stationEmptyName = createChargingStation({ baseName, stationInfo: { @@ -191,7 +191,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError(`${baseName}-00001: Missing templateName in stationInfo properties`)) }) - await it('Verify validateStationInfo() - Missing maximumPower', () => { + await it('should verify validateStationInfo() - Missing maximumPower', () => { const stationMissingPower = createChargingStation({ baseName, stationInfo: { @@ -208,7 +208,7 @@ await describe('Helpers test suite', async () => { }).toThrow(new BaseError(`${baseName}-00001: Missing maximumPower in stationInfo properties`)) }) - await it('Verify validateStationInfo() - Invalid maximumPower (zero)', () => { + await it('should verify validateStationInfo() - Invalid maximumPower (zero)', () => { const stationInvalidPower = createChargingStation({ baseName, stationInfo: { @@ -227,7 +227,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify validateStationInfo() - Missing maximumAmperage', () => { + await it('should verify validateStationInfo() - Missing maximumAmperage', () => { const stationMissingAmperage = createChargingStation({ baseName, stationInfo: { @@ -247,7 +247,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify validateStationInfo() - Invalid maximumAmperage (zero)', () => { + await it('should verify validateStationInfo() - Invalid maximumAmperage (zero)', () => { const stationInvalidAmperage = createChargingStation({ baseName, stationInfo: { @@ -267,7 +267,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify validateStationInfo() - Valid configuration passes', () => { + await it('should verify validateStationInfo() - Valid configuration passes', () => { const validStation = createChargingStation({ baseName, stationInfo: { @@ -285,7 +285,7 @@ await describe('Helpers test suite', async () => { }).not.toThrow() }) - await it('Verify validateStationInfo() - OCPP 2.0 requires EVSE', () => { + await it('should verify validateStationInfo() - OCPP 2.0 requires EVSE', () => { const stationOcpp20 = createChargingStation({ baseName, connectorsCount: 0, // Ensure no EVSEs are created @@ -309,7 +309,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify validateStationInfo() - OCPP 2.0.1 requires EVSE', () => { + await it('should verify validateStationInfo() - OCPP 2.0.1 requires EVSE', () => { const stationOcpp201 = createChargingStation({ baseName, connectorsCount: 0, // Ensure no EVSEs are created @@ -333,28 +333,28 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify checkChargingStationState() - Not started or starting', t => { + await it('should verify checkChargingStationState() - Not started or starting', t => { const warnMock = t.mock.method(logger, 'warn') const stationNotStarted = createChargingStation({ baseName, started: false, starting: false }) expect(checkChargingStationState(stationNotStarted, 'log prefix |')).toBe(false) expect(warnMock.mock.calls.length).toBe(1) }) - await it('Verify checkChargingStationState() - Starting returns true', t => { + await it('should verify checkChargingStationState() - Starting returns true', t => { const warnMock = t.mock.method(logger, 'warn') const stationStarting = createChargingStation({ baseName, started: false, starting: true }) expect(checkChargingStationState(stationStarting, 'log prefix |')).toBe(true) expect(warnMock.mock.calls.length).toBe(0) }) - await it('Verify checkChargingStationState() - Started returns true', t => { + await it('should verify checkChargingStationState() - Started returns true', t => { const warnMock = t.mock.method(logger, 'warn') const stationStarted = createChargingStation({ baseName, started: true, starting: false }) expect(checkChargingStationState(stationStarted, 'log prefix |')).toBe(true) expect(warnMock.mock.calls.length).toBe(0) }) - await it('Verify getPhaseRotationValue()', () => { + await it('should verify getPhaseRotationValue()', () => { expect(getPhaseRotationValue(0, 0)).toBe('0.RST') expect(getPhaseRotationValue(1, 0)).toBe('1.NotApplicable') expect(getPhaseRotationValue(2, 0)).toBe('2.NotApplicable') @@ -369,12 +369,12 @@ await describe('Helpers test suite', async () => { expect(getPhaseRotationValue(2, 3)).toBe('2.RST') }) - await it('Verify getMaxNumberOfEvses()', () => { + await it('should verify getMaxNumberOfEvses()', () => { expect(getMaxNumberOfEvses(undefined)).toBe(-1) expect(getMaxNumberOfEvses({})).toBe(0) }) - await it('Verify checkTemplate()', t => { + await it('should verify checkTemplate()', t => { const warnMock = t.mock.method(logger, 'warn') const errorMock = t.mock.method(logger, 'error') expect(() => { @@ -391,7 +391,7 @@ await describe('Helpers test suite', async () => { expect(warnMock.mock.calls.length).toBe(1) }) - await it('Verify checkConfiguration()', t => { + await it('should verify checkConfiguration()', t => { const errorMock = t.mock.method(logger, 'error') expect(() => { checkConfiguration(undefined, 'log prefix |', 'configuration.json') @@ -405,7 +405,7 @@ await describe('Helpers test suite', async () => { expect(errorMock.mock.calls.length).toBe(2) }) - await it('Verify checkStationInfoConnectorStatus()', t => { + await it('should verify checkStationInfoConnectorStatus()', t => { const warnMock = t.mock.method(logger, 'warn') checkStationInfoConnectorStatus(1, {} as ConnectorStatus, 'log prefix |', 'test-template.json') expect(warnMock.mock.calls.length).toBe(0) @@ -417,7 +417,7 @@ await describe('Helpers test suite', async () => { expect(connectorStatus.status).toBeUndefined() }) - await it('Verify getBootConnectorStatus() - default to Available when no bootStatus', () => { + await it('should verify getBootConnectorStatus() - default to Available when no bootStatus', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2 }) const connectorStatus = {} as ConnectorStatus expect(getBootConnectorStatus(chargingStation, 1, connectorStatus)).toBe( @@ -425,7 +425,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify getBootConnectorStatus() - use bootStatus from template', () => { + await it('should verify getBootConnectorStatus() - use bootStatus from template', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2 }) const connectorStatus = { bootStatus: ConnectorStatusEnum.Unavailable, @@ -435,7 +435,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify getBootConnectorStatus() - charging station unavailable overrides bootStatus', () => { + await it('should verify getBootConnectorStatus() - charging station unavailable overrides bootStatus', () => { const chargingStation = createChargingStation({ baseName, connectorDefaults: { availability: AvailabilityType.Inoperative }, @@ -449,7 +449,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify getBootConnectorStatus() - connector unavailable overrides bootStatus', () => { + await it('should verify getBootConnectorStatus() - connector unavailable overrides bootStatus', () => { const chargingStation = createChargingStation({ baseName, connectorDefaults: { availability: AvailabilityType.Inoperative }, @@ -464,7 +464,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify getBootConnectorStatus() - transaction in progress restores previous status', () => { + await it('should verify getBootConnectorStatus() - transaction in progress restores previous status', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2 }) const connectorStatus = { bootStatus: ConnectorStatusEnum.Available, @@ -476,7 +476,7 @@ await describe('Helpers test suite', async () => { ) }) - await it('Verify getBootConnectorStatus() - no transaction uses bootStatus over previous status', () => { + await it('should verify getBootConnectorStatus() - no transaction uses bootStatus over previous status', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2 }) const connectorStatus = { bootStatus: ConnectorStatusEnum.Available, @@ -489,35 +489,35 @@ await describe('Helpers test suite', async () => { }) // Tests for reservation helper functions - await it('Verify hasReservationExpired() - expired reservation', () => { + await it('should verify hasReservationExpired() - expired reservation', () => { expect(hasReservationExpired(createTestReservation(true))).toBe(true) }) - await it('Verify hasReservationExpired() - valid reservation', () => { + await it('should verify hasReservationExpired() - valid reservation', () => { expect(hasReservationExpired(createTestReservation(false))).toBe(false) }) - await it('Verify hasPendingReservation() - no reservation', () => { + await it('should verify hasPendingReservation() - no reservation', () => { const connectorStatus = {} as ConnectorStatus expect(hasPendingReservation(connectorStatus)).toBe(false) }) - await it('Verify hasPendingReservation() - with valid reservation', () => { + await it('should verify hasPendingReservation() - with valid reservation', () => { const connectorStatus = { reservation: createTestReservation(false) } as ConnectorStatus expect(hasPendingReservation(connectorStatus)).toBe(true) }) - await it('Verify hasPendingReservation() - with expired reservation', () => { + await it('should verify hasPendingReservation() - with expired reservation', () => { const connectorStatus = { reservation: createTestReservation(true) } as ConnectorStatus expect(hasPendingReservation(connectorStatus)).toBe(false) }) - await it('Verify hasPendingReservations() - no reservations (without EVSEs)', () => { + await it('should verify hasPendingReservations() - no reservations (without EVSEs)', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2 }) expect(hasPendingReservations(chargingStation)).toBe(false) }) - await it('Verify hasPendingReservations() - with pending reservation (without EVSEs)', () => { + await it('should verify hasPendingReservations() - with pending reservation (without EVSEs)', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2 }) const connectorStatus = chargingStation.connectors.get(1) if (connectorStatus != null) { @@ -526,7 +526,7 @@ await describe('Helpers test suite', async () => { expect(hasPendingReservations(chargingStation)).toBe(true) }) - await it('Verify hasPendingReservations() - no reservations (with EVSEs)', () => { + await it('should verify hasPendingReservations() - no reservations (with EVSEs)', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2, @@ -535,7 +535,7 @@ await describe('Helpers test suite', async () => { expect(hasPendingReservations(chargingStation)).toBe(false) }) - await it('Verify hasPendingReservations() - with pending reservation (with EVSEs)', () => { + await it('should verify hasPendingReservations() - with pending reservation (with EVSEs)', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2, @@ -549,7 +549,7 @@ await describe('Helpers test suite', async () => { expect(hasPendingReservations(chargingStation)).toBe(true) }) - await it('Verify hasPendingReservations() - with expired reservation only (with EVSEs)', () => { + await it('should verify hasPendingReservations() - with expired reservation only (with EVSEs)', () => { const chargingStation = createChargingStation({ baseName, connectorsCount: 2, diff --git a/tests/charging-station/helpers/StationHelpers.ts b/tests/charging-station/helpers/StationHelpers.ts index fc075105..68c1d7d5 100644 --- a/tests/charging-station/helpers/StationHelpers.ts +++ b/tests/charging-station/helpers/StationHelpers.ts @@ -49,6 +49,16 @@ export interface ChargingStationMocks { webSocket: MockWebSocket } +/** + * Options for customizing connector status creation + */ +export interface CreateConnectorStatusOptions { + /** Override availability (default: AvailabilityType.Operative) */ + availability?: AvailabilityType + /** Override status (default: ConnectorStatusEnum.Available) */ + status?: ConnectorStatusEnum +} + /** * Options for creating a mock ChargingStation instance */ @@ -157,6 +167,45 @@ export function cleanupChargingStation (station: ChargingStation): void { MockIdTagsCache.resetInstance() } +/** + * Create a connector status object with default values + * + * This is the canonical factory for creating ConnectorStatus objects in tests. + * Both ChargingStationFactory and StationHelpers use this function. + * @param _connectorId - Connector ID (unused, kept for API consistency) + * @param options - Optional overrides for default values + * @returns ConnectorStatus with default or customized values + * @example + * ```typescript + * // Default connector status + * const status = createConnectorStatus(1) + * + * // Customized connector status + * const status = createConnectorStatus(1, { availability: AvailabilityType.Inoperative }) + * ``` + */ +export function createConnectorStatus ( + _connectorId: number, + options: CreateConnectorStatusOptions = {} +): ConnectorStatus { + return { + availability: options.availability ?? AvailabilityType.Operative, + bootStatus: ConnectorStatusEnum.Available, + chargingProfiles: [], + energyActiveImportRegisterValue: 0, + idTagAuthorized: false, + idTagLocalAuthorized: false, + MeterValues: [], + status: options.status ?? ConnectorStatusEnum.Available, + transactionEnergyActiveImportRegisterValue: 0, + transactionId: undefined, + transactionIdTag: undefined, + transactionRemoteStarted: false, + transactionStart: undefined, + transactionStarted: false, + } as unknown as ConnectorStatus +} + /** * Creates a minimal mock ChargingStation-like object for testing * @@ -783,30 +832,6 @@ export async function waitForCondition ( } } -/** - * Create a connector status object with default values - * @param connectorId - Connector ID - * @returns Default connector status - */ -function createConnectorStatus (connectorId: number): ConnectorStatus { - return { - availability: AvailabilityType.Operative, - bootStatus: ConnectorStatusEnum.Available, - chargingProfiles: [], - energyActiveImportRegisterValue: 0, - idTagAuthorized: false, - idTagLocalAuthorized: false, - MeterValues: [], - status: ConnectorStatusEnum.Available, - transactionEnergyActiveImportRegisterValue: 0, - transactionId: undefined, - transactionIdTag: undefined, - transactionRemoteStarted: false, - transactionStart: undefined, - transactionStarted: false, - } as unknown as ConnectorStatus -} - /** * Reset a single connector status to default values * @param status - Connector status object to reset diff --git a/tests/charging-station/mocks/MockWebSocket.ts b/tests/charging-station/mocks/MockWebSocket.ts index 04e75bc7..32f2c6cb 100644 --- a/tests/charging-station/mocks/MockWebSocket.ts +++ b/tests/charging-station/mocks/MockWebSocket.ts @@ -186,3 +186,19 @@ export class MockWebSocket extends EventEmitter { this.emit('close', 1006, Buffer.from('Connection terminated')) } } + +/** + * Factory function to create a MockWebSocket configured for UI protocol + * @param protocol - UI protocol version (default: 'ui0.0.1') + * @returns MockWebSocket instance configured for UI testing + * @example + * ```typescript + * const uiWs = createUIProtocolMock() + * expect(uiWs.protocol).toBe('ui0.0.1') + * ``` + */ +export function createUIProtocolMock (protocol = 'ui0.0.1'): MockWebSocket { + const ws = new MockWebSocket('ws://localhost:8080/ui') + ws.protocol = protocol + return ws +} diff --git a/tests/charging-station/ocpp/2.0/OCPP20CertificateManager.test.ts b/tests/charging-station/ocpp/2.0/OCPP20CertificateManager.test.ts index 701dab7d..b126c688 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20CertificateManager.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20CertificateManager.test.ts @@ -65,7 +65,7 @@ await describe('OCPP20CertificateManager', async () => { }) await describe('storeCertificate', async () => { - await it('Should store a valid PEM certificate to the correct path', async () => { + await it('should store a valid PEM certificate to the correct path', async () => { const manager = new OCPP20CertificateManager() const result = await manager.storeCertificate( @@ -81,7 +81,7 @@ await describe('OCPP20CertificateManager', async () => { expect(result.filePath).toMatch(/\.pem$/) }) - await it('Should reject invalid PEM certificate without BEGIN/END markers', async () => { + await it('should reject invalid PEM certificate without BEGIN/END markers', async () => { const manager = new OCPP20CertificateManager() const result = await manager.storeCertificate( @@ -95,7 +95,7 @@ await describe('OCPP20CertificateManager', async () => { expect(result.error).toContain('Invalid PEM format') }) - await it('Should reject empty certificate data', async () => { + await it('should reject empty certificate data', async () => { const manager = new OCPP20CertificateManager() const result = await manager.storeCertificate( @@ -109,7 +109,7 @@ await describe('OCPP20CertificateManager', async () => { expect(result.error).toBeDefined() }) - await it('Should create certificate directory structure if not exists', async () => { + await it('should create certificate directory structure if not exists', async () => { const manager = new OCPP20CertificateManager() const result = await manager.storeCertificate( @@ -125,7 +125,7 @@ await describe('OCPP20CertificateManager', async () => { }) await describe('deleteCertificate', async () => { - await it('Should delete certificate by hash data', async () => { + await it('should delete certificate by hash data', async () => { const manager = new OCPP20CertificateManager() const hashData: CertificateHashDataType = { @@ -142,7 +142,7 @@ await describe('OCPP20CertificateManager', async () => { expect(['Accepted', 'NotFound', 'Failed']).toContain(result.status) }) - await it('Should return NotFound for non-existent certificate', async () => { + await it('should return NotFound for non-existent certificate', async () => { const manager = new OCPP20CertificateManager() const hashData: CertificateHashDataType = { @@ -158,7 +158,7 @@ await describe('OCPP20CertificateManager', async () => { expect(result.status).toBe('NotFound') }) - await it('Should handle filesystem errors gracefully', async () => { + await it('should handle filesystem errors gracefully', async () => { const manager = new OCPP20CertificateManager() const hashData: CertificateHashDataType = { @@ -176,7 +176,7 @@ await describe('OCPP20CertificateManager', async () => { }) await describe('getInstalledCertificates', async () => { - await it('Should return list of installed certificates for station', async () => { + await it('should return list of installed certificates for station', async () => { const manager = new OCPP20CertificateManager() const result = await manager.getInstalledCertificates(TEST_STATION_HASH_ID) @@ -185,7 +185,7 @@ await describe('OCPP20CertificateManager', async () => { expect(Array.isArray(result.certificateHashDataChain)).toBe(true) }) - await it('Should filter certificates by type when filter provided', async () => { + await it('should filter certificates by type when filter provided', async () => { const manager = new OCPP20CertificateManager() const filterTypes = [InstallCertificateUseEnumType.CSMSRootCertificate] @@ -195,7 +195,7 @@ await describe('OCPP20CertificateManager', async () => { expect(Array.isArray(result.certificateHashDataChain)).toBe(true) }) - await it('Should return empty list when no certificates installed', async () => { + await it('should return empty list when no certificates installed', async () => { const manager = new OCPP20CertificateManager() const result = await manager.getInstalledCertificates('empty-station-hash-id') @@ -204,7 +204,7 @@ await describe('OCPP20CertificateManager', async () => { expect(result.certificateHashDataChain).toHaveLength(0) }) - await it('Should support multiple certificate type filters', async () => { + await it('should support multiple certificate type filters', async () => { const manager = new OCPP20CertificateManager() const filterTypes = [ @@ -220,7 +220,7 @@ await describe('OCPP20CertificateManager', async () => { }) await describe('computeCertificateHash', async () => { - await it('Should compute hash data for valid PEM certificate', () => { + await it('should compute hash data for valid PEM certificate', () => { const manager = new OCPP20CertificateManager() const hashData = manager.computeCertificateHash(VALID_PEM_CERTIFICATE) @@ -235,7 +235,7 @@ await describe('OCPP20CertificateManager', async () => { expect(typeof hashData.serialNumber).toBe('string') }) - await it('Should return hex-encoded hash values', () => { + await it('should return hex-encoded hash values', () => { const manager = new OCPP20CertificateManager() const hashData = manager.computeCertificateHash(VALID_PEM_CERTIFICATE) @@ -245,7 +245,7 @@ await describe('OCPP20CertificateManager', async () => { expect(hashData.issuerKeyHash).toMatch(hexPattern) }) - await it('Should throw error for invalid PEM certificate', () => { + await it('should throw error for invalid PEM certificate', () => { const manager = new OCPP20CertificateManager() expect(() => { @@ -253,7 +253,7 @@ await describe('OCPP20CertificateManager', async () => { }).toThrow() }) - await it('Should throw error for empty certificate', () => { + await it('should throw error for empty certificate', () => { const manager = new OCPP20CertificateManager() expect(() => { @@ -261,7 +261,7 @@ await describe('OCPP20CertificateManager', async () => { }).toThrow() }) - await it('Should support SHA384 hash algorithm', () => { + await it('should support SHA384 hash algorithm', () => { const manager = new OCPP20CertificateManager() const hashData = manager.computeCertificateHash( @@ -273,7 +273,7 @@ await describe('OCPP20CertificateManager', async () => { expect(hashData.hashAlgorithm).toBe(HashAlgorithmEnumType.SHA384) }) - await it('Should support SHA512 hash algorithm', () => { + await it('should support SHA512 hash algorithm', () => { const manager = new OCPP20CertificateManager() const hashData = manager.computeCertificateHash( @@ -287,7 +287,7 @@ await describe('OCPP20CertificateManager', async () => { }) await describe('validateCertificateFormat', async () => { - await it('Should return true for valid PEM certificate', () => { + await it('should return true for valid PEM certificate', () => { const manager = new OCPP20CertificateManager() const isValid = manager.validateCertificateFormat(VALID_PEM_CERTIFICATE) @@ -295,7 +295,7 @@ await describe('OCPP20CertificateManager', async () => { expect(isValid).toBe(true) }) - await it('Should return false for certificate without BEGIN marker', () => { + await it('should return false for certificate without BEGIN marker', () => { const manager = new OCPP20CertificateManager() const isValid = manager.validateCertificateFormat(INVALID_PEM_NO_MARKERS) @@ -303,7 +303,7 @@ await describe('OCPP20CertificateManager', async () => { expect(isValid).toBe(false) }) - await it('Should return false for certificate with wrong markers', () => { + await it('should return false for certificate with wrong markers', () => { const manager = new OCPP20CertificateManager() const isValid = manager.validateCertificateFormat(INVALID_PEM_WRONG_MARKERS) @@ -311,7 +311,7 @@ await describe('OCPP20CertificateManager', async () => { expect(isValid).toBe(false) }) - await it('Should return false for empty string', () => { + await it('should return false for empty string', () => { const manager = new OCPP20CertificateManager() const isValid = manager.validateCertificateFormat(EMPTY_PEM_CERTIFICATE) @@ -319,14 +319,14 @@ await describe('OCPP20CertificateManager', async () => { expect(isValid).toBe(false) }) - await it('Should return false for null/undefined input', () => { + await it('should return false for null/undefined input', () => { const manager = new OCPP20CertificateManager() expect(manager.validateCertificateFormat(null as any)).toBe(false) expect(manager.validateCertificateFormat(undefined as any)).toBe(false) }) - await it('Should return true for certificate with extra whitespace', () => { + await it('should return true for certificate with extra whitespace', () => { const manager = new OCPP20CertificateManager() const pemWithWhitespace = ` @@ -344,7 +344,7 @@ await describe('OCPP20CertificateManager', async () => { }) await describe('getCertificatePath', async () => { - await it('Should return correct file path for certificate', () => { + await it('should return correct file path for certificate', () => { const manager = new OCPP20CertificateManager() const path = manager.getCertificatePath(TEST_STATION_HASH_ID, TEST_CERT_TYPE, 'SERIAL-12345') @@ -357,7 +357,7 @@ await describe('OCPP20CertificateManager', async () => { expect(path).toMatch(/\.pem$/) }) - await it('Should handle special characters in serial number', () => { + await it('should handle special characters in serial number', () => { const manager = new OCPP20CertificateManager() const path = manager.getCertificatePath( @@ -372,7 +372,7 @@ await describe('OCPP20CertificateManager', async () => { expect(filename).not.toContain('/') }) - await it('Should return different paths for different certificate types', () => { + await it('should return different paths for different certificate types', () => { const manager = new OCPP20CertificateManager() const csmsPath = manager.getCertificatePath( @@ -392,7 +392,7 @@ await describe('OCPP20CertificateManager', async () => { expect(v2gPath).toContain('V2GRootCertificate') }) - await it('Should return path following project convention', () => { + await it('should return path following project convention', () => { const manager = new OCPP20CertificateManager() const path = manager.getCertificatePath(TEST_STATION_HASH_ID, TEST_CERT_TYPE, 'SERIAL-12345') @@ -404,7 +404,7 @@ await describe('OCPP20CertificateManager', async () => { }) await describe('Edge cases and error handling', async () => { - await it('Should handle concurrent certificate operations', async () => { + await it('should handle concurrent certificate operations', async () => { const manager = new OCPP20CertificateManager() const results = await Promise.all([ @@ -427,7 +427,7 @@ await describe('OCPP20CertificateManager', async () => { }) }) - await it('Should handle very long certificate chains', async () => { + await it('should handle very long certificate chains', async () => { const manager = new OCPP20CertificateManager() const longChain = Array(5).fill(VALID_PEM_CERTIFICATE).join('\n') @@ -437,7 +437,7 @@ await describe('OCPP20CertificateManager', async () => { expect(result).toBeDefined() }) - await it('Should sanitize station hash ID for filesystem safety', () => { + await it('should sanitize station hash ID for filesystem safety', () => { const manager = new OCPP20CertificateManager() const maliciousHashId = '../../../etc/passwd' diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-CertificateSigned.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-CertificateSigned.test.ts index 4c63be47..3dff62be 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-CertificateSigned.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-CertificateSigned.test.ts @@ -125,7 +125,7 @@ await describe('I04 - CertificateSigned', async () => { const testableService = createTestableIncomingRequestService(incomingRequestService) await describe('Valid Certificate Chain Installation', async () => { - await it('Should accept valid certificate chain', async () => { + await it('should accept valid certificate chain', async () => { mockChargingStation.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -145,7 +145,7 @@ await describe('I04 - CertificateSigned', async () => { expect(response.status).toBe(GenericStatus.Accepted) }) - await it('Should accept single certificate (no chain)', async () => { + await it('should accept single certificate (no chain)', async () => { mockChargingStation.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -165,7 +165,7 @@ await describe('I04 - CertificateSigned', async () => { }) await describe('Invalid Certificate Handling', async () => { - await it('Should reject certificate with invalid PEM format', async () => { + await it('should reject certificate with invalid PEM format', async () => { const request: OCPP20CertificateSignedRequest = { certificateChain: INVALID_PEM_CERTIFICATE_MISSING_MARKERS, certificateType: CertificateSigningUseEnumType.ChargingStationCertificate, @@ -183,7 +183,7 @@ await describe('I04 - CertificateSigned', async () => { }) await describe('ChargingStationCertificate Reconnect Logic', async () => { - await it('Should trigger websocket reconnect for ChargingStationCertificate type', async () => { + await it('should trigger websocket reconnect for ChargingStationCertificate type', async () => { const mockCertManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -206,7 +206,7 @@ await describe('I04 - CertificateSigned', async () => { }) await describe('V2GCertificate Storage', async () => { - await it('Should store V2GCertificate separately without reconnect', async () => { + await it('should store V2GCertificate separately without reconnect', async () => { const mockCertManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -231,7 +231,7 @@ await describe('I04 - CertificateSigned', async () => { }) await describe('Certificate Manager Missing', async () => { - await it('Should return Rejected status with InternalError when certificate manager is missing', async () => { + await it('should return Rejected status with InternalError when certificate manager is missing', async () => { // Create a separate mock charging station without certificateManager const stationWithoutCertManager = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, @@ -264,7 +264,7 @@ await describe('I04 - CertificateSigned', async () => { }) await describe('Storage Failure Handling', async () => { - await it('Should return Rejected status when storage fails', async () => { + await it('should return Rejected status when storage fails', async () => { mockChargingStation.certificateManager = createMockCertificateManager({ storeCertificateResult: false, }) @@ -283,7 +283,7 @@ await describe('I04 - CertificateSigned', async () => { expect(response.statusInfo?.reasonCode).toBeDefined() }) - await it('Should return Rejected status when storage throws error', async () => { + await it('should return Rejected status when storage throws error', async () => { mockChargingStation.certificateManager = createMockCertificateManager({ storeCertificateError: new Error('Storage full'), }) @@ -304,7 +304,7 @@ await describe('I04 - CertificateSigned', async () => { }) await describe('Response Structure Validation', async () => { - await it('Should return response matching CertificateSignedResponse schema', async () => { + await it('should return response matching CertificateSignedResponse schema', async () => { mockChargingStation.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -340,7 +340,7 @@ await describe('I04 - CertificateSigned', async () => { } }) - await it('Should include statusInfo with reasonCode for rejection', async () => { + await it('should include statusInfo with reasonCode for rejection', async () => { const request: OCPP20CertificateSignedRequest = { certificateChain: INVALID_PEM_CERTIFICATE_MISSING_MARKERS, certificateType: CertificateSigningUseEnumType.ChargingStationCertificate, diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-ClearCache.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-ClearCache.test.ts index d1e9b2f6..f99573fa 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-ClearCache.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-ClearCache.test.ts @@ -31,7 +31,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () const testableService = createTestableIncomingRequestService(incomingRequestService) // FR: C11.FR.01 - CS SHALL attempt to clear its Authorization Cache - await it('Should handle ClearCache request successfully', async () => { + await it('should handle ClearCache request successfully', async () => { const response = await testableService.handleRequestClearCache(mockChargingStation) expect(response).toBeDefined() @@ -42,7 +42,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () }) // FR: C11.FR.02 - Return correct status based on cache clearing result - await it('Should return correct status based on cache clearing result', async () => { + await it('should return correct status based on cache clearing result', async () => { const response = await testableService.handleRequestClearCache(mockChargingStation) expect(response).toBeDefined() @@ -53,7 +53,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () // CLR-001: Verify Authorization Cache is cleared (not IdTagsCache) await describe('CLR-001 - ClearCache clears Authorization Cache', async () => { - await it('Should call authService.clearCache() on ClearCache request', async () => { + await it('should call authService.clearCache() on ClearCache request', async () => { // Create a mock auth service to verify clearCache is called let clearCacheCalled = false const mockAuthService = { @@ -83,7 +83,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () } }) - await it('Should NOT call idTagsCache.deleteIdTags() on ClearCache request', async () => { + await it('should NOT call idTagsCache.deleteIdTags() on ClearCache request', async () => { // Verify that IdTagsCache is not touched let deleteIdTagsCalled = false const originalDeleteIdTags = mockChargingStation.idTagsCache.deleteIdTags.bind(mockChargingStation.idTagsCache) @@ -106,7 +106,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () // CLR-002: Verify AuthCacheEnabled check per C11.FR.04 await describe('CLR-002 - AuthCacheEnabled Check (C11.FR.04)', async () => { - await it('Should return Rejected when AuthCacheEnabled is false', async () => { + await it('should return Rejected when AuthCacheEnabled is false', async () => { // Create a mock auth service with cache disabled const mockAuthService = { clearCache: (): Promise => { @@ -133,7 +133,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () } }) - await it('Should return Accepted when AuthCacheEnabled is true and clear succeeds', async () => { + await it('should return Accepted when AuthCacheEnabled is true and clear succeeds', async () => { // Create a mock auth service with cache enabled const mockAuthService = { clearCache: (): Promise => { @@ -161,7 +161,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () } }) - await it('Should return Rejected when clearCache throws an error', async () => { + await it('should return Rejected when clearCache throws an error', async () => { // Create a mock auth service that throws on clearCache const mockAuthService = { clearCache: (): Promise => { @@ -188,7 +188,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () } }) - await it('Should not attempt to clear cache when AuthCacheEnabled is false', async () => { + await it('should not attempt to clear cache when AuthCacheEnabled is false', async () => { let clearCacheAttempted = false const mockAuthService = { clearCache: (): Promise => { @@ -220,7 +220,7 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async () // C11.FR.05: IF the CS does not support an Authorization Cache → Rejected await describe('C11.FR.05 - No Authorization Cache Support', async () => { - await it('Should return Rejected when authService factory fails (no cache support)', async () => { + await it('should return Rejected when authService factory fails (no cache support)', async () => { // Mock factory to throw error (simulates no Authorization Cache support) const originalGetInstance = OCPPAuthServiceFactory.getInstance.bind(OCPPAuthServiceFactory) Object.assign(OCPPAuthServiceFactory, { diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-DeleteCertificate.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-DeleteCertificate.test.ts index e18be6af..696133fb 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-DeleteCertificate.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-DeleteCertificate.test.ts @@ -74,7 +74,7 @@ await describe('I04 - DeleteCertificate', async () => { const testableService = createTestableIncomingRequestService(incomingRequestService) await describe('Valid Certificate Deletion', async () => { - await it('Should accept deletion of existing certificate', async () => { + await it('should accept deletion of existing certificate', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ deleteCertificateResult: { status: 'Accepted' }, }) @@ -94,7 +94,7 @@ await describe('I04 - DeleteCertificate', async () => { expect(response.statusInfo).toBeUndefined() }) - await it('Should accept deletion with SHA384 hash algorithm', async () => { + await it('should accept deletion with SHA384 hash algorithm', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ deleteCertificateResult: { status: 'Accepted' }, }) @@ -114,7 +114,7 @@ await describe('I04 - DeleteCertificate', async () => { expect(response.statusInfo).toBeUndefined() }) - await it('Should accept deletion with SHA512 hash algorithm', async () => { + await it('should accept deletion with SHA512 hash algorithm', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ deleteCertificateResult: { status: 'Accepted' }, }) @@ -136,7 +136,7 @@ await describe('I04 - DeleteCertificate', async () => { }) await describe('Certificate Not Found', async () => { - await it('Should return NotFound for non-existent certificate', async () => { + await it('should return NotFound for non-existent certificate', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ deleteCertificateResult: { status: 'NotFound' }, }) @@ -154,7 +154,7 @@ await describe('I04 - DeleteCertificate', async () => { }) await describe('Deletion Failure Handling', async () => { - await it('Should return Failed status when deletion throws error', async () => { + await it('should return Failed status when deletion throws error', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ deleteCertificateError: new Error('Deletion failed'), }) @@ -172,7 +172,7 @@ await describe('I04 - DeleteCertificate', async () => { expect(response.statusInfo?.reasonCode).toBeDefined() }) - await it('Should return Failed with InternalError when certificateManager is missing', async () => { + await it('should return Failed with InternalError when certificateManager is missing', async () => { const stationWithoutCertManager = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, connectorsCount: 3, @@ -203,7 +203,7 @@ await describe('I04 - DeleteCertificate', async () => { }) await describe('Response Structure Validation', async () => { - await it('Should return response matching DeleteCertificateResponse schema', async () => { + await it('should return response matching DeleteCertificateResponse schema', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ deleteCertificateResult: { status: 'Accepted' }, }) @@ -239,7 +239,7 @@ await describe('I04 - DeleteCertificate', async () => { } }) - await it('Should include statusInfo with reasonCode for failure', async () => { + await it('should include statusInfo with reasonCode for failure', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ deleteCertificateError: new Error('Deletion failed'), }) diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetBaseReport.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetBaseReport.test.ts index 221816a3..6084cf25 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetBaseReport.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetBaseReport.test.ts @@ -65,7 +65,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B07.FR.01, B07.FR.07 - await it('Should handle GetBaseReport request with ConfigurationInventory', () => { + await it('should handle GetBaseReport request with ConfigurationInventory', () => { const request: OCPP20GetBaseReportRequest = { reportBase: ReportBaseEnumType.ConfigurationInventory, requestId: 1, @@ -78,7 +78,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.02 - await it('Should handle GetBaseReport request with FullInventory', () => { + await it('should handle GetBaseReport request with FullInventory', () => { const request: OCPP20GetBaseReportRequest = { reportBase: ReportBaseEnumType.FullInventory, requestId: 2, @@ -90,7 +90,7 @@ await describe('B07 - Get Base Report', async () => { expect(response.status).toBe(GenericDeviceModelStatusEnumType.Accepted) }) - await it('Should include registry variables with Actual attribute only for unsupported types', () => { + await it('should include registry variables with Actual attribute only for unsupported types', () => { const reportData = testableService.buildReportData( mockChargingStation, ReportBaseEnumType.FullInventory @@ -124,7 +124,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.03 - await it('Should handle GetBaseReport request with SummaryInventory', () => { + await it('should handle GetBaseReport request with SummaryInventory', () => { const request: OCPP20GetBaseReportRequest = { reportBase: ReportBaseEnumType.SummaryInventory, requestId: 3, @@ -137,7 +137,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.04 - await it('Should return NotSupported for unsupported reportBase', () => { + await it('should return NotSupported for unsupported reportBase', () => { const request: OCPP20GetBaseReportRequest = { reportBase: 'UnsupportedReportBase' as unknown as ReportBaseEnumType, requestId: 4, @@ -150,7 +150,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.05 - await it('Should return Accepted for ConfigurationInventory with configured station', () => { + await it('should return Accepted for ConfigurationInventory with configured station', () => { // Create a charging station with minimal configuration const request: OCPP20GetBaseReportRequest = { @@ -165,7 +165,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.06 - await it('Should build correct report data for ConfigurationInventory', () => { + await it('should build correct report data for ConfigurationInventory', () => { const request: OCPP20GetBaseReportRequest = { reportBase: ReportBaseEnumType.ConfigurationInventory, requestId: 6, @@ -200,7 +200,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.07 - await it('Should build correct report data for FullInventory with station info', () => { + await it('should build correct report data for FullInventory with station info', () => { const reportData = testableService.buildReportData( mockChargingStation, ReportBaseEnumType.FullInventory @@ -232,7 +232,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.08 - await it('Should build correct report data for SummaryInventory', () => { + await it('should build correct report data for SummaryInventory', () => { const reportData = testableService.buildReportData( mockChargingStation, ReportBaseEnumType.SummaryInventory @@ -254,7 +254,7 @@ await describe('B07 - Get Base Report', async () => { }) // ReportingValueSize truncation test - await it('Should truncate long SequenceList/MemberList values per ReportingValueSize', () => { + await it('should truncate long SequenceList/MemberList values per ReportingValueSize', () => { // Ensure ReportingValueSize is at a small value (default is Constants.OCPP_VALUE_ABSOLUTE_MAX_LENGTH). We will override configuration key if absent. const reportingSizeKey = StandardParametersKey.ReportingValueSize // Add or lower configuration key to 10 to force truncation @@ -305,7 +305,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.09 - await it('Should handle GetBaseReport with EVSE structure', () => { + await it('should handle GetBaseReport with EVSE structure', () => { // The createChargingStation should create a station with EVSEs const stationWithEvses = createChargingStation({ baseName: 'CS-EVSE-001', @@ -337,7 +337,7 @@ await describe('B07 - Get Base Report', async () => { }) // FR: B08.FR.10 - await it('Should validate unsupported reportBase correctly', () => { + await it('should validate unsupported reportBase correctly', () => { const reportData = testableService.buildReportData( mockChargingStation, 'InvalidReportBase' as unknown as ReportBaseEnumType diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetInstalledCertificateIds.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetInstalledCertificateIds.test.ts index 51c76461..ea1374c5 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetInstalledCertificateIds.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetInstalledCertificateIds.test.ts @@ -79,7 +79,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { const testableService = createTestableIncomingRequestService(incomingRequestService) await describe('Request All Certificate Types', async () => { - await it('Should return all certificates when no filter is provided', async () => { + await it('should return all certificates when no filter is provided', async () => { const mockCerts: CertificateHashDataChainType[] = [ createMockCertificateHashDataChain(GetCertificateIdUseEnumType.V2GRootCertificate, '111'), createMockCertificateHashDataChain(GetCertificateIdUseEnumType.MORootCertificate, '222'), @@ -104,7 +104,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { }) await describe('Request Filtered Certificate Types', async () => { - await it('Should return only V2GRootCertificate when filtered', async () => { + await it('should return only V2GRootCertificate when filtered', async () => { const v2gCert = createMockCertificateHashDataChain( GetCertificateIdUseEnumType.V2GRootCertificate, '111' @@ -130,7 +130,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { ) }) - await it('Should return multiple types when multiple filters provided', async () => { + await it('should return multiple types when multiple filters provided', async () => { const mockCerts: CertificateHashDataChainType[] = [ createMockCertificateHashDataChain(GetCertificateIdUseEnumType.V2GRootCertificate, '111'), createMockCertificateHashDataChain(GetCertificateIdUseEnumType.CSMSRootCertificate, '222'), @@ -157,7 +157,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { }) await describe('No Certificates Found', async () => { - await it('Should return Accepted with empty array when no certificates found', async () => { + await it('should return Accepted with empty array when no certificates found', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ getInstalledCertificatesResult: [], }) @@ -174,7 +174,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { expect(response.certificateHashDataChain).toBeUndefined() }) - await it('Should return NotFound when filtered type has no certificates', async () => { + await it('should return NotFound when filtered type has no certificates', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ getInstalledCertificatesResult: [], }) @@ -192,7 +192,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { }) await describe('Response Structure Validation', async () => { - await it('Should return response with required status field', async () => { + await it('should return response with required status field', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ getInstalledCertificatesResult: [], }) @@ -211,7 +211,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { ]).toContain(response.status) }) - await it('Should return valid CertificateHashDataChain structure', async () => { + await it('should return valid CertificateHashDataChain structure', async () => { const mockCert = createMockCertificateHashDataChain( GetCertificateIdUseEnumType.V2GRootCertificate, '123456' @@ -241,7 +241,7 @@ await describe('I04 - GetInstalledCertificateIds', async () => { }) await describe('Certificate Manager Missing', async () => { - await it('Should return NotFound when certificate manager is not available', async () => { + await it('should return NotFound when certificate manager is not available', async () => { const stationWithoutCertManager = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, connectorsCount: 3, diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetVariables.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetVariables.test.ts index 0f544972..65f363bb 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetVariables.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetVariables.test.ts @@ -55,7 +55,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.01 - await it('Should handle GetVariables request with valid variables', () => { + await it('should handle GetVariables request with valid variables', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -99,7 +99,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.02 - await it('Should handle GetVariables request with invalid variables', () => { + await it('should handle GetVariables request with invalid variables', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -142,7 +142,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.03 - await it('Should handle GetVariables request with unsupported attribute types', () => { + await it('should handle GetVariables request with unsupported attribute types', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -165,7 +165,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.04 - await it('Should reject AuthorizeRemoteStart under Connector component', () => { + await it('should reject AuthorizeRemoteStart under Connector component', () => { resetLimits(mockChargingStation) resetReportingValueSize(mockChargingStation) const request: OCPP20GetVariablesRequest = { @@ -186,7 +186,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.05 - await it('Should reject Target attribute for WebSocketPingInterval', () => { + await it('should reject Target attribute for WebSocketPingInterval', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -202,7 +202,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeStatus).toBe(GetVariableStatusEnumType.NotSupportedAttributeType) }) - await it('Should truncate variable value based on ReportingValueSize', () => { + await it('should truncate variable value based on ReportingValueSize', () => { // Set size below actual value length to force truncation setReportingValueSize(mockChargingStation, 2) const request: OCPP20GetVariablesRequest = { @@ -220,7 +220,7 @@ await describe('B06 - Get Variables', async () => { resetReportingValueSize(mockChargingStation) }) - await it('Should allow ReportingValueSize retrieval from DeviceDataCtrlr', () => { + await it('should allow ReportingValueSize retrieval from DeviceDataCtrlr', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -235,7 +235,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeValue).toBeDefined() }) - await it('Should enforce ItemsPerMessage limit', () => { + await it('should enforce ItemsPerMessage limit', () => { setStrictLimits(mockChargingStation, 1, 10000) const request: OCPP20GetVariablesRequest = { getVariableData: [ @@ -258,7 +258,7 @@ await describe('B06 - Get Variables', async () => { resetLimits(mockChargingStation) }) - await it('Should enforce BytesPerMessage limit (pre-calculation)', () => { + await it('should enforce BytesPerMessage limit (pre-calculation)', () => { setStrictLimits(mockChargingStation, 100, 10) const request: OCPP20GetVariablesRequest = { getVariableData: [ @@ -281,7 +281,7 @@ await describe('B06 - Get Variables', async () => { resetLimits(mockChargingStation) }) - await it('Should enforce BytesPerMessage limit (post-calculation)', () => { + await it('should enforce BytesPerMessage limit (post-calculation)', () => { // Build request likely to produce larger response due to status info entries const request: OCPP20GetVariablesRequest = { getVariableData: [ @@ -325,7 +325,7 @@ await describe('B06 - Get Variables', async () => { }) // Added tests for relocated components - await it('Should retrieve immutable DateTime from ClockCtrlr', () => { + await it('should retrieve immutable DateTime from ClockCtrlr', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -344,7 +344,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeValue).toBeDefined() }) - await it('Should retrieve MessageTimeout from OCPPCommCtrlr', () => { + await it('should retrieve MessageTimeout from OCPPCommCtrlr', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -364,7 +364,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeValue).toBeDefined() }) - await it('Should retrieve TxUpdatedInterval from SampledDataCtrlr and show default value', () => { + await it('should retrieve TxUpdatedInterval from SampledDataCtrlr and show default value', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -383,7 +383,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeValue).toBe('30') }) - await it('Should retrieve list/sequence defaults for FileTransferProtocols, TimeSource, NetworkConfigurationPriority', () => { + await it('should retrieve list/sequence defaults for FileTransferProtocols, TimeSource, NetworkConfigurationPriority', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -413,7 +413,7 @@ await describe('B06 - Get Variables', async () => { expect(netConfigPriority.attributeValue).toBe('1,2,3') }) - await it('Should retrieve list defaults for TxStartedMeasurands, TxEndedMeasurands, TxUpdatedMeasurands', () => { + await it('should retrieve list defaults for TxStartedMeasurands, TxEndedMeasurands, TxUpdatedMeasurands', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -450,7 +450,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.13 - await it('Should reject Target attribute for NetworkConfigurationPriority', () => { + await it('should reject Target attribute for NetworkConfigurationPriority', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -469,7 +469,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.15 - await it('Should return UnknownVariable when instance omitted for instance-specific MessageTimeout', () => { + await it('should return UnknownVariable when instance omitted for instance-specific MessageTimeout', () => { // MessageTimeout only registered with instance 'Default' const request: OCPP20GetVariablesRequest = { getVariableData: [ @@ -487,7 +487,7 @@ await describe('B06 - Get Variables', async () => { }) // FR: B06.FR.09 - await it('Should reject retrieval of explicit write-only variable CertificatePrivateKey', () => { + await it('should reject retrieval of explicit write-only variable CertificatePrivateKey', () => { // Explicit vendor-specific write-only variable from SecurityCtrlr const request: OCPP20GetVariablesRequest = { getVariableData: [ @@ -504,7 +504,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.WriteOnly) }) - await it('Should reject MinSet and MaxSet for WebSocketPingInterval', () => { + await it('should reject MinSet and MaxSet for WebSocketPingInterval', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -531,7 +531,7 @@ await describe('B06 - Get Variables', async () => { expect(maxSet.attributeValue).toBeUndefined() }) - await it('Should reject MinSet for MemberList variable TxStartPoint', () => { + await it('should reject MinSet for MemberList variable TxStartPoint', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -547,7 +547,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeStatus).toBe(GetVariableStatusEnumType.NotSupportedAttributeType) }) - await it('Should reject MaxSet for variable SecurityProfile (Actual only)', () => { + await it('should reject MaxSet for variable SecurityProfile (Actual only)', () => { const request: OCPP20GetVariablesRequest = { getVariableData: [ { @@ -563,7 +563,7 @@ await describe('B06 - Get Variables', async () => { expect(result.attributeStatus).toBe(GetVariableStatusEnumType.NotSupportedAttributeType) }) - await it('Should apply ValueSize then ReportingValueSize sequential truncation', () => { + await it('should apply ValueSize then ReportingValueSize sequential truncation', () => { // First apply a smaller ValueSize (5) then a smaller ReportingValueSize (3) setValueSize(mockChargingStation, 5) setReportingValueSize(mockChargingStation, 3) diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-InstallCertificate.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-InstallCertificate.test.ts index 4bb9ab74..64137e8d 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-InstallCertificate.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-InstallCertificate.test.ts @@ -88,7 +88,7 @@ await describe('I03 - InstallCertificate', async () => { const testableService = createTestableIncomingRequestService(incomingRequestService) await describe('Valid Certificate Installation', async () => { - await it('Should accept valid V2GRootCertificate', async () => { + await it('should accept valid V2GRootCertificate', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -109,7 +109,7 @@ await describe('I03 - InstallCertificate', async () => { expect(response.statusInfo).toBeUndefined() }) - await it('Should accept valid MORootCertificate', async () => { + await it('should accept valid MORootCertificate', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -127,7 +127,7 @@ await describe('I03 - InstallCertificate', async () => { expect(response.statusInfo).toBeUndefined() }) - await it('Should accept valid CSMSRootCertificate', async () => { + await it('should accept valid CSMSRootCertificate', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -145,7 +145,7 @@ await describe('I03 - InstallCertificate', async () => { expect(response.statusInfo).toBeUndefined() }) - await it('Should accept valid ManufacturerRootCertificate', async () => { + await it('should accept valid ManufacturerRootCertificate', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -165,7 +165,7 @@ await describe('I03 - InstallCertificate', async () => { }) await describe('Invalid Certificate Handling', async () => { - await it('Should reject certificate with invalid PEM format', async () => { + await it('should reject certificate with invalid PEM format', async () => { const request: OCPP20InstallCertificateRequest = { certificate: INVALID_PEM_CERTIFICATE_MISSING_MARKERS, certificateType: InstallCertificateUseEnumType.V2GRootCertificate, @@ -181,7 +181,7 @@ await describe('I03 - InstallCertificate', async () => { expect(typeof response.statusInfo?.reasonCode).toBe('string') }) - await it('Should reject expired certificate when validation is enabled', async () => { + await it('should reject expired certificate when validation is enabled', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ storeCertificateResult: false, }) @@ -205,7 +205,7 @@ await describe('I03 - InstallCertificate', async () => { }) await describe('Storage Failure Handling', async () => { - await it('Should return Failed status when storage is full', async () => { + await it('should return Failed status when storage is full', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ storeCertificateError: new Error('Storage full'), }) @@ -226,7 +226,7 @@ await describe('I03 - InstallCertificate', async () => { }) await describe('Response Structure Validation', async () => { - await it('Should return response matching InstallCertificateResponse schema', async () => { + await it('should return response matching InstallCertificateResponse schema', async () => { stationWithCertManager.certificateManager = createMockCertificateManager({ storeCertificateResult: true, }) @@ -263,7 +263,7 @@ await describe('I03 - InstallCertificate', async () => { } }) - await it('Should include statusInfo with reasonCode for rejection', async () => { + await it('should include statusInfo with reasonCode for rejection', async () => { const request: OCPP20InstallCertificateRequest = { certificate: INVALID_PEM_CERTIFICATE_MISSING_MARKERS, certificateType: InstallCertificateUseEnumType.V2GRootCertificate, diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStartTransaction.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStartTransaction.test.ts index bc0d16c4..245616eb 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStartTransaction.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStartTransaction.test.ts @@ -62,7 +62,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // FR: F01.FR.03, F01.FR.04, F01.FR.05, F01.FR.13 - await it('Should handle RequestStartTransaction with valid evseId and idToken', async () => { + await it('should handle RequestStartTransaction with valid evseId and idToken', async () => { const validRequest: OCPP20RequestStartTransactionRequest = { evseId: 1, idToken: { @@ -84,7 +84,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // FR: F01.FR.17, F02.FR.05 - Verify remoteStartId and idToken are stored for later TransactionEvent - await it('Should store remoteStartId and idToken in connector status for TransactionEvent', async () => { + await it('should store remoteStartId and idToken in connector status for TransactionEvent', async () => { const spyChargingStation = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, connectorsCount: 3, @@ -132,7 +132,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // FR: F01.FR.19 - await it('Should handle RequestStartTransaction with groupIdToken', async () => { + await it('should handle RequestStartTransaction with groupIdToken', async () => { const requestWithGroupToken: OCPP20RequestStartTransactionRequest = { evseId: 3, groupIdToken: { @@ -157,7 +157,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // OCPP 2.0.1 §2.10 ChargingProfile validation tests - await it('Should accept RequestStartTransaction with valid TxProfile (no transactionId)', async () => { + await it('should accept RequestStartTransaction with valid TxProfile (no transactionId)', async () => { const validChargingProfile: OCPP20ChargingProfileType = { chargingProfileKind: OCPP20ChargingProfileKindEnumType.Relative, chargingProfilePurpose: OCPP20ChargingProfilePurposeEnumType.TxProfile, @@ -199,7 +199,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // OCPP 2.0.1 §2.10: RequestStartTransaction requires chargingProfilePurpose=TxProfile - await it('Should reject RequestStartTransaction with non-TxProfile purpose (OCPP 2.0.1 §2.10)', async () => { + await it('should reject RequestStartTransaction with non-TxProfile purpose (OCPP 2.0.1 §2.10)', async () => { const invalidPurposeProfile: OCPP20ChargingProfileType = { chargingProfileKind: OCPP20ChargingProfileKindEnumType.Relative, chargingProfilePurpose: OCPP20ChargingProfilePurposeEnumType.TxDefaultProfile, @@ -240,7 +240,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // OCPP 2.0.1 §2.10: transactionId MUST NOT be present at RequestStartTransaction time - await it('Should reject RequestStartTransaction with TxProfile having transactionId set (OCPP 2.0.1 §2.10)', async () => { + await it('should reject RequestStartTransaction with TxProfile having transactionId set (OCPP 2.0.1 §2.10)', async () => { const profileWithTransactionId: OCPP20ChargingProfileType = { chargingProfileKind: OCPP20ChargingProfileKindEnumType.Relative, chargingProfilePurpose: OCPP20ChargingProfilePurposeEnumType.TxProfile, @@ -282,7 +282,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // FR: F01.FR.07 - await it('Should reject RequestStartTransaction for invalid evseId', async () => { + await it('should reject RequestStartTransaction for invalid evseId', async () => { const invalidEvseRequest: OCPP20RequestStartTransactionRequest = { evseId: 999, // Non-existent EVSE idToken: { @@ -299,7 +299,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // FR: F01.FR.09, F01.FR.10 - await it('Should reject RequestStartTransaction when connector is already occupied', async () => { + await it('should reject RequestStartTransaction when connector is already occupied', async () => { // First, start a transaction to occupy the connector const firstRequest: OCPP20RequestStartTransactionRequest = { evseId: 1, @@ -333,7 +333,7 @@ await describe('F01 & F02 - Remote Start Transaction', async () => { }) // FR: F02.FR.01 - await it('Should return proper response structure', async () => { + await it('should return proper response structure', async () => { const validRequest: OCPP20RequestStartTransactionRequest = { evseId: 1, idToken: { diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStopTransaction.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStopTransaction.test.ts index 8cf6b78e..2418c35b 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStopTransaction.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStopTransaction.test.ts @@ -135,7 +135,7 @@ await describe('F03 - Remote Stop Transaction', async () => { } // FR: F03.FR.02, F03.FR.03, F03.FR.07, F03.FR.09 - await it('Should successfully stop an active transaction', async () => { + await it('should successfully stop an active transaction', async () => { // Start a transaction first const transactionId = await startTransaction(1, 100) @@ -169,7 +169,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F03.FR.02, F03.FR.03 - await it('Should handle multiple active transactions correctly', async () => { + await it('should handle multiple active transactions correctly', async () => { // Reset once before starting multiple transactions resetConnectorTransactionStates() @@ -208,7 +208,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F03.FR.08 - await it('Should reject stop transaction for non-existent transaction ID', async () => { + await it('should reject stop transaction for non-existent transaction ID', async () => { // Clear previous transaction events sentTransactionEvents = [] @@ -231,7 +231,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F03.FR.08 - await it('Should reject stop transaction for invalid transaction ID format - empty string', async () => { + await it('should reject stop transaction for invalid transaction ID format - empty string', async () => { // Clear previous transaction events sentTransactionEvents = [] @@ -253,7 +253,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F03.FR.08 - await it('Should reject stop transaction for invalid transaction ID format - too long', async () => { + await it('should reject stop transaction for invalid transaction ID format - too long', async () => { // Clear previous transaction events sentTransactionEvents = [] @@ -277,7 +277,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F03.FR.02 - await it('Should accept valid transaction ID format - exactly 36 characters', async () => { + await it('should accept valid transaction ID format - exactly 36 characters', async () => { // Start a transaction first const transactionId = await startTransaction(1, 300) @@ -318,7 +318,7 @@ await describe('F03 - Remote Stop Transaction', async () => { expect(sentTransactionEvents).toHaveLength(1) }) - await it('Should handle TransactionEvent request failure gracefully', async () => { + await it('should handle TransactionEvent request failure gracefully', async () => { sentTransactionEvents = [] const failingChargingStation = createChargingStation({ @@ -380,7 +380,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F04.FR.01 - await it('Should return proper response structure', async () => { + await it('should return proper response structure', async () => { // Clear previous transaction events sentTransactionEvents = [] @@ -408,7 +408,7 @@ await describe('F03 - Remote Stop Transaction', async () => { expect(Object.keys(response as object)).toEqual(['status']) }) - await it('Should handle custom data in request payload', async () => { + await it('should handle custom data in request payload', async () => { // Start a transaction first const transactionId = await startTransaction(1, 500) @@ -437,7 +437,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F03.FR.07, F03.FR.09 - await it('Should validate TransactionEvent content correctly', async () => { + await it('should validate TransactionEvent content correctly', async () => { // Start a transaction first const transactionId = await startTransaction(2, 600) // Use EVSE 2 @@ -478,7 +478,7 @@ await describe('F03 - Remote Stop Transaction', async () => { }) // FR: F03.FR.09 - await it('Should include final meter values in TransactionEvent(Ended)', async () => { + await it('should include final meter values in TransactionEvent(Ended)', async () => { resetConnectorTransactionStates() const transactionId = await startTransaction(3, 700) diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-Reset.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-Reset.test.ts index 636d4e66..56e4e053 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-Reset.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-Reset.test.ts @@ -63,7 +63,7 @@ await describe('B11 & B12 - Reset', async () => { await describe('B11 - Reset - Without Ongoing Transaction', async () => { // FR: B11.FR.01 - await it('Should handle Reset request with Immediate type when no transactions', async () => { + await it('should handle Reset request with Immediate type when no transactions', async () => { const resetRequest: OCPP20ResetRequest = { type: ResetEnumType.Immediate, } @@ -84,7 +84,7 @@ await describe('B11 & B12 - Reset', async () => { ]).toContain(response.status) }) - await it('Should handle Reset request with OnIdle type when no transactions', async () => { + await it('should handle Reset request with OnIdle type when no transactions', async () => { const resetRequest: OCPP20ResetRequest = { type: ResetEnumType.OnIdle, } @@ -104,7 +104,7 @@ await describe('B11 & B12 - Reset', async () => { }) // FR: B11.FR.03 - await it('Should handle EVSE-specific reset request when no transactions', async () => { + await it('should handle EVSE-specific reset request when no transactions', async () => { const resetRequest: OCPP20ResetRequest = { evseId: 1, type: ResetEnumType.Immediate, @@ -124,7 +124,7 @@ await describe('B11 & B12 - Reset', async () => { ]).toContain(response.status) }) - await it('Should reject reset for non-existent EVSE when no transactions', async () => { + await it('should reject reset for non-existent EVSE when no transactions', async () => { const resetRequest: OCPP20ResetRequest = { evseId: 999, // Non-existent EVSE type: ResetEnumType.Immediate, @@ -142,7 +142,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.statusInfo?.additionalInfo).toContain('EVSE 999') }) - await it('Should return proper response structure for immediate reset without transactions', async () => { + await it('should return proper response structure for immediate reset without transactions', async () => { const resetRequest: OCPP20ResetRequest = { type: ResetEnumType.Immediate, } @@ -162,7 +162,7 @@ await describe('B11 & B12 - Reset', async () => { } }) - await it('Should return proper response structure for OnIdle reset without transactions', async () => { + await it('should return proper response structure for OnIdle reset without transactions', async () => { const resetRequest: OCPP20ResetRequest = { type: ResetEnumType.OnIdle, } @@ -176,7 +176,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Accepted) }) - await it('Should reject EVSE reset when not supported and no transactions', async () => { + await it('should reject EVSE reset when not supported and no transactions', async () => { // Mock charging station without EVSE support const originalHasEvses = mockChargingStation.hasEvses ;(mockChargingStation as { hasEvses: boolean }).hasEvses = false @@ -203,7 +203,7 @@ await describe('B11 & B12 - Reset', async () => { ;(mockChargingStation as { hasEvses: boolean }).hasEvses = originalHasEvses }) - await it('Should handle EVSE-specific reset without transactions', async () => { + await it('should handle EVSE-specific reset without transactions', async () => { const resetRequest: OCPP20ResetRequest = { evseId: 1, type: ResetEnumType.Immediate, @@ -222,7 +222,7 @@ await describe('B11 & B12 - Reset', async () => { await describe('B12 - Reset - With Ongoing Transaction', async () => { // FR: B12.FR.02 - await it('Should handle immediate reset with active transactions', async () => { + await it('should handle immediate reset with active transactions', async () => { // Mock active transactions mockStation.getNumberOfRunningTransactions = () => 1 @@ -244,7 +244,7 @@ await describe('B11 & B12 - Reset', async () => { }) // FR: B12.FR.01 - await it('Should handle OnIdle reset with active transactions', async () => { + await it('should handle OnIdle reset with active transactions', async () => { // Mock active transactions mockStation.getNumberOfRunningTransactions = () => 1 @@ -266,7 +266,7 @@ await describe('B11 & B12 - Reset', async () => { }) // FR: B12.FR.03 - await it('Should handle EVSE-specific reset with active transactions', async () => { + await it('should handle EVSE-specific reset with active transactions', async () => { // Mock active transactions mockStation.getNumberOfRunningTransactions = () => 1 @@ -290,7 +290,7 @@ await describe('B11 & B12 - Reset', async () => { mockStation.getNumberOfRunningTransactions = () => 0 }) - await it('Should reject EVSE reset when not supported with active transactions', async () => { + await it('should reject EVSE reset when not supported with active transactions', async () => { // Mock charging station without EVSE support and active transactions const originalHasEvses = mockChargingStation.hasEvses ;(mockChargingStation as { hasEvses: boolean }).hasEvses = false @@ -353,7 +353,7 @@ await describe('B11 & B12 - Reset', async () => { // Errata 2.14: OnIdle definition includes firmware updates // Charging station is NOT idle when firmware is Downloading, Downloaded, or Installing - await it('Should return Scheduled when firmware is Downloading', async () => { + await it('should return Scheduled when firmware is Downloading', async () => { const station = createTestStation() // Mock firmware status as Downloading Object.assign(station.stationInfo, { @@ -373,7 +373,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Scheduled) }) - await it('Should return Scheduled when firmware is Downloaded', async () => { + await it('should return Scheduled when firmware is Downloaded', async () => { const station = createTestStation() // Mock firmware status as Downloaded (waiting to install) Object.assign(station.stationInfo, { @@ -393,7 +393,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Scheduled) }) - await it('Should return Scheduled when firmware is Installing', async () => { + await it('should return Scheduled when firmware is Installing', async () => { const station = createTestStation() // Mock firmware status as Installing Object.assign(station.stationInfo, { @@ -413,7 +413,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Scheduled) }) - await it('Should return Accepted when firmware is Installed (complete)', async () => { + await it('should return Accepted when firmware is Installed (complete)', async () => { const station = createTestStation() // Mock firmware status as Installed (update complete) Object.assign(station.stationInfo, { @@ -433,7 +433,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Accepted) }) - await it('Should return Accepted when firmware status is Idle', async () => { + await it('should return Accepted when firmware status is Idle', async () => { const station = createTestStation() // Mock firmware status as Idle (no update in progress) Object.assign(station.stationInfo, { @@ -458,7 +458,7 @@ await describe('B11 & B12 - Reset', async () => { // Errata 2.14: OnIdle definition includes pending reservations // Charging station is NOT idle when a connector has a non-expired reservation - await it('Should return Scheduled when connector has non-expired reservation', async () => { + await it('should return Scheduled when connector has non-expired reservation', async () => { const station = createTestStation() // Create a reservation that expires in 1 hour (future) const futureExpiryDate = new Date(Date.now() + 3600000) @@ -491,7 +491,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Scheduled) }) - await it('Should return Accepted when reservation is expired', async () => { + await it('should return Accepted when reservation is expired', async () => { const station = createTestStation() // Create a reservation that expired 1 hour ago (past) const pastExpiryDate = new Date(Date.now() - 3600000) @@ -525,7 +525,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Accepted) }) - await it('Should return Accepted when no reservations exist', async () => { + await it('should return Accepted when no reservations exist', async () => { const station = createTestStation() // No reservations set (default state) @@ -546,7 +546,7 @@ await describe('B11 & B12 - Reset', async () => { await describe('Idle Condition', async () => { // Errata 2.14: Station is idle when NO transactions, NO firmware update, NO reservations - await it('Should return Accepted when all conditions clear (true idle state)', async () => { + await it('should return Accepted when all conditions clear (true idle state)', async () => { const station = createTestStation() // Ensure no transactions station.getNumberOfRunningTransactions = () => 0 @@ -569,7 +569,7 @@ await describe('B11 & B12 - Reset', async () => { expect(response.status).toBe(ResetStatusEnumType.Accepted) }) - await it('Should return Scheduled when multiple blocking conditions exist', async () => { + await it('should return Scheduled when multiple blocking conditions exist', async () => { const station = createTestStation() // Active transaction station.getNumberOfRunningTransactions = () => 1 diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-SetVariables.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-SetVariables.test.ts index f5ccfb6b..97e025c8 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-SetVariables.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-SetVariables.test.ts @@ -61,7 +61,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B05.FR.01, B05.FR.10 - await it('Should handle SetVariables request with valid writable variables', () => { + await it('should handle SetVariables request with valid writable variables', () => { const request: OCPP20SetVariablesRequest = { setVariableData: [ { @@ -105,7 +105,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.02 - await it('Should handle SetVariables request with invalid variables/components', () => { + await it('should handle SetVariables request with invalid variables/components', () => { const request: OCPP20SetVariablesRequest = { setVariableData: [ { @@ -134,7 +134,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.03 - await it('Should handle SetVariables request with unsupported attribute type', () => { + await it('should handle SetVariables request with unsupported attribute type', () => { const request: OCPP20SetVariablesRequest = { setVariableData: [ { @@ -156,7 +156,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.04 - await it('Should reject AuthorizeRemoteStart under Connector component for write', () => { + await it('should reject AuthorizeRemoteStart under Connector component for write', () => { const request: OCPP20SetVariablesRequest = { setVariableData: [ { @@ -177,7 +177,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.05 - await it('Should reject value exceeding max length at service level', () => { + await it('should reject value exceeding max length at service level', () => { const longValue = 'x'.repeat(2501) const request: OCPP20SetVariablesRequest = { setVariableData: [ @@ -199,7 +199,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.07 - await it('Should handle mixed SetVariables request with multiple outcomes', () => { + await it('should handle mixed SetVariables request with multiple outcomes', () => { const longValue = 'y'.repeat(2501) const request: OCPP20SetVariablesRequest = { setVariableData: [ @@ -258,7 +258,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.08 - await it('Should reject Target attribute for WebSocketPingInterval explicitly', () => { + await it('should reject Target attribute for WebSocketPingInterval explicitly', () => { const request: OCPP20SetVariablesRequest = { setVariableData: [ { @@ -278,7 +278,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.09 - await it('Should reject immutable DateTime variable', () => { + await it('should reject immutable DateTime variable', () => { const request: OCPP20SetVariablesRequest = { setVariableData: [ { @@ -298,7 +298,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.10 - await it('Should persist HeartbeatInterval and WebSocketPingInterval after setting', () => { + await it('should persist HeartbeatInterval and WebSocketPingInterval after setting', () => { const hbNew = (millisecondsToSeconds(Constants.DEFAULT_HEARTBEAT_INTERVAL) + 20).toString() const wsNew = (Constants.DEFAULT_WEBSOCKET_PING_INTERVAL + 20).toString() const setRequest: OCPP20SetVariablesRequest = { @@ -342,7 +342,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.11 - await it('Should revert non-persistent TxUpdatedInterval after runtime reset', async () => { + await it('should revert non-persistent TxUpdatedInterval after runtime reset', async () => { const txValue = '77' const setRequest: OCPP20SetVariablesRequest = { setVariableData: [ @@ -384,7 +384,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.12 - await it('Should reject all SetVariables when ItemsPerMessage limit exceeded', () => { + await it('should reject all SetVariables when ItemsPerMessage limit exceeded', () => { setStrictLimits(mockChargingStation, 1, 10000) const request: OCPP20SetVariablesRequest = { setVariableData: [ @@ -413,7 +413,7 @@ await describe('B05 - Set Variables', async () => { resetLimits(mockChargingStation) }) - await it('Should reject all SetVariables when BytesPerMessage limit exceeded (pre-calculation)', () => { + await it('should reject all SetVariables when BytesPerMessage limit exceeded (pre-calculation)', () => { // Set strict bytes limit low enough for request pre-estimate to exceed setStrictLimits(mockChargingStation, 100, 10) const request: OCPP20SetVariablesRequest = { @@ -441,7 +441,7 @@ await describe('B05 - Set Variables', async () => { resetLimits(mockChargingStation) }) - await it('Should reject all SetVariables when BytesPerMessage limit exceeded (post-calculation)', () => { + await it('should reject all SetVariables when BytesPerMessage limit exceeded (post-calculation)', () => { const request: OCPP20SetVariablesRequest = { setVariableData: [ { @@ -507,7 +507,7 @@ await describe('B05 - Set Variables', async () => { }) // Effective ConfigurationValueSize / ValueSize propagation tests - await it('Should enforce ConfigurationValueSize when ValueSize unset (service propagation)', () => { + await it('should enforce ConfigurationValueSize when ValueSize unset (service propagation)', () => { resetValueSizeLimits(mockChargingStation) setConfigurationValueSize(mockChargingStation, 100) upsertConfigurationKey(mockChargingStation, OCPP20RequiredVariableName.ValueSize, '') @@ -539,7 +539,7 @@ await describe('B05 - Set Variables', async () => { resetValueSizeLimits(mockChargingStation) }) - await it('Should enforce ValueSize when ConfigurationValueSize unset (service propagation)', () => { + await it('should enforce ValueSize when ConfigurationValueSize unset (service propagation)', () => { resetValueSizeLimits(mockChargingStation) upsertConfigurationKey( mockChargingStation, @@ -575,7 +575,7 @@ await describe('B05 - Set Variables', async () => { resetValueSizeLimits(mockChargingStation) }) - await it('Should use smaller ValueSize when ValueSize < ConfigurationValueSize (service propagation)', () => { + await it('should use smaller ValueSize when ValueSize < ConfigurationValueSize (service propagation)', () => { resetValueSizeLimits(mockChargingStation) setConfigurationValueSize(mockChargingStation, 400) setValueSize(mockChargingStation, 350) @@ -607,7 +607,7 @@ await describe('B05 - Set Variables', async () => { resetValueSizeLimits(mockChargingStation) }) - await it('Should use smaller ConfigurationValueSize when ConfigurationValueSize < ValueSize (service propagation)', () => { + await it('should use smaller ConfigurationValueSize when ConfigurationValueSize < ValueSize (service propagation)', () => { resetValueSizeLimits(mockChargingStation) setConfigurationValueSize(mockChargingStation, 260) setValueSize(mockChargingStation, 500) @@ -639,7 +639,7 @@ await describe('B05 - Set Variables', async () => { resetValueSizeLimits(mockChargingStation) }) - await it('Should fallback to default absolute max length when both limits invalid/non-positive', () => { + await it('should fallback to default absolute max length when both limits invalid/non-positive', () => { resetValueSizeLimits(mockChargingStation) setConfigurationValueSize(mockChargingStation, 0) setValueSize(mockChargingStation, -5) @@ -661,7 +661,7 @@ await describe('B05 - Set Variables', async () => { }) // FR: B07.FR.12 (updated behavior: ConnectionUrl now readable after set) - await it('Should allow ConnectionUrl read-back after setting', () => { + await it('should allow ConnectionUrl read-back after setting', () => { resetLimits(mockChargingStation) const url = 'wss://central.example.com/ocpp' const setRequest: OCPP20SetVariablesRequest = { @@ -692,7 +692,7 @@ await describe('B05 - Set Variables', async () => { resetLimits(mockChargingStation) }) - await it('Should accept ConnectionUrl with custom mqtt scheme (no scheme restriction)', () => { + await it('should accept ConnectionUrl with custom mqtt scheme (no scheme restriction)', () => { resetLimits(mockChargingStation) const url = 'mqtt://broker.internal:1883/ocpp' const setRequest: OCPP20SetVariablesRequest = { diff --git a/tests/charging-station/ocpp/2.0/OCPP20RequestService-BootNotification.test.ts b/tests/charging-station/ocpp/2.0/OCPP20RequestService-BootNotification.test.ts index 8dff0b81..8476227d 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20RequestService-BootNotification.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20RequestService-BootNotification.test.ts @@ -50,7 +50,7 @@ await describe('B01 - Cold Boot Charging Station', async () => { }) // FR: B01.FR.01 - await it('Should build BootNotification request payload correctly with PowerUp reason', () => { + await it('should build BootNotification request payload correctly with PowerUp reason', () => { const chargingStationInfo: ChargingStationType = { firmwareVersion: TEST_FIRMWARE_VERSION, model: TEST_CHARGE_POINT_MODEL, @@ -80,7 +80,7 @@ await describe('B01 - Cold Boot Charging Station', async () => { }) // FR: B01.FR.02 - await it('Should build BootNotification request payload correctly with ApplicationReset reason', () => { + await it('should build BootNotification request payload correctly with ApplicationReset reason', () => { const chargingStationInfo: ChargingStationType = { firmwareVersion: '2.1.3', model: 'Advanced Model X1', @@ -109,7 +109,7 @@ await describe('B01 - Cold Boot Charging Station', async () => { }) // FR: B01.FR.03 - await it('Should build BootNotification request payload correctly with minimal required fields', () => { + await it('should build BootNotification request payload correctly with minimal required fields', () => { const chargingStationInfo: ChargingStationType = { model: 'Basic Model', vendorName: 'Basic Vendor', @@ -137,7 +137,7 @@ await describe('B01 - Cold Boot Charging Station', async () => { }) // FR: B01.FR.04 - await it('Should handle all BootReasonEnumType values correctly', () => { + await it('should handle all BootReasonEnumType values correctly', () => { const chargingStationInfo: ChargingStationType = { model: TEST_CHARGE_POINT_MODEL, vendorName: TEST_CHARGE_POINT_VENDOR, @@ -174,7 +174,7 @@ await describe('B01 - Cold Boot Charging Station', async () => { }) // FR: B01.FR.05 - await it('Should validate payload structure matches OCPP20BootNotificationRequest interface', () => { + await it('should validate payload structure matches OCPP20BootNotificationRequest interface', () => { const chargingStationInfo: ChargingStationType = { customData: { vendorId: 'TEST_VENDOR', diff --git a/tests/charging-station/ocpp/2.0/OCPP20RequestService-HeartBeat.test.ts b/tests/charging-station/ocpp/2.0/OCPP20RequestService-HeartBeat.test.ts index 083f20fe..4fee3e52 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20RequestService-HeartBeat.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20RequestService-HeartBeat.test.ts @@ -48,7 +48,7 @@ await describe('G02 - Heartbeat', async () => { }) // FR: G02.FR.01 - await it('Should build HeartBeat request payload correctly with empty object', () => { + await it('should build HeartBeat request payload correctly with empty object', () => { const requestParams: OCPP20HeartbeatRequest = {} // Access the private buildRequestPayload method via type assertion @@ -64,7 +64,7 @@ await describe('G02 - Heartbeat', async () => { }) // FR: G02.FR.02 - await it('Should build HeartBeat request payload correctly without parameters', () => { + await it('should build HeartBeat request payload correctly without parameters', () => { // Test without passing any request parameters const payload = (requestService as any).buildRequestPayload( mockChargingStation, @@ -77,7 +77,7 @@ await describe('G02 - Heartbeat', async () => { }) // FR: G02.FR.03 - await it('Should validate payload structure matches OCPP20HeartbeatRequest interface', () => { + await it('should validate payload structure matches OCPP20HeartbeatRequest interface', () => { const requestParams: OCPP20HeartbeatRequest = {} const payload = (requestService as any).buildRequestPayload( @@ -95,7 +95,7 @@ await describe('G02 - Heartbeat', async () => { }) // FR: G02.FR.04 - await it('Should handle HeartBeat request consistently across multiple calls', () => { + await it('should handle HeartBeat request consistently across multiple calls', () => { const requestParams: OCPP20HeartbeatRequest = {} // Call buildRequestPayload multiple times to ensure consistency @@ -125,7 +125,7 @@ await describe('G02 - Heartbeat', async () => { }) // FR: G02.FR.05 - await it('Should handle HeartBeat request with different charging station configurations', () => { + await it('should handle HeartBeat request with different charging station configurations', () => { const alternativeChargingStation = createChargingStation({ baseName: 'CS-ALTERNATIVE-002', connectorsCount: 3, @@ -158,7 +158,7 @@ await describe('G02 - Heartbeat', async () => { }) // FR: G02.FR.06 - await it('Should verify HeartBeat request conforms to OCPP 2.0 specification', () => { + await it('should verify HeartBeat request conforms to OCPP 2.0 specification', () => { const requestParams: OCPP20HeartbeatRequest = {} const payload = (requestService as any).buildRequestPayload( diff --git a/tests/charging-station/ocpp/2.0/OCPP20RequestService-ISO15118.test.ts b/tests/charging-station/ocpp/2.0/OCPP20RequestService-ISO15118.test.ts index d98c0c96..65eac6bd 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20RequestService-ISO15118.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20RequestService-ISO15118.test.ts @@ -55,7 +55,7 @@ await describe('M02 - Get15118EVCertificate Request', async () => { }) await describe('EXI Install Action', async () => { - await it('Should forward EXI request unmodified for Install action', async () => { + await it('should forward EXI request unmodified for Install action', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -81,7 +81,7 @@ await describe('M02 - Get15118EVCertificate Request', async () => { }) await describe('EXI Update Action', async () => { - await it('Should forward EXI request unmodified for Update action', async () => { + await it('should forward EXI request unmodified for Update action', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -105,7 +105,7 @@ await describe('M02 - Get15118EVCertificate Request', async () => { }) await describe('CSMS Response Handling', async () => { - await it('Should return Accepted response with exiResponse from CSMS', async () => { + await it('should return Accepted response with exiResponse from CSMS', async () => { const { service } = createTestableRequestService({ sendMessageResponse: { exiResponse: MOCK_EXI_RESPONSE, @@ -125,7 +125,7 @@ await describe('M02 - Get15118EVCertificate Request', async () => { expect(response.exiResponse).toBe(MOCK_EXI_RESPONSE) }) - await it('Should return Failed response from CSMS', async () => { + await it('should return Failed response from CSMS', async () => { const { service } = createTestableRequestService({ sendMessageResponse: { exiResponse: '', @@ -150,7 +150,7 @@ await describe('M02 - Get15118EVCertificate Request', async () => { }) await describe('Schema Version Parameter', async () => { - await it('Should pass schema version correctly', async () => { + await it('should pass schema version correctly', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -173,7 +173,7 @@ await describe('M02 - Get15118EVCertificate Request', async () => { }) await describe('Base64 EXI Pass-Through', async () => { - await it('Should pass Base64 EXI string unchanged', async () => { + await it('should pass Base64 EXI string unchanged', async () => { const complexBase64EXI = 'VGhpcyBpcyBhIG1vcmUgY29tcGxleCBFWEkgcGF5bG9hZCB3aXRoIHNwZWNpYWwgY2hhcmFjdGVycyArLz0=' @@ -214,7 +214,7 @@ await describe('M03 - GetCertificateStatus Request', async () => { }) await describe('OCSP Request Data', async () => { - await it('Should send OCSP request data correctly', async () => { + await it('should send OCSP request data correctly', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -241,7 +241,7 @@ await describe('M03 - GetCertificateStatus Request', async () => { }) await describe('CSMS Response Handling', async () => { - await it('Should return Accepted response with ocspResult from CSMS', async () => { + await it('should return Accepted response with ocspResult from CSMS', async () => { const { service } = createTestableRequestService({ sendMessageResponse: { ocspResult: MOCK_OCSP_RESULT, @@ -259,7 +259,7 @@ await describe('M03 - GetCertificateStatus Request', async () => { expect(response.ocspResult).toBe(MOCK_OCSP_RESULT) }) - await it('Should return Failed response from CSMS', async () => { + await it('should return Failed response from CSMS', async () => { const { service } = createTestableRequestService({ sendMessageResponse: { status: GetCertificateStatusEnumType.Failed, @@ -281,7 +281,7 @@ await describe('M03 - GetCertificateStatus Request', async () => { }) await describe('Stub OCSP Response', async () => { - await it('Should handle stub OCSP response correctly', async () => { + await it('should handle stub OCSP response correctly', async () => { // This tests that the simulator doesn't make real network calls // Response is stubbed/mocked at the sendMessage level const stubOcspResult = 'U3R1YiBPQ1NQIFJlc3BvbnNlIERhdGE=' @@ -322,7 +322,7 @@ await describe('Request Command Names', async () => { websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL, }) - await it('Should send GET_15118_EV_CERTIFICATE command name', async () => { + await it('should send GET_15118_EV_CERTIFICATE command name', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -342,7 +342,7 @@ await describe('Request Command Names', async () => { expect(commandName).toBe(OCPP20RequestCommand.GET_15118_EV_CERTIFICATE) }) - await it('Should send GET_CERTIFICATE_STATUS command name', async () => { + await it('should send GET_CERTIFICATE_STATUS command name', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { diff --git a/tests/charging-station/ocpp/2.0/OCPP20RequestService-NotifyReport.test.ts b/tests/charging-station/ocpp/2.0/OCPP20RequestService-NotifyReport.test.ts index 3dd98a48..45a0ca67 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20RequestService-NotifyReport.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20RequestService-NotifyReport.test.ts @@ -50,7 +50,7 @@ await describe('B07/B08 - NotifyReport', async () => { }) // FR: B07.FR.03, B07.FR.04 - await it('Should build NotifyReport request payload correctly with minimal required fields', () => { + await it('should build NotifyReport request payload correctly with minimal required fields', () => { const requestParams: OCPP20NotifyReportRequest = { generatedAt: new Date('2023-10-22T10:30:00.000Z'), requestId: 123, @@ -72,7 +72,7 @@ await describe('B07/B08 - NotifyReport', async () => { expect(payload.reportData).toBeUndefined() }) - await it('Should build NotifyReport request payload correctly with reportData', () => { + await it('should build NotifyReport request payload correctly with reportData', () => { const reportData: ReportDataType[] = [ { component: { @@ -118,7 +118,7 @@ await describe('B07/B08 - NotifyReport', async () => { expect(payload.reportData).toHaveLength(1) }) - await it('Should build NotifyReport request payload correctly with multiple reportData items', () => { + await it('should build NotifyReport request payload correctly with multiple reportData items', () => { const reportData: ReportDataType[] = [ { component: { @@ -200,7 +200,7 @@ await describe('B07/B08 - NotifyReport', async () => { expect(payload.reportData).toHaveLength(3) }) - await it('Should build NotifyReport request payload correctly with fragmented report (tbc=true)', () => { + await it('should build NotifyReport request payload correctly with fragmented report (tbc=true)', () => { const reportData: ReportDataType[] = [ { component: { @@ -246,7 +246,7 @@ await describe('B07/B08 - NotifyReport', async () => { expect(payload.reportData).toHaveLength(1) }) - await it('Should build NotifyReport request payload correctly with empty reportData array', () => { + await it('should build NotifyReport request payload correctly with empty reportData array', () => { const requestParams: OCPP20NotifyReportRequest = { generatedAt: new Date('2023-10-22T09:00:00.000Z'), reportData: [], // Empty array @@ -271,7 +271,7 @@ await describe('B07/B08 - NotifyReport', async () => { expect(payload.reportData).toHaveLength(0) }) - await it('Should handle different AttributeEnumType values correctly', () => { + await it('should handle different AttributeEnumType values correctly', () => { const testAttributes = [AttributeEnumType.Actual] testAttributes.forEach((attributeType, index) => { @@ -318,7 +318,7 @@ await describe('B07/B08 - NotifyReport', async () => { }) }) - await it('Should handle different DataEnumType values correctly', () => { + await it('should handle different DataEnumType values correctly', () => { const testDataTypes = [ { dataType: DataEnumType.string, value: 'test string' }, { dataType: DataEnumType.integer, value: '42' }, @@ -369,7 +369,7 @@ await describe('B07/B08 - NotifyReport', async () => { }) }) - await it('Should validate payload structure matches OCPP20NotifyReportRequest interface', () => { + await it('should validate payload structure matches OCPP20NotifyReportRequest interface', () => { const reportData: ReportDataType[] = [ { component: { @@ -434,7 +434,7 @@ await describe('B07/B08 - NotifyReport', async () => { } }) - await it('Should handle complex reportData with multiple variable attributes', () => { + await it('should handle complex reportData with multiple variable attributes', () => { const reportData: ReportDataType[] = [ { component: { @@ -475,7 +475,7 @@ await describe('B07/B08 - NotifyReport', async () => { expect(payload.reportData[0].variableAttribute[0].type).toBe(AttributeEnumType.Actual) }) - await it('Should preserve all payload properties correctly', () => { + await it('should preserve all payload properties correctly', () => { const testDate = new Date('2023-10-22T11:22:33.444Z') const reportData: ReportDataType[] = [ { diff --git a/tests/charging-station/ocpp/2.0/OCPP20RequestService-SignCertificate.test.ts b/tests/charging-station/ocpp/2.0/OCPP20RequestService-SignCertificate.test.ts index e18f8c9b..1a8b0506 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20RequestService-SignCertificate.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20RequestService-SignCertificate.test.ts @@ -40,7 +40,7 @@ await describe('I02 - SignCertificate Request', async () => { } await describe('CSR Generation', async () => { - await it('Should generate CSR with PKCS#10 PEM format', async () => { + await it('should generate CSR with PKCS#10 PEM format', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -64,7 +64,7 @@ await describe('I02 - SignCertificate Request', async () => { expect(sentPayload.csr).toContain('-----END CERTIFICATE REQUEST-----') }) - await it('Should include OrganizationName from SecurityCtrlr config in CSR', async () => { + await it('should include OrganizationName from SecurityCtrlr config in CSR', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -92,7 +92,7 @@ await describe('I02 - SignCertificate Request', async () => { }) await describe('ChargingStationCertificate Type', async () => { - await it('Should send SignCertificateRequest with ChargingStationCertificate type', async () => { + await it('should send SignCertificateRequest with ChargingStationCertificate type', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -114,7 +114,7 @@ await describe('I02 - SignCertificate Request', async () => { }) await describe('V2GCertificate Type', async () => { - await it('Should send SignCertificateRequest with V2GCertificate type', async () => { + await it('should send SignCertificateRequest with V2GCertificate type', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -134,7 +134,7 @@ await describe('I02 - SignCertificate Request', async () => { }) await describe('CSMS Response Handling', async () => { - await it('Should return Accepted response from CSMS', async () => { + await it('should return Accepted response from CSMS', async () => { const { service } = createTestableRequestService({ sendMessageResponse: { status: GenericStatus.Accepted, @@ -150,7 +150,7 @@ await describe('I02 - SignCertificate Request', async () => { expect(response.status).toBe(GenericStatus.Accepted) }) - await it('Should return Rejected response from CSMS', async () => { + await it('should return Rejected response from CSMS', async () => { const { service } = createTestableRequestService({ sendMessageResponse: { status: GenericStatus.Rejected, @@ -173,7 +173,7 @@ await describe('I02 - SignCertificate Request', async () => { }) await describe('Optional Certificate Type', async () => { - await it('Should send SignCertificateRequest without certificateType when omitted', async () => { + await it('should send SignCertificateRequest without certificateType when omitted', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -192,7 +192,7 @@ await describe('I02 - SignCertificate Request', async () => { }) await describe('Request Payload Validation', async () => { - await it('Should build valid OCPP20SignCertificateRequest payload', async () => { + await it('should build valid OCPP20SignCertificateRequest payload', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -217,7 +217,7 @@ await describe('I02 - SignCertificate Request', async () => { expect(sentPayload.csr.length).toBeLessThanOrEqual(5500) // Max length per schema }) - await it('Should send SIGN_CERTIFICATE command name', async () => { + await it('should send SIGN_CERTIFICATE command name', async () => { const { sendMessageMock, service } = createTestableRequestService({ sendMessageResponse: { @@ -237,7 +237,7 @@ await describe('I02 - SignCertificate Request', async () => { }) await describe('Error Handling', async () => { - await it('Should generate CSR without certificate manager dependency', async () => { + await it('should generate CSR without certificate manager dependency', async () => { const stationWithoutCertManager = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, connectorsCount: 1, diff --git a/tests/charging-station/ocpp/2.0/OCPP20RequestService-StatusNotification.test.ts b/tests/charging-station/ocpp/2.0/OCPP20RequestService-StatusNotification.test.ts index cb9fe7bd..9bd0b808 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20RequestService-StatusNotification.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20RequestService-StatusNotification.test.ts @@ -49,7 +49,7 @@ await describe('G01 - Status Notification', async () => { }) // FR: G01.FR.01 - await it('Should build StatusNotification request payload correctly with Available status', () => { + await it('should build StatusNotification request payload correctly with Available status', () => { const testTimestamp = new Date('2024-01-15T10:30:00.000Z') const requestParams: OCPP20StatusNotificationRequest = { @@ -74,7 +74,7 @@ await describe('G01 - Status Notification', async () => { }) // FR: G01.FR.02 - await it('Should build StatusNotification request payload correctly with Occupied status', () => { + await it('should build StatusNotification request payload correctly with Occupied status', () => { const testTimestamp = new Date('2024-01-15T11:45:30.000Z') const requestParams: OCPP20StatusNotificationRequest = { @@ -98,7 +98,7 @@ await describe('G01 - Status Notification', async () => { }) // FR: G01.FR.03 - await it('Should build StatusNotification request payload correctly with Faulted status', () => { + await it('should build StatusNotification request payload correctly with Faulted status', () => { const testTimestamp = new Date('2024-01-15T12:15:45.500Z') const requestParams: OCPP20StatusNotificationRequest = { @@ -122,7 +122,7 @@ await describe('G01 - Status Notification', async () => { }) // FR: G01.FR.04 - await it('Should handle all OCPP20ConnectorStatusEnumType values correctly', () => { + await it('should handle all OCPP20ConnectorStatusEnumType values correctly', () => { const testTimestamp = new Date('2024-01-15T13:00:00.000Z') const statusValues = [ @@ -156,7 +156,7 @@ await describe('G01 - Status Notification', async () => { }) // FR: G01.FR.05 - await it('Should validate payload structure matches OCPP20StatusNotificationRequest interface', () => { + await it('should validate payload structure matches OCPP20StatusNotificationRequest interface', () => { const testTimestamp = new Date('2024-01-15T14:30:15.123Z') const requestParams: OCPP20StatusNotificationRequest = { @@ -194,7 +194,7 @@ await describe('G01 - Status Notification', async () => { }) // FR: G01.FR.06 - await it('Should handle edge case connector and EVSE IDs correctly', () => { + await it('should handle edge case connector and EVSE IDs correctly', () => { const testTimestamp = new Date('2024-01-15T15:45:00.000Z') // Test with connector ID 0 (valid in OCPP 2.0 for the charging station itself) @@ -239,7 +239,7 @@ await describe('G01 - Status Notification', async () => { }) // FR: G01.FR.07 - await it('Should handle different timestamp formats correctly', () => { + await it('should handle different timestamp formats correctly', () => { const testCases = [ new Date('2024-01-01T00:00:00.000Z'), // Start of year new Date('2024-12-31T23:59:59.999Z'), // End of year diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-CableFirst.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-CableFirst.test.ts index 4184eaad..17c6048e 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-CableFirst.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-CableFirst.test.ts @@ -54,7 +54,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { // E02.FR.01: Cable Plug Event Flow Tests // ========================================================================= await describe('Cable Plug Event Sequencing', async () => { - await it('Should generate CablePluggedIn event as first event in cable-first flow', () => { + await it('should generate CablePluggedIn event as first event in cable-first flow', () => { const connectorId = 1 const transactionId = generateUUID() @@ -77,7 +77,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { expect(cablePluggedEvent.transactionInfo.transactionId).toBe(transactionId) }) - await it('Should sequence CablePluggedIn → EVDetected → Charging correctly', () => { + await it('should sequence CablePluggedIn → EVDetected → Charging correctly', () => { const connectorId = 1 const transactionId = generateUUID() @@ -128,7 +128,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { expect(chargingStartedEvent.eventType).toBe(OCPP20TransactionEventEnumType.Updated) }) - await it('Should handle EVDeparted for cable removal ending transaction', () => { + await it('should handle EVDeparted for cable removal ending transaction', () => { const connectorId = 2 const transactionId = generateUUID() @@ -166,7 +166,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { // E02.FR.02: EV Detection Flow Tests // ========================================================================= await describe('EV Detection Flow', async () => { - await it('Should include EVDetected between cable plug and charging start', () => { + await it('should include EVDetected between cable plug and charging start', () => { const connectorId = 1 const transactionId = generateUUID() @@ -222,7 +222,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { // E02.FR.03: Connector Status Transitions // ========================================================================= await describe('Connector Status Transitions', async () => { - await it('Should track connector status through cable-first lifecycle', () => { + await it('should track connector status through cable-first lifecycle', () => { const connectorId = 1 // Get connector status object @@ -253,7 +253,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { expect(connectorStatus.transactionStarted).toBe(false) }) - await it('Should preserve transaction ID through cable-first flow states', () => { + await it('should preserve transaction ID through cable-first flow states', () => { const connectorId = 2 const transactionId = generateUUID() @@ -287,7 +287,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { // Full E02 Transaction Lifecycle Tests // ========================================================================= await describe('Full Cable-First Transaction Lifecycle', async () => { - await it('Should support complete cable-first → charging → cable-removal flow', () => { + await it('should support complete cable-first → charging → cable-removal flow', () => { const connectorId = 1 const transactionId = generateUUID() @@ -342,7 +342,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { expect(lifecycle.evDeparted.transactionInfo.transactionId).toBe(transactionId) }) - await it('Should handle suspended charging states in cable-first flow', () => { + await it('should handle suspended charging states in cable-first flow', () => { const connectorId = 3 const transactionId = generateUUID() @@ -411,7 +411,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { // Context-Based Trigger Reason Selection for Cable Events // ========================================================================= await describe('Context-Based Cable Event Trigger Selection', async () => { - await it('Should select CablePluggedIn from cable_action context with plugged_in state', () => { + await it('should select CablePluggedIn from cable_action context with plugged_in state', () => { const context: OCPP20TransactionContext = { cableState: 'plugged_in', source: 'cable_action', @@ -425,7 +425,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.CablePluggedIn) }) - await it('Should select EVDetected from cable_action context with detected state', () => { + await it('should select EVDetected from cable_action context with detected state', () => { const context: OCPP20TransactionContext = { cableState: 'detected', source: 'cable_action', @@ -439,7 +439,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.EVDetected) }) - await it('Should select EVDeparted from cable_action context with unplugged state', () => { + await it('should select EVDeparted from cable_action context with unplugged state', () => { const context: OCPP20TransactionContext = { cableState: 'unplugged', source: 'cable_action', @@ -458,7 +458,7 @@ await describe('E02 - Cable-First Transaction Flow', async () => { // Multiple Connector Independence Tests // ========================================================================= await describe('Multiple Connector Independence', async () => { - await it('Should maintain independent transaction sequences on different connectors', () => { + await it('should maintain independent transaction sequences on different connectors', () => { const transactionId1 = generateUUID() const transactionId2 = generateUUID() diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-IdTokenFirst.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-IdTokenFirst.test.ts index a2eb73e1..3212b638 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-IdTokenFirst.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-IdTokenFirst.test.ts @@ -54,7 +54,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { // E03.FR.13: Trigger Reason Selection for IdToken-First // ========================================================================= await describe('E03.FR.13 - Trigger Reason Selection', async () => { - await it('Should select Authorized trigger for IdToken-first transaction start', () => { + await it('should select Authorized trigger for IdToken-first transaction start', () => { // E03.FR.13: triggerReason SHALL be Authorized for IdToken-first const context: OCPP20TransactionContext = { authorizationMethod: 'idToken', @@ -69,7 +69,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.Authorized) }) - await it('Should select groupIdToken trigger for group authorization', () => { + await it('should select groupIdToken trigger for group authorization', () => { const context: OCPP20TransactionContext = { authorizationMethod: 'groupIdToken', source: 'local_authorization', @@ -83,7 +83,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.Authorized) }) - await it('Should differentiate IdToken-first from Cable-first by trigger reason', () => { + await it('should differentiate IdToken-first from Cable-first by trigger reason', () => { // IdToken-first: Authorized trigger const idTokenFirstContext: OCPP20TransactionContext = { authorizationMethod: 'idToken', @@ -116,7 +116,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { // E03.FR.01: IdToken Inclusion in TransactionEvent // ========================================================================= await describe('E03.FR.01 - IdToken in TransactionEvent', async () => { - await it('Should include idToken in first TransactionEvent after authorization', () => { + await it('should include idToken in first TransactionEvent after authorization', () => { const connectorId = 1 const transactionId = generateUUID() const idToken: OCPP20IdTokenType = { @@ -143,7 +143,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { expect(startedEvent.triggerReason).toBe(OCPP20TriggerReasonEnumType.Authorized) }) - await it('Should not include idToken in subsequent events (E03.FR.01 compliance)', () => { + await it('should not include idToken in subsequent events (E03.FR.01 compliance)', () => { const connectorId = 1 const transactionId = generateUUID() const idToken: OCPP20IdTokenType = { @@ -177,7 +177,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { expect(updatedEvent.idToken).toBeUndefined() }) - await it('Should support various IdToken types for E03 flow', () => { + await it('should support various IdToken types for E03 flow', () => { const connectorId = 1 const transactionId = generateUUID() @@ -231,7 +231,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { // Full E03 IdToken-First Transaction Lifecycle // ========================================================================= await describe('Full IdToken-First Transaction Lifecycle', async () => { - await it('Should support complete IdToken-first to cable to charging to end flow', () => { + await it('should support complete IdToken-first to cable to charging to end flow', () => { const connectorId = 1 const transactionId = generateUUID() const idToken: OCPP20IdTokenType = { @@ -303,7 +303,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { expect(endedEvent.transactionInfo.transactionId).toBe(transactionId) }) - await it('Should differentiate E03 lifecycle from E02 Cable-First lifecycle', () => { + await it('should differentiate E03 lifecycle from E02 Cable-First lifecycle', () => { const connectorId = 1 const e03TransactionId = generateUUID() const e02TransactionId = generateUUID() @@ -356,7 +356,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { // E03.FR.05/06: EVConnectionTimeOut Handling // ========================================================================= await describe('E03.FR.05/06 - EVConnectionTimeOut', async () => { - await it('Should support authorization cancellation event (cable not connected)', () => { + await it('should support authorization cancellation event (cable not connected)', () => { const connectorId = 1 const transactionId = generateUUID() const idToken: OCPP20IdTokenType = { @@ -398,7 +398,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { ) }) - await it('Should track sequence numbers correctly for timeout scenario', () => { + await it('should track sequence numbers correctly for timeout scenario', () => { const connectorId = 1 const transactionId = generateUUID() @@ -431,7 +431,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { // Authorization Status Handling // ========================================================================= await describe('Authorization Status in E03 Flow', async () => { - await it('Should support Deauthorized trigger for rejected authorization', () => { + await it('should support Deauthorized trigger for rejected authorization', () => { const context: OCPP20TransactionContext = { authorizationMethod: 'idToken', isDeauthorized: true, @@ -446,7 +446,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.Deauthorized) }) - await it('Should handle transaction end after token revocation', () => { + await it('should handle transaction end after token revocation', () => { const connectorId = 1 const transactionId = generateUUID() const idToken: OCPP20IdTokenType = { @@ -480,7 +480,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { expect(revokedEvent.triggerReason).toBe(OCPP20TriggerReasonEnumType.Deauthorized) }) - await it('Should support StopAuthorized trigger for normal transaction end', () => { + await it('should support StopAuthorized trigger for normal transaction end', () => { const context: OCPP20TransactionContext = { authorizationMethod: 'stopAuthorized', source: 'local_authorization', @@ -499,7 +499,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { // E03.FR.07/08: Sequence Numbers and Transaction ID // ========================================================================= await describe('E03.FR.07/08 - Sequence Numbers and Transaction ID', async () => { - await it('Should maintain continuous sequence numbers throughout E03 lifecycle', () => { + await it('should maintain continuous sequence numbers throughout E03 lifecycle', () => { const connectorId = 1 const transactionId = generateUUID() const idToken: OCPP20IdTokenType = { @@ -554,7 +554,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { }) }) - await it('Should use unique transaction ID (E03.FR.08)', () => { + await it('should use unique transaction ID (E03.FR.08)', () => { const connectorId = 1 OCPP20ServiceUtils.resetTransactionSequenceNumber(mockChargingStation, connectorId) @@ -593,7 +593,7 @@ await describe('E03 - IdToken-First Pre-Authorization Flow', async () => { // Multiple Connector Independence // ========================================================================= await describe('Multiple Connector Independence in E03 Flow', async () => { - await it('Should handle independent E03 transactions on different connectors', () => { + await it('should handle independent E03 transactions on different connectors', () => { const connector1 = 1 const connector2 = 2 const transaction1Id = generateUUID() diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Offline.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Offline.test.ts index 09240a59..d201956f 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Offline.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Offline.test.ts @@ -68,7 +68,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => }) await describe('Queue formation when offline', async () => { - await it('Should queue TransactionEvent when WebSocket is disconnected', async () => { + await it('should queue TransactionEvent when WebSocket is disconnected', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -94,7 +94,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => expect(connector.transactionEventQueue[0].seqNo).toBe(0) }) - await it('Should queue multiple TransactionEvents in order when offline', async () => { + await it('should queue multiple TransactionEvents in order when offline', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -144,7 +144,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => ) }) - await it('Should preserve seqNo in queued events', async () => { + await it('should preserve seqNo in queued events', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -186,7 +186,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => expect(connector.transactionEventQueue[1].seqNo).toBe(2) }) - await it('Should include timestamp in queued events', async () => { + await it('should include timestamp in queued events', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -215,7 +215,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => }) await describe('Queue draining when coming online', async () => { - await it('Should send all queued events when sendQueuedTransactionEvents is called', async () => { + await it('should send all queued events when sendQueuedTransactionEvents is called', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -249,7 +249,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => expect(sentRequests[1].payload.seqNo).toBe(1) }) - await it('Should clear queue after sending', async () => { + await it('should clear queue after sending', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -273,7 +273,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => expect(connector.transactionEventQueue.length).toBe(0) }) - await it('Should preserve FIFO order when draining queue', async () => { + await it('should preserve FIFO order when draining queue', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -316,7 +316,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => expect(sentRequests[2].payload.seqNo).toBe(2) }) - await it('Should handle empty queue gracefully', async () => { + await it('should handle empty queue gracefully', async () => { const connectorId = 1 await expect( @@ -326,7 +326,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => expect(sentRequests.length).toBe(0) }) - await it('Should handle null queue gracefully', async () => { + await it('should handle null queue gracefully', async () => { const connectorId = 1 const connector = mockChargingStation.getConnectorStatus(connectorId) connector.transactionEventQueue = undefined @@ -340,7 +340,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => }) await describe('Sequence number continuity across queue boundary', async () => { - await it('Should maintain seqNo continuity: online → offline → online', async () => { + await it('should maintain seqNo continuity: online → offline → online', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -398,7 +398,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => }) await describe('Multiple connectors with independent queues', async () => { - await it('Should maintain separate queues for each connector', async () => { + await it('should maintain separate queues for each connector', async () => { const transactionId1 = generateUUID() const transactionId2 = generateUUID() @@ -444,7 +444,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => ) }) - await it('Should drain queues independently per connector', async () => { + await it('should drain queues independently per connector', async () => { const transactionId1 = generateUUID() const transactionId2 = generateUUID() @@ -486,7 +486,7 @@ await describe('E02 - OCPP 2.0.1 Offline TransactionEvent Queueing', async () => }) await describe('Error handling during queue drain', async () => { - await it('Should continue sending remaining events if one fails', async () => { + await it('should continue sending remaining events if one fails', async () => { const connectorId = 1 const transactionId = generateUUID() let callCount = 0 diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Periodic.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Periodic.test.ts index 2b63b981..53de24dc 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Periodic.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-Periodic.test.ts @@ -71,7 +71,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' }) await describe('startTxUpdatedInterval', async () => { - await it('Should not start timer for non-OCPP 2.0 stations', () => { + await it('should not start timer for non-OCPP 2.0 stations', () => { const ocpp16Station = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, connectorsCount: 1, @@ -88,7 +88,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' expect(connector?.transactionTxUpdatedSetInterval).toBeUndefined() }) - await it('Should not start timer when interval is zero', () => { + await it('should not start timer when interval is zero', () => { const connectorId = 1 // Simulate startTxUpdatedInterval with zero interval @@ -100,7 +100,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' expect(connector.transactionTxUpdatedSetInterval).toBeUndefined() }) - await it('Should not start timer when interval is negative', () => { + await it('should not start timer when interval is negative', () => { const connectorId = 1 const connector = mockChargingStation.getConnectorStatus(connectorId) expect(connector).toBeDefined() @@ -109,7 +109,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' expect(connector.transactionTxUpdatedSetInterval).toBeUndefined() }) - await it('Should handle non-existent connector gracefully', () => { + await it('should handle non-existent connector gracefully', () => { const nonExistentConnectorId = 999 // Should not throw for non-existent connector @@ -123,7 +123,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' }) await describe('Periodic TransactionEvent generation', async () => { - await it('Should send TransactionEvent with MeterValuePeriodic trigger reason', async () => { + await it('should send TransactionEvent with MeterValuePeriodic trigger reason', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -148,7 +148,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' ) }) - await it('Should increment seqNo for each periodic event', async () => { + await it('should increment seqNo for each periodic event', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -182,7 +182,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' expect(connector?.transactionSeqNo).toBe(3) }) - await it('Should maintain correct eventType (Updated) for periodic events', async () => { + await it('should maintain correct eventType (Updated) for periodic events', async () => { const connectorId = 2 const transactionId = generateUUID() @@ -201,7 +201,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' expect(sentRequests[0].payload.eventType).toBe(OCPP20TransactionEventEnumType.Updated) }) - await it('Should include EVSE information in periodic events', async () => { + await it('should include EVSE information in periodic events', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -220,7 +220,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' expect(sentRequests[0].payload.evse.id).toBe(connectorId) }) - await it('Should include transactionInfo with correct transactionId', async () => { + await it('should include transactionInfo with correct transactionId', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -241,7 +241,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' }) await describe('Timer lifecycle integration', async () => { - await it('Should continue seqNo sequence across multiple periodic events', async () => { + await it('should continue seqNo sequence across multiple periodic events', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -282,7 +282,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' expect(endEvent.seqNo).toBe(4) }) - await it('Should handle multiple connectors with independent timers', async () => { + await it('should handle multiple connectors with independent timers', async () => { const transactionId1 = generateUUID() const transactionId2 = generateUUID() @@ -335,7 +335,7 @@ await describe('E02 - OCPP 2.0.1 Periodic TransactionEvent at TxUpdatedInterval' }) await describe('Error handling', async () => { - await it('Should handle network errors gracefully during periodic event', async () => { + await it('should handle network errors gracefully during periodic event', async () => { const errorMockChargingStation = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, connectorsCount: 1, diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts index 4520f432..1e4a5dbe 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts @@ -35,7 +35,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () // FR: E01.FR.01 - TransactionEventRequest structure validation await describe('buildTransactionEvent', async () => { - await it('Should build valid TransactionEvent Started with sequence number 0', () => { + await it('should build valid TransactionEvent Started with sequence number 0', () => { const connectorId = 1 const transactionId = generateUUID() const triggerReason = OCPP20TriggerReasonEnumType.Authorized @@ -68,7 +68,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(transactionEvent.seqNo).toBeGreaterThanOrEqual(0) }) - await it('Should increment sequence number for subsequent events', () => { + await it('should increment sequence number for subsequent events', () => { const connectorId = 2 const transactionId = generateUUID() @@ -114,7 +114,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(endEvent.transactionInfo.transactionId).toBe(transactionId) }) - await it('Should handle optional parameters correctly', () => { + await it('should handle optional parameters correctly', () => { const connectorId = 3 const transactionId = generateUUID() const options = { @@ -153,7 +153,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(transactionEvent.reservationId).toBe(67890) }) - await it('Should validate transaction ID format (identifier string ≤36 chars)', () => { + await it('should validate transaction ID format (identifier string ≤36 chars)', () => { const connectorId = 1 const invalidTransactionId = 'this-string-is-way-too-long-for-a-valid-transaction-id-exceeds-36-chars' @@ -173,7 +173,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () } }) - await it('Should handle all TriggerReason enum values', () => { + await it('should handle all TriggerReason enum values', () => { const connectorId = 1 const transactionId = generateUUID() @@ -222,7 +222,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () // FR: E02.FR.01 - TransactionEventRequest message sending await describe('sendTransactionEvent', async () => { - await it('Should send TransactionEvent and return response', async () => { + await it('should send TransactionEvent and return response', async () => { const connectorId = 1 const transactionId = generateUUID() @@ -239,7 +239,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(typeof response).toBe('object') }) - await it('Should handle errors gracefully', async () => { + await it('should handle errors gracefully', async () => { // Create a mock charging station that throws an error const errorMockChargingStation = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, @@ -278,7 +278,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () // FR: E01.FR.03 - Sequence number management await describe('resetTransactionSequenceNumber', async () => { - await it('Should reset sequence number to undefined', () => { + await it('should reset sequence number to undefined', () => { const connectorId = 1 // First, build a transaction event to set sequence number @@ -301,7 +301,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(connectorStatus?.transactionSeqNo).toBeUndefined() }) - await it('Should handle non-existent connector gracefully', () => { + await it('should handle non-existent connector gracefully', () => { const nonExistentConnectorId = 999 // Should not throw error for non-existent connector @@ -316,7 +316,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () // FR: E01.FR.02 - Schema compliance verification await describe('OCPP 2.0.1 Schema Compliance', async () => { - await it('Should produce schema-compliant TransactionEvent payloads', () => { + await it('should produce schema-compliant TransactionEvent payloads', () => { const connectorId = 1 const transactionId = generateUUID() @@ -371,7 +371,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(Object.values(OCPP20TriggerReasonEnumType)).toContain(transactionEvent.triggerReason) }) - await it('Should handle EVSE/connector mapping correctly', () => { + await it('should handle EVSE/connector mapping correctly', () => { const connectorId = 2 const transactionId = generateUUID() @@ -398,7 +398,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () // FR: E01.FR.04 - TriggerReason selection based on transaction context await describe('Context-Aware TriggerReason Selection', async () => { await describe('selectTriggerReason', async () => { - await it('Should select RemoteStart for remote_command context with RequestStartTransaction', () => { + await it('should select RemoteStart for remote_command context with RequestStartTransaction', () => { const context: OCPP20TransactionContext = { command: 'RequestStartTransaction', source: 'remote_command', @@ -412,7 +412,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.RemoteStart) }) - await it('Should select RemoteStop for remote_command context with RequestStopTransaction', () => { + await it('should select RemoteStop for remote_command context with RequestStopTransaction', () => { const context: OCPP20TransactionContext = { command: 'RequestStopTransaction', source: 'remote_command', @@ -426,7 +426,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.RemoteStop) }) - await it('Should select UnlockCommand for remote_command context with UnlockConnector', () => { + await it('should select UnlockCommand for remote_command context with UnlockConnector', () => { const context: OCPP20TransactionContext = { command: 'UnlockConnector', source: 'remote_command', @@ -440,7 +440,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.UnlockCommand) }) - await it('Should select ResetCommand for remote_command context with Reset', () => { + await it('should select ResetCommand for remote_command context with Reset', () => { const context: OCPP20TransactionContext = { command: 'Reset', source: 'remote_command', @@ -454,7 +454,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.ResetCommand) }) - await it('Should select Trigger for remote_command context with TriggerMessage', () => { + await it('should select Trigger for remote_command context with TriggerMessage', () => { const context: OCPP20TransactionContext = { command: 'TriggerMessage', source: 'remote_command', @@ -468,7 +468,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.Trigger) }) - await it('Should select Authorized for local_authorization context with idToken', () => { + await it('should select Authorized for local_authorization context with idToken', () => { const context: OCPP20TransactionContext = { authorizationMethod: 'idToken', source: 'local_authorization', @@ -482,7 +482,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.Authorized) }) - await it('Should select StopAuthorized for local_authorization context with stopAuthorized', () => { + await it('should select StopAuthorized for local_authorization context with stopAuthorized', () => { const context: OCPP20TransactionContext = { authorizationMethod: 'stopAuthorized', source: 'local_authorization', @@ -496,7 +496,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.StopAuthorized) }) - await it('Should select Deauthorized when isDeauthorized flag is true', () => { + await it('should select Deauthorized when isDeauthorized flag is true', () => { const context: OCPP20TransactionContext = { authorizationMethod: 'idToken', isDeauthorized: true, @@ -511,7 +511,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.Deauthorized) }) - await it('Should select CablePluggedIn for cable_action context with plugged_in', () => { + await it('should select CablePluggedIn for cable_action context with plugged_in', () => { const context: OCPP20TransactionContext = { cableState: 'plugged_in', source: 'cable_action', @@ -525,7 +525,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.CablePluggedIn) }) - await it('Should select EVDetected for cable_action context with detected', () => { + await it('should select EVDetected for cable_action context with detected', () => { const context: OCPP20TransactionContext = { cableState: 'detected', source: 'cable_action', @@ -539,7 +539,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.EVDetected) }) - await it('Should select EVDeparted for cable_action context with unplugged', () => { + await it('should select EVDeparted for cable_action context with unplugged', () => { const context: OCPP20TransactionContext = { cableState: 'unplugged', source: 'cable_action', @@ -553,7 +553,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.EVDeparted) }) - await it('Should select ChargingStateChanged for charging_state context', () => { + await it('should select ChargingStateChanged for charging_state context', () => { const context: OCPP20TransactionContext = { chargingStateChange: { from: OCPP20ChargingStateEnumType.Idle, @@ -570,7 +570,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.ChargingStateChanged) }) - await it('Should select MeterValuePeriodic for meter_value context with periodic flag', () => { + await it('should select MeterValuePeriodic for meter_value context with periodic flag', () => { const context: OCPP20TransactionContext = { isPeriodicMeterValue: true, source: 'meter_value', @@ -584,7 +584,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.MeterValuePeriodic) }) - await it('Should select MeterValueClock for meter_value context without periodic flag', () => { + await it('should select MeterValueClock for meter_value context without periodic flag', () => { const context: OCPP20TransactionContext = { isPeriodicMeterValue: false, source: 'meter_value', @@ -598,7 +598,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.MeterValueClock) }) - await it('Should select SignedDataReceived when isSignedDataReceived flag is true', () => { + await it('should select SignedDataReceived when isSignedDataReceived flag is true', () => { const context: OCPP20TransactionContext = { isSignedDataReceived: true, source: 'meter_value', @@ -612,7 +612,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.SignedDataReceived) }) - await it('Should select appropriate system events for system_event context', () => { + await it('should select appropriate system events for system_event context', () => { const testCases = [ { expected: OCPP20TriggerReasonEnumType.EVDeparted, systemEvent: 'ev_departed' as const }, { expected: OCPP20TriggerReasonEnumType.EVDetected, systemEvent: 'ev_detected' as const }, @@ -641,7 +641,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () } }) - await it('Should select EnergyLimitReached for energy_limit context', () => { + await it('should select EnergyLimitReached for energy_limit context', () => { const context: OCPP20TransactionContext = { source: 'energy_limit', } @@ -654,7 +654,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.EnergyLimitReached) }) - await it('Should select TimeLimitReached for time_limit context', () => { + await it('should select TimeLimitReached for time_limit context', () => { const context: OCPP20TransactionContext = { source: 'time_limit', } @@ -667,7 +667,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.TimeLimitReached) }) - await it('Should select AbnormalCondition for abnormal_condition context', () => { + await it('should select AbnormalCondition for abnormal_condition context', () => { const context: OCPP20TransactionContext = { abnormalCondition: 'OverCurrent', source: 'abnormal_condition', @@ -681,7 +681,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.AbnormalCondition) }) - await it('Should handle priority ordering with multiple applicable contexts', () => { + await it('should handle priority ordering with multiple applicable contexts', () => { // Test context with multiple applicable triggers - priority should be respected const context: OCPP20TransactionContext = { cableState: 'plugged_in', // Even lower priority @@ -699,7 +699,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.RemoteStart) }) - await it('Should fallback to Trigger for unknown context source', () => { + await it('should fallback to Trigger for unknown context source', () => { const context: OCPP20TransactionContext = { source: 'unknown_source' as any, // Invalid source to test fallback } @@ -712,7 +712,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(triggerReason).toBe(OCPP20TriggerReasonEnumType.Trigger) }) - await it('Should fallback to Trigger for incomplete context', () => { + await it('should fallback to Trigger for incomplete context', () => { const context: OCPP20TransactionContext = { source: 'remote_command', // Missing command field @@ -728,7 +728,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () }) await describe('buildTransactionEvent with context parameter', async () => { - await it('Should build TransactionEvent with auto-selected TriggerReason from context', () => { + await it('should build TransactionEvent with auto-selected TriggerReason from context', () => { const connectorId = 1 const transactionId = generateUUID() const context: OCPP20TransactionContext = { @@ -752,7 +752,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(transactionEvent.transactionInfo.transactionId).toBe(transactionId) }) - await it('Should pass through optional parameters correctly', () => { + await it('should pass through optional parameters correctly', () => { const connectorId = 2 const transactionId = generateUUID() const context: OCPP20TransactionContext = { @@ -785,7 +785,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () }) await describe('sendTransactionEvent with context parameter', async () => { - await it('Should send TransactionEvent with context-aware TriggerReason selection', async () => { + await it('should send TransactionEvent with context-aware TriggerReason selection', async () => { const connectorId = 1 const transactionId = generateUUID() const context: OCPP20TransactionContext = { @@ -806,7 +806,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(typeof response).toBe('object') }) - await it('Should handle context-aware error scenarios gracefully', async () => { + await it('should handle context-aware error scenarios gracefully', async () => { // Create error mock for this test const errorMockChargingStation = createChargingStation({ baseName: TEST_CHARGING_STATION_BASE_NAME, @@ -848,7 +848,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () }) await describe('Backward Compatibility', async () => { - await it('Should maintain compatibility with existing buildTransactionEvent calls', () => { + await it('should maintain compatibility with existing buildTransactionEvent calls', () => { const connectorId = 1 const transactionId = generateUUID() @@ -868,7 +868,7 @@ await describe('E01-E04 - OCPP 2.0.1 TransactionEvent Implementation', async () expect(oldEvent.seqNo).toBe(0) }) - await it('Should maintain compatibility with existing sendTransactionEvent calls', async () => { + await it('should maintain compatibility with existing sendTransactionEvent calls', async () => { const connectorId = 1 const transactionId = generateUUID() diff --git a/tests/charging-station/ocpp/2.0/OCPP20VariableManager.test.ts b/tests/charging-station/ocpp/2.0/OCPP20VariableManager.test.ts index aa55cee6..8891b140 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20VariableManager.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20VariableManager.test.ts @@ -79,7 +79,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { OCPP20VariableManager.getInstance().resetRuntimeOverrides() }) - await it('Verify that OCPP20VariableManager can be instantiated as singleton', () => { + await it('should verify that OCPP20VariableManager can be instantiated as singleton', () => { const manager1 = OCPP20VariableManager.getInstance() const manager2 = OCPP20VariableManager.getInstance() @@ -90,7 +90,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { await describe('getVariables method tests', async () => { const manager = OCPP20VariableManager.getInstance() - await it('Should handle valid OCPPCommCtrlr and TxCtrlr component requests', () => { + await it('should handle valid OCPPCommCtrlr and TxCtrlr component requests', () => { const request: OCPP20GetVariableDataType[] = [ { attributeType: AttributeEnumType.Actual, @@ -126,7 +126,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[1].attributeStatusInfo).toBeUndefined() }) - await it('Should accept default true value for AuthorizeRemoteStart (AuthCtrlr)', () => { + await it('should accept default true value for AuthorizeRemoteStart (AuthCtrlr)', () => { const manager = OCPP20VariableManager.getInstance() const request: OCPP20GetVariableDataType[] = [ { @@ -141,7 +141,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].component.name).toBe(OCPP20ComponentName.AuthCtrlr) }) - await it('Should accept setting and getting AuthorizeRemoteStart = true (AuthCtrlr)', () => { + await it('should accept setting and getting AuthorizeRemoteStart = true (AuthCtrlr)', () => { const setRes = manager.setVariables(mockChargingStation, [ { attributeValue: 'true', @@ -160,7 +160,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(getRes.attributeValue).toBe('true') }) - await it('Should reject invalid values for AuthorizeRemoteStart (AuthCtrlr)', () => { + await it('should reject invalid values for AuthorizeRemoteStart (AuthCtrlr)', () => { const invalidValues = ['', '1', 'TRUE', 'False', 'yes'] for (const val of invalidValues) { const res = manager.setVariables(mockChargingStation, [ @@ -175,7 +175,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { } }) - await it('Should handle invalid component gracefully', () => { + await it('should handle invalid component gracefully', () => { const request: OCPP20GetVariableDataType[] = [ { component: { name: 'InvalidComponent' as unknown as OCPP20ComponentName }, @@ -198,7 +198,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].attributeStatusInfo?.additionalInfo).toContain('Component InvalidComponent') }) - await it('Should handle unsupported attribute type gracefully', () => { + await it('should handle unsupported attribute type gracefully', () => { const request: OCPP20GetVariableDataType[] = [ { attributeType: AttributeEnumType.Target, // Not supported for this variable @@ -223,7 +223,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should reject Target attribute for WebSocketPingInterval', () => { + await it('should reject Target attribute for WebSocketPingInterval', () => { const request: OCPP20GetVariableDataType[] = [ { attributeType: AttributeEnumType.Target, @@ -237,7 +237,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].variable.name).toBe(OCPP20OptionalVariableName.WebSocketPingInterval) }) - await it('Should handle non-existent connector instance', () => { + await it('should handle non-existent connector instance', () => { const request: OCPP20GetVariableDataType[] = [ { component: { @@ -265,7 +265,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should handle multiple variables in single request', () => { + await it('should handle multiple variables in single request', () => { const request: OCPP20GetVariableDataType[] = [ { component: { name: OCPP20ComponentName.OCPPCommCtrlr }, @@ -312,7 +312,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[2].attributeStatusInfo).toBeUndefined() }) - await it('Should reject EVSE component as unsupported', () => { + await it('should reject EVSE component as unsupported', () => { const request: OCPP20GetVariableDataType[] = [ { component: { @@ -342,7 +342,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { const manager = OCPP20VariableManager.getInstance() const testable = createTestableVariableManager(manager) - await it('Should validate OCPPCommCtrlr component as always valid', () => { + await it('should validate OCPPCommCtrlr component as always valid', () => { // Behavior: Connector components are unsupported and isComponentValid returns false. // Scope: Per-connector variable validation not implemented; tests assert current behavior. const component: ComponentType = { name: OCPP20ComponentName.OCPPCommCtrlr } @@ -354,14 +354,14 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { // Behavior: Connector component validation returns false (unsupported). // Change process: Enable via OpenSpec proposal before altering this expectation. - await it('Should reject Connector component as unsupported even when connectors exist', () => { + await it('should reject Connector component as unsupported even when connectors exist', () => { const component: ComponentType = { instance: '1', name: OCPP20ComponentName.Connector } const isValid = testable.isComponentValid(mockChargingStation, component) expect(isValid).toBe(false) }) - await it('Should reject invalid connector instance', () => { + await it('should reject invalid connector instance', () => { const component: ComponentType = { instance: '999', name: OCPP20ComponentName.Connector } const isValid = testable.isComponentValid(mockChargingStation, component) @@ -373,7 +373,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { const manager = OCPP20VariableManager.getInstance() const testable = createTestableVariableManager(manager) - await it('Should support standard HeartbeatInterval variable', () => { + await it('should support standard HeartbeatInterval variable', () => { const component: ComponentType = { name: OCPP20ComponentName.OCPPCommCtrlr } const variable: VariableType = { name: OCPP20OptionalVariableName.HeartbeatInterval } @@ -381,7 +381,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(isSupported).toBe(true) }) - await it('Should support known OCPP variables', () => { + await it('should support known OCPP variables', () => { const component: ComponentType = { name: OCPP20ComponentName.ChargingStation } const variable: VariableType = { name: OCPP20OptionalVariableName.WebSocketPingInterval } @@ -389,9 +389,11 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(isSupported).toBe(true) }) - await it('Should reject unknown variables', () => { + await it('should reject unknown variables', () => { const component: ComponentType = { name: OCPP20ComponentName.OCPPCommCtrlr } - const variable: VariableType = { name: 'UnknownVariable' as unknown as OCPP20OptionalVariableName } + const variable: VariableType = { + name: 'UnknownVariable' as unknown as OCPP20OptionalVariableName, + } const isSupported = testable.isVariableSupported(component, variable) expect(isSupported).toBe(false) @@ -401,7 +403,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { await describe('setVariables method tests', async () => { const manager = OCPP20VariableManager.getInstance() - await it('Should accept setting writable variables (Actual default)', () => { + await it('should accept setting writable variables (Actual default)', () => { const request: OCPP20SetVariableDataType[] = [ { attributeValue: (Constants.DEFAULT_WEBSOCKET_PING_INTERVAL + 1).toString(), @@ -429,7 +431,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[1].attributeStatusInfo).toBeUndefined() }) - await it('Should reject setting variable on unknown component', () => { + await it('should reject setting variable on unknown component', () => { const request: OCPP20SetVariableDataType[] = [ { attributeValue: '20', @@ -445,7 +447,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.NotFound) }) - await it('Should reject setting unknown variable', () => { + await it('should reject setting unknown variable', () => { const request: OCPP20SetVariableDataType[] = [ { attributeValue: '10', @@ -461,7 +463,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.NotFound) }) - await it('Should reject unsupported attribute type', () => { + await it('should reject unsupported attribute type', () => { const request: OCPP20SetVariableDataType[] = [ { attributeType: AttributeEnumType.Target, @@ -478,7 +480,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.UnsupportedParam) }) - await it('Should reject value exceeding max length', () => { + await it('should reject value exceeding max length', () => { const longValue = 'x'.repeat(2501) const request: OCPP20SetVariableDataType[] = [ { @@ -498,7 +500,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should handle multiple mixed SetVariables in one call', () => { + await it('should handle multiple mixed SetVariables in one call', () => { const request: OCPP20SetVariableDataType[] = [ { attributeValue: (Constants.DEFAULT_WEBSOCKET_PING_INTERVAL + 2).toString(), @@ -522,7 +524,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].attributeStatusInfo).toBeUndefined() }) - await it('Should reject TxUpdatedInterval zero and negative and non-integer', () => { + await it('should reject TxUpdatedInterval zero and negative and non-integer', () => { const zeroReq: OCPP20SetVariableDataType[] = [ { attributeValue: '0', @@ -558,7 +560,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(nonIntRes.attributeStatusInfo?.additionalInfo).toContain('Positive integer') }) - await it('Should accept setting ConnectionUrl with valid ws URL', () => { + await it('should accept setting ConnectionUrl with valid ws URL', () => { const req: OCPP20SetVariableDataType[] = [ { attributeValue: 'ws://example.com/ocpp', @@ -571,7 +573,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatusInfo).toBeUndefined() }) - await it('Should accept ConnectionUrl with ftp scheme (no scheme restriction)', () => { + await it('should accept ConnectionUrl with ftp scheme (no scheme restriction)', () => { const req: OCPP20SetVariableDataType[] = [ { attributeValue: 'ftp://example.com/ocpp', @@ -584,7 +586,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatusInfo).toBeUndefined() }) - await it('Should accept ConnectionUrl with custom mqtt scheme', () => { + await it('should accept ConnectionUrl with custom mqtt scheme', () => { const req: OCPP20SetVariableDataType[] = [ { attributeValue: 'mqtt://broker.example.com/ocpp', @@ -597,7 +599,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatusInfo).toBeUndefined() }) - await it('Should allow ConnectionUrl retrieval after set', () => { + await it('should allow ConnectionUrl retrieval after set', () => { manager.setVariables(mockChargingStation, [ { attributeValue: 'wss://example.com/ocpp', @@ -618,7 +620,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(getResult.attributeStatusInfo).toBeUndefined() }) - await it('Should revert non-persistent TxUpdatedInterval after simulated restart', () => { + await it('should revert non-persistent TxUpdatedInterval after simulated restart', () => { manager.setVariables(mockChargingStation, [ { attributeValue: '99', @@ -643,7 +645,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(afterReset.attributeValue).toBe('30') }) - await it('Should keep persistent ConnectionUrl after simulated restart', () => { + await it('should keep persistent ConnectionUrl after simulated restart', () => { manager.setVariables(mockChargingStation, [ { attributeValue: 'https://central.example.com/ocpp', @@ -663,7 +665,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(getResult.attributeStatusInfo).toBeUndefined() }) - await it('Should reject Target attribute for WebSocketPingInterval', () => { + await it('should reject Target attribute for WebSocketPingInterval', () => { const request: OCPP20SetVariableDataType[] = [ { attributeType: AttributeEnumType.Target, @@ -678,7 +680,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(result[0].attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.UnsupportedParam) }) - await it('Should validate HeartbeatInterval positive integer >0', () => { + await it('should validate HeartbeatInterval positive integer >0', () => { const req: OCPP20SetVariableDataType[] = [ { attributeValue: ( @@ -693,7 +695,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatusInfo).toBeUndefined() }) - await it('Should reject HeartbeatInterval zero, negative, non-integer', () => { + await it('should reject HeartbeatInterval zero, negative, non-integer', () => { const zeroRes = manager.setVariables(mockChargingStation, [ { attributeValue: '0', @@ -723,7 +725,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(nonIntRes.attributeStatusInfo?.additionalInfo).toContain('Positive integer') }) - await it('Should accept WebSocketPingInterval zero (disable) and positive', () => { + await it('should accept WebSocketPingInterval zero (disable) and positive', () => { const zeroRes = manager.setVariables(mockChargingStation, [ { attributeValue: '0', @@ -744,7 +746,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(posRes.attributeStatusInfo).toBeUndefined() }) - await it('Should reject WebSocketPingInterval negative and non-integer', () => { + await it('should reject WebSocketPingInterval negative and non-integer', () => { const negRes = manager.setVariables(mockChargingStation, [ { attributeValue: '-2', @@ -765,7 +767,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(nonIntRes.attributeStatusInfo?.additionalInfo).toContain('Integer >= 0 required') }) - await it('Should validate EVConnectionTimeOut positive integer >0 and reject invalid', () => { + await it('should validate EVConnectionTimeOut positive integer >0 and reject invalid', () => { const okRes = manager.setVariables(mockChargingStation, [ { attributeValue: (Constants.DEFAULT_EV_CONNECTION_TIMEOUT + 5).toString(), @@ -804,7 +806,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(nonIntRes.attributeStatusInfo?.additionalInfo).toContain('Positive integer') }) - await it('Should validate MessageTimeout positive integer >0 and reject invalid', () => { + await it('should validate MessageTimeout positive integer >0 and reject invalid', () => { const okRes = manager.setVariables(mockChargingStation, [ { attributeValue: (mockChargingStation.getConnectionTimeout() + 5).toString(), @@ -843,7 +845,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(nonIntRes.attributeStatusInfo?.additionalInfo).toContain('Positive integer') }) - await it('Should avoid duplicate persistence operations when value unchanged', () => { + await it('should avoid duplicate persistence operations when value unchanged', () => { const keyBefore = getConfigurationKey( mockChargingStation, OCPP20OptionalVariableName.HeartbeatInterval as unknown as VariableType['name'] @@ -886,7 +888,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(keyAfterRevert?.value).toBe(originalValue) }) - await it('Should add missing configuration key with default during self-check', () => { + await it('should add missing configuration key with default during self-check', () => { deleteConfigurationKey( mockChargingStation, OCPP20RequiredVariableName.EVConnectionTimeOut as unknown as VariableType['name'], @@ -913,7 +915,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(after).toBeDefined() }) - await it('Should clear runtime overrides via resetRuntimeOverrides()', () => { + await it('should clear runtime overrides via resetRuntimeOverrides()', () => { manager.setVariables(mockChargingStation, [ { attributeValue: '123', @@ -939,7 +941,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(afterReset.attributeValue).toBe('30') }) - await it('Should reject HeartbeatInterval with leading whitespace', () => { + await it('should reject HeartbeatInterval with leading whitespace', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: ' 60', @@ -954,7 +956,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should reject HeartbeatInterval with trailing whitespace', () => { + await it('should reject HeartbeatInterval with trailing whitespace', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: '60 ', @@ -969,7 +971,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should reject HeartbeatInterval with plus sign prefix', () => { + await it('should reject HeartbeatInterval with plus sign prefix', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: '+10', @@ -984,7 +986,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should accept HeartbeatInterval with leading zeros', () => { + await it('should accept HeartbeatInterval with leading zeros', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: '007', @@ -996,7 +998,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatusInfo).toBeUndefined() }) - await it('Should reject HeartbeatInterval blank string', () => { + await it('should reject HeartbeatInterval blank string', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: '', @@ -1011,7 +1013,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should reject HeartbeatInterval with internal space', () => { + await it('should reject HeartbeatInterval with internal space', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: '6 0', @@ -1026,7 +1028,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should reject ConnectionUrl missing scheme', () => { + await it('should reject ConnectionUrl missing scheme', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: 'example.com/ocpp', @@ -1039,7 +1041,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatusInfo?.additionalInfo).toContain('Invalid URL format') }) - await it('Should reject ConnectionUrl exceeding max length', () => { + await it('should reject ConnectionUrl exceeding max length', () => { const longUrl = 'wss://example.com/' + 'a'.repeat(600) const res = manager.setVariables(mockChargingStation, [ { @@ -1055,7 +1057,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { ) }) - await it('Should reject HeartbeatInterval exceeding max length', () => { + await it('should reject HeartbeatInterval exceeding max length', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: '1'.repeat(11), @@ -1075,7 +1077,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { }) // Effective value size limit tests combining ConfigurationValueSize and ValueSize - await it('Should enforce ConfigurationValueSize when ValueSize unset', () => { + await it('should enforce ConfigurationValueSize when ValueSize unset', () => { resetValueSizeLimits(mockChargingStation) setConfigurationValueSize(mockChargingStation, 50) // remove ValueSize to simulate unset @@ -1103,7 +1105,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(tooLongRes.attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.TooLargeElement) }) - await it('Should enforce ValueSize when ConfigurationValueSize unset', () => { + await it('should enforce ValueSize when ConfigurationValueSize unset', () => { resetValueSizeLimits(mockChargingStation) setValueSize(mockChargingStation, 40) deleteConfigurationKey( @@ -1130,7 +1132,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(tooLongRes.attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.TooLargeElement) }) - await it('Should use smaller of ConfigurationValueSize and ValueSize (ValueSize smaller)', () => { + await it('should use smaller of ConfigurationValueSize and ValueSize (ValueSize smaller)', () => { resetValueSizeLimits(mockChargingStation) setConfigurationValueSize(mockChargingStation, 60) setValueSize(mockChargingStation, 55) @@ -1153,7 +1155,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(tooLongRes.attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.TooLargeElement) }) - await it('Should use smaller of ConfigurationValueSize and ValueSize (ConfigurationValueSize smaller)', () => { + await it('should use smaller of ConfigurationValueSize and ValueSize (ConfigurationValueSize smaller)', () => { resetValueSizeLimits(mockChargingStation) setConfigurationValueSize(mockChargingStation, 30) setValueSize(mockChargingStation, 100) @@ -1176,7 +1178,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(tooLongRes.attributeStatusInfo?.reasonCode).toBe(ReasonCodeEnumType.TooLargeElement) }) - await it('Should fallback to default limit when both invalid/non-positive', () => { + await it('should fallback to default limit when both invalid/non-positive', () => { resetValueSizeLimits(mockChargingStation) // set invalid values setConfigurationValueSize(mockChargingStation, 0) @@ -1195,7 +1197,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { await describe('List validation tests', async () => { const manager = OCPP20VariableManager.getInstance() - await it('Should accept valid updates to writable list/sequence list variables and reject read-only', () => { + await it('should accept valid updates to writable list/sequence list variables and reject read-only', () => { const updateAttempts: OCPP20SetVariableDataType[] = [ { attributeValue: 'HTTP,HTTPS', // FileTransferProtocols now ReadOnly -> expect rejection @@ -1242,7 +1244,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { } }) - await it('Should retrieve FileTransferProtocols default including FTPS (ReadOnly)', () => { + await it('should retrieve FileTransferProtocols default including FTPS (ReadOnly)', () => { const getRes = manager.getVariables(mockChargingStation, [ { component: { name: OCPP20ComponentName.OCPPCommCtrlr }, @@ -1253,7 +1255,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(getRes.attributeValue).toBe('HTTPS,FTPS,SFTP') }) - await it('Should keep FileTransferProtocols value unchanged after rejected update attempt', () => { + await it('should keep FileTransferProtocols value unchanged after rejected update attempt', () => { const beforeCfg = getConfigurationKey( mockChargingStation, OCPP20RequiredVariableName.FileTransferProtocols as unknown as VariableType['name'] @@ -1283,7 +1285,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(afterCfg?.value).toBe(beforeCfg?.value) }) - await it('Should reject removed TimeSource members RTC and Manual', () => { + await it('should reject removed TimeSource members RTC and Manual', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: 'NTP,GPS,RTC,Manual', // RTC & Manual no longer valid @@ -1296,7 +1298,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatusInfo?.additionalInfo).toContain('Member not in enumeration') }) - await it('Should accept extended TimeSource including RealTimeClock and MobileNetwork', () => { + await it('should accept extended TimeSource including RealTimeClock and MobileNetwork', () => { const res = manager.setVariables(mockChargingStation, [ { attributeValue: 'MobileNetwork,Heartbeat,NTP,GPS,RealTimeClock', @@ -1307,7 +1309,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeStatus).toBe(SetVariableStatusEnumType.Accepted) }) - await it('Should reject invalid list formats and members', () => { + await it('should reject invalid list formats and members', () => { interface ListVar { component: OCPP20ComponentName name: OCPP20RequiredVariableName @@ -1367,7 +1369,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { }) }) - await it('Should reject DataSigned in TxStopPoint list value', () => { + await it('should reject DataSigned in TxStopPoint list value', () => { const manager = OCPP20VariableManager.getInstance() const res = manager.setVariables(mockChargingStation, [ { @@ -1418,7 +1420,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { await describe('Get-time value truncation tests', async () => { const manager = OCPP20VariableManager.getInstance() - await it('Should truncate retrieved value using ValueSize only when ReportingValueSize absent', () => { + await it('should truncate retrieved value using ValueSize only when ReportingValueSize absent', () => { resetValueSizeLimits(mockChargingStation) // Ensure ReportingValueSize unset deleteConfigurationKey( @@ -1452,7 +1454,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { resetValueSizeLimits(mockChargingStation) }) - await it('Should apply ValueSize then ReportingValueSize sequential truncation', () => { + await it('should apply ValueSize then ReportingValueSize sequential truncation', () => { resetValueSizeLimits(mockChargingStation) // Store long value with large limits setValueSize(mockChargingStation, 300) @@ -1482,7 +1484,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { resetReportingValueSize(mockChargingStation) }) - await it('Should enforce absolute max character cap after truncation chain', () => { + await it('should enforce absolute max character cap after truncation chain', () => { resetValueSizeLimits(mockChargingStation) resetReportingValueSize(mockChargingStation) // Directly upsert configuration key with > absolute max length value bypassing set-time limit (which rejects > absolute max length) @@ -1508,7 +1510,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { resetReportingValueSize(mockChargingStation) }) - await it('Should not exceed variable maxLength even if ValueSize and ReportingValueSize set above it', () => { + await it('should not exceed variable maxLength even if ValueSize and ReportingValueSize set above it', () => { resetValueSizeLimits(mockChargingStation) resetReportingValueSize(mockChargingStation) // Store exactly variable maxLength value via setVariables (allowed per registry/spec) @@ -1545,7 +1547,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { await describe('Additional persistence and instance-scoped variable tests', async () => { const manager = OCPP20VariableManager.getInstance() - await it('Should auto-create persistent OrganizationName configuration key during self-check', () => { + await it('should auto-create persistent OrganizationName configuration key during self-check', () => { deleteConfigurationKey( mockChargingStation, OCPP20RequiredVariableName.OrganizationName as unknown as VariableType['name'], @@ -1572,7 +1574,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(after?.value).toBe('Example Charging Services Ltd') }) - await it('Should accept setting OrganizationName and require reboot per OCPP 2.0.1 specification', () => { + await it('should accept setting OrganizationName and require reboot per OCPP 2.0.1 specification', () => { const setRes = manager.setVariables(mockChargingStation, [ { attributeValue: 'NewOrgName', @@ -1591,7 +1593,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(getRes.attributeValue).toBe('NewOrgName') }) - await it('Should preserve OrganizationName value after resetRuntimeOverrides()', () => { + await it('should preserve OrganizationName value after resetRuntimeOverrides()', () => { manager.resetRuntimeOverrides() const res = manager.getVariables(mockChargingStation, [ { @@ -1604,7 +1606,7 @@ await describe('B05/B06 - OCPP20VariableManager test suite', async () => { expect(res.attributeValue).toBe('NewOrgName') }) - await it('Should create configuration key for instance-scoped MessageAttemptInterval and persist Actual value (Actual-only, no MinSet/MaxSet)', () => { + await it('should create configuration key for instance-scoped MessageAttemptInterval and persist Actual value (Actual-only, no MinSet/MaxSet)', () => { // Ensure no configuration key exists before operations const cfgBefore = getConfigurationKey( mockChargingStation, diff --git a/tests/charging-station/ocpp/auth/helpers/MockFactories.ts b/tests/charging-station/ocpp/auth/helpers/MockFactories.ts index 5e5b2382..aecf8905 100644 --- a/tests/charging-station/ocpp/auth/helpers/MockFactories.ts +++ b/tests/charging-station/ocpp/auth/helpers/MockFactories.ts @@ -261,11 +261,14 @@ export interface MockChargingStation { } /** - * Create a mock ChargingStation for auth module testing. + * Create a mock ChargingStation for auth module unit testing. + * + * Returns MockChargingStation interface - minimal interface for auth strategies. + * For OCPPAuthService tests requiring full ChargingStation type, use createMockAuthServiceTestStation(). * @param overrides - Partial MockChargingStation properties to override defaults * @returns Mock ChargingStation object with stubbed methods */ -export const createMockChargingStation = ( +export const createMockAuthChargingStation = ( overrides?: Partial ): MockChargingStation => ({ getConnectorStatus: () => ({ status: 'Available' }), diff --git a/tests/charging-station/ui-server/UIHttpServer.test.ts b/tests/charging-station/ui-server/UIHttpServer.test.ts index e064b489..6beff662 100644 --- a/tests/charging-station/ui-server/UIHttpServer.test.ts +++ b/tests/charging-station/ui-server/UIHttpServer.test.ts @@ -47,7 +47,7 @@ const createLargePayload = (status: ResponseStatus = ResponseStatus.SUCCESS) => }) await describe('UIHttpServer test suite', async () => { - await it('Verify sendResponse() deletes handler after sending', () => { + await it('should verify sendResponse() deletes handler after sending', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -61,7 +61,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.statusCode).toBe(200) }) - await it('Verify sendResponse() logs error when handler not found', () => { + await it('should verify sendResponse() logs error when handler not found', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) server.sendResponse([TEST_UUID, { status: ResponseStatus.SUCCESS }]) @@ -69,7 +69,7 @@ await describe('UIHttpServer test suite', async () => { expect(server.hasResponseHandler(TEST_UUID)).toBe(false) }) - await it('Verify sendResponse() sets correct status code for failure', () => { + await it('should verify sendResponse() sets correct status code for failure', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -81,7 +81,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.statusCode).toBe(400) }) - await it('Verify sendResponse() handles send errors gracefully', () => { + await it('should verify sendResponse() handles send errors gracefully', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() res.end = (): never => { @@ -94,7 +94,7 @@ await describe('UIHttpServer test suite', async () => { expect(server.hasResponseHandler(TEST_UUID)).toBe(false) }) - await it('Verify sendResponse() sets correct Content-Type header', () => { + await it('should verify sendResponse() sets correct Content-Type header', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -104,7 +104,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.headers['Content-Type']).toBe('application/json') }) - await it('Verify response handlers cleanup', () => { + await it('should verify response handlers cleanup', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res1 = new MockServerResponse() const res2 = new MockServerResponse() @@ -120,7 +120,7 @@ await describe('UIHttpServer test suite', async () => { expect(server.getResponseHandlersSize()).toBe(0) }) - await it('Verify handlers cleared on server stop', () => { + await it('should verify handlers cleared on server stop', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -132,7 +132,7 @@ await describe('UIHttpServer test suite', async () => { expect(server.getResponseHandlersSize()).toBe(0) }) - await it('Verify response payload serialization', () => { + await it('should verify response payload serialization', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() const payload = { @@ -149,7 +149,7 @@ await describe('UIHttpServer test suite', async () => { expect(parsedBody.hashIdsSucceeded).toEqual(['station-1', 'station-2']) }) - await it('Verify response with error details', () => { + await it('should verify response with error details', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() const payload = { @@ -168,13 +168,13 @@ await describe('UIHttpServer test suite', async () => { expect(parsedBody.hashIdsFailed).toEqual(['station-1']) }) - await it('Verify valid HTTP configuration', () => { + await it('should verify valid HTTP configuration', () => { const server = new UIHttpServer(createHttpServerConfig()) expect(server).toBeDefined() }) - await it('Verify HTTP server with custom config', () => { + await it('should verify HTTP server with custom config', () => { const config = createMockUIServerConfiguration({ options: { host: 'localhost', @@ -188,7 +188,7 @@ await describe('UIHttpServer test suite', async () => { }) await describe('Gzip compression', async () => { - await it('Verify no compression when acceptsGzip is false', () => { + await it('should verify no compression when acceptsGzip is false', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -200,7 +200,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.headers['Content-Type']).toBe('application/json') }) - await it('Verify no compression for small responses', () => { + await it('should verify no compression for small responses', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -212,7 +212,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.headers['Content-Type']).toBe('application/json') }) - await it('Verify no compression below threshold', () => { + await it('should verify no compression below threshold', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() const smallPayload = { @@ -227,7 +227,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.headers['Content-Encoding']).toBeUndefined() }) - await it('Verify compression headers for large responses', async () => { + await it('should verify compression headers for large responses', async () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -242,7 +242,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.headers.Vary).toBe('Accept-Encoding') }) - await it('Verify compressed response decompresses to original payload', async () => { + await it('should verify compressed response decompresses to original payload', async () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() const payload = createLargePayload() @@ -263,7 +263,7 @@ await describe('UIHttpServer test suite', async () => { expect(parsedBody.data).toBe(payload.data) }) - await it('Verify no compression when acceptsGzip context is missing', () => { + await it('should verify no compression when acceptsGzip context is missing', () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() @@ -274,7 +274,7 @@ await describe('UIHttpServer test suite', async () => { expect(res.headers['Content-Type']).toBe('application/json') }) - await it('Verify acceptsGzip context cleanup after response', async () => { + await it('should verify acceptsGzip context cleanup after response', async () => { const server = new TestableUIHttpServer(createHttpServerConfig()) const res = new MockServerResponse() diff --git a/tests/charging-station/ui-server/UIServerSecurity.test.ts b/tests/charging-station/ui-server/UIServerSecurity.test.ts index 7cd64e6f..d13cedfb 100644 --- a/tests/charging-station/ui-server/UIServerSecurity.test.ts +++ b/tests/charging-station/ui-server/UIServerSecurity.test.ts @@ -20,39 +20,39 @@ const RATE_WINDOW_EXPIRY_DELAY_MS = 110 await describe('UIServerSecurity test suite', async () => { await describe('isValidCredential()', async () => { - await it('Verify matching credentials return true', () => { + await it('should verify matching credentials return true', () => { expect(isValidCredential('myPassword123', 'myPassword123')).toBe(true) }) - await it('Verify non-matching credentials return false', () => { + await it('should verify non-matching credentials return false', () => { expect(isValidCredential('password1', 'password2')).toBe(false) }) - await it('Verify empty string credentials match', () => { + await it('should verify empty string credentials match', () => { expect(isValidCredential('', '')).toBe(true) }) - await it('Verify different length credentials return false', () => { + await it('should verify different length credentials return false', () => { // cspell:disable-next-line expect(isValidCredential('short', 'verylongpassword')).toBe(false) }) }) await describe('createBodySizeLimiter()', async () => { - await it('Verify bytes under limit return true', () => { + await it('should verify bytes under limit return true', () => { const limiter = createBodySizeLimiter(1000) expect(limiter(500)).toBe(true) }) - await it('Verify accumulated bytes exceeding limit return false', () => { + await it('should verify accumulated bytes exceeding limit return false', () => { const limiter = createBodySizeLimiter(1000) limiter(600) expect(limiter(500)).toBe(false) }) - await it('Verify exact limit boundary returns true', () => { + await it('should verify exact limit boundary returns true', () => { const limiter = createBodySizeLimiter(1000) expect(limiter(1000)).toBe(true) @@ -60,7 +60,7 @@ await describe('UIServerSecurity test suite', async () => { }) await describe('createRateLimiter()', async () => { - await it('Verify requests under limit are allowed', () => { + await it('should verify requests under limit are allowed', () => { const limiter = createRateLimiter(5, 1000) for (let i = 0; i < 5; i++) { @@ -68,7 +68,7 @@ await describe('UIServerSecurity test suite', async () => { } }) - await it('Verify requests exceeding limit are blocked', () => { + await it('should verify requests exceeding limit are blocked', () => { const limiter = createRateLimiter(3, 1000) limiter('192.168.1.1') limiter('192.168.1.1') @@ -77,7 +77,7 @@ await describe('UIServerSecurity test suite', async () => { expect(limiter('192.168.1.1')).toBe(false) }) - await it('Verify window resets after time expires', async () => { + await it('should verify window resets after time expires', async () => { const limiter = createRateLimiter(2, 100) limiter('10.0.0.1') limiter('10.0.0.1') @@ -88,7 +88,7 @@ await describe('UIServerSecurity test suite', async () => { expect(limiter('10.0.0.1')).toBe(true) }) - await it('Verify new IPs rejected when at max tracked capacity', () => { + await it('should verify new IPs rejected when at max tracked capacity', () => { const limiter = createRateLimiter(10, 60000, 3) expect(limiter('192.168.1.1')).toBe(true) @@ -97,7 +97,7 @@ await describe('UIServerSecurity test suite', async () => { expect(limiter('192.168.1.4')).toBe(false) }) - await it('Verify existing IPs still allowed when at capacity', () => { + await it('should verify existing IPs still allowed when at capacity', () => { const limiter = createRateLimiter(10, 60000, 2) expect(limiter('192.168.1.1')).toBe(true) @@ -106,7 +106,7 @@ await describe('UIServerSecurity test suite', async () => { expect(limiter('192.168.1.2')).toBe(true) }) - await it('Verify expired entries cleanup when at capacity', async () => { + await it('should verify expired entries cleanup when at capacity', async () => { const limiter = createRateLimiter(10, 50, 2) expect(limiter('192.168.1.1')).toBe(true) expect(limiter('192.168.1.2')).toBe(true) @@ -118,23 +118,23 @@ await describe('UIServerSecurity test suite', async () => { }) await describe('isValidNumberOfStations()', async () => { - await it('Verify valid number of stations returns true', () => { + await it('should verify valid number of stations returns true', () => { expect(isValidNumberOfStations(50, DEFAULT_MAX_STATIONS)).toBe(true) }) - await it('Verify exceeding max stations returns false', () => { + await it('should verify exceeding max stations returns false', () => { expect(isValidNumberOfStations(150, DEFAULT_MAX_STATIONS)).toBe(false) }) - await it('Verify zero stations returns false', () => { + await it('should verify zero stations returns false', () => { expect(isValidNumberOfStations(0, DEFAULT_MAX_STATIONS)).toBe(false) }) - await it('Verify negative stations returns false', () => { + await it('should verify negative stations returns false', () => { expect(isValidNumberOfStations(-5, DEFAULT_MAX_STATIONS)).toBe(false) }) - await it('Verify exact max stations boundary returns true', () => { + await it('should verify exact max stations boundary returns true', () => { expect(isValidNumberOfStations(DEFAULT_MAX_STATIONS, DEFAULT_MAX_STATIONS)).toBe(true) }) }) diff --git a/tests/charging-station/ui-server/UIServerTestUtils.ts b/tests/charging-station/ui-server/UIServerTestUtils.ts index 7f5fa811..64ccaae8 100644 --- a/tests/charging-station/ui-server/UIServerTestUtils.ts +++ b/tests/charging-station/ui-server/UIServerTestUtils.ts @@ -20,6 +20,11 @@ import { ProcedureName, ResponseStatus, } from '../../../src/types/index.js' +import { waitForCondition } from '../helpers/StationHelpers.js' +import { MockWebSocket as BaseMockWebSocket } from '../mocks/MockWebSocket.js' + +// Re-export waitForCondition for backward compatibility +export { waitForCondition } export const createMockUIServerConfiguration = ( overrides?: Partial @@ -95,33 +100,28 @@ export class MockServerResponse extends EventEmitter { } } -export class MockWebSocket extends EventEmitter { - public protocol = 'ui0.0.1' - public readyState = 1 // OPEN - public sentMessages: string[] = [] - - public close (code?: number): void { - this.readyState = 3 // CLOSED - this.emit('close', code, Buffer.from('')) +/** + * MockWebSocket for UI protocol testing + * + * Extends base MockWebSocket with UI-specific helper methods. + * Uses 'ui0.0.1' protocol by default. + */ +export class MockWebSocket extends BaseMockWebSocket { + constructor () { + super('ws://localhost:8080/ui') + this.protocol = 'ui0.0.1' } - public getLastSentMessage (): ProtocolResponse | undefined { - if (this.sentMessages.length === 0) { + /** + * Get last sent message parsed as ProtocolResponse + * @returns Parsed ProtocolResponse or undefined if no messages + */ + public getLastSentMessageAsResponse (): ProtocolResponse | undefined { + const lastMsg = this.getLastSentMessage() + if (lastMsg == null) { return undefined } - return JSON.parse(this.sentMessages[this.sentMessages.length - 1]) as ProtocolResponse - } - - public send (data: string): void { - this.sentMessages.push(data) - } - - public simulateError (error: Error): void { - this.emit('error', error) - } - - public simulateMessage (data: string): void { - this.emit('message', Buffer.from(data)) + return JSON.parse(lastMsg) as ProtocolResponse } } @@ -181,22 +181,6 @@ export const createMalformedRequest = (): string => { return JSON.stringify({ not: 'an array' }) } -export const waitForCondition = async ( - condition: () => boolean, - timeout = 1000, - interval = 10 -): Promise => { - const startTime = Date.now() - while (!condition()) { - if (Date.now() - startTime > timeout) { - throw new Error('Timeout waiting for condition') - } - await new Promise(resolve => { - setTimeout(resolve, interval) - }) - } -} - export const createMockBroadcastResponse = ( uuid: string, hashId: string, diff --git a/tests/charging-station/ui-server/UIWebSocketServer.test.ts b/tests/charging-station/ui-server/UIWebSocketServer.test.ts index 11cfd8c9..0d949e26 100644 --- a/tests/charging-station/ui-server/UIWebSocketServer.test.ts +++ b/tests/charging-station/ui-server/UIWebSocketServer.test.ts @@ -35,7 +35,7 @@ class TestableUIWebSocketServer extends UIWebSocketServer { } await describe('UIWebSocketServer test suite', async () => { - await it('Verify sendResponse() deletes handler after sending', () => { + await it('should verify sendResponse() deletes handler after sending', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const ws = new MockWebSocket() @@ -49,7 +49,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(ws.sentMessages.length).toBe(1) }) - await it('Verify sendResponse() logs error when handler not found', () => { + await it('should verify sendResponse() logs error when handler not found', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -58,7 +58,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(server.hasResponseHandler(TEST_UUID)).toBe(false) }) - await it('Verify sendResponse() deletes handler when WebSocket not open', () => { + await it('should verify sendResponse() deletes handler when WebSocket not open', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const ws = new MockWebSocket() @@ -71,7 +71,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(ws.sentMessages.length).toBe(0) }) - await it('Verify sendResponse() handles send errors gracefully', () => { + await it('should verify sendResponse() handles send errors gracefully', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const ws = new MockWebSocket() @@ -86,7 +86,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(server.hasResponseHandler(TEST_UUID)).toBe(false) }) - await it('Verify broadcast handler persistence (issue #1642)', async () => { + await it('should verify broadcast handler persistence (issue #1642)', async () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const mockService = new MockUIServiceBroadcast() @@ -108,7 +108,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(server.hasResponseHandler(TEST_UUID)).toBe(false) }) - await it('Verify non-broadcast handler immediate deletion', async () => { + await it('should verify non-broadcast handler immediate deletion', async () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const mockService = new MockUIServiceNonBroadcast() @@ -127,7 +127,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(server.hasResponseHandler(TEST_UUID)).toBe(false) }) - await it('Verify error handler cleanup', async () => { + await it('should verify error handler cleanup', async () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const mockService = new MockUIServiceError() @@ -145,7 +145,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(server.getResponseHandlersSize()).toBe(1) }) - await it('Verify response handlers cleanup', () => { + await it('should verify response handlers cleanup', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const ws1 = new MockWebSocket() @@ -163,7 +163,7 @@ await describe('UIWebSocketServer test suite', async () => { expect(server.getResponseHandlersSize()).toBe(0) }) - await it('Verify handlers cleared on server stop', () => { + await it('should verify handlers cleared on server stop', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) const ws = new MockWebSocket() @@ -176,14 +176,14 @@ await describe('UIWebSocketServer test suite', async () => { expect(server.getResponseHandlersSize()).toBe(0) }) - await it('Verify valid WebSocket configuration', () => { + await it('should verify valid WebSocket configuration', () => { const config = createMockUIServerConfiguration() const server = new UIWebSocketServer(config) expect(server).toBeDefined() }) - await it('Verify WebSocket server with custom config', () => { + await it('should verify WebSocket server with custom config', () => { const config = createMockUIServerConfiguration({ options: { host: 'localhost', diff --git a/tests/charging-station/ui-server/ui-services/AbstractUIService.test.ts b/tests/charging-station/ui-server/ui-services/AbstractUIService.test.ts index 5aef755f..78b0da79 100644 --- a/tests/charging-station/ui-server/ui-services/AbstractUIService.test.ts +++ b/tests/charging-station/ui-server/ui-services/AbstractUIService.test.ts @@ -27,7 +27,7 @@ class TestableUIWebSocketServer extends UIWebSocketServer { } await describe('AbstractUIService test suite', async () => { - await it('Verify sendResponse checks for response handler existence', () => { + await it('should verify sendResponse checks for response handler existence', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -43,7 +43,7 @@ await describe('AbstractUIService test suite', async () => { expect(server.hasResponseHandler(TEST_UUID)).toBe(false) }) - await it('Verify requestHandler returns response for LIST_CHARGING_STATIONS', async () => { + await it('should verify requestHandler returns response for LIST_CHARGING_STATIONS', async () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -70,7 +70,7 @@ await describe('AbstractUIService test suite', async () => { } }) - await it('Verify requestHandler returns response for LIST_TEMPLATES', async () => { + await it('should verify requestHandler returns response for LIST_TEMPLATES', async () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -99,7 +99,7 @@ await describe('AbstractUIService test suite', async () => { } }) - await it('Verify requestHandler returns error response for unknown procedure', async () => { + await it('should verify requestHandler returns error response for unknown procedure', async () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -123,7 +123,7 @@ await describe('AbstractUIService test suite', async () => { } }) - await it('Verify broadcast channel request tracking initialization', () => { + await it('should verify broadcast channel request tracking initialization', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -138,7 +138,7 @@ await describe('AbstractUIService test suite', async () => { } }) - await it('Verify broadcast channel cleanup on stop', () => { + await it('should verify broadcast channel cleanup on stop', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -153,7 +153,7 @@ await describe('AbstractUIService test suite', async () => { } }) - await it('Verify requestHandler handles errors gracefully', async () => { + await it('should verify requestHandler handles errors gracefully', async () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -176,7 +176,7 @@ await describe('AbstractUIService test suite', async () => { } }) - await it('Verify UI service initialization', () => { + await it('should verify UI service initialization', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) @@ -190,7 +190,7 @@ await describe('AbstractUIService test suite', async () => { } }) - await it('Verify multiple service registrations', () => { + await it('should verify multiple service registrations', () => { const config = createMockUIServerConfiguration() const server = new TestableUIWebSocketServer(config) diff --git a/tests/exception/BaseError.test.ts b/tests/exception/BaseError.test.ts index 1a341ac7..8349fa70 100644 --- a/tests/exception/BaseError.test.ts +++ b/tests/exception/BaseError.test.ts @@ -8,7 +8,7 @@ import { describe, it } from 'node:test' import { BaseError } from '../../src/exception/BaseError.js' await describe('BaseError test suite', async () => { - await it('Verify that BaseError can be instantiated', () => { + await it('should verify that BaseError can be instantiated', () => { const baseError = new BaseError() expect(baseError).toBeInstanceOf(BaseError) expect(baseError.name).toBe('BaseError') @@ -19,7 +19,7 @@ await describe('BaseError test suite', async () => { expect(baseError.date).toBeInstanceOf(Date) }) - await it('Verify that BaseError can be instantiated with a message', () => { + await it('should verify that BaseError can be instantiated with a message', () => { const baseError = new BaseError('Test message') expect(baseError).toBeInstanceOf(BaseError) expect(baseError.message).toBe('Test message') diff --git a/tests/exception/OCPPError.test.ts b/tests/exception/OCPPError.test.ts index 8145b5cf..d83b18b6 100644 --- a/tests/exception/OCPPError.test.ts +++ b/tests/exception/OCPPError.test.ts @@ -10,7 +10,7 @@ import { ErrorType } from '../../src/types/index.js' import { Constants } from '../../src/utils/Constants.js' await describe('OCPPError test suite', async () => { - await it('Verify that OCPPError can be instantiated', () => { + await it('should verify that OCPPError can be instantiated', () => { const ocppError = new OCPPError(ErrorType.GENERIC_ERROR, '') expect(ocppError).toBeInstanceOf(OCPPError) expect(ocppError.name).toBe('OCPPError') diff --git a/tests/types/ConfigurationData.test.ts b/tests/types/ConfigurationData.test.ts index 6f6b704a..a1651cc5 100644 --- a/tests/types/ConfigurationData.test.ts +++ b/tests/types/ConfigurationData.test.ts @@ -12,20 +12,20 @@ import { } from '../../src/types/ConfigurationData.js' await describe('ConfigurationData test suite', async () => { - await it('Verify ConfigurationSection enumeration', () => { + await it('should verify ConfigurationSection enumeration', () => { expect(ConfigurationSection.log).toBe('log') expect(ConfigurationSection.performanceStorage).toBe('performanceStorage') expect(ConfigurationSection.uiServer).toBe('uiServer') expect(ConfigurationSection.worker).toBe('worker') }) - await it('Verify SupervisionUrlDistribution enumeration', () => { + await it('should verify SupervisionUrlDistribution enumeration', () => { expect(SupervisionUrlDistribution.CHARGING_STATION_AFFINITY).toBe('charging-station-affinity') expect(SupervisionUrlDistribution.RANDOM).toBe('random') expect(SupervisionUrlDistribution.ROUND_ROBIN).toBe('round-robin') }) - await it('Verify ApplicationProtocolVersion enumeration', () => { + await it('should verify ApplicationProtocolVersion enumeration', () => { expect(ApplicationProtocolVersion.VERSION_11).toBe('1.1') expect(ApplicationProtocolVersion.VERSION_20).toBe('2.0') }) diff --git a/tests/utils/AsyncLock.test.ts b/tests/utils/AsyncLock.test.ts index 58646289..1ec5edd1 100644 --- a/tests/utils/AsyncLock.test.ts +++ b/tests/utils/AsyncLock.test.ts @@ -9,7 +9,7 @@ import { describe, it } from 'node:test' import { AsyncLock, AsyncLockType } from '../../src/utils/AsyncLock.js' await describe('AsyncLock test suite', async () => { - await it('Verify runExclusive() on sync fn', () => { + await it('should verify runExclusive() on sync fn', () => { const runs = 10 const executed: number[] = [] let count = 0 @@ -26,7 +26,7 @@ await describe('AsyncLock test suite', async () => { } }) - await it('Verify runExclusive() on async fn', () => { + await it('should verify runExclusive() on async fn', () => { const runs = 10 const executed: number[] = [] let count = 0 diff --git a/tests/utils/ConfigurationUtils.test.ts b/tests/utils/ConfigurationUtils.test.ts index 30e6015e..9d49f962 100644 --- a/tests/utils/ConfigurationUtils.test.ts +++ b/tests/utils/ConfigurationUtils.test.ts @@ -15,17 +15,17 @@ import { } from '../../src/utils/ConfigurationUtils.js' await describe('ConfigurationUtils test suite', async () => { - await it('Verify logPrefix()', () => { + await it('should verify logPrefix()', () => { expect(logPrefix()).toContain(' Simulator configuration |') }) - await it('Verify buildPerformanceUriFilePath()', () => { + await it('should verify buildPerformanceUriFilePath()', () => { const result = buildPerformanceUriFilePath('test.json') expect(result).toContain('test.json') expect(result).toMatch(/^file:\/\/.*test\.json$/) }) - await it('Verify getDefaultPerformanceStorageUri()', () => { + await it('should verify getDefaultPerformanceStorageUri()', () => { // Test JSON_FILE storage type const jsonUri = getDefaultPerformanceStorageUri(StorageType.JSON_FILE) expect(jsonUri).toMatch(/^file:\/\/.*\.json$/) @@ -42,7 +42,7 @@ await describe('ConfigurationUtils test suite', async () => { }).toThrow(Error) }) - await it('Verify handleFileException()', t => { + await it('should verify handleFileException()', t => { const mockConsoleError = t.mock.method(console, 'error') const error = new Error() as NodeJS.ErrnoException error.code = 'ENOENT' @@ -52,7 +52,7 @@ await describe('ConfigurationUtils test suite', async () => { expect(mockConsoleError.mock.calls.length).toBe(1) }) - await it('Verify checkWorkerElementsPerWorker()', () => { + await it('should verify checkWorkerElementsPerWorker()', () => { // These calls should not throw exceptions expect(() => { checkWorkerElementsPerWorker(undefined) diff --git a/tests/utils/ElectricUtils.test.ts b/tests/utils/ElectricUtils.test.ts index 9ebf495a..1b1377bb 100644 --- a/tests/utils/ElectricUtils.test.ts +++ b/tests/utils/ElectricUtils.test.ts @@ -8,25 +8,25 @@ import { describe, it } from 'node:test' import { ACElectricUtils, DCElectricUtils } from '../../src/utils/ElectricUtils.js' await describe('ElectricUtils test suite', async () => { - await it('Verify DCElectricUtils.power()', () => { + await it('should verify DCElectricUtils.power()', () => { expect(DCElectricUtils.power(230, 1)).toBe(230) }) - await it('Verify DCElectricUtils.amperage()', () => { + await it('should verify DCElectricUtils.amperage()', () => { expect(DCElectricUtils.amperage(1, 230)).toBe(0) }) - await it('Verify ACElectricUtils.powerTotal()', () => { + await it('should verify ACElectricUtils.powerTotal()', () => { expect(ACElectricUtils.powerTotal(3, 230, 1)).toBe(690) }) - await it('Verify ACElectricUtils.powerPerPhase()', () => { + await it('should verify ACElectricUtils.powerPerPhase()', () => { expect(ACElectricUtils.powerPerPhase(230, 1)).toBe(230) }) - await it('Verify ACElectricUtils.amperageTotal()', () => { + await it('should verify ACElectricUtils.amperageTotal()', () => { expect(ACElectricUtils.amperageTotal(3, 1)).toBe(3) }) - await it('Verify ACElectricUtils.amperageTotalFromPower()', () => { + await it('should verify ACElectricUtils.amperageTotalFromPower()', () => { expect(ACElectricUtils.amperageTotalFromPower(690, 230)).toBe(3) }) - await it('Verify ACElectricUtils.amperagePerPhaseFromPower()', () => { + await it('should verify ACElectricUtils.amperagePerPhaseFromPower()', () => { expect(ACElectricUtils.amperagePerPhaseFromPower(3, 690, 230)).toBe(1) }) }) diff --git a/tests/utils/ErrorUtils.test.ts b/tests/utils/ErrorUtils.test.ts index 85682bb7..2a0ed0b7 100644 --- a/tests/utils/ErrorUtils.test.ts +++ b/tests/utils/ErrorUtils.test.ts @@ -23,7 +23,7 @@ import { createChargingStation } from '../ChargingStationFactory.js' await describe('ErrorUtils test suite', async () => { const chargingStation = createChargingStation({ baseName: 'CS-TEST' }) - await it('Verify handleFileException()', t => { + await it('should verify handleFileException()', t => { const consoleWarnMock = t.mock.method(console, 'warn') const consoleErrorMock = t.mock.method(console, 'error') const warnMock = t.mock.method(logger, 'warn') @@ -55,7 +55,7 @@ await describe('ErrorUtils test suite', async () => { expect(consoleErrorMock.mock.calls.length).toBe(1) }) - await it('Verify handleSendMessageError()', t => { + await it('should verify handleSendMessageError()', t => { const errorMock = t.mock.method(logger, 'error') const logPrefixMock = t.mock.method(chargingStation, 'logPrefix') const error = new Error() @@ -80,7 +80,7 @@ await describe('ErrorUtils test suite', async () => { expect(errorMock.mock.calls.length).toBe(2) }) - await it('Verify handleIncomingRequestError()', t => { + await it('should verify handleIncomingRequestError()', t => { const errorMock = t.mock.method(logger, 'error') const logPrefixMock = t.mock.method(chargingStation, 'logPrefix') const error = new Error() diff --git a/tests/utils/StatisticUtils.test.ts b/tests/utils/StatisticUtils.test.ts index d578bc9c..c2c7adc0 100644 --- a/tests/utils/StatisticUtils.test.ts +++ b/tests/utils/StatisticUtils.test.ts @@ -8,21 +8,21 @@ import { describe, it } from 'node:test' import { average, max, median, min, percentile, std } from '../../src/utils/StatisticUtils.js' await describe('StatisticUtils test suite', async () => { - await it('Verify average()', () => { + await it('should verify average()', () => { expect(average([])).toBe(0) expect(average([0.08])).toBe(0.08) expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.1642857142857146) expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.8533333333333335) }) - await it('Verify median()', () => { + await it('should verify median()', () => { expect(median([])).toBe(0) expect(median([0.08])).toBe(0.08) expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05) expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535) }) - await it('Verify min()', () => { + await it('should verify min()', () => { expect(min()).toBe(Number.POSITIVE_INFINITY) expect(min(0, 1)).toBe(0) expect(min(1, 0)).toBe(0) @@ -30,7 +30,7 @@ await describe('StatisticUtils test suite', async () => { expect(min(-1, 0)).toBe(-1) }) - await it('Verify max()', () => { + await it('should verify max()', () => { expect(max()).toBe(Number.NEGATIVE_INFINITY) expect(max(0, 1)).toBe(1) expect(max(1, 0)).toBe(1) @@ -38,7 +38,7 @@ await describe('StatisticUtils test suite', async () => { expect(max(-1, 0)).toBe(0) }) - await it('Verify percentile()', () => { + await it('should verify percentile()', () => { expect(percentile([], 25)).toBe(0) expect(percentile([0.08], 50)).toBe(0.08) const array0 = [0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03] @@ -51,7 +51,7 @@ await describe('StatisticUtils test suite', async () => { expect(percentile(array0, 100)).toBe(6.04) }) - await it('Verify std()', () => { + await it('should verify std()', () => { expect(std([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(2.1879050645374383) }) }) diff --git a/tests/utils/Utils.test.ts b/tests/utils/Utils.test.ts index 4d91042f..a980380d 100644 --- a/tests/utils/Utils.test.ts +++ b/tests/utils/Utils.test.ts @@ -45,7 +45,7 @@ import { } from '../../src/utils/Utils.js' await describe('Utils test suite', async () => { - await it('Verify generateUUID()/validateUUID()', () => { + await it('should verify generateUUID()/validateUUID()', () => { const uuid = generateUUID() expect(uuid).toBeDefined() expect(uuid.length).toEqual(36) @@ -66,7 +66,7 @@ await describe('Utils test suite', async () => { expect(validateUUID(true)).toBe(false) }) - await it('Verify validateIdentifierString()', () => { + await it('should verify validateIdentifierString()', () => { expect(validateIdentifierString('550e8400-e29b-41d4-a716-446655440000', 36)).toBe(true) expect(validateIdentifierString('CSMS-TXN-12345', 36)).toBe(true) expect(validateIdentifierString('a', 36)).toBe(true) @@ -81,7 +81,7 @@ await describe('Utils test suite', async () => { expect(validateIdentifierString('valid', 4)).toBe(false) }) - await it('Verify sleep()', async t => { + await it('should verify sleep()', async t => { /** * Timer mock pattern for testing asynchronous timer-based operations. * Uses Node.js test module's built-in timer mocking API. @@ -125,21 +125,21 @@ await describe('Utils test suite', async () => { } }) - await it('Verify formatDurationMilliSeconds()', () => { + await it('should verify formatDurationMilliSeconds()', () => { expect(formatDurationMilliSeconds(0)).toBe('0 seconds') expect(formatDurationMilliSeconds(900)).toBe('0 seconds') expect(formatDurationMilliSeconds(1000)).toBe('1 second') expect(formatDurationMilliSeconds(hoursToMilliseconds(4380))).toBe('182 days 12 hours') }) - await it('Verify formatDurationSeconds()', () => { + await it('should verify formatDurationSeconds()', () => { expect(formatDurationSeconds(0)).toBe('0 seconds') expect(formatDurationSeconds(0.9)).toBe('0 seconds') expect(formatDurationSeconds(1)).toBe('1 second') expect(formatDurationSeconds(hoursToSeconds(4380))).toBe('182 days 12 hours') }) - await it('Verify isValidDate()', () => { + await it('should verify isValidDate()', () => { expect(isValidDate(undefined)).toBe(false) expect(isValidDate(-1)).toBe(true) expect(isValidDate(0)).toBe(true) @@ -149,7 +149,7 @@ await describe('Utils test suite', async () => { expect(isValidDate(new Date())).toBe(true) }) - await it('Verify convertToDate()', () => { + await it('should verify convertToDate()', () => { expect(convertToDate(undefined)).toBe(undefined) expect(convertToDate(null)).toBe(undefined) expect(() => convertToDate('')).toThrow(new Error("Cannot convert to date: ''")) @@ -165,7 +165,7 @@ await describe('Utils test suite', async () => { expect(date).toStrictEqual(new Date(dateStr)) }) - await it('Verify convertToInt()', () => { + await it('should verify convertToInt()', () => { expect(convertToInt(undefined)).toBe(0) expect(convertToInt(null)).toBe(0) expect(convertToInt(0)).toBe(0) @@ -186,7 +186,7 @@ await describe('Utils test suite', async () => { }).toThrow("Cannot convert to integer: 'NaN'") }) - await it('Verify convertToFloat()', () => { + await it('should verify convertToFloat()', () => { expect(convertToFloat(undefined)).toBe(0) expect(convertToFloat(null)).toBe(0) expect(convertToFloat(0)).toBe(0) @@ -207,7 +207,7 @@ await describe('Utils test suite', async () => { }).toThrow("Cannot convert to float: 'NaN'") }) - await it('Verify convertToBoolean()', () => { + await it('should verify convertToBoolean()', () => { expect(convertToBoolean(undefined)).toBe(false) expect(convertToBoolean(null)).toBe(false) expect(convertToBoolean('true')).toBe(true) @@ -224,14 +224,14 @@ await describe('Utils test suite', async () => { expect(convertToBoolean('NoNBoolean')).toBe(false) }) - await it('Verify secureRandom()', () => { + await it('should verify secureRandom()', () => { const random = secureRandom() expect(typeof random === 'number').toBe(true) expect(random).toBeGreaterThanOrEqual(0) expect(random).toBeLessThan(1) }) - await it('Verify roundTo()', () => { + await it('should verify roundTo()', () => { expect(roundTo(0, 2)).toBe(0) expect(roundTo(0.5, 0)).toBe(1) expect(roundTo(0.5, 2)).toBe(0.5) @@ -246,7 +246,7 @@ await describe('Utils test suite', async () => { expect(roundTo(-5.015, 2)).toBe(-5.02) }) - await it('Verify getRandomFloat()', () => { + await it('should verify getRandomFloat()', () => { let randomFloat = getRandomFloat() expect(typeof randomFloat === 'number').toBe(true) expect(randomFloat).toBeGreaterThanOrEqual(0) @@ -261,7 +261,7 @@ await describe('Utils test suite', async () => { expect(randomFloat).toBeLessThanOrEqual(0) }) - await it('Verify extractTimeSeriesValues()', () => { + await it('should verify extractTimeSeriesValues()', () => { expect( extractTimeSeriesValues( new CircularBuffer(Array, Constants.DEFAULT_CIRCULAR_BUFFER_CAPACITY) @@ -277,7 +277,7 @@ await describe('Utils test suite', async () => { expect(extractTimeSeriesValues(circularBuffer)).toEqual([1.1, 2.2, 3.3]) }) - await it('Verify isAsyncFunction()', () => { + await it('should verify isAsyncFunction()', () => { expect(isAsyncFunction(null)).toBe(false) expect(isAsyncFunction(undefined)).toBe(false) expect(isAsyncFunction(true)).toBe(false) @@ -352,7 +352,7 @@ await describe('Utils test suite', async () => { expect(isAsyncFunction(TestClass.testStaticAsync)).toBe(true) }) - await it('Verify clone()', () => { + await it('should verify clone()', () => { const obj = { 1: 1 } expect(clone(obj)).toStrictEqual(obj) expect(clone(obj) === obj).toBe(false) @@ -384,7 +384,7 @@ await describe('Utils test suite', async () => { expect(() => clone(weakSet)).toThrow(new Error('# could not be cloned.')) }) - await it('Verify once()', () => { + await it('should verify once()', () => { let called = 0 const fn = (): number => ++called const onceFn = once(fn) @@ -399,7 +399,7 @@ await describe('Utils test suite', async () => { expect(result3).toBe(1) }) - await it('Verify has()', () => { + await it('should verify has()', () => { expect(has('', 'test')).toBe(false) expect(has('test', '')).toBe(false) expect(has('test', 'test')).toBe(false) @@ -417,7 +417,7 @@ await describe('Utils test suite', async () => { expect(has(2, { 1: '1' })).toBe(false) }) - await it('Verify isEmpty()', () => { + await it('should verify isEmpty()', () => { expect(isEmpty('')).toBe(true) expect(isEmpty(' ')).toBe(true) expect(isEmpty(' ')).toBe(true) @@ -435,7 +435,7 @@ await describe('Utils test suite', async () => { expect(isEmpty(new WeakSet())).toBe(false) }) - await it('Verify isNotEmptyString()', () => { + await it('should verify isNotEmptyString()', () => { expect(isNotEmptyString('')).toBe(false) expect(isNotEmptyString(' ')).toBe(false) expect(isNotEmptyString(' ')).toBe(false) @@ -453,7 +453,7 @@ await describe('Utils test suite', async () => { expect(isNotEmptyString(new WeakSet())).toBe(false) }) - await it('Verify isNotEmptyArray()', () => { + await it('should verify isNotEmptyArray()', () => { expect(isNotEmptyArray([])).toBe(false) expect(isNotEmptyArray([1, 2])).toBe(true) expect(isNotEmptyArray(['1', '2'])).toBe(true) @@ -469,13 +469,13 @@ await describe('Utils test suite', async () => { expect(isNotEmptyArray(new WeakSet())).toBe(false) }) - await it('Verify insertAt()', () => { + await it('should verify insertAt()', () => { expect(insertAt('test', 'ing', 'test'.length)).toBe('testing') // eslint-disable-next-line @cspell/spellchecker expect(insertAt('test', 'ing', 2)).toBe('teingst') }) - await it('Verify convertToIntOrNaN()', () => { + await it('should verify convertToIntOrNaN()', () => { expect(convertToIntOrNaN(undefined)).toBe(0) expect(convertToIntOrNaN(null)).toBe(0) expect(convertToIntOrNaN('0')).toBe(0) @@ -486,7 +486,7 @@ await describe('Utils test suite', async () => { expect(Number.isNaN(convertToIntOrNaN('abc'))).toBe(true) }) - await it('Verify isArraySorted()', () => { + await it('should verify isArraySorted()', () => { expect(isArraySorted([], (a, b) => a - b)).toBe(true) expect(isArraySorted([1], (a, b) => a - b)).toBe(true) expect(isArraySorted([1, 2, 3, 4, 5], (a, b) => a - b)).toBe(true) @@ -494,7 +494,7 @@ await describe('Utils test suite', async () => { expect(isArraySorted([2, 1, 3, 4, 5], (a, b) => a - b)).toBe(false) }) - await it('Verify clampToSafeTimerValue()', () => { + await it('should verify clampToSafeTimerValue()', () => { expect(clampToSafeTimerValue(0)).toBe(0) expect(clampToSafeTimerValue(1000)).toBe(1000) expect(clampToSafeTimerValue(Constants.MAX_SETINTERVAL_DELAY)).toBe( @@ -512,7 +512,7 @@ await describe('Utils test suite', async () => { // Exponential Backoff Algorithm Tests (WebSocket Reconnection) // ------------------------------------------------------------------------- - await it('Verify exponentialDelay() with default parameters', () => { + await it('should verify exponentialDelay() with default parameters', () => { // Formula: delay = 2^retryNumber * delayFactor + (0-20% random jitter) // With default delayFactor = 100ms @@ -537,7 +537,7 @@ await describe('Utils test suite', async () => { expect(delay3).toBeLessThanOrEqual(960) // 800 + 20% max jitter }) - await it('Verify exponentialDelay() with custom delayFactor', () => { + await it('should verify exponentialDelay() with custom delayFactor', () => { // Custom delayFactor = 50ms const delay0 = exponentialDelay(0, 50) expect(delay0).toBeGreaterThanOrEqual(50) @@ -553,7 +553,7 @@ await describe('Utils test suite', async () => { expect(delay2).toBeLessThanOrEqual(960) }) - await it('Verify exponentialDelay() exponential growth pattern', () => { + await it('should verify exponentialDelay() exponential growth pattern', () => { // Verify that delays follow 2^n exponential growth pattern const delayFactor = 100 @@ -573,7 +573,7 @@ await describe('Utils test suite', async () => { } }) - await it('Verify exponentialDelay() includes random jitter', () => { + await it('should verify exponentialDelay() includes random jitter', () => { // Run multiple times to verify jitter produces different values const delays = new Set() const retryNumber = 3 @@ -590,7 +590,7 @@ await describe('Utils test suite', async () => { expect(delays.size).toBeGreaterThan(1) }) - await it('Verify exponentialDelay() jitter is within 0-20% range', () => { + await it('should verify exponentialDelay() jitter is within 0-20% range', () => { // For a given retry, jitter should add 0-20% of base delay const retryNumber = 4 const delayFactor = 100 @@ -607,7 +607,7 @@ await describe('Utils test suite', async () => { } }) - await it('Verify exponentialDelay() handles edge cases', () => { + await it('should verify exponentialDelay() handles edge cases', () => { // Default retryNumber (0) const defaultRetry = exponentialDelay() expect(defaultRetry).toBeGreaterThanOrEqual(100) // 2^0 * 100 @@ -625,7 +625,7 @@ await describe('Utils test suite', async () => { expect(smallFactor).toBeLessThan(5) // 4 + 20% }) - await it('Verify exponentialDelay() for WebSocket reconnection scenarios', () => { + await it('should verify exponentialDelay() for WebSocket reconnection scenarios', () => { // Simulate typical WebSocket reconnection delay sequence const delayFactor = 100 // Default used in ChargingStation.reconnect() diff --git a/tests/worker/WorkerUtils.test.ts b/tests/worker/WorkerUtils.test.ts index 9ff80058..39e416d8 100644 --- a/tests/worker/WorkerUtils.test.ts +++ b/tests/worker/WorkerUtils.test.ts @@ -15,7 +15,7 @@ import { } from '../../src/worker/WorkerUtils.js' await describe('WorkerUtils test suite', async () => { - await it('Verify checkWorkerProcessType()', () => { + await it('should verify checkWorkerProcessType()', () => { // Valid worker process types should not throw expect(() => { checkWorkerProcessType(WorkerProcessType.dynamicPool) @@ -33,7 +33,7 @@ await describe('WorkerUtils test suite', async () => { }).toThrow(SyntaxError) }) - await it('Verify sleep()', async t => { + await it('should verify sleep()', async t => { t.mock.timers.enable({ apis: ['setTimeout'] }) try { const delay = 10 // 10ms for fast test execution @@ -52,7 +52,7 @@ await describe('WorkerUtils test suite', async () => { } }) - await it('Verify defaultExitHandler()', t => { + await it('should verify defaultExitHandler()', t => { const mockConsoleInfo = t.mock.method(console, 'info') const mockConsoleError = t.mock.method(console, 'error') @@ -85,7 +85,7 @@ await describe('WorkerUtils test suite', async () => { expect(mockConsoleError.mock.calls.length).toBe(1) }) - await it('Verify defaultErrorHandler()', t => { + await it('should verify defaultErrorHandler()', t => { const mockConsoleError = t.mock.method(console, 'error') const testError = new Error('Test error message') @@ -99,7 +99,7 @@ await describe('WorkerUtils test suite', async () => { expect(mockConsoleError.mock.calls.length).toBe(2) }) - await it('Verify randomizeDelay()', () => { + await it('should verify randomizeDelay()', () => { const baseDelay = 1000 const tolerance = baseDelay * 0.2 // 20% tolerance as per implementation -- 2.43.0