]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
fix(test-isolation): move mock instances to beforeEach in OCPP 2.0 tests
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 28 Feb 2026 15:48:00 +0000 (16:48 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 28 Feb 2026 15:48:00 +0000 (16:48 +0100)
Move module-level mock instances inside beforeEach blocks to ensure
proper test isolation per TEST_STYLE_GUIDE.md requirements.

- 11 IncomingRequestService test files fixed
- 1 VariableManager test file fixed
- 1 ServiceUtils-TransactionEvent test file fixed
- 1 TestUtils file updated with JSDoc documentation

Each test now gets fresh mock instances, eliminating potential
cross-test state contamination.

14 files changed:
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-CertificateSigned.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-ClearCache.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-DeleteCertificate.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetBaseReport.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetInstalledCertificateIds.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-GetVariables.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-InstallCertificate.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStartTransaction.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-RequestStopTransaction.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-Reset.test.ts
tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-SetVariables.test.ts
tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent-IdTokenFirst.test.ts
tests/charging-station/ocpp/2.0/OCPP20TestUtils.ts
tests/charging-station/ocpp/2.0/OCPP20VariableManager.test.ts

index 2227f8c59f56ad9d9253d2bab134c75186b1c9e6..00fb18df643cd387cfa800a2ab9cb6929c2ff336 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 import { expect } from '@std/expect'
-import { afterEach, describe, it, mock, type Mock } from 'node:test'
+import { afterEach, beforeEach, describe, it, mock, type Mock } from 'node:test'
 
 import type { ChargingStation } from '../../../../src/charging-station/index.js'
 import type {
@@ -105,29 +105,31 @@ const createMockCertificateManager = (
 })
 
 await describe('I04 - CertificateSigned', async () => {
+  let mockChargingStation: TestableChargingStationWithCertificate
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    }) as TestableChargingStationWithCertificate
+    mockChargingStation.certificateManager = createMockCertificateManager()
+    mockChargingStation.closeWSConnection = mock.fn()
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
+  })
+
   afterEach(() => {
     mock.restoreAll()
   })
