diff --git a/e2e/valeurs-erronees.e2e-spec.ts b/e2e/valeurs-erronees.e2e-spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..d18afcd4f3d7b5264cd4b8ea47adde8983825ecd --- /dev/null +++ b/e2e/valeurs-erronees.e2e-spec.ts @@ -0,0 +1,60 @@ +import { browser } from "protractor"; +import { CalculatorPage } from "./calculator.po"; +import { ListPage } from "./list.po"; +import { Navbar } from "./navbar.po"; +import { PreferencesPage } from "./preferences.po"; + +describe("ngHyd - check invalid values are removed - ", () => { + let listPage: ListPage; + let prefPage: PreferencesPage; + let navBar: Navbar; + let calcPage: CalculatorPage; + + beforeEach(async () => { + prefPage = new PreferencesPage(); + listPage = new ListPage(); + navBar = new Navbar(); + calcPage = new CalculatorPage(); + + // disable evil option "empty fields on module creation" + await prefPage.navigateTo(); + await browser.sleep(200); + await prefPage.disableEvilEmptyFields(); + await browser.sleep(200); + }); + + it("when switching to another calculator", async () => { + // open PAB dimensions calculator + await navBar.clickNewCalculatorButton(); + await listPage.clickMenuEntryForCalcType(5); + await browser.sleep(200); + + // modify W input with invalid value + const inputW = calcPage.getInputById("W"); + await browser.sleep(200); + await inputW.clear(); + await browser.sleep(200); + await inputW.sendKeys("-1"); + await browser.sleep(200); + + // open another calculator + await navBar.clickNewCalculatorButton(); + await listPage.clickMenuEntryForCalcType(12); + await browser.sleep(200); + + // back to first calculator + await navBar.openNthCalculator(0); + await browser.sleep(200); + + // check invalid value is removed + const w = await inputW.getAttribute("value"); + await browser.sleep(200); + expect(w).toEqual(""); + + // check that "compute" button is disabled + const calcButton = calcPage.getCalculateButton(); + const disabledState = await calcButton.getAttribute("disabled"); + const disabled = disabledState === null || disabledState === "true"; + expect(disabled).toBe(true); + }); +}); diff --git a/src/app/components/generic-input/generic-input.component.ts b/src/app/components/generic-input/generic-input.component.ts index 3dc390d50f261a0dab352154f62a34000e46b885..c30e69123c3fdd550ca1706144355a280100c1a9 100644 --- a/src/app/components/generic-input/generic-input.component.ts +++ b/src/app/components/generic-input/generic-input.component.ts @@ -154,11 +154,14 @@ export abstract class GenericInputComponentDirective implements OnChanges { this.emitValidChanged(); } // répercussion des erreurs sur le Form angular, pour faire apparaître/disparaître les mat-error + // setTimeout(() => { // en cas de pb, décommenter le timeout if (b) { this.inputField.control.setErrors(null); } else { this.inputField.control.setErrors({ "incorrect": true }); } + // this.inputField.control.markAsTouched(); + // }, 100); } private validateModel(): boolean { diff --git a/src/app/components/ngparam-input/ngparam-input.component.ts b/src/app/components/ngparam-input/ngparam-input.component.ts index 2449f691efa1e7b2a0a98f4ab34b284107a801f5..781e29b15614cb04192292ed2c465c22c6939f95 100644 --- a/src/app/components/ngparam-input/ngparam-input.component.ts +++ b/src/app/components/ngparam-input/ngparam-input.component.ts @@ -2,7 +2,7 @@ import { Component, ChangeDetectorRef, OnDestroy, Input, ElementRef } from "@angular/core"; -import { Message, Observer } from "jalhyd"; +import { Message, MessageCode, Observer } from "jalhyd"; import { I18nService } from "../../services/internationalisation.service"; import { NgParameter } from "../../formulaire/elements/ngparam"; @@ -99,6 +99,9 @@ export class NgParamInputComponent extends GenericInputComponentDirective implem msg = "internal error, model undefined"; } else { try { + if (!this._paramDef.allowEmpty && v === undefined) { + throw new Message(MessageCode.ERROR_PARAMDEF_VALUE_UNDEFINED); + } this._paramDef.checkValue(v); valid = true; } catch (e) { @@ -148,6 +151,9 @@ export class NgParamInputComponent extends GenericInputComponentDirective implem } public ngOnDestroy() { + if (!this.isValid && this.getModelValue() !== undefined) { + this.setModelValue(this, undefined); + } this._paramDef.removeObserver(this); } } diff --git a/src/app/formulaire/elements/ngparam.ts b/src/app/formulaire/elements/ngparam.ts index 43d7cb29815ed0c8e42baa5fa9910fa2b0b810a5..c4d6c146e010d746c54e61c8ede01b2311d3cd03 100644 --- a/src/app/formulaire/elements/ngparam.ts +++ b/src/app/formulaire/elements/ngparam.ts @@ -32,8 +32,6 @@ export class NgParameter extends InputField implements Observer { /** set to true to disable UI validation on this input */ private _allowEmpty = false; - public unit: string; - public radioConfig: ParamRadioConfig; public disabled: boolean; @@ -207,6 +205,10 @@ export class NgParameter extends InputField implements Observer { return this._paramDef.valueMode; } + public get unit() { + return this._paramDef.unit; + } + /** * Unlinks the parameter and updates its value when value mode changes */ @@ -496,7 +498,7 @@ export class NgParameter extends InputField implements Observer { if (this._paramDef.symbol === rep.prmDef.symbol) { this._paramDef.loadObjectRepresentation(rep.prmDef); this._allowEmpty = rep.allowEmpty; - this.unit = rep.unit; + this._paramDef.setUnit(rep.unit); this.radioConfig = rep.radioConfig; } } @@ -581,7 +583,6 @@ export class NgParameter extends InputField implements Observer { if (json["allowEmpty"] !== undefined && typeof json["allowEmpty"] === "boolean") { this._allowEmpty = json["allowEmpty"]; } - this.unit = this.paramDefinition.unit; this.radioConfig = this.getRadioConfig(); if (json["calculable"] !== undefined && json["calculable"] === false) { this.radioConfig = Math.min(ParamCalculability.FREE, this.getRadioConfig());