diff --git a/packages/form/addon/components/document-validity.js b/packages/form/addon/components/document-validity.js index 52c7cb800..eb418ef2e 100644 --- a/packages/form/addon/components/document-validity.js +++ b/packages/form/addon/components/document-validity.js @@ -54,6 +54,10 @@ export default class DocumentValidity extends Component { for (const field of this.args.document.fields) { yield field.validate.linked().perform(); + + if (field.question.hasFormatValidators) { + yield field.save.linked().perform(); + } } if (this.isValid) { diff --git a/packages/form/addon/gql/fragments/field.graphql b/packages/form/addon/gql/fragments/field.graphql index dce6b1b14..42ee2ed1b 100644 --- a/packages/form/addon/gql/fragments/field.graphql +++ b/packages/form/addon/gql/fragments/field.graphql @@ -15,12 +15,7 @@ fragment SimpleQuestion on Question { } placeholder formatValidators { - edges { - node { - slug - regex - } - } + totalCount } hintText } @@ -33,12 +28,7 @@ fragment SimpleQuestion on Question { } placeholder formatValidators { - edges { - node { - slug - regex - } - } + totalCount } hintText } @@ -50,6 +40,9 @@ fragment SimpleQuestion on Question { value } placeholder + formatValidators { + totalCount + } hintText } ... on FloatQuestion { @@ -61,6 +54,9 @@ fragment SimpleQuestion on Question { value } placeholder + formatValidators { + totalCount + } hintText } ... on ChoiceQuestion { @@ -79,6 +75,9 @@ fragment SimpleQuestion on Question { id value } + formatValidators { + totalCount + } hintText } ... on MultipleChoiceQuestion { @@ -97,12 +96,21 @@ fragment SimpleQuestion on Question { id value } + formatValidators { + totalCount + } hintText } ... on DynamicChoiceQuestion { + formatValidators { + totalCount + } hintText } ... on DynamicMultipleChoiceQuestion { + formatValidators { + totalCount + } hintText } ... on DateQuestion { @@ -110,6 +118,9 @@ fragment SimpleQuestion on Question { id value } + formatValidators { + totalCount + } hintText } ... on StaticQuestion { @@ -120,6 +131,9 @@ fragment SimpleQuestion on Question { hintText } ... on FilesQuestion { + formatValidators { + totalCount + } hintText } ... on ActionButtonQuestion { diff --git a/packages/form/addon/lib/question.js b/packages/form/addon/lib/question.js index abf89a605..d49b1cda8 100644 --- a/packages/form/addon/lib/question.js +++ b/packages/form/addon/lib/question.js @@ -192,4 +192,8 @@ export default class Question extends Base { ].includes(this.raw.__typename)) ); } + + get hasFormatValidators() { + return (this.raw.formatValidators?.totalCount ?? 0) > 0; + } } diff --git a/packages/form/package.json b/packages/form/package.json index f44d5ea67..4f5a284df 100644 --- a/packages/form/package.json +++ b/packages/form/package.json @@ -67,6 +67,7 @@ "ember-load-initializers": "3.0.1", "ember-qunit": "9.0.4", "ember-resolver": "13.1.1", + "ember-sinon-qunit": "7.5.0", "ember-source": "6.1.0", "ember-source-channel-url": "3.0.0", "ember-try": "4.0.0", @@ -75,6 +76,7 @@ "qunit": "2.24.1", "qunit-dom": "3.5.0", "sass": "1.93.2", + "sinon": "21.0.0", "uikit": "3.23.13", "uuid": "13.0.0", "webpack": "5.101.3" diff --git a/packages/form/tests/integration/components/cf-field/input/action-button-test.js b/packages/form/tests/integration/components/cf-field/input/action-button-test.js index b430271c4..f27507eb4 100644 --- a/packages/form/tests/integration/components/cf-field/input/action-button-test.js +++ b/packages/form/tests/integration/components/cf-field/input/action-button-test.js @@ -21,6 +21,8 @@ module( const validField = new (class { @tracked isValid = true; + question = { hasFormatValidators: false }; + @restartableTask *validate() { yield assert.step("validate"); @@ -35,7 +37,7 @@ module( return !this.isValid; } - question = { raw: { label: "foo" } }; + question = { raw: { label: "foo" }, hasFormatValidators: false }; @restartableTask validate() { diff --git a/packages/form/tests/integration/components/document-validity-test.js b/packages/form/tests/integration/components/document-validity-test.js index 59a72e8e3..713c6b8e3 100644 --- a/packages/form/tests/integration/components/document-validity-test.js +++ b/packages/form/tests/integration/components/document-validity-test.js @@ -2,6 +2,7 @@ import { render, click, scrollTo, settled } from "@ember/test-helpers"; import { hbs } from "ember-cli-htmlbars"; import { setupMirage } from "ember-cli-mirage/test-support"; import { module, test } from "qunit"; +import { stub } from "sinon"; import { rawDocumentWithWorkItem } from "../../unit/lib/data"; @@ -100,4 +101,36 @@ module("Integration | Component | document-validity", function (hooks) { await click("button"); await assert.verifySteps(["valid"]); }); + + test("it can be triggered manually", async function (assert) { + stub(this.field.question, "hasFormatValidators").get(() => true); + stub(this.field.save, "linked").returnsThis(); + stub(this.field.save, "perform").callsFake(() => { + this.field._errors = [ + { + type: "format", + context: { errorMsg: "Error!" }, + value: "test", + }, + ]; + + assert.step("save"); + }); + + await render(hbs` +

+ {{#if isValid}} + Valid + {{else}} + Invalid + {{/if}} +

+ +
`); + + assert.dom("p").hasText("Valid"); + await click("button"); + assert.dom("p").hasText("Invalid"); + assert.verifySteps(["save"]); + }); }); diff --git a/packages/form/tests/test-helper.js b/packages/form/tests/test-helper.js index 6c19b385e..5706c2668 100644 --- a/packages/form/tests/test-helper.js +++ b/packages/form/tests/test-helper.js @@ -1,6 +1,7 @@ import { setApplication } from "@ember/test-helpers"; import { start, setupEmberOnerrorValidation } from "ember-qunit"; import { loadTests } from "ember-qunit/test-loader"; +import setupSinon from "ember-sinon-qunit"; import * as QUnit from "qunit"; import { setup } from "qunit-dom"; @@ -13,4 +14,6 @@ setupEmberOnerrorValidation(); loadTests(); setup(QUnit.assert); +setupSinon(); + start(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8133940e5..fadb964d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1010,6 +1010,9 @@ importers: ember-resolver: specifier: 13.1.1 version: 13.1.1 + ember-sinon-qunit: + specifier: 7.5.0 + version: 7.5.0(@babel/core@7.28.4)(ember-source@6.1.0(@glimmer/component@1.1.2(@babel/core@7.28.4))(@glint/template@1.5.2)(rsvp@4.8.5)(webpack@5.101.3))(qunit@2.24.1)(sinon@21.0.0) ember-source: specifier: 6.1.0 version: 6.1.0(@glimmer/component@1.1.2(@babel/core@7.28.4))(@glint/template@1.5.2)(rsvp@4.8.5)(webpack@5.101.3) @@ -1034,6 +1037,9 @@ importers: sass: specifier: 1.93.2 version: 1.93.2 + sinon: + specifier: 21.0.0 + version: 21.0.0 uikit: specifier: 3.23.13 version: 3.23.13