- Extract createMockCertificateManager to OCPP20TestUtils.ts (was duplicated 4x)
- Consolidate 5 createMock*AuthorizationResult into single parameterized factory
- Add createMockIdentifier with OCPP version parameter (deprecate version-specific ones)
- Remove unused wrapper functions from certificate test files
Reduces code duplication and improves maintainability.
Jérôme Benoit [Sat, 28 Feb 2026 20:04:10 +0000 (21:04 +0100)]
docs(tests): update TEST_STYLE_GUIDE to reference new factory
- Updated TEST_STYLE_GUIDE.md to use createMockChargingStation
- Fixed comment in ChargingStationTestUtils.ts
- Removed references to deleted ChargingStationFactory.ts
Jérôme Benoit [Sat, 28 Feb 2026 20:02:51 +0000 (21:02 +0100)]
refactor(tests): fix TypeScript errors in auth and variable manager tests
- Fixed OCPPAuthIntegration.test.ts to use createMockChargingStation with destructuring
- Corrected import path in AuthComponentFactory.test.ts (../../../../ → ../../../)
- Fixed OCPP20VariableManager.test.ts type errors by properly extracting .station property
- All 291 tests passing
- Zero migration-related TypeScript compilation errors
Jérôme Benoit [Sat, 28 Feb 2026 19:54:21 +0000 (20:54 +0100)]
refactor(tests): delete deprecated ChargingStationFactory and fix remaining imports
- Deleted ChargingStationFactory.ts and ChargingStationFactory.test.ts
- Fixed broken imports in 3 utility test files (ConfigurationKeyUtils, Helpers, ErrorUtils)
- Migrated remaining createChargingStation() calls to createMockChargingStation()
- Added createMockChargingStationTemplate() support in StationHelpers
- All 291 tests passing
Jérôme Benoit [Sat, 28 Feb 2026 19:34:22 +0000 (20:34 +0100)]
refactor(tests): migrate all test files to createMockChargingStation
- Migrated 20 OCPP 2.0 test files to use createMockChargingStation
- Migrated 4 utility test files to use consolidated imports
- Added createChargingStation and createChargingStationTemplate re-exports to ChargingStationTestUtils
- All 291 tests passing
Jérôme Benoit [Sat, 28 Feb 2026 17:43:48 +0000 (18:43 +0100)]
refactor(tests): standardize cleanup and strict equality
- Migrate 15 test files to use standardCleanup() from TestLifecycleHelpers
- Replace all 27 .toEqual() with .toStrictEqual() across 10 files
- Fix import path in OCPP20CertificateManager.test.ts
This completes P0 (cleanup standardization) and P1 (strict equality)
from the test audit. All 291 tests pass.
Jérôme Benoit [Sat, 28 Feb 2026 17:13:24 +0000 (18:13 +0100)]
fix(test-isolation): make OCPP20VariableManager tests self-contained
- FileTransferProtocols: init config key via getVariables first
- OrganizationName: set value explicitly instead of relying on previous test
Each test initializes its own state via fresh mockChargingStation from beforeEach.
Fixes Windows CI failure caused by test execution order assumptions.
Jérôme Benoit [Sat, 28 Feb 2026 17:05:27 +0000 (18:05 +0100)]
refactor(tests): move mock creation from it() to beforeEach()
- Refactor OCPPAuthServiceImpl.test.ts: declare mocks at describe level, initialize in beforeEach()
- Refactor OCPPAuthServiceFactory.test.ts: same pattern for consistency
- Refactor InMemoryAuthCache.test.ts: move common mockResult to beforeEach()
Aligns with TEST_STYLE_GUIDE.md recommendation for test isolation pattern.
Jérôme Benoit [Sat, 28 Feb 2026 16:41:55 +0000 (17:41 +0100)]
refactor(tests): harmonize test suite structure and eliminate duplication
- Consolidate 5 TransactionEvent variant files into single parameterized test
- Reduce OCPPAuthIntegration.test.ts scope (422→196 lines, focus on integration)
- Remove duplicate resetConnectorTransactionStates function, use shared utility
- Merge OCPP20AuthAdapter-Offline.test.ts into main adapter test file
- Add beforeEach hooks for mock initialization in ChargingStation tests
- Standardize OCPP requirement codes in describe blocks (I02-I04, G03)
- Consolidate eslint-disable comments with explanatory reasons
- Fix JSDoc header positions in OCPP 2.0 test files
- Use standardCleanup() for consistent timer mock reset
Net reduction: ~400 lines of test code while maintaining full coverage
Jérôme Benoit [Sat, 28 Feb 2026 16:08:14 +0000 (17:08 +0100)]
fix(test-type-safety): remove unsafe type casts and add factory helper
Phase 1 (Type Safety):
- Remove 16 'undefined as unknown as' casts from 8 auth test files
- Add createStationWithCertificateManager() helper to OCPP20TestUtils
- Migrate 3 certificate test files to use the new type-safe helper
Phase 2 (Enhancements):
- Add explanatory comments to 9 ESLint override directives
- Update TEST_STYLE_GUIDE.md with new factory documentation
Jérôme Benoit [Sat, 28 Feb 2026 15:36:56 +0000 (16:36 +0100)]
fix(test-isolation): move mock creation to beforeEach in CableFirst test
- Move mockChargingStation initialization from module level to beforeEach()
- Declare mockChargingStation as let at describe scope per TEST_STYLE_GUIDE.md
- Ensures each test receives fresh mock instances
- Fixes CRITICAL test isolation violation per test audit
- All 12 tests in E02 - Cable-First Transaction Flow pass
Jérôme Benoit [Sat, 28 Feb 2026 14:06:42 +0000 (15:06 +0100)]
refactor(tests): remove eslint-disable and fix type safety issues
- Remove file-level eslint-disable comments from OCPP 2.0 transaction tests
- Replace `as any` casts with proper TypeScript types (ChargingStation, SentRequest)
- Fix test isolation by moving state reset to beforeEach hooks
- Use `stationInfo = undefined` pattern instead of delete with any cast
- Remove unnecessary async keywords and optional chains per lint rules
Jérôme Benoit [Sat, 28 Feb 2026 13:09:50 +0000 (14:09 +0100)]
refactor(tests): remove file-level eslint-disable and fix as any casts
- Remove blanket eslint-disable comments from OCPP 2.0 test files
- Fix improper 'as any' casts in afterEach cleanup (use union types)
- Add targeted inline eslint-disable-next-line for legitimate test cases
(testing null/undefined inputs for edge case validation)
Jérôme Benoit [Fri, 27 Feb 2026 22:54:59 +0000 (23:54 +0100)]
refactor(tests): improve test isolation and remove dead code
- Fix module-level state sharing in 6 OCPP 2.0 RequestService tests
- Remove unused createMockTemplate function from StationHelpers
- Remove unused TestStationHelper, TestTimerHelper, TestEnvironmentHelper classes (206 LOC)
- Add createMockAuthCache and createMockOCPPAdapter factories
- Update TEST_STYLE_GUIDE.md with test isolation best practices
- Clean up orphaned imports after dead code removal
Jérôme Benoit [Fri, 27 Feb 2026 22:31:29 +0000 (23:31 +0100)]
refactor(tests): add testable interface to eliminate eslint-disable comments
- Add TestableOCPP20RequestService interface and factory function
- Remove file-level eslint-disable from 3 OCPP20RequestService test files
- Use type assertions instead of generic type parameters for type safety
- Follows TEST_STYLE_GUIDE.md recommendation for testable interfaces
Jérôme Benoit [Fri, 27 Feb 2026 22:14:12 +0000 (23:14 +0100)]
test: add afterEach cleanup to all test files
Add afterEach with mock.restoreAll() to 27 test files.
Ensures 100% coverage for mock cleanup (63/63 files).
Prevents test pollution between test runs.
Follows TEST_STYLE_GUIDE.md standards.
Jérôme Benoit [Fri, 27 Feb 2026 22:03:44 +0000 (23:03 +0100)]
test: harmonize test names and add mock factories
- Replace 164 'should verify' patterns with descriptive test names
- Add createLoggerMocks() and createConsoleMocks() to TestLifecycleHelpers
- Add afterEach cleanup to ErrorUtils, WorkerUtils, ConfigurationUtils tests
- Align all test names with TEST_STYLE_GUIDE.md conventions
Jérôme Benoit [Fri, 27 Feb 2026 20:05:21 +0000 (21:05 +0100)]
fix(tests): bind method reference in ClearCache test
- Use .bind() for deleteIdTags method reference (line 89)
- Ensures proper 'this' context when method is restored and called
- Reduces lint errors from 41 to 40 (1 error fixed)
- All 291 tests still passing
Jérôme Benoit [Fri, 27 Feb 2026 20:03:12 +0000 (21:03 +0100)]
fix(tests): remove non-null assertions in InstallCertificate test
- Replace stationInfo! with stationInfo (safe - always initialized)
- Lines 188 and 203 in OCPP20IncomingRequestService-InstallCertificate.test.ts
- Reduces lint errors from 43 to 41 (2 errors fixed)
- All 291 tests still passing
Jérôme Benoit [Fri, 27 Feb 2026 20:00:20 +0000 (21:00 +0100)]
chore(tests): remove unused imports and variables
- Remove AvailabilityType from ChargingStation-Connectors.test.ts
- Remove ChargingStationConfiguration from StationHelpers.ts
- Remove minimalChargingStation variable from GetBaseReport.test.ts
- Remove OCPP20GetVariableDataType from SetVariables.test.ts
- Remove 3 unused imports from NotifyReport.test.ts
- Reduces lint errors from 50 to 43 (7 errors fixed)
- All 291 tests still passing
Jérôme Benoit [Fri, 27 Feb 2026 19:49:18 +0000 (20:49 +0100)]
chore(tests): auto-fix lint errors (sorting and unused imports)
- Fix export ordering in ChargingStationTestUtils.ts
- Fix object property sorting in OCPPAuthIntegration.test.ts
- Reduces lint errors from 61 to 50 (11 auto-fixed)
- All 291 tests still passing
Jérôme Benoit [Fri, 27 Feb 2026 19:17:11 +0000 (20:17 +0100)]
fix(tests): add afterEach cleanup to RemoteStartAuth test
- Added afterEach hook to clear mock references
- Prevents test pollution between test cases
- Only 1 file was missing cleanup (not 33 as initially audited)
- All 280 tests passing
Jérôme Benoit [Fri, 27 Feb 2026 19:07:37 +0000 (20:07 +0100)]
fix(tests): make auth integration tests deterministic
- Removed probabilistic assertion expect(successRate).toBeGreaterThan(50)
- Replaced live integration calls with deterministic mocks
- Used mock patterns from MockFactories.ts throughout
- All 27 auth tests now have explicit 100% pass/fail criteria
- Tests produce consistent results on repeated runs
- Preserved all test scenarios and coverage
Impact:
- Eliminated ~200 'as any' casts across 15 files
- Removed ~50 eslint-disable directives
- Full type safety with IntelliSense support
- All 280 tests passing
Note: 48 lint errors remain (import ordering, unsafe assignments).
Will address in follow-up commit.
Jérôme Benoit [Fri, 27 Feb 2026 18:18:14 +0000 (19:18 +0100)]
refactor(tests): consolidate duplicate test constants
- Delete duplicate OCPP20TestConstants.ts file
- Update all 21 OCPP 2.0 test files to import from canonical ChargingStationTestConstants.js
- All 7 constants verified as available in canonical source:
* TEST_CHARGING_STATION_BASE_NAME
* TEST_CHARGE_POINT_MODEL
* TEST_CHARGE_POINT_SERIAL_NUMBER
* TEST_CHARGE_POINT_VENDOR
* TEST_FIRMWARE_VERSION
* TEST_CONNECTOR_VALID_INSTANCE
* TEST_CONNECTOR_INVALID_INSTANCE
- Test suite passes with 280/280 tests passing
Jérôme Benoit [Fri, 27 Feb 2026 17:44:35 +0000 (18:44 +0100)]
fix(tests): move ocppVersion inside stationInfo in auth mock factory
The mock factory was placing ocppVersion at the root level of the mock
ChargingStation, but AuthComponentFactory.createAdapters() looks for
chargingStation.stationInfo?.ocppVersion, causing all auth service tests
to fail with 'OCPP version not found in charging station' error.
Jérôme Benoit [Fri, 27 Feb 2026 17:03:01 +0000 (18:03 +0100)]
fix(tests): ensure proper test isolation and cleanup
Add afterEach hooks to reset singleton state and clear factory caches
between tests, preventing state leakage across test files.
Changes:
- OCPP20VariableManager.test.ts: Reset runtime overrides after each test
- OCPPAuthServiceFactory.test.ts: Clear all cached instances after each test
- OCPP20IncomingRequestService-SetVariables.test.ts: Reset variable manager
- OCPP20IncomingRequestService-GetVariables.test.ts: Reset variable manager
- OCPP20IncomingRequestService-GetBaseReport.test.ts: Reset variable manager
Verified: All 280 tests pass on consecutive runs (test && test)
Jérôme Benoit [Fri, 27 Feb 2026 16:51:41 +0000 (17:51 +0100)]
refactor(tests): reduce eslint-disable comments with proper typing
- Add MockOCPPRequestService and MockOCPPIncomingRequestService interfaces
- Export TestChargingStation type for typed mock service access
- Remove 14 eslint-disable comments from ChargingStationFactory.test.ts
- Remove 4 eslint-disable comments from ConfigurationKeyUtils.test.ts
- Use Partial<ChargingStationOcppConfiguration> for missing config tests
Remaining 43 inline eslint-disable comments are all legitimate:
- no-empty-function: Testing empty callbacks
- require-await: Mock async implementations
- no-explicit-any: Testing validators with invalid inputs
Jérôme Benoit [Fri, 27 Feb 2026 16:46:22 +0000 (17:46 +0100)]
refactor(tests): consolidate mock station creation utilities
Replaced 17 inline mock station objects in OCPPAuthServiceFactory.test.ts
with calls to createMockAuthServiceTestStation() from MockFactories.ts.
This reduces test file from 327 to 228 lines (~30% reduction) while
maintaining identical test behavior.
Remaining auth adapter tests retain inline mocks due to test-specific
method requirements (inAcceptedState, getLocalAuthListEnabled, etc.)
that are appropriately kept close to their test context.
Jérôme Benoit [Fri, 27 Feb 2026 16:39:10 +0000 (17:39 +0100)]
docs(tests): add file-level JSDoc to test files
Add @file and @description JSDoc comments to all 58 test files
that were missing file-level documentation. Each JSDoc identifies
the module under test and provides a brief description of the
test coverage scope.
E03 IdToken-First Pre-Authorization Flow (16 tests):
- E03.FR.01: IdToken inclusion in TransactionEvent (once per transaction)
- E03.FR.05/06: EVConnectionTimeOut handling (authorization cancellation)
- E03.FR.07/08: Sequence number continuity and unique transaction IDs
- E03.FR.13: Authorized trigger reason for IdToken-first start
- Authorization status handling (Deauthorized, StopAuthorized)
- Full IdToken-first lifecycle (authorize -> cable -> charge -> end)
- Differentiation from E02 Cable-First flow by trigger reason
- Multiple connector independence verification
Tests verify the IdToken-first flow where user presents their ID token
BEFORE connecting the cable, as opposed to E02 Cable-First where the
cable is connected first.
B02/B03 Pending/Rejected Boot Notification Behavior (11 tests):
- Store interval from Pending/Rejected responses
- State transitions: Pending→Accepted, Pending→Rejected, Rejected→Accepted
- Use interval as heartbeat when in Pending state
- Block message initiation when in Rejected state
- Preserve connector states during Rejected state
- Support configurable retry intervals
E02 Cable-First Transaction Flow (12 tests):
- Cable plug event sequencing and EV detection flow
- Connector status transitions (Available→Occupied)
- Full Cable-First transaction lifecycle
- Context-based trigger reason selection
- Multiple connector independence
Jérôme Benoit [Fri, 27 Feb 2026 02:24:13 +0000 (03:24 +0100)]
refactor(tests): rename createRealChargingStation to createMockChargingStation
- Rename function to reflect its nature as a lightweight stub, not a real instance
- Update all usages in ChargingStation.test.ts
- Add EVSE 0 with connector 0 for station-level availability checks in EVSE mode
- Add StopTransactionReason parameter to stop() method signature
- Add comment explaining deleteConfiguration parameter usage in delete()
- Update interface and type names to match (MockChargingStationOptions/Result)
- Update JSDoc and file header to reflect mock terminology
Jérôme Benoit [Fri, 27 Feb 2026 02:01:36 +0000 (03:01 +0100)]
fix(tests): add missing getEvseStatus method and harmonize mock factory types
- Add getEvseStatus() method to ChargingStationFactory mock (fixes CI failure)
- Add explicit return types to all mock methods matching ChargingStation class
- Add OCPP SRPC terms to cspell dictionary (SRPC, CALLRESULT, CALLERROR, CALLRESULTERROR)
- Import ConnectorStatus and EvseStatus types for type safety
Jérôme Benoit [Fri, 27 Feb 2026 01:12:00 +0000 (02:12 +0100)]
test(charging-station): add lifecycle prototype test to validate mocking strategy
- Create ChargingStation.test.ts with minimal test structure
- One test: validates station instantiation and start() state transition
- Uses createRealChargingStation() from test utilities
- Proper cleanup with afterEach hook
- BLOCKING validation passed - mocking strategy confirmed working
- Fix ESLint errors: proper ChargingStation type import
- Add getEvseStatus(evseId) to ChargingStation
- Add hasPendingReservation/hasPendingReservations to Helpers
- Standardize transactionId checks to != null
- Add unit tests for reservation helper functions
Jérôme Benoit [Thu, 26 Feb 2026 23:16:08 +0000 (00:16 +0100)]
fix(test): use fake timers to prevent Reset test hangs on Windows
Reset handlers (scheduleResetOnIdle, scheduleEvseResetOnIdle, scheduleEvseReset)
create setInterval/setTimeout/setImmediate timers that are never cleaned up.
Node.js test runner on Windows waits for all timers before loading next test file,
causing indefinite hangs.
Solution: Use Node.js mock.timers API with beforeEach(enable) + afterEach(reset)
pattern, validated against GitHub Desktop, AFFiNE, and official Node.js docs.
Jérôme Benoit [Thu, 26 Feb 2026 23:05:03 +0000 (00:05 +0100)]
test(ocpp2): dichotomous search - skip Reset test instead of SetVariables
Reset was the last test to complete before the Windows CI hang.
The hang occurs when loading the next test file (SetVariables), indicating
Reset (or earlier) is not cleaning up properly.
Re-enabled: SetVariables test
Skipped: Reset test for further investigation
Jérôme Benoit [Tue, 24 Feb 2026 17:46:42 +0000 (18:46 +0100)]
fix: replace c8 with native Node.js test coverage
- Remove c8 dependency (yargs@17.7.2 incompatible with Node.js 25)
- Use --experimental-test-coverage for native coverage
- Rename coverage script to test:coverage
- Optimize CI to avoid double test runs on coverage matrix
- Add INSTALL_CERTIFICATE to OCPP20IncomingRequestCommand enum
- Implement handleRequestInstallCertificate() with validation and storage
- Handle both boolean (test mock) and object (real) return types
- All 9 handler tests passing
Add comprehensive test suite for OCPP 2.0.1 GetInstalledCertificateIds handler:
- Return all certificates when no filter provided
- Filter by certificate type (V2GRootCertificate, etc.)
- Multiple filter types support
- Empty result returns Accepted status (per OCPP spec)
- Certificate manager missing returns NotFound
- Response structure validation with CertificateHashDataChain
* fix(ocpp2): register GetCertificateStatus handler in incomingRequestHandlers Map
Handler implementation was complete but not registered in the Map,
causing OCPP messages to fail routing to the handler.
This completes Task 8 of certificate management implementation.
- Add handleRequestCertificateSigned method to process incoming signed certificates
- Validates PEM format and stores via CertificateManager
- Triggers websocket reconnect for ChargingStationCertificate type
- Returns Rejected with InternalError if certificateManager unavailable
- Export OCPP20CertificateSigned request/response types
* fix(ocpp2): resolve linting errors in CertificateSigned handler
- Fix import order: move OCPP20CertificateSignedRequest/Response before OCPP20ComponentName (perfectionist/sort-named-imports)
- Fix Map entry order: swap GET_BASE_REPORT and GET_CERTIFICATE_STATUS to alphabetical order (perfectionist/sort-maps)
- Fix method position: move handleRequestCertificateSigned to correct alphabetical position (perfectionist/sort-classes)
- Add eslint-disable comments for necessary any usage in certificateManager access (@typescript-eslint/no-unsafe-assignment)
* fix(ocpp2): resolve linting errors in certificate management
- Remove await from synchronous certificate manager method calls
- Remove async from test functions without await expressions
- Fix Promise.all() with non-Promise values in tests
- Auto-format code to match project style
All tests passing (125/125), build passes, 0 linting errors.
* feat(ocpp2): implement SignCertificate request method with mock CSR
- Add requestSignCertificate() method to OCPP20RequestService
- Generate simplified mock CSR for simulator testing (NOT PKCS#10 compliant)
- Extract OrganizationName from SecurityCtrlr.OrganizationName config
- Support optional CertificateSigningUseEnumType parameter
- Add comprehensive test suite (10 test scenarios)
- Fix all linting errors (import order, method order, JSDoc alignment)
Mock CSR Structure:
- JSON-based format with algorithm, keySize, publicKey, subject, timestamp
- Base64 encoded and wrapped in PEM headers
- NOT cryptographically valid PKCS#10 CSR
- Suitable for OCPP protocol testing in simulator context only
IMPORTANT: This implementation is for simulator testing purposes only.
Do NOT use in production environments. Real CSMS expecting valid PKCS#10
CSR will reject this format. No external dependencies added per plan
constraint (line 574).
Test Status:
- All linting passes (0 errors, 50 pre-existing warnings)
- Build passes (258ms)
- Tests cannot run due to poolifier ESM/CommonJS compatibility issue
(documented in issues.md - not a code problem)
Refs: Task 9 - SignCertificate Request Method
* feat(ocpp2): implement Get15118EVCertificate and GetCertificateStatus request methods
Implements ISO 15118 certificate request methods:
- Get15118EVCertificate: forwards EXI-encoded cert requests (pass-through)
- GetCertificateStatus: requests OCSP certificate status from CSMS
Both methods follow established pattern (generateUUID -> sendMessage).
EXI payloads passed through unchanged (no decode/encode).
OCSP implementation is stub for simulator (no real network calls).
Tests: 12 comprehensive tests verify EXI pass-through and OCSP data flow.
* [autofix.ci] apply automated fixes
* fix(ocpp2): address PR review feedback for certificate management
- Fix toEndWith matcher: use toMatch(/\.pem$/) for vitest compatibility
- Fix path assertion: extract filename before checking special characters
- Fix GetInstalledCertificateIds: return NotFound when result is empty
- Fix deleteCertificate: return Failed instead of NotFound on outer error
- Add enum mapping: convert GetCertificateIdUseEnumType to InstallCertificateUseEnumType
- Fix JSDoc: remove duplicate @param and orphaned comment blocks
- Fix multi-cert PEM: use extractFirstCertificate for chained certificates
- Add comment to empty catch block explaining error swallowing intent
* test(ocpp20): align tests with OCPP 2.0.1 spec-compliant implementation
- GetInstalledCertificateIds: return NotFound (not Accepted) when no certificates match
- GetCertificateStatus: test stub behavior returning Failed/NotEnabled (OCSP not implemented)
- InstallCertificate: fix mock to return StoreCertificateResult object instead of boolean
* [autofix.ci] apply automated fixes
* [autofix.ci] apply automated fixes
* fix(tests): add missing hasIdTags mock method
The ChargingStationFactory mock was missing hasIdTags() method,
causing tests to fail on Windows when isIdTokenLocalAuthorized()
was called during authorization checks.
* fix(tests): align DeleteCertificate mock return type with handler expectation
The handler expects { status: 'Accepted' | 'NotFound' | 'Failed' } but the test
mock was returning boolean values, causing tests to fail on Windows CI.
* [autofix.ci] apply automated fixes
* fix(ocpp2): fix charging profile validation for stackLevel 0 and improve test isolation
- Fix validateChargingProfile() to use null checks instead of falsy checks,
allowing valid profiles with stackLevel: 0 to pass validation
- Add resetConnectorTransactionState() helper in OCPP20TestUtils for proper
test isolation between RequestStartTransaction tests
- Refactor test to verify connector status storage rather than TransactionEvent
capture, improving test reliability across platforms
* fix: remove duplicate resetConnectorTransactionState function
* fix(ocpp2): address PR review issues for certificate management
- fix childCertificateHashData type to be array per OCPP 2.0.1 spec
- fix unsafe type casting using hasCertificateManager() type guard
- fix storeCertificate to accept CertificateSigningUseEnumType union
- remove unnecessary optional chain on storeResult.success
- document mock CSR behavior and OCSP stub limitation in README
* chore: untrack .sisyphus directory from PR
The .sisyphus directory contains local planning artifacts that should
not be part of the PR. It is now gitignored on main.
* fix: resolve linting warnings for clean format output
- Fix JSDoc @throws format in OCPP20CertificateManager.ts
- Add missing @param/@returns documentation for computeFallbackCertificateHash
- Add cspell dictionary entries for issuerkeyhash/issuernamehash
- Add cspell ignore directive for Base64 mock data strings
- Fix invalid string literals to proper ReasonCodeEnumType enum values
OCPP 2.0.1 defines GetCertificateStatus as CS→CSMS (outgoing),
not CSMS→CS (incoming). The charging station sends OCSP requests
to the central system for certificate validation.
* docs: correct OCSP status and enable docs/ tracking
- Update README to reflect actual OCSP behavior (returns Failed, not Good)
- Remove docs/ from .gitignore to track OCPP specifications
- Fix issuerKeyHash to use issuer certificate's public key per RFC 6960 4.1.1
- Add optional issuerCertPem parameter to computeCertificateHash
- Detect self-signed certificates and use correct key for hashing
- Add validateCertificatePath to prevent path traversal attacks
- Validate resolved paths stay within certificate storage directory
- Reject ../../../etc/passwd and /etc/passwd style attacks
* refactor(ocpp2): convert certificate manager file I/O to async
- Replace readFileSync/writeFileSync with async fs/promises equivalents
- Convert deleteCertificate, getInstalledCertificates, storeCertificate to async
- Add async pathExists helper using stat
- Update all test callers to use async/await
- Prevents blocking event loop during certificate file operations
- Fix lint: remove unnecessary escape in sanitizePath regex (Wave 2 cleanup)
* fix(ocpp2): use path.sep for cross-platform path validation
The path traversal check used hardcoded '/' separator which fails on Windows.
Using node:path sep constant ensures proper behavior on all platforms.
The regex patterns in sanitizePath() were double-escaped in source,
causing them to not match actual '..' sequences or path separators.
- Change /\.\./g to /\.\./g to match literal '..'
- Change /[/\\]/g to /[/\]/g to match / and \ characters
- Replace matches with '_' instead of empty string for clarity
The GetCertificateStatus incoming handler was removed in a previous commit
because GetCertificateStatus is an outgoing request per OCPP 2.0.1 spec,
not an incoming message that the charging station handles.
These tests were testing a handler that no longer exists.
* fix(ocpp2): add OCPP 2.0.1 §2.10 TxProfile validation for RequestStartTransaction
- Validate chargingProfilePurpose must be TxProfile (reject TxDefaultProfile, etc.)
- Validate transactionId must not be set for new transaction profiles
- Fixes Windows CI test failures for RequestStartTransaction tests
- Add explanatory comments to empty catch blocks for clarity
- Extract getStationCertificatesBasePath() helper to reduce duplication
- Refactor deleteCertificate, getInstalledCertificates, getCertificatePath to use helper
- Fix spelling: unparseable → unparsable
* refactor(ocpp2): use DeleteCertificateStatusEnumType instead of string literals
Replace string literal union type with DeleteCertificateStatusEnumType enum:
- Update DeleteCertificateResult interface to use enum type
- Replace string literals in deleteCertificate method returns
- Replace string comparisons with enum values in handler
* feat(ocpp2): add TRIGGER_MESSAGE and UNLOCK_CONNECTOR to OCPP20IncomingRequestCommand enum
* refactor(ocpp2): use OCPP20IncomingRequestCommand enum for context.command type and comparisons
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
* fix(ocpp2): implement ClearCache and Reset OnIdle fixes per audit (CLR-001, CLR-002, RST-001)
- Override handleRequestClearCache() for OCPP 2.0.1 to use Authorization Cache
- Add AuthCacheEnabled check per C11.FR.04 (return Rejected if disabled)
- Extend Reset OnIdle to check firmware updates and reservations per errata 2.14
- Add comprehensive test coverage for ClearCache spec compliance
- Update base class signature to support async ClearCache in OCPP 2.0.1
- Fix ESLint errors in test file (remove unnecessary conditionals, bind methods)
- Add comprehensive test coverage for Reset OnIdle behavior
- Test firmware update blocking (Downloading/Downloaded/Installing states)
- Test reservation blocking (non-expired vs expired reservations)
- Test true idle state when all conditions clear
- Test multiple blocking conditions simultaneously
- All 116 tests passing with no regressions
* test(ocpp2): add C11.FR.05 test for Authorization Cache not supported scenario
- Add comprehensive test coverage for Reset OnIdle behavior
- Test firmware update blocking (Downloading/Downloaded/Installing states)
- Test reservation blocking (non-expired vs expired reservations)
- Test true idle state when all conditions clear
- Test multiple blocking conditions simultaneously
- All 116 tests passing with no regressions
Jérôme Benoit [Mon, 23 Feb 2026 22:48:03 +0000 (23:48 +0100)]
fix(ocpp2): implement ClearCache and Reset OnIdle fixes per audit (CLR-001, CLR-002, RST-001)
- Override handleRequestClearCache() for OCPP 2.0.1 to use Authorization Cache
- Add AuthCacheEnabled check per C11.FR.04 (return Rejected if disabled)
- Extend Reset OnIdle to check firmware updates and reservations per errata 2.14
- Add comprehensive test coverage for ClearCache spec compliance
- Update base class signature to support async ClearCache in OCPP 2.0.1
- Fix ESLint errors in test file (remove unnecessary conditionals, bind methods)