From bbe3e3b6581b1e44eadaec06230687233c37c5b2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 17 Sep 2026 21:09:14 +0200 Subject: [PATCH] refactor: adopt canonical helpers over reimplementations (#2120) --- .../meter-values/TransactionIntervalUtils.ts | 5 +++-- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 2 +- tests/charging-station/Bootstrap.test.ts | 3 +-- ...ngStation-AutoRegisterOcppProtocol.test.ts | 2 +- .../ChargingStation-NumberOfPhases.test.ts | 2 +- .../ChargingStation-ResetIdentity.test.ts | 2 +- .../ChargingStationTestConstants.ts | 4 +++- .../TemplateValidation.test.ts | 4 ++-- .../TransactionEventQueueUtils.test.ts | 4 ++-- .../TransactionIntervalUtils.test.ts | 2 +- ...rgingStationWorkerBroadcastChannel.test.ts | 19 ++++++++-------- .../meter-values/CoherentMeterValues.test.ts | 12 +++++----- .../meter-values/EvProfiles.test.ts | 2 +- ...comingRequestService-LocalAuthList.test.ts | 8 ++++--- ...omingRequestService-TriggerMessage.test.ts | 2 +- .../ocpp/1.6/OCPP16ServiceUtils.test.ts | 3 ++- .../ocpp/1.6/OCPP16TestUtils.ts | 2 +- ...comingRequestService-LocalAuthList.test.ts | 2 +- ...omingRequestService-TriggerMessage.test.ts | 2 +- .../OCPP20ResponseService-CacheUpdate.test.ts | 2 +- ...20ResponseService-TransactionEvent.test.ts | 4 ++-- ...P20ServiceUtils-AlignedMeterValues.test.ts | 12 +++++----- .../2.0/OCPP20ServiceUtils-AuthCache.test.ts | 2 +- ...CPP20ServiceUtils-TransactionEvent.test.ts | 22 ++++++++++--------- .../ocpp/auth/OCPPAuthIntegration.test.ts | 6 ++--- .../auth/adapters/OCPP16AuthAdapter.test.ts | 5 +++-- .../auth/adapters/OCPP20AuthAdapter.test.ts | 2 +- .../ocpp/auth/cache/InMemoryAuthCache.test.ts | 4 ++-- .../InMemoryLocalAuthListManager.test.ts | 8 ++++--- .../auth/strategies/LocalAuthStrategy.test.ts | 3 ++- .../ui-server/UIMCPServer-Integration.test.ts | 3 ++- tests/utils/ConfigurationValidation.test.ts | 4 ++-- ui/cli/tests/renderers.test.ts | 9 ++++++-- ui/common/src/utils/payloadBuilders.ts | 6 ++--- ui/common/tests/mocks.ts | 8 +++---- ui/web/src/shared/utils/stationStatus.ts | 20 ++++++++--------- ui/web/tests/unit/helpers.ts | 18 +++++++-------- 37 files changed, 116 insertions(+), 104 deletions(-) diff --git a/src/charging-station/meter-values/TransactionIntervalUtils.ts b/src/charging-station/meter-values/TransactionIntervalUtils.ts index efef3b33..1280b6fa 100644 --- a/src/charging-station/meter-values/TransactionIntervalUtils.ts +++ b/src/charging-station/meter-values/TransactionIntervalUtils.ts @@ -1,5 +1,5 @@ import { type ConnectorStatus, CurrentType, MeterValueMeasurand } from '../../types/index.js' -import { isEmpty } from '../../utils/index.js' +import { Constants, isEmpty } from '../../utils/index.js' export interface TransactionIntervalState { consumed: number @@ -112,7 +112,8 @@ export const getRepresentedTransactionIntervalEnergyWh = ( : Number.parseFloat(sampledValue.value) if (!Number.isFinite(value)) continue const unit = sampledValue.unitOfMeasure?.unit ?? sampledValue.unit - const unitMultiplier = unit === 'kWh' ? 1000 : unit === 'MWh' ? 1_000_000 : 1 + const unitMultiplier = + unit === 'kWh' ? Constants.UNIT_DIVIDER_KILO : unit === 'MWh' ? 1_000_000 : 1 const decimalMultiplier = 10 ** (sampledValue.unitOfMeasure?.multiplier ?? 0) const phaseMultiplier = /^L[123](?:-N)?$/.test(sampledValue.phase ?? '') ? numberOfPhases : 1 const locationMultiplier = diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index d0b61685..99111484 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -2346,7 +2346,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { Connectors: { 0: {}, 1: {} }, supervisionUrl: TEST_SUPERVISION_URL, }) - const before = structuredClone(parsed) + const before = clone(parsed) validateTemplate(parsed, 'immutable.json') diff --git a/tests/charging-station/TransactionEventQueueUtils.test.ts b/tests/charging-station/TransactionEventQueueUtils.test.ts index b8009caf..9b027e16 100644 --- a/tests/charging-station/TransactionEventQueueUtils.test.ts +++ b/tests/charging-station/TransactionEventQueueUtils.test.ts @@ -41,7 +41,7 @@ import { OCPP20TriggerReasonEnumType, OCPP20UnitEnumType, } from '../../src/types/index.js' -import { Constants } from '../../src/utils/index.js' +import { clone, Constants } from '../../src/utils/index.js' import { standardCleanup } from '../helpers/TestLifecycleHelpers.js' const validateTransactionEvent = createAjv().compile(transactionEventRequestSchema) @@ -1219,7 +1219,7 @@ await describe('TransactionEventQueueUtils', async () => { transactionEventQueue: existingEvents, transactionId, } as unknown as ConnectorStatus - const queueSnapshot = structuredClone(existingEvents) + const queueSnapshot = clone(existingEvents) const candidate = toQueuedEvent({ customData: { payload: 'x'.repeat(400_000), vendorId: 'test' }, eventType: OCPP20TransactionEventEnumType.Updated, diff --git a/tests/charging-station/TransactionIntervalUtils.test.ts b/tests/charging-station/TransactionIntervalUtils.test.ts index 32c3acfe..b4aa964b 100644 --- a/tests/charging-station/TransactionIntervalUtils.test.ts +++ b/tests/charging-station/TransactionIntervalUtils.test.ts @@ -14,7 +14,7 @@ import { recordTransactionIntervalConsumption, restoreTransactionIntervalState, truncateTransactionIntervalValue, -} from '../../src/charging-station/meter-values/TransactionIntervalUtils.js' +} from '../../src/charging-station/meter-values/index.js' import { standardCleanup } from '../helpers/TestLifecycleHelpers.js' await describe('TransactionIntervalUtils', async () => { diff --git a/tests/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.test.ts b/tests/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.test.ts index d5a3678a..2fcb4b78 100644 --- a/tests/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.test.ts +++ b/tests/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.test.ts @@ -6,7 +6,6 @@ */ import assert from 'node:assert/strict' -import { randomUUID } from 'node:crypto' import { afterEach, describe, it, mock } from 'node:test' import { ChargingStationWorkerBroadcastChannel } from '../../../src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.js' @@ -51,7 +50,7 @@ import { StandardParametersKey, VendorParametersKey, } from '../../../src/types/index.js' -import { Constants } from '../../../src/utils/index.js' +import { Constants, generateUUID } from '../../../src/utils/index.js' import { flushMicrotasks, setupConnectorWithTransaction, @@ -2005,7 +2004,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.GET_15118_EV_CERTIFICATE, { hashIds: [station.stationInfo?.hashId] }, ], @@ -2025,7 +2024,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.LOG_STATUS_NOTIFICATION, { hashIds: [station.stationInfo?.hashId] }, ], @@ -2045,7 +2044,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.NOTIFY_CUSTOMER_INFORMATION, { hashIds: [station.stationInfo?.hashId] }, ], @@ -2065,7 +2064,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.NOTIFY_REPORT, { hashIds: [station.stationInfo?.hashId] }, ], @@ -2085,7 +2084,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.SECURITY_EVENT_NOTIFICATION, { hashIds: [station.stationInfo?.hashId] }, ], @@ -2119,7 +2118,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.METER_VALUES, { connectorId: 1, hashIds: [station.stationInfo?.hashId] }, ], @@ -2243,7 +2242,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.METER_VALUES, { evseId: 1, hashIds: [station.stationInfo?.hashId] }, ], @@ -2285,7 +2284,7 @@ await describe('ChargingStationWorkerBroadcastChannel', async () => { testable.requestHandler({ data: [ - randomUUID(), + generateUUID(), BroadcastChannelProcedureName.METER_VALUES, { connectorId: 1, diff --git a/tests/charging-station/meter-values/CoherentMeterValues.test.ts b/tests/charging-station/meter-values/CoherentMeterValues.test.ts index 9dba091d..1887902f 100644 --- a/tests/charging-station/meter-values/CoherentMeterValues.test.ts +++ b/tests/charging-station/meter-values/CoherentMeterValues.test.ts @@ -11,12 +11,12 @@ import assert from 'node:assert/strict' import { afterEach, describe, it } from 'node:test' -import type { BuildVersionedSampledValue } from '../../../src/charging-station/meter-values/CoherentMeterValueBuilder.js' import type { + BuildVersionedSampledValue, CoherentSession, EvProfile, ICoherentContext, -} from '../../../src/charging-station/meter-values/types.js' +} from '../../../src/charging-station/meter-values/index.js' import type { ChargingStationInfo, ConnectorStatus, @@ -25,18 +25,16 @@ import type { SampledValueTemplate, } from '../../../src/types/index.js' -import { - buildCoherentMeterValue, - buildCoherentMeterValueSnapshot, -} from '../../../src/charging-station/meter-values/CoherentMeterValueBuilder.js' import { computeCoherentSample, disposeCoherentSessionRuntime, } from '../../../src/charging-station/meter-values/CoherentSampleComputer.js' import { + buildCoherentMeterValue, + buildCoherentMeterValueSnapshot, createCoherentSession, resolveRootSeed, -} from '../../../src/charging-station/meter-values/CoherentSession.js' +} from '../../../src/charging-station/meter-values/index.js' import { hashLabel } from '../../../src/charging-station/meter-values/PRNG.js' import { buildOCPP20SampledValue } from '../../../src/charging-station/ocpp/2.0/OCPP20RequestBuilders.js' import { diff --git a/tests/charging-station/meter-values/EvProfiles.test.ts b/tests/charging-station/meter-values/EvProfiles.test.ts index 2945517a..a2c74870 100644 --- a/tests/charging-station/meter-values/EvProfiles.test.ts +++ b/tests/charging-station/meter-values/EvProfiles.test.ts @@ -12,7 +12,7 @@ import assert from 'node:assert/strict' import { afterEach, describe, it } from 'node:test' -import type { EvProfile } from '../../../src/charging-station/meter-values/types.js' +import type { EvProfile } from '../../../src/charging-station/meter-values/index.js' import { interpolateChargingCurve, diff --git a/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-LocalAuthList.test.ts b/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-LocalAuthList.test.ts index 1f4aaf28..ca4a550b 100644 --- a/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-LocalAuthList.test.ts +++ b/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-LocalAuthList.test.ts @@ -11,11 +11,13 @@ import type { ChargingStation } from '../../../../src/charging-station/index.js' import type { LocalAuthListManager, OCPPAuthService, -} from '../../../../src/charging-station/ocpp/auth/interfaces/OCPPAuthService.js' +} from '../../../../src/charging-station/ocpp/auth/index.js' import type { OCPP16SendLocalListRequest } from '../../../../src/types/index.js' -import { InMemoryLocalAuthListManager } from '../../../../src/charging-station/ocpp/auth/cache/InMemoryLocalAuthListManager.js' -import { OCPPAuthServiceFactory } from '../../../../src/charging-station/ocpp/auth/services/OCPPAuthServiceFactory.js' +import { + InMemoryLocalAuthListManager, + OCPPAuthServiceFactory, +} from '../../../../src/charging-station/ocpp/auth/index.js' import { OCPP16AuthorizationStatus, OCPP16StandardParametersKey, diff --git a/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-TriggerMessage.test.ts b/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-TriggerMessage.test.ts index 0b767847..40813f0a 100644 --- a/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-TriggerMessage.test.ts +++ b/tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-TriggerMessage.test.ts @@ -20,7 +20,7 @@ import type { RequestParams, } from '../../../../src/types/index.js' -import { TransactionMeterValueDeliveryBarrier } from '../../../../src/charging-station/meter-values/TransactionMeterValueDeliveryBarrier.js' +import { TransactionMeterValueDeliveryBarrier } from '../../../../src/charging-station/meter-values/index.js' import { createTestableIncomingRequestService } from '../../../../src/charging-station/ocpp/1.6/__testable__/index.js' import { OCPP16IncomingRequestService } from '../../../../src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.js' import { OCPP16ServiceUtils } from '../../../../src/charging-station/ocpp/1.6/OCPP16ServiceUtils.js' diff --git a/tests/charging-station/ocpp/1.6/OCPP16ServiceUtils.test.ts b/tests/charging-station/ocpp/1.6/OCPP16ServiceUtils.test.ts index fc92df8b..c5bf529d 100644 --- a/tests/charging-station/ocpp/1.6/OCPP16ServiceUtils.test.ts +++ b/tests/charging-station/ocpp/1.6/OCPP16ServiceUtils.test.ts @@ -51,6 +51,7 @@ import { OCPPVersion, type RequestParams, } from '../../../../src/types/index.js' +import { clone } from '../../../../src/utils/index.js' import { flushMicrotasks, setupConnectorWithTransaction, @@ -1514,7 +1515,7 @@ await describe('OCPP16ServiceUtils — pure functions', async () => { timestamp: new Date('2026-09-08T12:34:56.000Z'), }, ] - const expectedTransactionData = structuredClone(transactionData) + const expectedTransactionData = clone(transactionData) const stop = OCPP16ServiceUtils.stopTransactionOnConnector(station, 1, undefined, { transactionData, diff --git a/tests/charging-station/ocpp/1.6/OCPP16TestUtils.ts b/tests/charging-station/ocpp/1.6/OCPP16TestUtils.ts index 65cd5874..aeae4cf6 100644 --- a/tests/charging-station/ocpp/1.6/OCPP16TestUtils.ts +++ b/tests/charging-station/ocpp/1.6/OCPP16TestUtils.ts @@ -459,7 +459,7 @@ export const ReservationFixtures = { connectorId = 1, reservationId = 1, idTag = TEST_ID_TAG, - expiryDate = new Date(Date.now() + 3600000) + expiryDate = new Date(Date.now() + Constants.MS_PER_HOUR) ) => ({ connectorId, expiryDate, diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-LocalAuthList.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-LocalAuthList.test.ts index bb95c584..eca41fa9 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-LocalAuthList.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-LocalAuthList.test.ts @@ -7,7 +7,7 @@ import assert from 'node:assert/strict' import { afterEach, beforeEach, describe, it } from 'node:test' import type { ChargingStation } from '../../../../src/charging-station/index.js' -import type { LocalAuthListManager } from '../../../../src/charging-station/ocpp/auth/interfaces/OCPPAuthService.js' +import type { LocalAuthListManager } from '../../../../src/charging-station/ocpp/auth/index.js' import { buildConfigKey } from '../../../../src/charging-station/index.js' import { createTestableIncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/__testable__/index.js' diff --git a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-TriggerMessage.test.ts b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-TriggerMessage.test.ts index dce77bbc..4db42dad 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-TriggerMessage.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20IncomingRequestService-TriggerMessage.test.ts @@ -21,7 +21,7 @@ import type { MockChargingStation } from '../../helpers/StationHelpers.js' import { ChargingStation } from '../../../../src/charging-station/ChargingStation.js' import { addConfigurationKey, buildConfigKey } from '../../../../src/charging-station/index.js' -import { TransactionMeterValueDeliveryBarrier } from '../../../../src/charging-station/meter-values/TransactionMeterValueDeliveryBarrier.js' +import { TransactionMeterValueDeliveryBarrier } from '../../../../src/charging-station/meter-values/index.js' import { createTestableIncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/__testable__/index.js' import { OCPP20IncomingRequestService } from '../../../../src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.js' import { OCPP20ServiceUtils } from '../../../../src/charging-station/ocpp/2.0/OCPP20ServiceUtils.js' diff --git a/tests/charging-station/ocpp/2.0/OCPP20ResponseService-CacheUpdate.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ResponseService-CacheUpdate.test.ts index bc454166..a2e5a283 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ResponseService-CacheUpdate.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ResponseService-CacheUpdate.test.ts @@ -8,7 +8,7 @@ import assert from 'node:assert/strict' import { afterEach, beforeEach, describe, it } from 'node:test' import type { ChargingStation } from '../../../../src/charging-station/index.js' -import type { AuthCache } from '../../../../src/charging-station/ocpp/auth/interfaces/OCPPAuthService.js' +import type { AuthCache } from '../../../../src/charging-station/ocpp/auth/index.js' import { AuthResultStatus, diff --git a/tests/charging-station/ocpp/2.0/OCPP20ResponseService-TransactionEvent.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ResponseService-TransactionEvent.test.ts index 53714424..a26042b8 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ResponseService-TransactionEvent.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ResponseService-TransactionEvent.test.ts @@ -36,7 +36,7 @@ import { OCPP20TransactionEventEnumType, OCPPVersion, } from '../../../../src/types/index.js' -import { Constants } from '../../../../src/utils/index.js' +import { clone, Constants } from '../../../../src/utils/index.js' import { flushMicrotasks, setupConnectorWithTransaction, @@ -381,7 +381,7 @@ await describe('D01 - TransactionEvent Response', async () => { OCPP20TransactionEventEnumType.Started ) staleRequest.seqNo = 0 - const replacementRequest = structuredClone(staleRequest) + const replacementRequest = clone(staleRequest) connectorStatus.transactionEventQueue = [ { request: replacementRequest, seqNo: 0, timestamp: replacementRequest.timestamp }, ] diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AlignedMeterValues.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AlignedMeterValues.test.ts index 94dc59ef..8c01efcc 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AlignedMeterValues.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AlignedMeterValues.test.ts @@ -10,7 +10,7 @@ import type { Mock } from 'node:test' import assert from 'node:assert/strict' import { afterEach, beforeEach, describe, it, mock } from 'node:test' -import type { CoherentSession } from '../../../../src/charging-station/meter-values/types.js' +import type { CoherentSession } from '../../../../src/charging-station/meter-values/index.js' import type { ChargingStationInfo, ConnectorStatus, @@ -36,8 +36,10 @@ import { getConfigurationKey, } from '../../../../src/charging-station/index.js' import { computeCoherentSample } from '../../../../src/charging-station/meter-values/CoherentSampleComputer.js' -import { recordTransactionIntervalConsumption } from '../../../../src/charging-station/meter-values/TransactionIntervalUtils.js' -import { TransactionMeterValueDeliveryBarrier } from '../../../../src/charging-station/meter-values/TransactionMeterValueDeliveryBarrier.js' +import { + recordTransactionIntervalConsumption, + TransactionMeterValueDeliveryBarrier, +} from '../../../../src/charging-station/meter-values/index.js' import { createTestableIncomingRequestService, type TestableOCPP20IncomingRequestService, @@ -83,7 +85,7 @@ import { SigningMethodEnumType, Voltage, } from '../../../../src/types/index.js' -import { Constants } from '../../../../src/utils/index.js' +import { clone, Constants } from '../../../../src/utils/index.js' import { setupConnectorWithTransaction, standardCleanup, @@ -7460,7 +7462,7 @@ await describe('J01 - Autonomous clock-aligned MeterValues (#2011 Category 2F)', unit: 'Wh', }, ] as unknown as EvseStatus['MeterValues'] - stationEvse.MeterValues = structuredClone(sharedMeterValues) + stationEvse.MeterValues = clone(sharedMeterValues) evseStatus.MeterValues = sharedMeterValues upsertConfigurationKey(mockStation, ALIGNED_DATA_INTERVAL_KEY, '60') upsertConfigurationKey(mockStation, ALIGNED_ENABLED_KEY, 'true') diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AuthCache.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AuthCache.test.ts index d8c0be5a..2edb3488 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AuthCache.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-AuthCache.test.ts @@ -8,7 +8,7 @@ import assert from 'node:assert/strict' import { afterEach, beforeEach, describe, it } from 'node:test' import type { ChargingStation } from '../../../../src/charging-station/index.js' -import type { AuthCache } from '../../../../src/charging-station/ocpp/auth/interfaces/OCPPAuthService.js' +import type { AuthCache } from '../../../../src/charging-station/ocpp/auth/index.js' import { OCPP20ServiceUtils } from '../../../../src/charging-station/ocpp/2.0/OCPP20ServiceUtils.js' import { 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 bab684d2..24acb93a 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts @@ -13,7 +13,7 @@ import assert from 'node:assert/strict' import { afterEach, beforeEach, describe, it, mock } from 'node:test' -import type { CoherentSession } from '../../../../src/charging-station/meter-values/types.js' +import type { CoherentSession } from '../../../../src/charging-station/meter-values/index.js' import type { ConnectorStatus, EmptyObject, EvseStatus } from '../../../../src/types/index.js' import { ChargingStation } from '../../../../src/charging-station/ChargingStation.js' @@ -22,8 +22,10 @@ import { preparePersistedTransactionEventQueue, } from '../../../../src/charging-station/HelpersConnectorStatus.js' import { addConfigurationKey, buildConfigKey } from '../../../../src/charging-station/index.js' -import { recordTransactionIntervalConsumption } from '../../../../src/charging-station/meter-values/TransactionIntervalUtils.js' -import { TransactionMeterValueDeliveryBarrier } from '../../../../src/charging-station/meter-values/TransactionMeterValueDeliveryBarrier.js' +import { + recordTransactionIntervalConsumption, + TransactionMeterValueDeliveryBarrier, +} from '../../../../src/charging-station/meter-values/index.js' import { createTestableResponseService } from '../../../../src/charging-station/ocpp/2.0/__testable__/index.js' import { buildOCPP20SampledValue } from '../../../../src/charging-station/ocpp/2.0/OCPP20RequestBuilders.js' import { OCPP20ResponseService } from '../../../../src/charging-station/ocpp/2.0/OCPP20ResponseService.js' @@ -72,7 +74,7 @@ import { SigningMethodEnumType, Voltage, } from '../../../../src/types/index.js' -import { Constants, generateUUID } from '../../../../src/utils/index.js' +import { clone, Constants, generateUUID } from '../../../../src/utils/index.js' import { flushMicrotasks, setupConnectorWithTransaction, @@ -4451,7 +4453,7 @@ await describe('OCPP20 TransactionEvent ServiceUtils', async () => { requestParams.onTransportError?.(replayFailure, false) throw replayFailure } - transportedRequests.push(structuredClone(request)) + transportedRequests.push(clone(request)) requestParams.onMessageSent?.() requestParams.onResponseReceived?.() return {} @@ -8698,7 +8700,7 @@ await describe('OCPP20 TransactionEvent ServiceUtils', async () => { connectorStatus.transactionStarting = true connectorStatus.transactionRestored = true const queuedEvent = connectorStatus.transactionEventQueue[0] - const originalPayload = structuredClone(queuedEvent.request) + const originalPayload = clone(queuedEvent.request) const saveQueueSpy = mock.method(station, 'saveTransactionEventQueues') online = true @@ -9491,7 +9493,7 @@ await describe('OCPP20 TransactionEvent ServiceUtils', async () => { 64 ) const originalQueue = [queuedUpdated] - const originalEvent = structuredClone(queuedUpdated) + const originalEvent = clone(queuedUpdated) connectorStatus.transactionEventQueue = originalQueue mock.method(mockTracking.station, 'persistTransactionEventQueues', () => { persistenceStarted.resolve(undefined) @@ -9499,7 +9501,7 @@ await describe('OCPP20 TransactionEvent ServiceUtils', async () => { }) const savedQueues: unknown[][] = [] mock.method(mockTracking.station, 'saveTransactionEventQueues', () => { - savedQueues.push(structuredClone(connectorStatus.transactionEventQueue ?? [])) + savedQueues.push(clone(connectorStatus.transactionEventQueue ?? [])) }) const stopped = OCPP20ServiceUtils.requestStopTransaction( @@ -10353,7 +10355,7 @@ await describe('OCPP20 TransactionEvent ServiceUtils', async () => { 64 ) const originalQueue = [queuedUpdated] - const originalEvent = structuredClone(queuedUpdated) + const originalEvent = clone(queuedUpdated) connectorStatus.transactionEventQueue = originalQueue let persistenceCalls = 0 mock.method(mockTracking.station, 'persistTransactionEventQueues', () => { @@ -10524,7 +10526,7 @@ await describe('OCPP20 TransactionEvent ServiceUtils', async () => { timestamp: new Date(10_000), }, ] - const originalEndedMeterValues = structuredClone(connectorStatus.transactionEndedMeterValues) + const originalEndedMeterValues = clone(connectorStatus.transactionEndedMeterValues) OCPP20ServiceUtils.startEndedMeterValues(mockTracking.station, connectorId, 60_000, 1) await assert.rejects( diff --git a/tests/charging-station/ocpp/auth/OCPPAuthIntegration.test.ts b/tests/charging-station/ocpp/auth/OCPPAuthIntegration.test.ts index 0bdbf594..c8138d55 100644 --- a/tests/charging-station/ocpp/auth/OCPPAuthIntegration.test.ts +++ b/tests/charging-station/ocpp/auth/OCPPAuthIntegration.test.ts @@ -9,14 +9,14 @@ import { afterEach, beforeEach, describe, it } from 'node:test' import type { ChargingStation } from '../../../../src/charging-station/index.js' import { InMemoryAuthCache } from '../../../../src/charging-station/ocpp/auth/cache/InMemoryAuthCache.js' -import { OCPPAuthServiceImpl } from '../../../../src/charging-station/ocpp/auth/services/OCPPAuthServiceImpl.js' -import { LocalAuthStrategy } from '../../../../src/charging-station/ocpp/auth/strategies/LocalAuthStrategy.js' import { AuthContext, AuthenticationMethod, AuthResultStatus, IdentifierType, -} from '../../../../src/charging-station/ocpp/auth/types/AuthTypes.js' +} from '../../../../src/charging-station/ocpp/auth/index.js' +import { OCPPAuthServiceImpl } from '../../../../src/charging-station/ocpp/auth/services/OCPPAuthServiceImpl.js' +import { LocalAuthStrategy } from '../../../../src/charging-station/ocpp/auth/strategies/LocalAuthStrategy.js' import { OCPPVersion } from '../../../../src/types/index.js' import { standardCleanup } from '../../../helpers/TestLifecycleHelpers.js' import { createMockChargingStation } from '../../helpers/StationHelpers.js' diff --git a/tests/charging-station/ocpp/auth/adapters/OCPP16AuthAdapter.test.ts b/tests/charging-station/ocpp/auth/adapters/OCPP16AuthAdapter.test.ts index 4f2dda24..049e2734 100644 --- a/tests/charging-station/ocpp/auth/adapters/OCPP16AuthAdapter.test.ts +++ b/tests/charging-station/ocpp/auth/adapters/OCPP16AuthAdapter.test.ts @@ -15,8 +15,9 @@ import { AuthenticationMethod, AuthResultStatus, IdentifierType, -} from '../../../../../src/charging-station/ocpp/auth/types/AuthTypes.js' +} from '../../../../../src/charging-station/ocpp/auth/index.js' import { OCPP16AuthorizationStatus, OCPPVersion } from '../../../../../src/types/index.js' +import { Constants } from '../../../../../src/utils/index.js' import { standardCleanup } from '../../../../helpers/TestLifecycleHelpers.js' import { TEST_ID_TAG_VALID } from '../../../ChargingStationTestConstants.js' import { createMockAuthorizationResult, createMockIdentifier } from '../helpers/MockFactories.js' @@ -39,7 +40,7 @@ await describe('OCPP16AuthAdapter', async () => { new Promise(resolve => { resolve({ idTagInfo: { - expiryDate: new Date(Date.now() + 86400000), + expiryDate: new Date(Date.now() + Constants.MS_PER_DAY), parentIdTag: undefined, status: OCPP16AuthorizationStatus.ACCEPTED, }, diff --git a/tests/charging-station/ocpp/auth/adapters/OCPP20AuthAdapter.test.ts b/tests/charging-station/ocpp/auth/adapters/OCPP20AuthAdapter.test.ts index 7f80781c..d7e9bb44 100644 --- a/tests/charging-station/ocpp/auth/adapters/OCPP20AuthAdapter.test.ts +++ b/tests/charging-station/ocpp/auth/adapters/OCPP20AuthAdapter.test.ts @@ -15,7 +15,7 @@ import { AuthenticationMethod, AuthResultStatus, IdentifierType, -} from '../../../../../src/charging-station/ocpp/auth/types/AuthTypes.js' +} from '../../../../../src/charging-station/ocpp/auth/index.js' import { OCPP20AuthorizationStatusEnumType, OCPP20IdTokenEnumType, diff --git a/tests/charging-station/ocpp/auth/cache/InMemoryAuthCache.test.ts b/tests/charging-station/ocpp/auth/cache/InMemoryAuthCache.test.ts index 7e812105..bf8da084 100644 --- a/tests/charging-station/ocpp/auth/cache/InMemoryAuthCache.test.ts +++ b/tests/charging-station/ocpp/auth/cache/InMemoryAuthCache.test.ts @@ -5,13 +5,13 @@ import assert from 'node:assert/strict' import { afterEach, beforeEach, describe, it } from 'node:test' -import type { AuthorizationResult } from '../../../../../src/charging-station/ocpp/auth/types/AuthTypes.js' +import type { AuthorizationResult } from '../../../../../src/charging-station/ocpp/auth/index.js' import { InMemoryAuthCache } from '../../../../../src/charging-station/ocpp/auth/cache/InMemoryAuthCache.js' import { AuthenticationMethod, AuthResultStatus, -} from '../../../../../src/charging-station/ocpp/auth/types/AuthTypes.js' +} from '../../../../../src/charging-station/ocpp/auth/index.js' import { standardCleanup, withMockTimers } from '../../../../helpers/TestLifecycleHelpers.js' import { createMockAuthorizationResult } from '../helpers/MockFactories.js' diff --git a/tests/charging-station/ocpp/auth/cache/InMemoryLocalAuthListManager.test.ts b/tests/charging-station/ocpp/auth/cache/InMemoryLocalAuthListManager.test.ts index 68447a50..87d8203d 100644 --- a/tests/charging-station/ocpp/auth/cache/InMemoryLocalAuthListManager.test.ts +++ b/tests/charging-station/ocpp/auth/cache/InMemoryLocalAuthListManager.test.ts @@ -5,10 +5,12 @@ import assert from 'node:assert/strict' import { afterEach, beforeEach, describe, it } from 'node:test' -import type { DifferentialAuthEntry } from '../../../../../src/charging-station/ocpp/auth/interfaces/OCPPAuthService.js' -import type { LocalAuthEntry } from '../../../../../src/charging-station/ocpp/auth/interfaces/OCPPAuthService.js' +import type { + DifferentialAuthEntry, + LocalAuthEntry, +} from '../../../../../src/charging-station/ocpp/auth/index.js' -import { InMemoryLocalAuthListManager } from '../../../../../src/charging-station/ocpp/auth/cache/InMemoryLocalAuthListManager.js' +import { InMemoryLocalAuthListManager } from '../../../../../src/charging-station/ocpp/auth/index.js' import { standardCleanup } from '../../../../helpers/TestLifecycleHelpers.js' const createEntry = ( diff --git a/tests/charging-station/ocpp/auth/strategies/LocalAuthStrategy.test.ts b/tests/charging-station/ocpp/auth/strategies/LocalAuthStrategy.test.ts index 0fe78be9..5fa4dc56 100644 --- a/tests/charging-station/ocpp/auth/strategies/LocalAuthStrategy.test.ts +++ b/tests/charging-station/ocpp/auth/strategies/LocalAuthStrategy.test.ts @@ -17,6 +17,7 @@ import { AuthResultStatus, IdentifierType, } from '../../../../../src/charging-station/ocpp/auth/types/AuthTypes.js' +import { Constants } from '../../../../../src/utils/index.js' import { standardCleanup } from '../../../../helpers/TestLifecycleHelpers.js' import { createMockAuthCache, @@ -104,7 +105,7 @@ await describe('LocalAuthStrategy', async () => { await it('should authenticate using local auth list', () => { mockLocalAuthListManager.getEntry = () => ({ - expiryDate: new Date(Date.now() + 86400000), + expiryDate: new Date(Date.now() + Constants.MS_PER_DAY), identifier: 'LOCAL_TAG', metadata: { source: 'local' }, status: 'accepted', diff --git a/tests/charging-station/ui-server/UIMCPServer-Integration.test.ts b/tests/charging-station/ui-server/UIMCPServer-Integration.test.ts index 1e821b29..85f06c37 100644 --- a/tests/charging-station/ui-server/UIMCPServer-Integration.test.ts +++ b/tests/charging-station/ui-server/UIMCPServer-Integration.test.ts @@ -5,6 +5,7 @@ import type { AddressInfo } from 'node:net' +import { format } from 'date-fns' import assert from 'node:assert/strict' import { request as httpRequest, type Server } from 'node:http' import { join } from 'node:path' @@ -200,7 +201,7 @@ await describe('UIMCPServer HTTP Integration', async () => { await it('should return log content with default date (current local date)', async () => { // Arrange const now = new Date() - const todayDate = `${now.getFullYear().toString()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}` + const todayDate = format(now, 'yyyy-MM-dd') writeTempFile( logTmpDir, `combined-${todayDate}.log`, diff --git a/tests/utils/ConfigurationValidation.test.ts b/tests/utils/ConfigurationValidation.test.ts index 21920219..b12833ef 100644 --- a/tests/utils/ConfigurationValidation.test.ts +++ b/tests/utils/ConfigurationValidation.test.ts @@ -15,7 +15,7 @@ import { DEPRECATED_KEY_REMAPPINGS, } from '../../src/utils/index.js' import { ConfigurationValidationError, validateConfiguration } from '../../src/utils/index.js' -import { logger } from '../../src/utils/index.js' +import { clone, logger } from '../../src/utils/index.js' import { standardCleanup } from '../helpers/TestLifecycleHelpers.js' import { buildLegacyConfiguration, @@ -276,7 +276,7 @@ await describe('ConfigurationValidation', async () => { await it('should not mutate the caller-supplied parsed object', t => { t.mock.method(console, 'warn', () => undefined) const parsed = buildLegacyConfiguration() - const before = structuredClone(parsed) + const before = clone(parsed) validateConfiguration(parsed, 'immutable.json') diff --git a/ui/cli/tests/renderers.test.ts b/ui/cli/tests/renderers.test.ts index 6acd0bfd..5603496b 100644 --- a/ui/cli/tests/renderers.test.ts +++ b/ui/cli/tests/renderers.test.ts @@ -1,6 +1,11 @@ import assert from 'node:assert' import { describe, it } from 'node:test' -import { OCPP16AvailabilityType, OCPP16ChargePointStatus, ResponseStatus } from 'ui-common' +import { + OCPP16AvailabilityType, + OCPP16ChargePointStatus, + ResponseStatus, + WebSocketReadyState, +} from 'ui-common' import { tryRenderPayload } from '../src/output/renderers.js' import { captureStream } from './helpers.js' @@ -25,7 +30,7 @@ const stationListPayload = { ocppVersion: '2.0.1', templateName: 'test.station-template', }, - wsState: 1, + wsState: WebSocketReadyState.OPEN, }, ], status: ResponseStatus.SUCCESS, diff --git a/ui/common/src/utils/payloadBuilders.ts b/ui/common/src/utils/payloadBuilders.ts index 790fed1d..169a8045 100644 --- a/ui/common/src/utils/payloadBuilders.ts +++ b/ui/common/src/utils/payloadBuilders.ts @@ -20,7 +20,7 @@ export function buildAuthorizePayload ( ): RequestPayload { if (isOCPP20x(ocppVersion)) { return { - idToken: { idToken: idTag, type: OCPP20IdTokenEnumType.ISO14443 }, + idToken: buildIdToken(idTag), } } assertOCPP16OrUndefined(ocppVersion) @@ -63,9 +63,7 @@ export function buildStartTransactionPayload ( connectorId, eventType: OCPP20TransactionEventEnumType.STARTED, ...(options?.evseId != null && { evseId: options.evseId }), - ...(options?.idTag != null && { - idToken: { idToken: options.idTag, type: OCPP20IdTokenEnumType.ISO14443 }, - }), + ...(options?.idTag != null && { idToken: buildIdToken(options.idTag) }), }, procedureName: ProcedureName.TRANSACTION_EVENT, } diff --git a/ui/common/tests/mocks.ts b/ui/common/tests/mocks.ts index c429f64b..d8dbde09 100644 --- a/ui/common/tests/mocks.ts +++ b/ui/common/tests/mocks.ts @@ -1,6 +1,6 @@ /** @file Shared mock factories for WebSocket-based tests */ -import type { WebSocketLike } from '../src/client/types.js' +import { type WebSocketLike, WebSocketReadyState } from '../src/client/types.js' export interface MockWebSocketLike extends WebSocketLike { sentMessages: string[] @@ -19,11 +19,11 @@ export function createMockWebSocketLike (): MockWebSocketLike { let onmessageFn: ((event: { data: string }) => void) | null = null let onopenFn: (() => void) | null = null const sentMessages: string[] = [] - let readyState: 0 | 1 | 2 | 3 = 1 + let readyState: WebSocketReadyState = WebSocketReadyState.OPEN return { close (code?: number, reason?: string) { - readyState = 3 + readyState = WebSocketReadyState.CLOSED oncloseFn?.({ code: code ?? 1000, reason: reason ?? '' }) }, get onclose () { @@ -58,7 +58,7 @@ export function createMockWebSocketLike (): MockWebSocketLike { }, sentMessages, triggerClose (code?: number, reason?: string) { - readyState = 3 + readyState = WebSocketReadyState.CLOSED oncloseFn?.({ code: code ?? 1000, reason: reason ?? '' }) }, triggerError (message) { diff --git a/ui/web/src/shared/utils/stationStatus.ts b/ui/web/src/shared/utils/stationStatus.ts index ae8479fc..1f5aec87 100644 --- a/ui/web/src/shared/utils/stationStatus.ts +++ b/ui/web/src/shared/utils/stationStatus.ts @@ -4,7 +4,12 @@ * These are not Vue composables (no reactive state) — they are pure utility functions * consumed exclusively by skin components via the shared layer. */ -import type { ChargingStationData, ConnectorEntry, Status } from 'ui-common' +import { + type ChargingStationData, + type ConnectorEntry, + type Status, + WebSocketReadyState, +} from 'ui-common' /** * Status variant type for UI display. @@ -82,11 +87,6 @@ export function getConnectorStatusVariant (status?: string): StatusVariant { return CONNECTOR_STATUS_VARIANT[status.toLowerCase()] ?? 'idle' } -const WS_STATE_CLOSED = 3 -const WS_STATE_CLOSING = 2 -const WS_STATE_CONNECTING = 0 -const WS_STATE_OPEN = 1 - /** * Maps a WebSocket ready state to a display variant. * @param wsState - The WebSocket readyState value @@ -94,13 +94,13 @@ const WS_STATE_OPEN = 1 */ export function getWebSocketStateVariant (wsState?: number): StatusVariant { switch (wsState) { - case WS_STATE_CLOSED: + case WebSocketReadyState.CLOSED: return 'err' - case WS_STATE_CLOSING: + case WebSocketReadyState.CLOSING: return 'warn' - case WS_STATE_CONNECTING: + case WebSocketReadyState.CONNECTING: return 'warn' - case WS_STATE_OPEN: + case WebSocketReadyState.OPEN: return 'ok' default: return 'idle' diff --git a/ui/web/tests/unit/helpers.ts b/ui/web/tests/unit/helpers.ts index 9d256aed..8ff70427 100644 --- a/ui/web/tests/unit/helpers.ts +++ b/ui/web/tests/unit/helpers.ts @@ -2,7 +2,7 @@ * @file Shared test utilities for Vue.js web UI unit tests * @description MockWebSocket, withSetup composable helper, mock factories. */ -import { ResponseStatus } from 'ui-common' +import { ResponseStatus, WebSocketReadyState } from 'ui-common' import { vi } from 'vitest' import { type App, createApp } from 'vue' @@ -73,23 +73,21 @@ export const ToggleButtonStub = { // ── MockWebSocket ───────────────────────────────────────────────────────────── export class MockWebSocket { - static readonly CLOSED = 3 - static readonly CLOSING = 2 - static readonly CONNECTING = 0 + static readonly CLOSED = WebSocketReadyState.CLOSED + static readonly CLOSING = WebSocketReadyState.CLOSING static lastInstance: MockWebSocket | null = null - static readonly OPEN = 1 + static readonly OPEN = WebSocketReadyState.OPEN addEventListener: ReturnType close: ReturnType - readonly CLOSED = 3 - readonly CLOSING = 2 - readonly CONNECTING = 0 + readonly CLOSED = WebSocketReadyState.CLOSED + readonly CLOSING = WebSocketReadyState.CLOSING onclose: ((event: CloseEvent) => void) | null = null onerror: ((event: Event) => void) | null = null onmessage: ((event: MessageEvent) => void) | null = null onopen: (() => void) | null = null - readonly OPEN = 1 - readyState: number = MockWebSocket.CONNECTING + readonly OPEN = WebSocketReadyState.OPEN + readyState: number = WebSocketReadyState.CONNECTING removeEventListener: ReturnType send: ReturnType sentMessages: string[] = [] -- 2.53.0