-
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  }) as TestableChargingStationWithCertificate
-
-  mockChargingStation.certificateManager = createMockCertificateManager()
-  // Mock closeWSConnection for reconnect tests
-  mockChargingStation.closeWSConnection = mock.fn()
-
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
-
   await describe('Valid Certificate Chain Installation', async () => {
     await it('should accept valid certificate chain', async () => {
       mockChargingStation.certificateManager = createMockCertificateManager({
index b28fa9b4a64f9dd420c106b3570bf07edea2b11c..a9e1a43edcbe5d3968c14379d21a0449f0c0ddfe 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it, mock } from 'node:test'
 
 import { createTestableIncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/__testable__/index.js'
 import { OCPP20IncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.js'
@@ -19,21 +19,26 @@ await describe('C11 - Clear Authorization Data in Authorization Cache', async ()
     mock.restoreAll()
   })
 
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
   })
 
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
-
   // FR: C11.FR.01 - CS SHALL attempt to clear its Authorization Cache
   await it('should handle ClearCache request successfully', async () => {
     const response = await testableService.handleRequestClearCache(mockChargingStation)
index 7408c7c8c0aade5b4cbc3b4bc4ca50675ea8c1c2..6138c821b0fb158eda53bb1747b21c481a5a09da 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it, mock } from 'node:test'
 
 import type { ChargingStationWithCertificateManager } from '../../../../src/charging-station/ocpp/2.0/OCPP20CertificateManager.js'
 
@@ -58,25 +58,31 @@ await describe('I04 - DeleteCertificate', async () => {
     mock.restoreAll()
   })
 
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  })
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let stationWithCertManager: ChargingStationWithCertificateManager
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
 
-  // Cast to allow setting certificateManager property
-  const stationWithCertManager =
-    mockChargingStation as unknown as ChargingStationWithCertificateManager
-  stationWithCertManager.certificateManager = createMockCertificateManager()
+    // Cast to allow setting certificateManager property
+    stationWithCertManager = mockChargingStation as unknown as ChargingStationWithCertificateManager
+    stationWithCertManager.certificateManager = createMockCertificateManager()
 
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
+  })
 
   await describe('Valid Certificate Deletion', async () => {
     await it('should accept deletion of existing certificate', async () => {
index 6084cf25cda34d529d9149bc1a5587b6331fd9d2..222ed7aa0d59f60fb4ac65702411e7836b1cf1a4 100644 (file)
@@ -1,5 +1,5 @@
 import { expect } from '@std/expect'
-import { afterEach, describe, it } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
 
 import {
   addConfigurationKey,
@@ -39,25 +39,31 @@ import {
 } from '../../ChargingStationTestConstants.js'
 
 await describe('B07 - Get Base Report', async () => {
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      chargePointModel: TEST_CHARGE_POINT_MODEL,
-      chargePointSerialNumber: TEST_CHARGE_POINT_SERIAL_NUMBER,
-      chargePointVendor: TEST_CHARGE_POINT_VENDOR,
-      firmwareVersion: TEST_FIRMWARE_VERSION,
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  })
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        chargePointModel: TEST_CHARGE_POINT_MODEL,
+        chargePointSerialNumber: TEST_CHARGE_POINT_SERIAL_NUMBER,
+        chargePointVendor: TEST_CHARGE_POINT_VENDOR,
+        firmwareVersion: TEST_FIRMWARE_VERSION,
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
 
-  const incomingRequestService = new OCPP20IncomingRequestService()
+    incomingRequestService = new OCPP20IncomingRequestService()
 
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
+    testableService = createTestableIncomingRequestService(incomingRequestService)
+  })
 
   // Reset singleton state after each test to ensure test isolation
   afterEach(() => {
index 8eb242917927836c599c9010a80d2d3c0eb41d41..1eb1696efeed3e9e5f79b9132fee5f7a2a38c170 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it, mock } from 'node:test'
 
 import type { ChargingStationWithCertificateManager } from '../../../../src/charging-station/ocpp/2.0/OCPP20CertificateManager.js'
 
@@ -59,29 +59,36 @@ const createMockCertificateManager = (
 })
 
 await describe('I04 - GetInstalledCertificateIds', async () => {
-  afterEach(() => {
-    mock.restoreAll()
-  })
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let stationWithCertManager: ChargingStationWithCertificateManager
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
 
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  })
+    // Cast to allow setting certificateManager property
+    stationWithCertManager =
+      mockChargingStation as unknown as ChargingStationWithCertificateManager
+    stationWithCertManager.certificateManager = createMockCertificateManager()
 
-  // Cast to allow setting certificateManager property
-  const stationWithCertManager =
-    mockChargingStation as unknown as ChargingStationWithCertificateManager
-  stationWithCertManager.certificateManager = createMockCertificateManager()
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
+  })
 
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
+  afterEach(() => {
+    mock.restoreAll()
+  })
 
   await describe('Request All Certificate Types', async () => {
     await it('should return all certificates when no filter is provided', async () => {
index 65f363bbce70d52397b2ddbe7c5687a8abf3f90a..196006f879093246e26b7938e6d95e34dddb07d9 100644 (file)
@@ -4,7 +4,7 @@
  */
 import { expect } from '@std/expect'
 import { millisecondsToSeconds } from 'date-fns'
-import { afterEach, describe, it } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
 
 import { OCPP20IncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.js'
 import { OCPP20VariableManager } from '../../../../src/charging-station/ocpp/2.0/OCPP20VariableManager.js'
@@ -35,20 +35,24 @@ import {
 } from './OCPP20TestUtils.js'
 
 await describe('B06 - Get Variables', async () => {
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let incomingRequestService: OCPP20IncomingRequestService
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
+    incomingRequestService = new OCPP20IncomingRequestService()
   })
 
-  const incomingRequestService = new OCPP20IncomingRequestService()
-
   // Reset singleton state after each test to ensure test isolation
   afterEach(() => {
     OCPP20VariableManager.getInstance().resetRuntimeOverrides()
index 6d47f906243f348571145ea9f49d529a18c039e7..eb0e47d2495740d75e194f651c0a064f7a40cbc4 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it, mock } from 'node:test'
 
 import type { ChargingStationWithCertificateManager } from '../../../../src/charging-station/ocpp/2.0/OCPP20CertificateManager.js'
 
@@ -72,25 +72,32 @@ await describe('I03 - InstallCertificate', async () => {
     mock.restoreAll()
   })
 
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  })
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let stationWithCertManager: ChargingStationWithCertificateManager
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
 
-  // Cast to allow setting certificateManager property
-  const stationWithCertManager =
-    mockChargingStation as unknown as ChargingStationWithCertificateManager
-  stationWithCertManager.certificateManager = createMockCertificateManager()
+    // Cast to allow setting certificateManager property
+    stationWithCertManager =
+      mockChargingStation as unknown as ChargingStationWithCertificateManager
+    stationWithCertManager.certificateManager = createMockCertificateManager()
 
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
+  })
 
   await describe('Valid Certificate Installation', async () => {
     await it('should accept valid V2GRootCertificate', async () => {
index 245616eb5064205c6f216162f3a6e3a2f507c4aa..0998a1c9b5b2ab97f61d8058138b3dc42394434b 100644 (file)
@@ -31,25 +31,26 @@ import {
 } from './OCPP20TestUtils.js'
 
 await describe('F01 & F02 - Remote Start Transaction', async () => {
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    ocppRequestService: {
-      requestHandler: async () => Promise.resolve({}),
-    },
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  })
-
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
-
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
   beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      ocppRequestService: {
+        requestHandler: async () => Promise.resolve({}),
+      },
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
     const stationId = mockChargingStation.stationInfo?.chargingStationId ?? 'unknown'
     OCPPAuthServiceFactory.setInstanceForTesting(stationId, createMockAuthService())
     resetConnectorTransactionState(mockChargingStation)
index 2418c35b58a4bbc1b4dc7f778215a4edf81e5a94..c0f1a3556c25b1e70fd0a129e3810c6a731c7318 100644 (file)
@@ -35,47 +35,48 @@ import { resetLimits, resetReportingValueSize } from './OCPP20TestUtils.js'
 
 await describe('F03 - Remote Stop Transaction', async () => {
   let sentTransactionEvents: OCPP20TransactionEventRequest[] = []
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
 
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    ocppRequestService: {
-      requestHandler: async (
-        _chargingStation: unknown,
-        commandName: unknown,
-        commandPayload: unknown
-      ) => {
-        if (commandName === OCPP20RequestCommand.TRANSACTION_EVENT) {
-          sentTransactionEvents.push(commandPayload as OCPP20TransactionEventRequest)
+  beforeEach(() => {
+    sentTransactionEvents = []
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      ocppRequestService: {
+        requestHandler: async (
+          _chargingStation: unknown,
+          commandName: unknown,
+          commandPayload: unknown
+        ) => {
+          if (commandName === OCPP20RequestCommand.TRANSACTION_EVENT) {
+            sentTransactionEvents.push(commandPayload as OCPP20TransactionEventRequest)
+            return Promise.resolve({})
+          }
           return Promise.resolve({})
-        }
-        return Promise.resolve({})
+        },
       },
-    },
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  })
-
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
-
-  beforeEach(() => {
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
     const stationId = mockChargingStation.stationInfo?.chargingStationId ?? 'unknown'
     OCPPAuthServiceFactory.setInstanceForTesting(stationId, createMockAuthService())
+    resetLimits(mockChargingStation)
+    resetReportingValueSize(mockChargingStation)
   })
 
   afterEach(() => {
     OCPPAuthServiceFactory.clearAllInstances()
   })
 
-  resetLimits(mockChargingStation)
-  resetReportingValueSize(mockChargingStation)
-
   /**
    * Helper function to reset all connector transaction states
    */
index 56e4e0539863fe06a96ccfa7ae9bf37474ed8ab5..edda58685c75b39650b630aa9c7861e0637da93a 100644 (file)
@@ -28,39 +28,47 @@ import { createChargingStation } from '../../../ChargingStationFactory.js'
 import { TEST_CHARGING_STATION_BASE_NAME } from '../../ChargingStationTestConstants.js'
 
 await describe('B11 & B12 - Reset', async () => {
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let mockStation: ReturnType<typeof createChargingStation> & {
+    getNumberOfRunningTransactions: () => number
+    reset: () => Promise<void>
+  }
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
   beforeEach(() => {
     mock.timers.enable({ apis: ['setInterval', 'setTimeout', 'setImmediate'] })
+
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+        resetTime: 5000,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
+
+    // Add missing method to mock using interface extension pattern
+    interface MockChargingStation extends ChargingStation {
+      getNumberOfRunningTransactions: () => number
+      reset: () => Promise<void>
+    }
+    mockStation = mockChargingStation as MockChargingStation
+    mockStation.getNumberOfRunningTransactions = () => 0
+    mockStation.reset = () => Promise.resolve()
+
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
   })
 
   afterEach(() => {
     mock.timers.reset()
   })
 
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-      resetTime: 5000,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
-  })
-
-  // Add missing method to mock using interface extension pattern
-  interface MockChargingStation extends ChargingStation {
-    getNumberOfRunningTransactions: () => number
-    reset: () => Promise<void>
-  }
-  const mockStation = mockChargingStation as MockChargingStation
-  mockStation.getNumberOfRunningTransactions = () => 0
-  mockStation.reset = () => Promise.resolve()
-
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
-
   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 () => {
index 97e025c8e37b6f1470f29dbb2be1ed91469fb13e..9444c174ef599623e7c280b607c7bcd10f703fd5 100644 (file)
@@ -5,7 +5,7 @@
 
 import { expect } from '@std/expect'
 import { millisecondsToSeconds } from 'date-fns'
-import { afterEach, describe, it } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
 
 import { createTestableIncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/__testable__/index.js'
 import { OCPP20IncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.js'
@@ -40,21 +40,26 @@ import {
 } from './OCPP20TestUtils.js'
 
 await describe('B05 - Set Variables', async () => {
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppStrictCompliance: false,
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+  let incomingRequestService: OCPP20IncomingRequestService
+  let testableService: ReturnType<typeof createTestableIncomingRequestService>
+
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppStrictCompliance: false,
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
+    incomingRequestService = new OCPP20IncomingRequestService()
+    testableService = createTestableIncomingRequestService(incomingRequestService)
   })
 
-  const incomingRequestService = new OCPP20IncomingRequestService()
-  const testableService = createTestableIncomingRequestService(incomingRequestService)
-
   // Reset singleton state after each test to ensure test isolation
   afterEach(() => {
     OCPP20VariableManager.getInstance().resetRuntimeOverrides()
index 9830cc02892124269e0b295f5538f3201b94ef82..ef87b37ad31d1f7fdb12d4d4b274b77773d73f57 100644 (file)
@@ -3,7 +3,7 @@
  * @description Unit tests for OCPP 2.0 IdToken-first pre-authorization flow (E03)
  */
 import { expect } from '@std/expect'
-import { afterEach, describe, it } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
 
 import { OCPP20ServiceUtils } from '../../../../src/charging-station/ocpp/2.0/OCPP20ServiceUtils.js'
 import {
@@ -42,10 +42,12 @@ import {
  * - E02: Cable connection -> EV detection -> Authorization -> Charging
  */
 await describe('E03 - IdToken-First Pre-Authorization Flow', async () => {
-  const mockChargingStation = createMockOCPP20TransactionTestStation()
+  let mockChargingStation: ReturnType<typeof createMockOCPP20TransactionTestStation>
 
-  // Reset limits and state before tests
-  resetLimits(mockChargingStation)
+  beforeEach(() => {
+    mockChargingStation = createMockOCPP20TransactionTestStation()
+    resetLimits(mockChargingStation)
+  })
 
   afterEach(() => {
     resetConnectorTransactionState(mockChargingStation)
index 0451ebf4c32b56f803fc90b464322793f31955c3..d41584ba53379e0549b93adea1045b453ba4e188 100644 (file)
@@ -348,8 +348,9 @@ function ensureConfig (chargingStation: ChargingStation): ConfigurationKey[] {
  */
 export const IdTokenFixtures = {
   /**
-   * Central (server-side) token
-   * @param idToken
+   * Central (server-side) token.
+   * @param idToken - The ID token string.
+   * @returns An OCPP20IdTokenType with Central type.
    */
   central: (idToken = 'CENTRAL_TOKEN_001'): OCPP20IdTokenType => ({
     idToken,
@@ -357,8 +358,9 @@ export const IdTokenFixtures = {
   }),
 
   /**
-   * eMAID contract identifier token
-   * @param idToken
+   * eMAID contract identifier token.
+   * @param idToken - The eMAID token string.
+   * @returns An OCPP20IdTokenType with eMAID type.
    */
   emaid: (idToken = 'DE*ABC*E123456*1'): OCPP20IdTokenType => ({
     idToken,
@@ -366,8 +368,9 @@ export const IdTokenFixtures = {
   }),
 
   /**
-   * ISO14443 RFID token (most common type)
-   * @param idToken
+   * ISO14443 RFID token (most common type).
+   * @param idToken - The RFID token string.
+   * @returns An OCPP20IdTokenType with ISO14443 type.
    */
   iso14443: (idToken = 'TEST_RFID_TOKEN_001'): OCPP20IdTokenType => ({
     idToken,
@@ -375,15 +378,19 @@ export const IdTokenFixtures = {
   }),
 
   /**
-   * ISO15693 RFID token
-   * @param idToken
+   * ISO15693 RFID token.
+   * @param idToken - The ISO15693 token string.
+   * @returns An OCPP20IdTokenType with ISO15693 type.
    */
   iso15693: (idToken = 'TEST_ISO15693_001'): OCPP20IdTokenType => ({
     idToken,
     type: OCPP20IdTokenEnumType.ISO15693,
   }),
 
-  /** NoAuthorization token (free charging) */
+  /**
+   * NoAuthorization token (free charging).
+   * @returns An OCPP20IdTokenType with NoAuthorization type.
+   */
   noAuth: (): OCPP20IdTokenType => ({
     idToken: '',
     type: OCPP20IdTokenEnumType.NoAuthorization,
@@ -398,21 +405,28 @@ export const TransactionContextFixtures = {
   // ===== Local Authorization Contexts =====
 
   /**
-   * Abnormal condition (with optional condition type)
-   * @param condition
+   * Abnormal condition (with optional condition type).
+   * @param condition - The abnormal condition type.
+   * @returns An OCPP20TransactionContext for abnormal conditions.
    */
   abnormalCondition: (condition = 'OverCurrent'): OCPP20TransactionContext => ({
     abnormalCondition: condition,
     source: 'abnormal_condition',
   }),
 
-  /** Cable plugged in (E02 cable-first start) */
+  /**
+   * Cable plugged in (E02 cable-first start).
+   * @returns An OCPP20TransactionContext for cable plugged in.
+   */
   cablePluggedIn: (): OCPP20TransactionContext => ({
     cableState: 'plugged_in',
     source: 'cable_action',
   }),
 
-  /** Deauthorization (token revoked or invalid) */
+  /**
+   * Deauthorization (token revoked or invalid).
+   * @returns An OCPP20TransactionContext for deauthorization.
+   */
   deauthorized: (): OCPP20TransactionContext => ({
     authorizationMethod: 'idToken',
     isDeauthorized: true,
@@ -421,18 +435,27 @@ export const TransactionContextFixtures = {
 
   // ===== Cable Action Contexts (E02 flow) =====
 
-  /** Energy limit reached */
+  /**
+   * Energy limit reached.
+   * @returns An OCPP20TransactionContext for energy limit reached.
+   */
   energyLimitReached: (): OCPP20TransactionContext => ({
     source: 'energy_limit',
   }),
 
-  /** EV communication lost */
+  /**
+   * EV communication lost.
+   * @returns An OCPP20TransactionContext for EV communication lost.
+   */
   evCommunicationLost: (): OCPP20TransactionContext => ({
     source: 'system_event',
     systemEvent: 'ev_communication_lost',
   }),
 
-  /** EV connect timeout */
+  /**
+   * EV connect timeout.
+   * @returns An OCPP20TransactionContext for EV connect timeout.
+   */
   evConnectTimeout: (): OCPP20TransactionContext => ({
     source: 'system_event',
     systemEvent: 'ev_connect_timeout',
@@ -440,21 +463,28 @@ export const TransactionContextFixtures = {
 
   // ===== Remote Command Contexts =====
 
-  /** Cable unplugged / EV departed */
+  /**
+   * Cable unplugged / EV departed.
+   * @returns An OCPP20TransactionContext for EV departure.
+   */
   evDeparted: (): OCPP20TransactionContext => ({
     cableState: 'unplugged',
     source: 'cable_action',
   }),
 
-  /** EV detected after cable connection */
+  /**
+   * EV detected after cable connection.
+   * @returns An OCPP20TransactionContext for EV detection.
+   */
   evDetected: (): OCPP20TransactionContext => ({
     cableState: 'detected',
     source: 'cable_action',
   }),
 
   /**
-   * IdToken-first authorization (E03 flow start)
-   * @param authorizationMethod
+   * IdToken-first authorization (E03 flow start).
+   * @param authorizationMethod - The authorization method used.
+   * @returns An OCPP20TransactionContext for IdToken authorization.
    */
   idTokenAuthorized: (
     authorizationMethod: 'groupIdToken' | 'idToken' = 'idToken'
@@ -463,13 +493,19 @@ export const TransactionContextFixtures = {
     source: 'local_authorization',
   }),
 
-  /** Clock-aligned meter value */
+  /**
+   * Clock-aligned meter value.
+   * @returns An OCPP20TransactionContext for clock-aligned meter values.
+   */
   meterValueClock: (): OCPP20TransactionContext => ({
     isPeriodicMeterValue: false,
     source: 'meter_value',
   }),
 
-  /** Periodic meter value (sampled interval) */
+  /**
+   * Periodic meter value (sampled interval).
+   * @returns An OCPP20TransactionContext for periodic meter values.
+   */
   meterValuePeriodic: (): OCPP20TransactionContext => ({
     isPeriodicMeterValue: true,
     source: 'meter_value',
@@ -477,19 +513,28 @@ export const TransactionContextFixtures = {
 
   // ===== Meter Value Contexts =====
 
-  /** Remote start transaction request */
+  /**
+   * Remote start transaction request.
+   * @returns An OCPP20TransactionContext for remote start.
+   */
   remoteStart: (): OCPP20TransactionContext => ({
     command: 'RequestStartTransaction',
     source: 'remote_command',
   }),
 
-  /** Remote stop transaction request */
+  /**
+   * Remote stop transaction request.
+   * @returns An OCPP20TransactionContext for remote stop.
+   */
   remoteStop: (): OCPP20TransactionContext => ({
     command: 'RequestStopTransaction',
     source: 'remote_command',
   }),
 
-  /** Reset command */
+  /**
+   * Reset command.
+   * @returns An OCPP20TransactionContext for reset.
+   */
   reset: (): OCPP20TransactionContext => ({
     command: 'Reset',
     source: 'remote_command',
@@ -497,13 +542,19 @@ export const TransactionContextFixtures = {
 
   // ===== System Event Contexts =====
 
-  /** Signed data received */
+  /**
+   * Signed data received.
+   * @returns An OCPP20TransactionContext for signed data.
+   */
   signedData: (): OCPP20TransactionContext => ({
     isSignedDataReceived: true,
     source: 'meter_value',
   }),
 
-  /** Stop authorized by local token presentation */
+  /**
+   * Stop authorized by local token presentation.
+   * @returns An OCPP20TransactionContext for stop authorization.
+   */
   stopAuthorized: (): OCPP20TransactionContext => ({
     authorizationMethod: 'stopAuthorized',
     source: 'local_authorization',
@@ -511,12 +562,18 @@ export const TransactionContextFixtures = {
 
   // ===== Limit Contexts =====
 
-  /** Time limit reached */
+  /**
+   * Time limit reached.
+   * @returns An OCPP20TransactionContext for time limit.
+   */
   timeLimitReached: (): OCPP20TransactionContext => ({
     source: 'time_limit',
   }),
 
-  /** Trigger message command */
+  /**
+   * Trigger message command.
+   * @returns An OCPP20TransactionContext for trigger message.
+   */
   triggerMessage: (): OCPP20TransactionContext => ({
     command: 'TriggerMessage',
     source: 'remote_command',
@@ -524,7 +581,10 @@ export const TransactionContextFixtures = {
 
   // ===== Abnormal Condition Contexts =====
 
-  /** Unlock connector command */
+  /**
+   * Unlock connector command.
+   * @returns An OCPP20TransactionContext for unlock connector.
+   */
   unlockConnector: (): OCPP20TransactionContext => ({
     command: 'UnlockConnector',
     source: 'remote_command',
index ade54289fe4bce7b19f7fd8cf969ce10af0e05c0..95648da0c2aed14e3338022dcac250deddd4805e 100644 (file)
@@ -5,7 +5,7 @@
 
 import { expect } from '@std/expect'
 import { millisecondsToSeconds } from 'date-fns'
-import { afterEach, describe, it } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
 
 import {
   deleteConfigurationKey,
@@ -63,16 +63,21 @@ function buildWsExampleUrl (targetLength: number, fillerChar = 'a'): string {
 }
 
 await describe('B05/B06 - OCPP20VariableManager test suite', async () => {
-  // Create mock ChargingStation with EVSEs for OCPP 2.0 testing
-  const mockChargingStation = createChargingStation({
-    baseName: TEST_CHARGING_STATION_BASE_NAME,
-    connectorsCount: 3,
-    evseConfiguration: { evsesCount: 3 },
-    heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
-    stationInfo: {
-      ocppVersion: OCPPVersion.VERSION_201,
-    },
-    websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+  // Type declaration for mock ChargingStation
+  let mockChargingStation: ReturnType<typeof createChargingStation>
+
+  // Initialize mock ChargingStation before each test
+  beforeEach(() => {
+    mockChargingStation = createChargingStation({
+      baseName: TEST_CHARGING_STATION_BASE_NAME,
+      connectorsCount: 3,
+      evseConfiguration: { evsesCount: 3 },
+      heartbeatInterval: Constants.DEFAULT_HEARTBEAT_INTERVAL,
+      stationInfo: {
+        ocppVersion: OCPPVersion.VERSION_201,
+      },
+      websocketPingInterval: Constants.DEFAULT_WEBSOCKET_PING_INTERVAL,
+    })
   })
 
   // Reset singleton state after each test to ensure test isolation