Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ObjectType): fix required message for properties not being replaced #79

Merged
merged 3 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .codesandbox/ci.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"sandboxes": ["new"]
}
20 changes: 11 additions & 9 deletions src/MixedType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ export class MixedType<ValueType = any, DataType = any, E = ErrorMessageType, L
this.fieldLabel
);

const checkStatus = validator(value, this.priorityRules);
const checkResult = validator(value, this.priorityRules);

if (checkStatus) {
return checkStatus;
// If the priority rule fails, return the result directly
if (checkResult) {
return checkResult;
}

if (!this.required && isEmpty(value)) {
Expand Down Expand Up @@ -124,9 +125,10 @@ export class MixedType<ValueType = any, DataType = any, E = ErrorMessageType, L

return new Promise(resolve =>
validator(value, this.priorityRules)
.then((checkStatus: CheckResult<E | string> | void | null) => {
if (checkStatus) {
resolve(checkStatus);
.then((checkResult: CheckResult<E | string> | void | null) => {
// If the priority rule fails, return the result directly
if (checkResult) {
resolve(checkResult);
}
})
.then(() => {
Expand All @@ -135,9 +137,9 @@ export class MixedType<ValueType = any, DataType = any, E = ErrorMessageType, L
}
})
.then(() => validator(value, this.rules))
.then((checkStatus: CheckResult<E | string> | void | null) => {
if (checkStatus) {
resolve(checkStatus);
.then((checkResult: CheckResult<E | string> | void | null) => {
if (checkResult) {
resolve(checkResult);
}
resolve({ hasError: false });
})
Expand Down
4 changes: 2 additions & 2 deletions src/ObjectType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class ObjectType<DataType = any, E = ErrorMessageType> extends MixedType<
if (type.required && !checkRequired(value, type.trim, type.emptyAllowed)) {
return {
hasError: true,
errorMessage: formatErrorMessage<E>(this.requiredMessage || this.locale.isRequired, {
errorMessage: formatErrorMessage<E>(type.requiredMessage || type.locale?.isRequired, {
name: type.fieldLabel || childFieldKey || fieldName
})
};
Expand Down Expand Up @@ -75,7 +75,7 @@ export class ObjectType<DataType = any, E = ErrorMessageType> extends MixedType<
if (type.required && !checkRequired(value, type.trim, type.emptyAllowed)) {
return Promise.resolve({
hasError: true,
errorMessage: formatErrorMessage<E>(this.requiredMessage || this.locale.isRequired, {
errorMessage: formatErrorMessage<E>(type.requiredMessage || type.locale?.isRequired, {
name: type.fieldLabel || childFieldKey || fieldName
})
});
Expand Down
7 changes: 7 additions & 0 deletions src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ export class Schema<DataType = any, ErrorMsgType = string> {
return Object.keys(this.$spec);
}

/**
* Get the schema specification
*/
getSchemaSpec() {
return this.$spec;
}

checkForField<T extends keyof DataType>(
fieldName: T,
data: DataType,
Expand Down
68 changes: 68 additions & 0 deletions test/MixedTypeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,74 @@ describe('#MixedType', () => {
schema2.checkForField('str', { str: '12' }).hasError.should.equal(true);
schema2.checkForField('str', { str: '12' }).errorMessage.should.equal('error');
});

describe('priority - async', () => {
it('Should have the correct priority', async () => {
const schema = SchemaModel({
name: StringType()
.isEmail('error1')
.addRule(() => false, 'error2')
});

const result = await schema.checkAsync({ name: 'a' });

expect(result).to.deep.equal({
name: { hasError: true, errorMessage: 'error1' }
});

const schema2 = SchemaModel({
name: StringType()
.isEmail('error1')
.addRule(() => false, 'error2', true)
});

const result2 = await schema2.checkAsync({ name: 'a' });

expect(result2).to.deep.equal({
name: { hasError: true, errorMessage: 'error2' }
});

const schema3 = SchemaModel({
name: StringType().addRule(() => true, 'error2', true)
});

const result3 = await schema3.checkAsync({ name: 'a' });

expect(result3).to.deep.equal({
name: { hasError: false }
});
});

it('Should be isRequired with a higher priority than addRule', async () => {
const schema = SchemaModel({
str: StringType()
.isRequired('required')
.addRule(value => value === '', 'error')
});

const result = await schema.checkAsync({ str: '' });

expect(result).to.deep.equal({
str: { hasError: true, errorMessage: 'required' }
});

const result2 = await schema.checkAsync({ str: '12' });

expect(result2).to.deep.equal({
str: { hasError: true, errorMessage: 'error' }
});

const schema2 = SchemaModel({
str: StringType().addRule(value => value === '', 'error')
});

const result3 = await schema2.checkAsync({ str: '12' });

expect(result3).to.deep.equal({
str: { hasError: true, errorMessage: 'error' }
});
});
});
});

describe('required', () => {
Expand Down
90 changes: 90 additions & 0 deletions test/ObjectTypeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,4 +323,94 @@ describe('#ObjectType', () => {
const result = await schema.checkAsync({ user: null });
expect(result).to.deep.equal({ user: { hasError: false } });
});

it('Should replace default required message', () => {
const schema = new Schema({
user: ObjectType().shape({
email1: StringType().isEmail().isRequired(),
email2: StringType().isEmail().isRequired('Email is required')
})
});

const result = schema.check({ user: { email1: '', email2: '' } });

expect(result.user.object.email1.errorMessage).to.equal('email1 is a required field');
expect(result.user.object.email2.errorMessage).to.equal('Email is required');
});

it('Should replace default required message with async', async () => {
const schema = new Schema({
user: ObjectType().shape({
email1: StringType().isEmail().isRequired(),
email2: StringType().isEmail().isRequired('Email is required')
})
});

const result = await schema.checkAsync({ user: { email1: '', email2: '' } });

expect(result.user.object.email1.errorMessage).to.equal('email1 is a required field');
expect(result.user.object.email2.errorMessage).to.equal('Email is required');
});

describe('priority', () => {
it('Should have the correct priority', () => {
const schema = new Schema({
user: ObjectType().shape({
name: StringType()
.isEmail('error1')
.addRule(() => false, 'error2')
})
});

const result = schema.check({ user: { name: 'a' } });

expect(result.user.object).to.deep.equal({
name: { hasError: true, errorMessage: 'error1' }
});

const schema2 = new Schema({
user: ObjectType().shape({
name: StringType()
.isEmail('error1')
.addRule(() => false, 'error2', true)
})
});

const result2 = schema2.check({ user: { name: 'a' } });

expect(result2.user.object).to.deep.equal({
name: { hasError: true, errorMessage: 'error2' }
});
});

it('Should have the correct priority with async', async () => {
const schema = new Schema({
user: ObjectType().shape({
name: StringType()
.isEmail('error1')
.addRule(() => false, 'error2')
})
});

const result = await schema.checkAsync({ user: { name: 'a' } });

expect(result.user.object).to.deep.equal({
name: { hasError: true, errorMessage: 'error1' }
});

const schema2 = new Schema({
user: ObjectType().shape({
name: StringType()
.isEmail('error1')
.addRule(() => false, 'error2', true)
})
});

const result2 = await schema2.checkAsync({ user: { name: 'a' } });

expect(result2.user.object).to.deep.equal({
name: { hasError: true, errorMessage: 'error2' }
});
});
});
});
9 changes: 9 additions & 0 deletions test/SchemaSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ describe('#Schema', () => {
});
});

it('Should get the schema spec by calling getSchemaSpec', () => {
const model = SchemaModel({
username: StringType().isRequired(),
email: StringType().isEmail()
});

model.getSchemaSpec().should.deep.equal(model.$spec);
});

describe('## getKeys', () => {
it('Should return keys', () => {
const model = SchemaModel({
Expand Down
Loading