Skip to content

Commit

Permalink
Fix fieldSubmit not calling validate method
Browse files Browse the repository at this point in the history
  • Loading branch information
qduc committed Oct 8, 2018
1 parent 0593b87 commit c82c44b
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/fields/abstractField.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function attributesDirective(el, binding, vnode) {
}

export default {
props: ["model", "schema", "formOptions", "disabled"],
props: ["vfg", "model", "schema", "formOptions", "disabled"],

data() {
return {
Expand Down
11 changes: 7 additions & 4 deletions src/fields/core/fieldSubmit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<script>
import abstractField from "../abstractField";
import { isFunction, isEmpty } from "lodash";
import { get as objGet, isFunction, isEmpty } from "lodash";
export default {
mixins: [abstractField],
Expand All @@ -15,10 +15,13 @@ export default {
// prevent a <form /> from having it's submit event triggered
// when we have to validate data first
$event.preventDefault();
let errors = this.$parent.validate();
let validateAsync = objGet(this.formOptions, "validateAsync", false);
let errors = this.vfg.validate();
let handleErrors = errors => {
if (!isEmpty(errors) && isFunction(this.schema.onValidationError)) {
this.schema.onValidationError(this.model, this.schema, errors, $event);
if ((validateAsync && !isEmpty(errors)) || (!validateAsync && !errors)) {
if (isFunction(this.schema.onValidationError)) {
this.schema.onValidationError(this.model, this.schema, errors, $event);
}
} else if (isFunction(this.schema.onSubmit)) {
this.schema.onSubmit(this.model, this.schema, $event);
}
Expand Down
5 changes: 3 additions & 2 deletions src/formGenerator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
div.vue-form-generator(v-if='schema != null')
fieldset(v-if="schema.fields", :is='tag')
template(v-for='field in fields')
form-group(v-if='fieldVisible(field)', :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated")
form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated")

template(v-for='group in groups')
fieldset(:is='tag', :class='getFieldRowClasses(group)')
legend(v-if='group.legend') {{ group.legend }}
template(v-for='field in group.fields')
form-group(v-if='fieldVisible(field)', :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated")
form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated")
</template>

<script>
Expand Down Expand Up @@ -59,6 +59,7 @@ export default {
data() {
return {
vfg: this,
errors: [] // Validation errors
};
},
Expand Down
6 changes: 5 additions & 1 deletion src/formGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</label>

<div class="field-wrap">
<component ref="child" :is="getFieldType(field)" :disabled="fieldDisabled(field)" :model="model" :schema="field" :formOptions="options" @model-updated="onModelUpdated" @validated="onFieldValidated"></component>
<component ref="child" :is="getFieldType(field)" :vfg="vfg" :disabled="fieldDisabled(field)" :model="model" :schema="field" :formOptions="options" @model-updated="onModelUpdated" @validated="onFieldValidated"></component>
<div v-if="buttonVisibility(field)" class="buttons">
<button v-for="(btn, index) in field.buttons" @click="buttonClickHandler(btn, field, $event)" :class="btn.classes" :key="index" v-text="btn.label"></button>
</div>
Expand All @@ -33,6 +33,10 @@ export default {
components: fieldComponents,
mixins: [formMixin],
props: {
vfg: {
type: Object,
required: true
},
model: Object,
options: {
type: Object
Expand Down
90 changes: 70 additions & 20 deletions test/unit/specs/fields/fieldSubmit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,23 @@ function createField2(data, methods) {

describe("fieldSubmit.vue", () => {
describe("check template", () => {
let vfg = {};
let schema = {
type: "submit",
buttonText: "Submit form",
inputName: "",
validateBeforeSubmit: false,
onSubmit() {},
onSubmit: sinon.spy(),
fieldClasses: ["applied-class", "another-class"]
};
let formOptions = {
validateAsync: false
};
let model = { name: "John Doe" };
let input;

before(() => {
createField2({ schema, model, disabled: false });
createField2({ vfg, schema, formOptions, model, disabled: false });
input = wrapper.find("input");
});

Expand All @@ -43,43 +47,89 @@ describe("fieldSubmit.vue", () => {
});

describe("valid form", () => {
it.skip("should not call validate if validateBeforeSubmit is false", () => {
schema.onSubmit = sinon.spy();
let cb = sinon.spy();
wrapper.vm.$parent.validate = cb;
before(() => {
vfg.validate = () => true;
sinon.spy(vfg, "validate");
});

afterEach(() => {
schema.onSubmit.resetHistory();
vfg.validate.resetHistory();
});

it("should not call validate but should call onSubmit if validateBeforeSubmit is false", () => {
input.trigger("click");

input.click();
expect(cb.called).to.be.false;
expect(vfg.validate.notCalled).to.be.true;
expect(schema.onSubmit.calledOnce).to.be.true;
expect(schema.onSubmit.calledWith(model, schema)).to.be.true;
});

it.skip("should call validate if validateBeforeSubmit is true", () => {
it("should call validate and onSubmit if validateBeforeSubmit is true", () => {
schema.validateBeforeSubmit = true;
schema.onSubmit = sinon.spy();
let cb = sinon.spy();
wrapper.vm.$parent.validate = cb;

input.trigger("click");

expect(cb.called).to.be.true;
expect(vfg.validate.called).to.be.true;
expect(schema.onSubmit.called).to.be.true;
});
});

describe("invalid form", () => {
it.skip("should not call onSubmit if validateBeforeSubmit is true", () => {
before(() => {
vfg.validate = () => false;
sinon.spy(vfg, "validate");
});

afterEach(() => {
schema.onSubmit.resetHistory();
vfg.validate.resetHistory();
});

it("should call validate but should not call onSubmit if validateBeforeSubmit is true", () => {
schema.validateBeforeSubmit = true;

input.trigger("click");

expect(vfg.validate.called).to.be.true;
expect(schema.onSubmit.notCalled).to.be.true;
});
});

describe("async validate", () => {
before(() => {
formOptions.validateAsync = true;
vfg.validate = sinon.stub();
schema.onSubmit = sinon.spy();
let cb = sinon.spy(() => {
return ["an error occurred"];
});

afterEach(() => {
vfg.validate.reset();
schema.onSubmit.resetHistory();
});

describe("valid form", () => {
it("should call validate and onSubmit if validateBeforeSubmit is true", async function () {
schema.validateBeforeSubmit = true;
vfg.validate.resolves([]);

await input.trigger("click");

expect(vfg.validate.called).to.be.true;
expect(schema.onSubmit.called).to.be.true;
});
wrapper.vm.$parent.validate = cb;
});

input.trigger("click");
describe("invalid form", () => {
it("should call validate but should not call onSubmit if validateBeforeSubmit is true", async function () {
schema.validateBeforeSubmit = true;
vfg.validate.resolves(["Error"]);

expect(cb.called).to.be.true;
expect(schema.onSubmit.called).to.be.true;
await input.trigger("click");

expect(vfg.validate.called).to.be.true;
expect(schema.onSubmit.notCalled).to.be.true;
});
});
});

Expand Down

0 comments on commit c82c44b

Please sign in to comment.