test: improve ErrorUtils coverage
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 7 Jun 2024 13:02:00 +0000 (15:02 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 7 Jun 2024 13:02:00 +0000 (15:02 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/OCPPIncomingRequestService.ts
src/utils/ErrorUtils.ts
src/utils/index.ts
tests/utils/ErrorUtils.test.ts

index 017de863c678f8c66d9c66d83085dfa35226156b..64cefe58653da3c955c6ec1d0537d1597f5a710e 100644 (file)
@@ -106,6 +106,7 @@ import {
   convertToDate,
   convertToInt,
   formatDurationMilliSeconds,
+  handleIncomingRequestError,
   isAsyncFunction,
   isNotEmptyArray,
   isNotEmptyString,
@@ -1577,7 +1578,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         })
         ftpClient?.close()
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        return this.handleIncomingRequestError<GetDiagnosticsResponse>(
+        return handleIncomingRequestError<GetDiagnosticsResponse>(
           chargingStation,
           OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
           error as Error,
@@ -1647,7 +1648,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_UNKNOWN_VENDOR_ID
     } catch (error) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      return this.handleIncomingRequestError<OCPP16DataTransferResponse>(
+      return handleIncomingRequestError<OCPP16DataTransferResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.DATA_TRANSFER,
         error as Error,
@@ -1730,7 +1731,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       chargingStation.getConnectorStatus(connectorId)!.status = OCPP16ChargePointStatus.Available
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      return this.handleIncomingRequestError<OCPP16ReserveNowResponse>(
+      return handleIncomingRequestError<OCPP16ReserveNowResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.RESERVE_NOW,
         error as Error,
@@ -1768,7 +1769,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_ACCEPTED
     } catch (error) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      return this.handleIncomingRequestError<GenericResponse>(
+      return handleIncomingRequestError<GenericResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.CANCEL_RESERVATION,
         error as Error,
index 06165c2f0514ec79399fa1483b39458bb8ade616..545438d5d61dda84a995c1c4351562a1c8a94e1b 100644 (file)
@@ -7,12 +7,11 @@ import { type ChargingStation, getIdTagsFile } from '../../charging-station/inde
 import { OCPPError } from '../../exception/index.js'
 import type {
   ClearCacheResponse,
-  HandleErrorParams,
   IncomingRequestCommand,
   JsonType,
   OCPPVersion
 } from '../../types/index.js'
-import { logger, setDefaultErrorParams } from '../../utils/index.js'
+import { logger } from '../../utils/index.js'
 import { OCPPConstants } from './OCPPConstants.js'
 import { ajvErrorsToErrorType } from './OCPPServiceUtils.js'
 type Ajv = _Ajv.default
@@ -50,28 +49,6 @@ export abstract class OCPPIncomingRequestService extends EventEmitter {
     return OCPPIncomingRequestService.instance as T
   }
 
-  protected handleIncomingRequestError<T extends JsonType>(
-    chargingStation: ChargingStation,
-    commandName: IncomingRequestCommand,
-    error: Error,
-    params: HandleErrorParams<T> = { throwError: true, consoleOut: false }
-  ): T | undefined {
-    params = setDefaultErrorParams(params)
-    logger.error(
-      `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
-      error
-    )
-    if (params.throwError === false && params.errorResponse != null) {
-      return params.errorResponse
-    }
-    if (params.throwError === true && params.errorResponse == null) {
-      throw error
-    }
-    if (params.throwError === true && params.errorResponse != null) {
-      return params.errorResponse
-    }
-  }
-
   protected validateIncomingRequestPayload<T extends JsonType>(
     chargingStation: ChargingStation,
     commandName: IncomingRequestCommand,
index fb23b133476395afa0bd1dc18b651b8f50614146..0a444c6b1f5d945e5577dd7fbebc6ec235df16e6 100644 (file)
@@ -16,6 +16,8 @@ import type {
 import { logger } from './Logger.js'
 import { isNotEmptyString } from './Utils.js'
 
+const moduleName = 'ErrorUtils'
+
 const defaultErrorParams = {
   throwError: true,
   consoleOut: false
@@ -90,7 +92,7 @@ export const handleSendMessageError = (
 ): void => {
   params = setDefaultErrorParams(params, { throwError: false, consoleOut: false })
   logger.error(
-    `${chargingStation.logPrefix()} Send ${getMessageTypeString(messageType)} command '${commandName}' error:`,
+    `${chargingStation.logPrefix()} ${moduleName}.handleSendMessageError: Send ${getMessageTypeString(messageType)} command '${commandName}' error:`,
     error
   )
   if (params.throwError === true) {
@@ -98,6 +100,28 @@ export const handleSendMessageError = (
   }
 }
 
+export const handleIncomingRequestError = <T extends JsonType>(
+  chargingStation: ChargingStation,
+  commandName: IncomingRequestCommand,
+  error: Error,
+  params: HandleErrorParams<T> = { throwError: true, consoleOut: false }
+): T | undefined => {
+  params = setDefaultErrorParams(params)
+  logger.error(
+    `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
+    error
+  )
+  if (params.throwError === false && params.errorResponse != null) {
+    return params.errorResponse
+  }
+  if (params.throwError === true && params.errorResponse == null) {
+    throw error
+  }
+  if (params.throwError === true && params.errorResponse != null) {
+    return params.errorResponse
+  }
+}
+
 export const setDefaultErrorParams = <T extends JsonType>(
   params: HandleErrorParams<T>,
   defaultParams: HandleErrorParams<T> = defaultErrorParams
index a35887c7d3b53c48bf035d9511fb4933a6bad58e..5fedbc57e20ab849439f4628c28390b4433015f5 100644 (file)
@@ -10,6 +10,7 @@ export { Constants } from './Constants.js'
 export { ACElectricUtils, DCElectricUtils } from './ElectricUtils.js'
 export {
   handleFileException,
+  handleIncomingRequestError,
   handleSendMessageError,
   handleUncaughtException,
   handleUnhandledRejection,
index 907d05fad5f136fbfed17f7fe527a813aa8114e9..59c455f94df9f7ae4aa9a70efda1acb1ab19b45e 100644 (file)
@@ -2,10 +2,27 @@ import { describe, it } from 'node:test'
 
 import { expect } from 'expect'
 
-import { FileType } from '../../src/types/index.js'
-import { handleFileException, setDefaultErrorParams } from '../../src/utils/ErrorUtils.js'
+import type { ChargingStation } from '../../src/charging-station/index.js'
+import {
+  FileType,
+  GenericStatus,
+  IncomingRequestCommand,
+  MessageType,
+  RequestCommand
+} from '../../src/types/index.js'
+import {
+  handleFileException,
+  handleIncomingRequestError,
+  handleSendMessageError,
+  setDefaultErrorParams
+} from '../../src/utils/ErrorUtils.js'
 
 await describe('ErrorUtils test suite', async () => {
+  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
+  const chargingStation = {
+    logPrefix: () => 'CS-TEST |'
+  } as ChargingStation
+
   await it('Verify handleFileException()', () => {
     const error = new Error()
     error.code = 'ENOENT'
@@ -19,6 +36,48 @@ await describe('ErrorUtils test suite', async () => {
     }).not.toThrow()
   })
 
+  await it('Verify handleSendMessageError()', () => {
+    const error = new Error()
+    expect(() => {
+      handleSendMessageError(
+        chargingStation,
+        RequestCommand.BOOT_NOTIFICATION,
+        MessageType.CALL_MESSAGE,
+        error
+      )
+    }).not.toThrow()
+    expect(() => {
+      handleSendMessageError(
+        chargingStation,
+        RequestCommand.BOOT_NOTIFICATION,
+        MessageType.CALL_MESSAGE,
+        error,
+        { throwError: true }
+      )
+    }).toThrow(error)
+  })
+
+  await it('Verify handleIncomingRequestError()', () => {
+    const error = new Error()
+    expect(() => {
+      handleIncomingRequestError(chargingStation, IncomingRequestCommand.CLEAR_CACHE, error)
+    }).toThrow(error)
+    expect(() => {
+      handleIncomingRequestError(chargingStation, IncomingRequestCommand.CLEAR_CACHE, error, {
+        throwError: false
+      })
+    }).not.toThrow()
+    const errorResponse = {
+      status: GenericStatus.Rejected
+    }
+    expect(
+      handleIncomingRequestError(chargingStation, IncomingRequestCommand.CLEAR_CACHE, error, {
+        throwError: false,
+        errorResponse
+      })
+    ).toStrictEqual(errorResponse)
+  })
+
   await it('Verify setDefaultErrorParams()', () => {
     expect(setDefaultErrorParams({})).toStrictEqual({ throwError: true, consoleOut: false })
     expect(setDefaultErrorParams({ throwError: false })).toStrictEqual({