From ffcbd103ee3603a4948adbbef62e4fbcee6554d8 Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Thu, 25 Apr 2024 16:28:01 +0200 Subject: [PATCH 1/6] N21-1677 introduce incompleteOperational --- ...rnal-tool-configuration-status.response.ts | 9 ++++- ...text-external-tool-configuration-status.ts | 3 ++ .../modules/tool/common/domain/error/index.ts | 2 +- ...atory-value-missing-loggable.exception.ts} | 8 ++--- ...-value-missing.loggable-exception.spec.ts} | 10 +++--- ...l-value-missing-loggable-exception.spec.ts | 0 ...tional-value-missing-loggable-exception.ts | 33 +++++++++++++++++++ .../src/modules/tool/common/domain/index.ts | 2 +- .../mapper/tool-status-response.mapper.ts | 1 + .../parameter-array-entry-validator.spec.ts | 4 +-- .../parameter-entry-value-validator.spec.ts | 10 ++++-- .../rules/parameter-entry-value-validator.ts | 12 +++++-- .../tool-configuration-status.service.spec.ts | 12 +++++-- .../tool-configuration-status.service.ts | 12 +++++-- 14 files changed, 94 insertions(+), 24 deletions(-) rename apps/server/src/modules/tool/common/domain/error/{tool-parameter-value-missing.loggable-exception.ts => tool-parameter-mandatory-value-missing-loggable.exception.ts} (74%) rename apps/server/src/modules/tool/common/domain/error/{tool-parameter-value-missing.loggable-exception.spec.ts => tool-parameter-mandatory-value-missing.loggable-exception.spec.ts} (65%) create mode 100644 apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.spec.ts create mode 100644 apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts diff --git a/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts b/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts index 8a4fa696b23..ed3cfab98bd 100644 --- a/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts +++ b/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts @@ -17,10 +17,16 @@ export class ContextExternalToolConfigurationStatusResponse { @ApiProperty({ type: Boolean, - description: 'True, if a configured parameter on the context external tool is missing a value', + description: 'True, if a mandatory parameter on the context external tool is missing a value', }) isIncompleteOnScopeContext: boolean; + @ApiProperty({ + type: Boolean, + description: 'True, if a optional parameter on the context external tool is missing a value', + }) + isIncompleteOperationalOnScopeContext: boolean; + @ApiProperty({ type: Boolean, description: 'Is the tool deactivated, because of superhero or school administrator', @@ -31,6 +37,7 @@ export class ContextExternalToolConfigurationStatusResponse { this.isOutdatedOnScopeSchool = props.isOutdatedOnScopeSchool; this.isOutdatedOnScopeContext = props.isOutdatedOnScopeContext; this.isIncompleteOnScopeContext = props.isIncompleteOnScopeContext; + this.isIncompleteOperationalOnScopeContext = props.isIncompleteOperationalOnScopeContext; this.isDeactivated = props.isDeactivated; } } diff --git a/apps/server/src/modules/tool/common/domain/context-external-tool-configuration-status.ts b/apps/server/src/modules/tool/common/domain/context-external-tool-configuration-status.ts index 72daab380e8..b46506f0399 100644 --- a/apps/server/src/modules/tool/common/domain/context-external-tool-configuration-status.ts +++ b/apps/server/src/modules/tool/common/domain/context-external-tool-configuration-status.ts @@ -7,10 +7,13 @@ export class ContextExternalToolConfigurationStatus { isDeactivated: boolean; + isIncompleteOperationalOnScopeContext: boolean; + constructor(props: ContextExternalToolConfigurationStatus) { this.isOutdatedOnScopeSchool = props.isOutdatedOnScopeSchool; this.isOutdatedOnScopeContext = props.isOutdatedOnScopeContext; this.isIncompleteOnScopeContext = props.isIncompleteOnScopeContext; + this.isIncompleteOperationalOnScopeContext = props.isIncompleteOperationalOnScopeContext; this.isDeactivated = props.isDeactivated; } } diff --git a/apps/server/src/modules/tool/common/domain/error/index.ts b/apps/server/src/modules/tool/common/domain/error/index.ts index 22ea23bcfd9..4a712ec7fa3 100644 --- a/apps/server/src/modules/tool/common/domain/error/index.ts +++ b/apps/server/src/modules/tool/common/domain/error/index.ts @@ -3,5 +3,5 @@ export { ToolParameterRequiredLoggableException } from './tool-parameter-require export { ToolParameterUnknownLoggableException } from './tool-parameter-unknown.loggable-exception'; export { ToolParameterValueRegexLoggableException } from './tool-parameter-value-regex.loggable-exception'; export { ToolParameterTypeMismatchLoggableException } from './tool-parameter-type-mismatch.loggable-exception'; -export { ToolParameterValueMissingLoggableException } from './tool-parameter-value-missing.loggable-exception'; +export { ToolParameterMandatoryValueMissingLoggableException } from './tool-parameter-mandatory-value-missing-loggable.exception'; export { ContextExternalToolNameAlreadyExistsLoggableException } from './context-external-tool-name-already-exists.loggable-exception'; diff --git a/apps/server/src/modules/tool/common/domain/error/tool-parameter-value-missing.loggable-exception.ts b/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing-loggable.exception.ts similarity index 74% rename from apps/server/src/modules/tool/common/domain/error/tool-parameter-value-missing.loggable-exception.ts rename to apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing-loggable.exception.ts index b3569357fe0..901b0c9bc9a 100644 --- a/apps/server/src/modules/tool/common/domain/error/tool-parameter-value-missing.loggable-exception.ts +++ b/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing-loggable.exception.ts @@ -4,13 +4,13 @@ import { EntityId } from '@shared/domain/types'; import { HttpStatus } from '@nestjs/common'; import { CustomParameter } from '../custom-parameter.do'; -export class ToolParameterValueMissingLoggableException extends BusinessError implements Loggable { +export class ToolParameterMandatoryValueMissingLoggableException extends BusinessError implements Loggable { constructor(private readonly validatableToolId: EntityId | undefined, private readonly parameter: CustomParameter) { super( { - type: 'TOOL_PARAMETER_VALUE_MISSING', - title: 'Missing tool parameter value', - defaultMessage: 'The parameter has no value.', + type: 'TOOL_PARAMETER_MANDATORY_VALUE_MISSING', + title: 'Missing mandatory tool parameter value', + defaultMessage: 'The mandatory parameter has no value.', }, HttpStatus.BAD_REQUEST, { diff --git a/apps/server/src/modules/tool/common/domain/error/tool-parameter-value-missing.loggable-exception.spec.ts b/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing.loggable-exception.spec.ts similarity index 65% rename from apps/server/src/modules/tool/common/domain/error/tool-parameter-value-missing.loggable-exception.spec.ts rename to apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing.loggable-exception.spec.ts index 44a0ac62e26..3ee5d61593c 100644 --- a/apps/server/src/modules/tool/common/domain/error/tool-parameter-value-missing.loggable-exception.spec.ts +++ b/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing.loggable-exception.spec.ts @@ -1,16 +1,14 @@ import { customParameterFactory } from '@shared/testing'; import { CustomParameter } from '../custom-parameter.do'; -import { ToolParameterValueMissingLoggableException } from './tool-parameter-value-missing.loggable-exception'; +import { ToolParameterMandatoryValueMissingLoggableException } from './tool-parameter-mandatory-value-missing-loggable.exception'; -describe(ToolParameterValueMissingLoggableException.name, () => { +describe(ToolParameterMandatoryValueMissingLoggableException.name, () => { describe('getLogMessage', () => { const setup = () => { const parameter: CustomParameter = customParameterFactory.build(); - const exception: ToolParameterValueMissingLoggableException = new ToolParameterValueMissingLoggableException( - 'toolId', - parameter - ); + const exception: ToolParameterMandatoryValueMissingLoggableException = + new ToolParameterMandatoryValueMissingLoggableException('toolId', parameter); return { parameter, diff --git a/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.spec.ts b/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.spec.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts b/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts new file mode 100644 index 00000000000..aa2a2e12600 --- /dev/null +++ b/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts @@ -0,0 +1,33 @@ +import { HttpStatus } from '@nestjs/common'; +import { BusinessError } from '@shared/common'; +import { ErrorLogMessage, Loggable, LogMessage, ValidationErrorLogMessage } from '@src/core/logger'; +import { EntityId } from '@shared/domain/types'; +import { CustomParameter } from '../custom-parameter.do'; + +export class ToolParameterOptionalValueMissingLoggableException extends BusinessError implements Loggable { + constructor(private readonly validatableToolId: EntityId | undefined, private readonly parameter: CustomParameter) { + super( + { + type: 'VALUE_MISSING_ON_OPTIONAL_TOOL_PARAMETER', + title: 'Missing value on optional tool parameter', + defaultMessage: 'The optional parameter has no value.', + }, + HttpStatus.BAD_REQUEST, + { + parameter, + validatableToolId, + } + ); + } + + getLogMessage(): LogMessage | ErrorLogMessage | ValidationErrorLogMessage { + return { + type: this.type, + message: this.message, + data: { + parameterName: this.parameter.name, + validatableToolId: this.validatableToolId, + }, + }; + } +} diff --git a/apps/server/src/modules/tool/common/domain/index.ts b/apps/server/src/modules/tool/common/domain/index.ts index be02ad54afe..55f7ca2d68e 100644 --- a/apps/server/src/modules/tool/common/domain/index.ts +++ b/apps/server/src/modules/tool/common/domain/index.ts @@ -4,7 +4,7 @@ export { ToolParameterUnknownLoggableException, ToolParameterValueRegexLoggableException, ToolParameterTypeMismatchLoggableException, - ToolParameterValueMissingLoggableException, + ToolParameterMandatoryValueMissingLoggableException, ContextExternalToolNameAlreadyExistsLoggableException, } from './error'; export * from './custom-parameter.do'; diff --git a/apps/server/src/modules/tool/common/mapper/tool-status-response.mapper.ts b/apps/server/src/modules/tool/common/mapper/tool-status-response.mapper.ts index 665da76b84b..8822b2ad1a0 100644 --- a/apps/server/src/modules/tool/common/mapper/tool-status-response.mapper.ts +++ b/apps/server/src/modules/tool/common/mapper/tool-status-response.mapper.ts @@ -8,6 +8,7 @@ export class ToolStatusResponseMapper { isOutdatedOnScopeSchool: status.isOutdatedOnScopeSchool, isOutdatedOnScopeContext: status.isOutdatedOnScopeContext, isIncompleteOnScopeContext: status.isIncompleteOnScopeContext, + isIncompleteOperationalOnScopeContext: status.isIncompleteOperationalOnScopeContext, isDeactivated: status.isDeactivated, }); diff --git a/apps/server/src/modules/tool/common/service/validation/rules/parameter-array-entry-validator.spec.ts b/apps/server/src/modules/tool/common/service/validation/rules/parameter-array-entry-validator.spec.ts index aa9c5ea2114..6704abe4857 100644 --- a/apps/server/src/modules/tool/common/service/validation/rules/parameter-array-entry-validator.spec.ts +++ b/apps/server/src/modules/tool/common/service/validation/rules/parameter-array-entry-validator.spec.ts @@ -4,7 +4,7 @@ import { CustomParameter, CustomParameterEntry, ToolParameterRequiredLoggableException, - ToolParameterValueMissingLoggableException, + ToolParameterMandatoryValueMissingLoggableException, } from '../../../domain'; import { ParameterArrayEntryValidator } from './parameter-array-entry-validator'; @@ -83,7 +83,7 @@ describe(ParameterArrayEntryValidator.name, () => { const result: ValidationError[] = new ParameterArrayEntryValidator().validate(entries, declarations, undefined); - expect(result[0]).toBeInstanceOf(ToolParameterValueMissingLoggableException); + expect(result[0]).toBeInstanceOf(ToolParameterMandatoryValueMissingLoggableException); }); }); }); diff --git a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts index 8acc86f8a7b..eabc146a659 100644 --- a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts +++ b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts @@ -1,6 +1,10 @@ import { ValidationError } from '@shared/common'; import { customParameterFactory } from '@shared/testing'; -import { CustomParameter, CustomParameterEntry, ToolParameterValueMissingLoggableException } from '../../../domain'; +import { + CustomParameter, + CustomParameterEntry, + ToolParameterMandatoryValueMissingLoggableException, +} from '../../../domain'; import { ParameterEntryValueValidator } from './parameter-entry-value-validator'; describe(ParameterEntryValueValidator.name, () => { @@ -51,7 +55,7 @@ describe(ParameterEntryValueValidator.name, () => { const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); - expect(result[0]).toBeInstanceOf(ToolParameterValueMissingLoggableException); + expect(result[0]).toBeInstanceOf(ToolParameterMandatoryValueMissingLoggableException); }); }); @@ -75,7 +79,7 @@ describe(ParameterEntryValueValidator.name, () => { const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); - expect(result[0]).toBeInstanceOf(ToolParameterValueMissingLoggableException); + expect(result[0]).toBeInstanceOf(ToolParameterMandatoryValueMissingLoggableException); }); }); }); diff --git a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts index ba88e74725b..4700443594c 100644 --- a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts +++ b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts @@ -1,6 +1,11 @@ import { ValidationError } from '@shared/common'; import { EntityId } from '@shared/domain/types'; -import { CustomParameter, CustomParameterEntry, ToolParameterValueMissingLoggableException } from '../../../domain'; +import { + CustomParameter, + CustomParameterEntry, + ToolParameterMandatoryValueMissingLoggableException, +} from '../../../domain'; +import { ToolParameterOptionalValueMissingLoggableException } from '../../../domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { ParameterEntryValidator } from './parameter-entry-validator'; export class ParameterEntryValueValidator implements ParameterEntryValidator { @@ -10,7 +15,10 @@ export class ParameterEntryValueValidator implements ParameterEntryValidator { toolId: EntityId | undefined ): ValidationError[] { if (entry.value === undefined || entry.value === '') { - return [new ToolParameterValueMissingLoggableException(toolId, declaration)]; + if (declaration.isOptional) { + return [new ToolParameterOptionalValueMissingLoggableException(toolId, declaration)]; + } + return [new ToolParameterMandatoryValueMissingLoggableException(toolId, declaration)]; } return []; diff --git a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts index d4c6d4a55b4..044ca358d21 100644 --- a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts +++ b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts @@ -10,7 +10,7 @@ import { import { ContextExternalToolConfigurationStatus, ToolParameterDuplicateLoggableException, - ToolParameterValueMissingLoggableException, + ToolParameterMandatoryValueMissingLoggableException, } from '../../common/domain'; import { CommonToolValidationService } from '../../common/service'; import { ToolConfigurationStatusService } from './tool-configuration-status.service'; @@ -77,6 +77,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: false, isOutdatedOnScopeContext: false, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: false, }); }); @@ -131,6 +132,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: true, isOutdatedOnScopeContext: false, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: false, }); }); @@ -185,6 +187,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: false, isOutdatedOnScopeContext: true, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: false, }); }); @@ -239,6 +242,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: true, isOutdatedOnScopeContext: true, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: false, }); }); @@ -273,7 +277,7 @@ describe(ToolConfigurationStatusService.name, () => { commonToolValidationService.validateParameters.mockReturnValueOnce([]); commonToolValidationService.validateParameters.mockReturnValueOnce([ - new ToolParameterValueMissingLoggableException(undefined, customParameter), + new ToolParameterMandatoryValueMissingLoggableException(undefined, customParameter), new ToolParameterDuplicateLoggableException(undefined, customParameter.name), ]); @@ -297,6 +301,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: false, isOutdatedOnScopeContext: true, isIncompleteOnScopeContext: true, + isIncompleteOperationalOnScopeContext: true, isDeactivated: false, }); }); @@ -336,6 +341,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: true, isOutdatedOnScopeContext: true, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: true, }); }); @@ -374,6 +380,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: true, isOutdatedOnScopeContext: true, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: true, }); }); @@ -412,6 +419,7 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: true, isOutdatedOnScopeContext: true, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: false, }); }); diff --git a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts index a5c4868ba25..fb11bd82d62 100644 --- a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts +++ b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts @@ -2,8 +2,9 @@ import { Injectable } from '@nestjs/common/decorators/core/injectable.decorator' import { ValidationError } from '@shared/common'; import { ContextExternalToolConfigurationStatus, - ToolParameterValueMissingLoggableException, + ToolParameterMandatoryValueMissingLoggableException, } from '../../common/domain'; +import { ToolParameterOptionalValueMissingLoggableException } from '../../common/domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { CommonToolValidationService } from '../../common/service'; import { ExternalTool } from '../../external-tool/domain'; import { SchoolExternalTool } from '../../school-external-tool/domain'; @@ -21,6 +22,7 @@ export class ToolConfigurationStatusService { const configurationStatus: ContextExternalToolConfigurationStatus = new ContextExternalToolConfigurationStatus({ isOutdatedOnScopeContext: false, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isOutdatedOnScopeSchool: false, isDeactivated: this.isToolDeactivated(externalTool, schoolExternalTool), }); @@ -44,10 +46,16 @@ export class ToolConfigurationStatusService { if ( contextParameterErrors.some( - (error: ValidationError) => error instanceof ToolParameterValueMissingLoggableException + (error: ValidationError) => error instanceof ToolParameterMandatoryValueMissingLoggableException ) ) { configurationStatus.isIncompleteOnScopeContext = true; + } else if ( + contextParameterErrors.some( + (error: ValidationError) => error instanceof ToolParameterOptionalValueMissingLoggableException + ) + ) { + configurationStatus.isIncompleteOperationalOnScopeContext = true; } } From 3117fec4ed2d26db0fd65f8e6aba4442e5fbeed7 Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Fri, 26 Apr 2024 08:51:01 +0200 Subject: [PATCH 2/6] N21-1677 exceptions + tests --- ...y-value-missing.loggable-exception.spec.ts | 4 +- ...l-value-missing-loggable-exception.spec.ts | 35 ++++++ ...tional-value-missing-loggable-exception.ts | 1 + .../parameter-entry-value-validator.spec.ts | 118 +++++++++++++----- .../tool-configuration-status.service.spec.ts | 46 ++++++- ...l-configuration-status-response.factory.ts | 1 + .../tool/tool-configuration-status.factory.ts | 1 + 7 files changed, 172 insertions(+), 34 deletions(-) diff --git a/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing.loggable-exception.spec.ts b/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing.loggable-exception.spec.ts index 3ee5d61593c..1dc12574766 100644 --- a/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing.loggable-exception.spec.ts +++ b/apps/server/src/modules/tool/common/domain/error/tool-parameter-mandatory-value-missing.loggable-exception.spec.ts @@ -22,8 +22,8 @@ describe(ToolParameterMandatoryValueMissingLoggableException.name, () => { const result = exception.getLogMessage(); expect(result).toEqual({ - type: 'TOOL_PARAMETER_VALUE_MISSING', - message: 'The parameter has no value.', + type: 'TOOL_PARAMETER_MANDATORY_VALUE_MISSING', + message: 'The mandatory parameter has no value.', stack: exception.stack, data: { parameterName: parameter.name, diff --git a/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.spec.ts b/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.spec.ts index e69de29bb2d..2c047219822 100644 --- a/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.spec.ts +++ b/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.spec.ts @@ -0,0 +1,35 @@ +import { customParameterFactory } from '@shared/testing'; +import { CustomParameter } from '../custom-parameter.do'; +import { ToolParameterOptionalValueMissingLoggableException } from './tool-parameter-optional-value-missing-loggable-exception'; + +describe(ToolParameterOptionalValueMissingLoggableException.name, () => { + describe('getLogMessage', () => { + const setup = () => { + const parameter: CustomParameter = customParameterFactory.build(); + + const exception: ToolParameterOptionalValueMissingLoggableException = + new ToolParameterOptionalValueMissingLoggableException('toolId', parameter); + + return { + parameter, + exception, + }; + }; + + it('should return log message', () => { + const { exception, parameter } = setup(); + + const result = exception.getLogMessage(); + + expect(result).toStrictEqual({ + type: 'VALUE_MISSING_ON_OPTIONAL_TOOL_PARAMETER', + message: 'The optional parameter has no value.', + stack: exception.stack, + data: { + parameterName: parameter.name, + validatableToolId: 'toolId', + }, + }); + }); + }); +}); diff --git a/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts b/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts index aa2a2e12600..203987dce0b 100644 --- a/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts +++ b/apps/server/src/modules/tool/common/domain/error/tool-parameter-optional-value-missing-loggable-exception.ts @@ -24,6 +24,7 @@ export class ToolParameterOptionalValueMissingLoggableException extends Business return { type: this.type, message: this.message, + stack: this.stack, data: { parameterName: this.parameter.name, validatableToolId: this.validatableToolId, diff --git a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts index eabc146a659..427aa51e1e1 100644 --- a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts +++ b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts @@ -5,6 +5,7 @@ import { CustomParameterEntry, ToolParameterMandatoryValueMissingLoggableException, } from '../../../domain'; +import { ToolParameterOptionalValueMissingLoggableException } from '../../../domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { ParameterEntryValueValidator } from './parameter-entry-value-validator'; describe(ParameterEntryValueValidator.name, () => { @@ -34,52 +35,107 @@ describe(ParameterEntryValueValidator.name, () => { }); }); - describe('when the parameter value is an empty string', () => { - const setup = () => { - const declaration: CustomParameter = customParameterFactory.build({ - name: 'param1', - }); - const entry: CustomParameterEntry = new CustomParameterEntry({ - name: 'param1', - value: '', + describe('when parameter is mandatory', () => { + describe('when the parameter value is an empty string', () => { + const setup = () => { + const declaration: CustomParameter = customParameterFactory.build({ + name: 'param1', + }); + const entry: CustomParameterEntry = new CustomParameterEntry({ + name: 'param1', + value: '', + }); + + return { + entry, + declaration, + }; + }; + + it('should return a validation error', () => { + const { entry, declaration } = setup(); + + const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); + + expect(result[0]).toBeInstanceOf(ToolParameterMandatoryValueMissingLoggableException); }); + }); - return { - entry, - declaration, + describe('when the parameter value is undefined', () => { + const setup = () => { + const declaration: CustomParameter = customParameterFactory.build({ + name: 'param1', + }); + const entry: CustomParameterEntry = new CustomParameterEntry({ + name: 'param1', + }); + + return { + entry, + declaration, + }; }; - }; - it('should return a validation error', () => { - const { entry, declaration } = setup(); + it('should return a validation error', () => { + const { entry, declaration } = setup(); - const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); + const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); - expect(result[0]).toBeInstanceOf(ToolParameterMandatoryValueMissingLoggableException); + expect(result[0]).toBeInstanceOf(ToolParameterMandatoryValueMissingLoggableException); + }); }); }); - describe('when the parameter value is undefined', () => { - const setup = () => { - const declaration: CustomParameter = customParameterFactory.build({ - name: 'param1', - }); - const entry: CustomParameterEntry = new CustomParameterEntry({ - name: 'param1', + describe('when parameter is optional', () => { + describe('when the parameter value is an empty string', () => { + const setup = () => { + const declaration: CustomParameter = customParameterFactory.build({ + name: 'param1', + isOptional: true, + }); + const entry: CustomParameterEntry = new CustomParameterEntry({ + name: 'param1', + value: '', + }); + + return { + entry, + declaration, + }; + }; + + it('should return a validation error', () => { + const { entry, declaration } = setup(); + + const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); + + expect(result[0]).toBeInstanceOf(ToolParameterOptionalValueMissingLoggableException); }); + }); - return { - entry, - declaration, + describe('when the parameter value is undefined', () => { + const setup = () => { + const declaration: CustomParameter = customParameterFactory.build({ + name: 'param1', + isOptional: true, + }); + const entry: CustomParameterEntry = new CustomParameterEntry({ + name: 'param1', + }); + + return { + entry, + declaration, + }; }; - }; - it('should return a validation error', () => { - const { entry, declaration } = setup(); + it('should return a validation error', () => { + const { entry, declaration } = setup(); - const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); + const result: ValidationError[] = new ParameterEntryValueValidator().validate(entry, declaration, undefined); - expect(result[0]).toBeInstanceOf(ToolParameterMandatoryValueMissingLoggableException); + expect(result[0]).toBeInstanceOf(ToolParameterOptionalValueMissingLoggableException); + }); }); }); }); diff --git a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts index 044ca358d21..c75d333f2fd 100644 --- a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts +++ b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts @@ -12,6 +12,7 @@ import { ToolParameterDuplicateLoggableException, ToolParameterMandatoryValueMissingLoggableException, } from '../../common/domain'; +import { ToolParameterOptionalValueMissingLoggableException } from '../../common/domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { CommonToolValidationService } from '../../common/service'; import { ToolConfigurationStatusService } from './tool-configuration-status.service'; @@ -264,7 +265,7 @@ describe(ToolConfigurationStatusService.name, () => { }); }); - describe('when validation of ContextExternalTool throws at least 1 missing value errors', () => { + describe('when validation of ContextExternalTool throws at least 1 missing value on mandatory parameter errors', () => { const setup = () => { const customParameter = customParameterFactory.build(); const externalTool = externalToolFactory.buildWithId({ parameters: [customParameter] }); @@ -301,6 +302,49 @@ describe(ToolConfigurationStatusService.name, () => { isOutdatedOnScopeSchool: false, isOutdatedOnScopeContext: true, isIncompleteOnScopeContext: true, + isIncompleteOperationalOnScopeContext: false, + isDeactivated: false, + }); + }); + }); + + describe('when validation of ContextExternalTool throws at least 1 missing value on optional parameter errors', () => { + const setup = () => { + const customParameter = customParameterFactory.build(); + const externalTool = externalToolFactory.buildWithId({ parameters: [customParameter] }); + const schoolExternalTool = schoolExternalToolFactory.buildWithId({ + toolId: externalTool.id as string, + }); + const contextExternalTool = contextExternalToolFactory + .withSchoolExternalToolRef(schoolExternalTool.id as string) + .buildWithId(); + + commonToolValidationService.validateParameters.mockReturnValueOnce([]); + commonToolValidationService.validateParameters.mockReturnValueOnce([ + new ToolParameterOptionalValueMissingLoggableException(undefined, customParameter), + new ToolParameterDuplicateLoggableException(undefined, customParameter.name), + ]); + + return { + externalTool, + schoolExternalTool, + contextExternalTool, + }; + }; + + it('should return incomplete operational as tool status', () => { + const { externalTool, schoolExternalTool, contextExternalTool } = setup(); + + const status: ContextExternalToolConfigurationStatus = service.determineToolConfigurationStatus( + externalTool, + schoolExternalTool, + contextExternalTool + ); + + expect(status).toEqual({ + isOutdatedOnScopeSchool: false, + isOutdatedOnScopeContext: true, + isIncompleteOnScopeContext: false, isIncompleteOperationalOnScopeContext: true, isDeactivated: false, }); diff --git a/apps/server/src/shared/testing/factory/context-external-tool-configuration-status-response.factory.ts b/apps/server/src/shared/testing/factory/context-external-tool-configuration-status-response.factory.ts index 9954fd3797f..2075119bf72 100644 --- a/apps/server/src/shared/testing/factory/context-external-tool-configuration-status-response.factory.ts +++ b/apps/server/src/shared/testing/factory/context-external-tool-configuration-status-response.factory.ts @@ -7,6 +7,7 @@ export const contextExternalToolConfigurationStatusResponseFactory = isOutdatedOnScopeContext: false, isOutdatedOnScopeSchool: false, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: false, }; }); diff --git a/apps/server/src/shared/testing/factory/domainobject/tool/tool-configuration-status.factory.ts b/apps/server/src/shared/testing/factory/domainobject/tool/tool-configuration-status.factory.ts index 838c57978c6..64fed88854c 100644 --- a/apps/server/src/shared/testing/factory/domainobject/tool/tool-configuration-status.factory.ts +++ b/apps/server/src/shared/testing/factory/domainobject/tool/tool-configuration-status.factory.ts @@ -6,6 +6,7 @@ export const toolConfigurationStatusFactory = Factory.define Date: Tue, 30 Apr 2024 07:45:02 +0200 Subject: [PATCH 3/6] N21-1677 logic + tests --- .../tool-configuration-status.service.spec.ts | 45 +++++++++++++++++++ .../tool-configuration-status.service.ts | 29 ++++++++---- ...status-outdated.loggable-exception.spec.ts | 4 ++ ...tool-status-outdated.loggable-exception.ts | 5 +++ .../service/tool-launch.service.spec.ts | 3 +- .../service/tool-launch.service.ts | 9 +++- 6 files changed, 84 insertions(+), 11 deletions(-) diff --git a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts index c75d333f2fd..159bc3bedb5 100644 --- a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts +++ b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts @@ -280,6 +280,7 @@ describe(ToolConfigurationStatusService.name, () => { commonToolValidationService.validateParameters.mockReturnValueOnce([ new ToolParameterMandatoryValueMissingLoggableException(undefined, customParameter), new ToolParameterDuplicateLoggableException(undefined, customParameter.name), + new ToolParameterOptionalValueMissingLoggableException(undefined, customParameter), ]); return { @@ -351,6 +352,50 @@ describe(ToolConfigurationStatusService.name, () => { }); }); + describe('when validation of ContextExternalTool throws only missing value on optional parameter errors', () => { + const setup = () => { + const customParameter = customParameterFactory.build(); + const externalTool = externalToolFactory.buildWithId({ parameters: [customParameter] }); + const schoolExternalTool = schoolExternalToolFactory.buildWithId({ + toolId: externalTool.id as string, + }); + const contextExternalTool = contextExternalToolFactory + .withSchoolExternalToolRef(schoolExternalTool.id as string) + .buildWithId(); + + commonToolValidationService.validateParameters.mockReturnValueOnce([]); + commonToolValidationService.validateParameters.mockReturnValueOnce([ + new ToolParameterOptionalValueMissingLoggableException(undefined, customParameter), + new ToolParameterOptionalValueMissingLoggableException(undefined, customParameter), + new ToolParameterOptionalValueMissingLoggableException(undefined, customParameter), + ]); + + return { + externalTool, + schoolExternalTool, + contextExternalTool, + }; + }; + + it('should return incomplete operational as tool status', () => { + const { externalTool, schoolExternalTool, contextExternalTool } = setup(); + + const status: ContextExternalToolConfigurationStatus = service.determineToolConfigurationStatus( + externalTool, + schoolExternalTool, + contextExternalTool + ); + + expect(status).toEqual({ + isOutdatedOnScopeSchool: false, + isOutdatedOnScopeContext: false, + isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: true, + isDeactivated: false, + }); + }); + }); + describe('when SchoolExternalTool is deactivated', () => { const setup = () => { const externalTool = externalToolFactory.buildWithId(); diff --git a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts index fb11bd82d62..9508d56aaa1 100644 --- a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts +++ b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts @@ -50,11 +50,10 @@ export class ToolConfigurationStatusService { ) ) { configurationStatus.isIncompleteOnScopeContext = true; - } else if ( - contextParameterErrors.some( - (error: ValidationError) => error instanceof ToolParameterOptionalValueMissingLoggableException - ) - ) { + } else if (this.isIncompleteOperational(contextParameterErrors) && !this.isOutdated(contextParameterErrors)) { + configurationStatus.isIncompleteOperationalOnScopeContext = true; + configurationStatus.isOutdatedOnScopeContext = false; + } else if (this.isIncompleteOperational(contextParameterErrors) && this.isOutdated(contextParameterErrors)) { configurationStatus.isIncompleteOperationalOnScopeContext = true; } } @@ -63,10 +62,22 @@ export class ToolConfigurationStatusService { } private isToolDeactivated(externalTool: ExternalTool, schoolExternalTool: SchoolExternalTool) { - if (externalTool.isDeactivated || (schoolExternalTool.status && schoolExternalTool.status.isDeactivated)) { - return true; - } + return !!(externalTool.isDeactivated || (schoolExternalTool.status && schoolExternalTool.status.isDeactivated)); + } + + private isIncompleteOperational(errors: ValidationError[]) { + return errors.some((error: ValidationError) => error instanceof ToolParameterOptionalValueMissingLoggableException); + } + + private isOutdated(contextParameterErrors: ValidationError[]): boolean { + const parameterWithoutOptional: ValidationError[] = contextParameterErrors.filter( + (error: ValidationError) => !this.isOptional(error) + ); + + return parameterWithoutOptional.length > 0; + } - return false; + isOptional(error: ValidationError): boolean { + return error instanceof ToolParameterOptionalValueMissingLoggableException; } } diff --git a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.spec.ts b/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.spec.ts index 814dfad394c..6c9346143f4 100644 --- a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.spec.ts +++ b/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.spec.ts @@ -13,6 +13,8 @@ describe('ToolStatusOutdatedLoggableException', () => { toolId, toolConfigStatus.isOutdatedOnScopeSchool, toolConfigStatus.isOutdatedOnScopeContext, + toolConfigStatus.isIncompleteOnScopeContext, + toolConfigStatus.isIncompleteOperationalOnScopeContext, toolConfigStatus.isDeactivated ); @@ -35,6 +37,8 @@ describe('ToolStatusOutdatedLoggableException', () => { toolId: 'toolId', isOutdatedOnScopeSchool: false, isOutdatedOnScopeContext: false, + isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: false, }, }); diff --git a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts b/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts index 84b358e2ec6..ab62ab6377e 100644 --- a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts +++ b/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts @@ -8,6 +8,8 @@ export class ToolStatusOutdatedLoggableException extends BadRequestException imp private readonly toolId: EntityId, private readonly isOutdatedOnScopeSchool: boolean, private readonly isOutdatedOnScopeContext: boolean, + private readonly isIncompleteOnScopeContext: boolean, + private readonly isIncompleteOperationalOnScopeContext: boolean, private readonly isDeactivated: boolean ) { super(); @@ -15,6 +17,7 @@ export class ToolStatusOutdatedLoggableException extends BadRequestException imp getLogMessage(): LogMessage | ErrorLogMessage | ValidationErrorLogMessage { return { + // TODO refactor exception to status not launchable type: 'TOOL_STATUS_OUTDATED', message: 'The status of the tool is outdated and cannot be launched by the user.', stack: this.stack, @@ -23,6 +26,8 @@ export class ToolStatusOutdatedLoggableException extends BadRequestException imp toolId: this.toolId, isOutdatedOnScopeSchool: this.isOutdatedOnScopeSchool, isOutdatedOnScopeContext: this.isOutdatedOnScopeContext, + isIncompleteOnScopeContext: this.isIncompleteOnScopeContext, + isIncompleteOperationalOnScopeContext: this.isIncompleteOperationalOnScopeContext, isDeactivated: this.isDeactivated, }, }; diff --git a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts index 8d20046076f..8e8bddb6beb 100644 --- a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts +++ b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts @@ -236,6 +236,7 @@ describe('ToolLaunchService', () => { isOutdatedOnScopeContext: true, isOutdatedOnScopeSchool: true, isIncompleteOnScopeContext: false, + isIncompleteOperationalOnScopeContext: false, isDeactivated: true, }) ); @@ -253,7 +254,7 @@ describe('ToolLaunchService', () => { const func = () => service.getLaunchData(userId, launchParams.contextExternalTool); await expect(func).rejects.toThrow( - new ToolStatusOutdatedLoggableException(userId, contextExternalToolId, true, true, true) + new ToolStatusOutdatedLoggableException(userId, contextExternalToolId, true, true, false, false, true) ); }); }); diff --git a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts index 362dec70c21..1b0a15b02e5 100644 --- a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts +++ b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts @@ -96,12 +96,19 @@ export class ToolLaunchService { contextExternalTool ); - if (status.isOutdatedOnScopeSchool || status.isOutdatedOnScopeContext || status.isDeactivated) { + if ( + status.isOutdatedOnScopeSchool || + status.isOutdatedOnScopeContext || + status.isDeactivated || + status.isIncompleteOnScopeContext + ) { throw new ToolStatusOutdatedLoggableException( userId, contextExternalTool.id ?? '', status.isOutdatedOnScopeSchool, status.isOutdatedOnScopeContext, + status.isIncompleteOnScopeContext, + status.isIncompleteOperationalOnScopeContext, status.isDeactivated ); } From 69d694e02709e6c73b1305f01d244c08bebdeb4c Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Tue, 30 Apr 2024 08:14:15 +0200 Subject: [PATCH 4/6] N21-1677 imports + barrel --- apps/server/src/modules/tool/common/domain/error/index.ts | 1 + apps/server/src/modules/tool/common/domain/index.ts | 1 + .../validation/rules/parameter-entry-value-validator.spec.ts | 2 +- .../service/validation/rules/parameter-entry-value-validator.ts | 2 +- .../service/tool-configuration-status.service.spec.ts | 2 +- .../service/tool-configuration-status.service.ts | 2 +- .../error/tool-status-outdated.loggable-exception.ts | 1 - 7 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/server/src/modules/tool/common/domain/error/index.ts b/apps/server/src/modules/tool/common/domain/error/index.ts index 4a712ec7fa3..d9913ba0510 100644 --- a/apps/server/src/modules/tool/common/domain/error/index.ts +++ b/apps/server/src/modules/tool/common/domain/error/index.ts @@ -5,3 +5,4 @@ export { ToolParameterValueRegexLoggableException } from './tool-parameter-value export { ToolParameterTypeMismatchLoggableException } from './tool-parameter-type-mismatch.loggable-exception'; export { ToolParameterMandatoryValueMissingLoggableException } from './tool-parameter-mandatory-value-missing-loggable.exception'; export { ContextExternalToolNameAlreadyExistsLoggableException } from './context-external-tool-name-already-exists.loggable-exception'; +export { ToolParameterOptionalValueMissingLoggableException } from './tool-parameter-optional-value-missing-loggable-exception'; diff --git a/apps/server/src/modules/tool/common/domain/index.ts b/apps/server/src/modules/tool/common/domain/index.ts index 55f7ca2d68e..2deae9c5f56 100644 --- a/apps/server/src/modules/tool/common/domain/index.ts +++ b/apps/server/src/modules/tool/common/domain/index.ts @@ -5,6 +5,7 @@ export { ToolParameterValueRegexLoggableException, ToolParameterTypeMismatchLoggableException, ToolParameterMandatoryValueMissingLoggableException, + ToolParameterOptionalValueMissingLoggableException, ContextExternalToolNameAlreadyExistsLoggableException, } from './error'; export * from './custom-parameter.do'; diff --git a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts index 427aa51e1e1..4784f3054c8 100644 --- a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts +++ b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.spec.ts @@ -4,8 +4,8 @@ import { CustomParameter, CustomParameterEntry, ToolParameterMandatoryValueMissingLoggableException, + ToolParameterOptionalValueMissingLoggableException, } from '../../../domain'; -import { ToolParameterOptionalValueMissingLoggableException } from '../../../domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { ParameterEntryValueValidator } from './parameter-entry-value-validator'; describe(ParameterEntryValueValidator.name, () => { diff --git a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts index 4700443594c..191367d7c8f 100644 --- a/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts +++ b/apps/server/src/modules/tool/common/service/validation/rules/parameter-entry-value-validator.ts @@ -4,8 +4,8 @@ import { CustomParameter, CustomParameterEntry, ToolParameterMandatoryValueMissingLoggableException, + ToolParameterOptionalValueMissingLoggableException, } from '../../../domain'; -import { ToolParameterOptionalValueMissingLoggableException } from '../../../domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { ParameterEntryValidator } from './parameter-entry-validator'; export class ParameterEntryValueValidator implements ParameterEntryValidator { diff --git a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts index 159bc3bedb5..a73384fed12 100644 --- a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts +++ b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.spec.ts @@ -11,8 +11,8 @@ import { ContextExternalToolConfigurationStatus, ToolParameterDuplicateLoggableException, ToolParameterMandatoryValueMissingLoggableException, + ToolParameterOptionalValueMissingLoggableException, } from '../../common/domain'; -import { ToolParameterOptionalValueMissingLoggableException } from '../../common/domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { CommonToolValidationService } from '../../common/service'; import { ToolConfigurationStatusService } from './tool-configuration-status.service'; diff --git a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts index 9508d56aaa1..56c02af20af 100644 --- a/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts +++ b/apps/server/src/modules/tool/context-external-tool/service/tool-configuration-status.service.ts @@ -3,8 +3,8 @@ import { ValidationError } from '@shared/common'; import { ContextExternalToolConfigurationStatus, ToolParameterMandatoryValueMissingLoggableException, + ToolParameterOptionalValueMissingLoggableException, } from '../../common/domain'; -import { ToolParameterOptionalValueMissingLoggableException } from '../../common/domain/error/tool-parameter-optional-value-missing-loggable-exception'; import { CommonToolValidationService } from '../../common/service'; import { ExternalTool } from '../../external-tool/domain'; import { SchoolExternalTool } from '../../school-external-tool/domain'; diff --git a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts b/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts index ab62ab6377e..bc0f7f23f66 100644 --- a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts +++ b/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts @@ -17,7 +17,6 @@ export class ToolStatusOutdatedLoggableException extends BadRequestException imp getLogMessage(): LogMessage | ErrorLogMessage | ValidationErrorLogMessage { return { - // TODO refactor exception to status not launchable type: 'TOOL_STATUS_OUTDATED', message: 'The status of the tool is outdated and cannot be launched by the user.', stack: this.stack, From 7b345756107d2092acaecdfd401d379a7d20bb44 Mon Sep 17 00:00:00 2001 From: Malte Berg Date: Mon, 6 May 2024 09:55:52 +0200 Subject: [PATCH 5/6] add ctl seed data --- backup/setup/external-tools.json | 44 +++++++++++++++++++++++++ backup/setup/school-external-tools.json | 24 ++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/backup/setup/external-tools.json b/backup/setup/external-tools.json index a503656bd01..f838e056f99 100644 --- a/backup/setup/external-tools.json +++ b/backup/setup/external-tools.json @@ -420,6 +420,50 @@ "version": 1, "isDeactivated": false }, + { + "_id": { + "$oid": "65fc0fcda519d4a3b71193e0" + }, + "createdAt": { + "$date": { + "$numberLong": "1701358084733" + } + }, + "updatedAt": { + "$date": { + "$numberLong": "1701358362888" + } + }, + "name": "CY Test Tool Optional Protected Parameter", + "config_type": "basic", + "config_baseUrl": "https://google.com/search", + "parameters": [ + { + "name": "search", + "displayName": "Suchparameter", + "description": "Danch wird gesucht", + "scope": "context", + "location": "query", + "type": "string", + "isOptional": false, + "isProtected": false + }, + { + "name": "protected", + "displayName": "geschützter Parameter", + "description": "Dieser parameter wird nicht mitkopiert", + "scope": "context", + "location": "query", + "type": "string", + "isOptional": true, + "isProtected": true + } + ], + "isHidden": false, + "openNewTab": false, + "version": 1, + "isDeactivated": false + }, { "_id": { "$oid": "65f958bdd8b35469f14032b1" diff --git a/backup/setup/school-external-tools.json b/backup/setup/school-external-tools.json index 722bb9d7c50..96dd5f72cf6 100644 --- a/backup/setup/school-external-tools.json +++ b/backup/setup/school-external-tools.json @@ -266,6 +266,30 @@ "isOutdatedOnScopeSchool": false } }, + { + "createdAt": { + "$date": { + "$numberLong": "1701358140061" + } + }, + "updatedAt": { + "$date": { + "$numberLong": "1701358140061" + } + }, + "tool": { + "$oid": "65fc0fcda519d4a3b71193e0" + }, + "school": { + "$oid": "5fa2c5ccb229544f2c69666c" + }, + "schoolParameters": [], + "toolVersion": 1, + "status": { + "isDeactivated": false, + "isOutdatedOnScopeSchool": false + } + }, { "_id": { "$oid": "65fd74c4d1c1ddf3bb2b05de" From 104306b08a3ad40ed97dfc79c57729db329663bf Mon Sep 17 00:00:00 2001 From: Mrika Llabani Date: Mon, 6 May 2024 10:05:30 +0200 Subject: [PATCH 6/6] N21-1677 review changes + rename exc --- ...text-external-tool-configuration-status.response.ts | 3 ++- .../server/src/modules/tool/tool-launch/error/index.ts | 2 +- ...l-status-not-launchable.loggable-exception.spec.ts} | 8 ++++---- ...> tool-status-not-launchable.loggable-exception.ts} | 6 +++--- .../tool-launch/service/tool-launch.service.spec.ts | 8 ++++---- .../tool/tool-launch/service/tool-launch.service.ts | 10 +++++----- 6 files changed, 19 insertions(+), 18 deletions(-) rename apps/server/src/modules/tool/tool-launch/error/{tool-status-outdated.loggable-exception.spec.ts => tool-status-not-launchable.loggable-exception.spec.ts} (79%) rename apps/server/src/modules/tool/tool-launch/error/{tool-status-outdated.loggable-exception.ts => tool-status-not-launchable.loggable-exception.ts} (83%) diff --git a/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts b/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts index ed3cfab98bd..96b5adf31c3 100644 --- a/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts +++ b/apps/server/src/modules/tool/common/controller/dto/context-external-tool-configuration-status.response.ts @@ -23,7 +23,8 @@ export class ContextExternalToolConfigurationStatusResponse { @ApiProperty({ type: Boolean, - description: 'True, if a optional parameter on the context external tool is missing a value', + description: + 'True, if a optional parameter on the context external tool is missing a value. This is happening, when course is copied.', }) isIncompleteOperationalOnScopeContext: boolean; diff --git a/apps/server/src/modules/tool/tool-launch/error/index.ts b/apps/server/src/modules/tool/tool-launch/error/index.ts index 020b8510ff5..f64d075ac0a 100644 --- a/apps/server/src/modules/tool/tool-launch/error/index.ts +++ b/apps/server/src/modules/tool/tool-launch/error/index.ts @@ -1,3 +1,3 @@ -export * from './tool-status-outdated.loggable-exception'; +export * from './tool-status-not-launchable.loggable-exception'; export * from './missing-tool-parameter-value.loggable-exception'; export * from './parameter-type-not-implemented.loggable-exception'; diff --git a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.spec.ts b/apps/server/src/modules/tool/tool-launch/error/tool-status-not-launchable.loggable-exception.spec.ts similarity index 79% rename from apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.spec.ts rename to apps/server/src/modules/tool/tool-launch/error/tool-status-not-launchable.loggable-exception.spec.ts index 6c9346143f4..3c081301fdd 100644 --- a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.spec.ts +++ b/apps/server/src/modules/tool/tool-launch/error/tool-status-not-launchable.loggable-exception.spec.ts @@ -1,14 +1,14 @@ import { toolConfigurationStatusFactory } from '@shared/testing'; -import { ToolStatusOutdatedLoggableException } from './tool-status-outdated.loggable-exception'; +import { ToolStatusNotLaunchableLoggableException } from './tool-status-not-launchable.loggable-exception'; -describe('ToolStatusOutdatedLoggableException', () => { +describe('ToolStatusNotLaunchableLoggableException', () => { describe('getLogMessage', () => { const setup = () => { const toolId = 'toolId'; const userId = 'userId'; const toolConfigStatus = toolConfigurationStatusFactory.build(); - const exception = new ToolStatusOutdatedLoggableException( + const exception = new ToolStatusNotLaunchableLoggableException( userId, toolId, toolConfigStatus.isOutdatedOnScopeSchool, @@ -29,7 +29,7 @@ describe('ToolStatusOutdatedLoggableException', () => { const result = exception.getLogMessage(); expect(result).toEqual({ - type: 'TOOL_STATUS_OUTDATED', + type: 'TOOL_STATUS_NOT_LAUNCHABLE', message: expect.any(String), stack: expect.any(String), data: { diff --git a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts b/apps/server/src/modules/tool/tool-launch/error/tool-status-not-launchable.loggable-exception.ts similarity index 83% rename from apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts rename to apps/server/src/modules/tool/tool-launch/error/tool-status-not-launchable.loggable-exception.ts index bc0f7f23f66..c78ff80e764 100644 --- a/apps/server/src/modules/tool/tool-launch/error/tool-status-outdated.loggable-exception.ts +++ b/apps/server/src/modules/tool/tool-launch/error/tool-status-not-launchable.loggable-exception.ts @@ -2,7 +2,7 @@ import { BadRequestException } from '@nestjs/common'; import { EntityId } from '@shared/domain/types'; import { ErrorLogMessage, Loggable, LogMessage, ValidationErrorLogMessage } from '@src/core/logger'; -export class ToolStatusOutdatedLoggableException extends BadRequestException implements Loggable { +export class ToolStatusNotLaunchableLoggableException extends BadRequestException implements Loggable { constructor( private readonly userId: EntityId, private readonly toolId: EntityId, @@ -17,8 +17,8 @@ export class ToolStatusOutdatedLoggableException extends BadRequestException imp getLogMessage(): LogMessage | ErrorLogMessage | ValidationErrorLogMessage { return { - type: 'TOOL_STATUS_OUTDATED', - message: 'The status of the tool is outdated and cannot be launched by the user.', + type: 'TOOL_STATUS_NOT_LAUNCHABLE', + message: 'The status of the tool cannot be launched by the user.', stack: this.stack, data: { userId: this.userId, diff --git a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts index 8e8bddb6beb..3bf4b57df06 100644 --- a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts +++ b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.spec.ts @@ -14,7 +14,7 @@ import { BasicToolConfig, ExternalTool } from '../../external-tool/domain'; import { ExternalToolService } from '../../external-tool'; import { SchoolExternalToolWithId } from '../../school-external-tool/domain'; import { SchoolExternalToolService } from '../../school-external-tool'; -import { ToolStatusOutdatedLoggableException } from '../error'; +import { ToolStatusNotLaunchableLoggableException } from '../error'; import { LaunchRequestMethod, ToolLaunchData, ToolLaunchDataType, ToolLaunchRequest } from '../types'; import { BasicToolLaunchStrategy, @@ -23,7 +23,7 @@ import { ToolLaunchParams, } from './launch-strategy'; import { ToolLaunchService } from './tool-launch.service'; -import { ToolConfigurationStatusService } from '../../context-external-tool/service/tool-configuration-status.service'; +import { ToolConfigurationStatusService } from '../../context-external-tool/service'; describe('ToolLaunchService', () => { let module: TestingModule; @@ -248,13 +248,13 @@ describe('ToolLaunchService', () => { }; }; - it('should throw ToolStatusOutdatedLoggableException', async () => { + it('should throw ToolStatusNotLaunchableLoggableException', async () => { const { launchParams, userId, contextExternalToolId } = setup(); const func = () => service.getLaunchData(userId, launchParams.contextExternalTool); await expect(func).rejects.toThrow( - new ToolStatusOutdatedLoggableException(userId, contextExternalToolId, true, true, false, false, true) + new ToolStatusNotLaunchableLoggableException(userId, contextExternalToolId, true, true, false, false, true) ); }); }); diff --git a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts index 1b0a15b02e5..3e02cfbdd7d 100644 --- a/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts +++ b/apps/server/src/modules/tool/tool-launch/service/tool-launch.service.ts @@ -3,12 +3,12 @@ import { EntityId } from '@shared/domain/types'; import { ContextExternalToolConfigurationStatus } from '../../common/domain'; import { ToolConfigType } from '../../common/enum'; import { ContextExternalTool } from '../../context-external-tool/domain'; -import { ToolConfigurationStatusService } from '../../context-external-tool/service/tool-configuration-status.service'; +import { ToolConfigurationStatusService } from '../../context-external-tool/service'; import { ExternalTool } from '../../external-tool/domain'; -import { ExternalToolService } from '../../external-tool/service'; +import { ExternalToolService } from '../../external-tool'; import { SchoolExternalTool } from '../../school-external-tool/domain'; -import { SchoolExternalToolService } from '../../school-external-tool/service'; -import { ToolStatusOutdatedLoggableException } from '../error'; +import { SchoolExternalToolService } from '../../school-external-tool'; +import { ToolStatusNotLaunchableLoggableException } from '../error'; import { ToolLaunchMapper } from '../mapper'; import { ToolLaunchData, ToolLaunchRequest } from '../types'; import { @@ -102,7 +102,7 @@ export class ToolLaunchService { status.isDeactivated || status.isIncompleteOnScopeContext ) { - throw new ToolStatusOutdatedLoggableException( + throw new ToolStatusNotLaunchableLoggableException( userId, contextExternalTool.id ?? '', status.isOutdatedOnScopeSchool,