### Lifecycle Helpers (`helpers/TestLifecycleHelpers.ts`)
-| Utility | Purpose |
-| --------------------------------- | ------------------------------------ |
-| `standardCleanup()` | **MANDATORY** afterEach cleanup |
-| `withMockTimers()` | Execute test with timer mocking |
-| `createTimerScope()` | Manual timer control |
-| `setupConnectorWithTransaction()` | Setup connector in transaction state |
-| `clearConnectorTransaction()` | Clear connector transaction state |
+| Utility | Purpose |
+| --------------------------------- | ---------------------------------------- |
+| `standardCleanup()` | **MANDATORY** afterEach cleanup |
+| `withMockTimers()` | Execute test with timer mocking |
+| `createTimerScope()` | Manual timer control |
+| `createLoggerMocks()` | Create logger spies (error, warn) |
+| `createConsoleMocks()` | Create console spies (error, warn, info) |
+| `setupConnectorWithTransaction()` | Setup connector in transaction state |
+| `clearConnectorTransaction()` | Clear connector transaction state |
### Mock Classes (`mocks/`)
* @description Unit tests for OCPP configuration key management utilities
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import type { ChargingStationOcppConfiguration } from '../../src/types/index.js'
await describe('ConfigurationKeyUtils', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('GetConfigurationKey', async () => {
await it('should return undefined when configurationKey array is missing', () => {
}) as Reservation
await it('should return formatted charging station ID with index', () => {
- // Arrange & Act & Assert
expect(getChargingStationId(1, chargingStationTemplate)).toBe(
`${TEST_CHARGING_STATION_BASE_NAME}-00001`
)
})
await it('should return consistent hash ID for same template and index', () => {
- // Arrange & Act & Assert
expect(getHashId(1, chargingStationTemplate)).toBe(
'b4b1e8ec4fca79091d99ea9a7ea5901548010e6c0e98be9296f604b9d68734444dfdae73d7d406b6124b42815214d088'
)
})
await it('should return correct phase rotation value for connector and phase count', () => {
- // Arrange & Act & Assert
expect(getPhaseRotationValue(0, 0)).toBe('0.RST')
expect(getPhaseRotationValue(1, 0)).toBe('1.NotApplicable')
expect(getPhaseRotationValue(2, 0)).toBe('2.NotApplicable')
})
await it('should return -1 for undefined EVSEs and 0 for empty object', () => {
- // Arrange & Act & Assert
expect(getMaxNumberOfEvses(undefined)).toBe(-1)
expect(getMaxNumberOfEvses({})).toBe(0)
})
// Tests for reservation helper functions
await it('should return true when reservation has expired', () => {
- // Arrange & Act & Assert
expect(hasReservationExpired(createTestReservation(true))).toBe(true)
})
await it('should return false when reservation is still valid', () => {
- // Arrange & Act & Assert
expect(hasReservationExpired(createTestReservation(false))).toBe(false)
})
await it('should return false when connector has no reservation', () => {
- // Arrange & Act & Assert
const connectorStatus = {} as ConnectorStatus
expect(hasPendingReservation(connectorStatus)).toBe(false)
})
await it('should return true when connector has valid pending reservation', () => {
- // Arrange & Act & Assert
const connectorStatus = { reservation: createTestReservation(false) } as ConnectorStatus
expect(hasPendingReservation(connectorStatus)).toBe(true)
})
await it('should return false when connector reservation has expired', () => {
- // Arrange & Act & Assert
const connectorStatus = { reservation: createTestReservation(true) } as ConnectorStatus
expect(hasPendingReservation(connectorStatus)).toBe(false)
})
await it('should return false when no reservations exist (connector mode)', () => {
- // Arrange & Act & Assert
const { station: chargingStation } = createMockChargingStation({
connectorsCount: 2,
TEST_CHARGING_STATION_BASE_NAME,
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('Valid Certificate Chain Installation', async () => {
await it('should accept valid certificate chain', async () => {
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
await describe('C11 - Clear Authorization Data in Authorization Cache', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
let station: ChargingStation
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
import type { ChargingStationWithCertificateManager } from '../../../../src/charging-station/ocpp/2.0/OCPP20CertificateManager.js'
await describe('I04 - DeleteCertificate', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
let station: ChargingStation
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
import type { ChargingStationWithCertificateManager } from '../../../../src/charging-station/ocpp/2.0/OCPP20CertificateManager.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('Request All Certificate Types', async () => {
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
import type { ChargingStationWithCertificateManager } from '../../../../src/charging-station/ocpp/2.0/OCPP20CertificateManager.js'
await describe('I03 - InstallCertificate', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
let mockChargingStation: ChargingStation
* @description Unit tests for OCPP 2.0 BootNotification request building (B01)
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
// FR: B01.FR.01
* @description Unit tests for OCPP 2.0 Heartbeat request building (G02)
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
// FR: G02.FR.01
/* cspell:ignore Bvbn NQIF CBCYX */
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import { createTestableRequestService } from '../../../../src/charging-station/ocpp/2.0/__testable__/index.js'
import {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('EXI Install Action', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('OCSP Request Data', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await it('should send GET_15118_EV_CERTIFICATE command name', async () => {
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
// FR: B07.FR.03, B07.FR.04
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('CSR Generation', async () => {
* @description Unit tests for OCPP 2.0 StatusNotification request building (G01)
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/index.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
// FR: G01.FR.01
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../src/charging-station/ChargingStation.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('OCPP 1.6 Authentication', async () => {
* @description Unit tests for OCPP 1.6 authentication adapter
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../../src/charging-station/ChargingStation.js'
import type { OCPP16AuthorizeResponse } from '../../../../../src/types/ocpp/1.6/Responses.js'
})
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
})
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
* @description Unit tests for in-memory authorization cache conformance (G03.FR.01)
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { AuthorizationResult } from '../../../../../src/charging-station/ocpp/auth/types/AuthTypes.js'
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('G03.FR.01.001 - Cache Hit Behavior', async () => {
* @description Unit tests for certificate-based authentication strategy
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type { ChargingStation } from '../../../../../src/charging-station/ChargingStation.js'
import type { OCPPAuthAdapter } from '../../../../../src/charging-station/ocpp/auth/interfaces/OCPPAuthService.js'
})
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
* @description Unit tests for local authorization strategy (cache and local list)
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type {
AuthCache,
})
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
await strategy.initialize(config)
})
- afterEach(() => {
- // Reset mock properties to prevent state pollution between tests
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
- delete (mockLocalAuthListManager as any).getEntry
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
- delete (mockAuthCache as any).get
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
- delete (mockAuthCache as any).set
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
- delete (mockAuthCache as any).remove
- mock.restoreAll()
- })
-
await it('should authenticate using local auth list', async () => {
mockLocalAuthListManager.getEntry = async () =>
await Promise.resolve({
* @description Unit tests for remote (CSMS) authorization strategy
*/
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import type {
AuthCache,
})
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
* @description Unit tests for authentication type definitions and mappings
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import {
AuthContext,
await describe('AuthTypes', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('IdentifierTypeGuards', async () => {
await it('should correctly identify OCPP 1.6 types', () => {
* @description Unit tests for authentication helper utilities
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import {
AuthContext,
await describe('AuthHelpers', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('calculateTTL', async () => {
await it('should return undefined for undefined expiry date', () => {
* @description Unit tests for authentication validation utilities
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import {
type AuthConfiguration,
await describe('AuthValidators', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('isValidCacheTTL', async () => {
await it('should return true for undefined TTL', () => {
// Copyright Jerome Benoit. 2021-2025. All Rights Reserved.
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import {
type AuthConfiguration,
await describe('AuthConfigValidator', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await describe('validate', async () => {
await it('should accept valid configuration', () => {
// Copyright Jerome Benoit. 2024-2025. All Rights Reserved.
import { expect } from '@std/expect'
-import { afterEach, beforeEach, describe, it, mock } from 'node:test'
+import { afterEach, beforeEach, describe, it } from 'node:test'
import { gunzipSync } from 'node:zlib'
import type { UUIDv4 } from '../../../src/types/index.js'
})
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
})
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
// Copyright Jerome Benoit. 2024-2025. All Rights Reserved.
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import {
createBodySizeLimiter,
await describe('UIServerSecurity', async () => {
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
await describe('IsValidCredential', async () => {
// Copyright Jerome Benoit. 2024-2025. All Rights Reserved.
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import type { UUIDv4 } from '../../../src/types/index.js'
await describe('UIWebSocketServer', async () => {
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
await it('should delete response handler after successful send', () => {
// Copyright Jerome Benoit. 2024-2025. All Rights Reserved.
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import { ProcedureName, ProtocolVersion, ResponseStatus } from '../../../../src/types/index.js'
import { standardCleanup } from '../../../helpers/TestLifecycleHelpers.js'
await describe('AbstractUIService', async () => {
afterEach(() => {
- mock.restoreAll()
standardCleanup()
})
await it('should check response handler existence before sending', () => {
* @description Unit tests for base error class functionality
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import { BaseError } from '../../src/exception/BaseError.js'
import { standardCleanup } from '../helpers/TestLifecycleHelpers.js'
await describe('BaseError', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await it('should create instance with default values', () => {
const baseError = new BaseError()
* @description Unit tests for OCPP-specific error class
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import { OCPPError } from '../../src/exception/OCPPError.js'
import { ErrorType } from '../../src/types/index.js'
await describe('OCPPError', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await it('should create instance with error code and default values', () => {
* @description Unit tests for configuration data types and enumerations
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import {
ApplicationProtocolVersion,
await describe('ConfigurationData', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await it('should define ConfigurationSection enumeration values', () => {
*/
import { expect } from '@std/expect'
import { randomInt } from 'node:crypto'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import { AsyncLock, AsyncLockType } from '../../src/utils/AsyncLock.js'
import { standardCleanup } from '../helpers/TestLifecycleHelpers.js'
await describe('AsyncLock', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await it('should run synchronous functions exclusively in sequence', () => {
const runs = 10
* @description Unit tests for electrical calculations (AC/DC power, amperage)
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import { ACElectricUtils, DCElectricUtils } from '../../src/utils/ElectricUtils.js'
import { standardCleanup } from '../helpers/TestLifecycleHelpers.js'
await describe('ElectricUtils', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await it('should calculate DC power from voltage and current', () => {
expect(DCElectricUtils.power(230, 1)).toBe(230)
* @description Unit tests for statistical calculation utilities
*/
import { expect } from '@std/expect'
-import { afterEach, describe, it, mock } from 'node:test'
+import { afterEach, describe, it } from 'node:test'
import { average, max, median, min, percentile, std } from '../../src/utils/StatisticUtils.js'
import { standardCleanup } from '../helpers/TestLifecycleHelpers.js'
await describe('StatisticUtils', async () => {
afterEach(() => {
standardCleanup()
- mock.restoreAll()
})
await it('should calculate arithmetic mean of array values', () => {
expect(average([])).toBe(0)