Skip to content

Commit b9839c1

Browse files
alencarlucasdavimacedo
authored andcommitted
feat: Avoid setting a relation as required or with a defaultValue (#5922)
* feat: Avoid setting a relation as required or with a defaultValue * chore: Test to update a class with a relation field with options * chore: Improve tests
1 parent fddd9c2 commit b9839c1

File tree

2 files changed

+118
-6
lines changed

2 files changed

+118
-6
lines changed

spec/schemas.spec.js

+100
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ describe('schemas', () => {
431431
defaultValue: false,
432432
},
433433
defaultZero: { type: 'Number', defaultValue: 0 },
434+
relation: { type: 'Relation', targetClass: 'SomeClass' }
434435
},
435436
},
436437
}).then(async response => {
@@ -457,6 +458,7 @@ describe('schemas', () => {
457458
defaultValue: false,
458459
},
459460
defaultZero: { type: 'Number', defaultValue: 0 },
461+
relation: { type: 'Relation', targetClass: 'SomeClass' }
460462
},
461463
classLevelPermissions: defaultClassLevelPermissions,
462464
});
@@ -479,10 +481,108 @@ describe('schemas', () => {
479481
expect(obj.get('defaultFalse')).toEqual(false);
480482
expect(obj.get('defaultZero')).toEqual(0);
481483
expect(obj.get('ptr')).toBeUndefined();
484+
expect(obj.get('relation')).toBeUndefined();
482485
done();
483486
});
484487
});
485488

489+
it('try to set a relation field as a required field', async (done) => {
490+
try {
491+
await request({
492+
url: 'http://localhost:8378/1/schemas',
493+
method: 'POST',
494+
headers: masterKeyHeaders,
495+
json: true,
496+
body: {
497+
className: 'NewClassWithRelationRequired',
498+
fields: {
499+
foo: { type: 'String' },
500+
relation: { type: 'Relation', targetClass: 'SomeClass', required: true }
501+
},
502+
},
503+
});
504+
fail('should fail');
505+
} catch (e) {
506+
expect(e.data.code).toEqual(111);
507+
}
508+
done();
509+
});
510+
511+
it('try to set a relation field with a default value', async (done) => {
512+
try {
513+
await request({
514+
url: 'http://localhost:8378/1/schemas',
515+
method: 'POST',
516+
headers: masterKeyHeaders,
517+
json: true,
518+
body: {
519+
className: 'NewClassRelationWithOptions',
520+
fields: {
521+
foo: { type: 'String' },
522+
relation: { type: 'Relation', targetClass: 'SomeClass', defaultValue: { __type: 'Relation', className: '_User' } }
523+
},
524+
},
525+
});
526+
fail('should fail');
527+
} catch (e) {
528+
expect(e.data.code).toEqual(111);
529+
}
530+
done();
531+
});
532+
533+
it('try to update schemas with a relation field with options', async (done) => {
534+
await request({
535+
url: 'http://localhost:8378/1/schemas',
536+
method: 'POST',
537+
headers: masterKeyHeaders,
538+
json: true,
539+
body: {
540+
className: 'NewClassRelationWithOptions',
541+
fields: {
542+
foo: { type: 'String' }
543+
},
544+
},
545+
});
546+
try {
547+
await request({
548+
url: 'http://localhost:8378/1/schemas/NewClassRelationWithOptions',
549+
method: 'POST',
550+
headers: masterKeyHeaders,
551+
json: true,
552+
body: {
553+
className: 'NewClassRelationWithOptions',
554+
fields: {
555+
relation: { type: 'Relation', targetClass: 'SomeClass', required: true }
556+
},
557+
_method: "PUT"
558+
}
559+
});
560+
fail('should fail');
561+
} catch (e) {
562+
expect(e.data.code).toEqual(111);
563+
}
564+
565+
try {
566+
await request({
567+
url: 'http://localhost:8378/1/schemas/NewClassRelationWithOptions',
568+
method: 'POST',
569+
headers: masterKeyHeaders,
570+
json: true,
571+
body: {
572+
className: 'NewClassRelationWithOptions',
573+
fields: {
574+
relation: { type: 'Relation', targetClass: 'SomeClass', defaultValue: { __type: 'Relation', className: '_User' } }
575+
},
576+
_method: "PUT"
577+
}
578+
});
579+
fail('should fail');
580+
} catch (e) {
581+
expect(e.data.code).toEqual(111);
582+
}
583+
done();
584+
});
585+
486586
it('validated the data type of default values when creating a new class', async () => {
487587
try {
488588
await request({

src/Controllers/SchemaController.js

+18-6
Original file line numberDiff line numberDiff line change
@@ -898,22 +898,34 @@ export default class SchemaController {
898898
error: 'field ' + fieldName + ' cannot be added',
899899
};
900900
}
901-
const type = fields[fieldName];
902-
const error = fieldTypeIsInvalid(type);
901+
const fieldType = fields[fieldName];
902+
const error = fieldTypeIsInvalid(fieldType);
903903
if (error) return { code: error.code, error: error.message };
904-
if (type.defaultValue !== undefined) {
905-
let defaultValueType = getType(type.defaultValue);
904+
if (fieldType.defaultValue !== undefined) {
905+
let defaultValueType = getType(fieldType.defaultValue);
906906
if (typeof defaultValueType === 'string') {
907907
defaultValueType = { type: defaultValueType };
908+
} else if (typeof defaultValueType === 'object' && fieldType.type === 'Relation') {
909+
return {
910+
code: Parse.Error.INCORRECT_TYPE,
911+
error: `The 'default value' option is not applicable for ${typeToString(fieldType)}`
912+
};
908913
}
909-
if (!dbTypeMatchesObjectType(type, defaultValueType)) {
914+
if (!dbTypeMatchesObjectType(fieldType, defaultValueType)) {
910915
return {
911916
code: Parse.Error.INCORRECT_TYPE,
912917
error: `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(
913-
type
918+
fieldType
914919
)} but got ${typeToString(defaultValueType)}`,
915920
};
916921
}
922+
} else if (fieldType.required) {
923+
if (typeof fieldType === 'object' && fieldType.type === 'Relation') {
924+
return {
925+
code: Parse.Error.INCORRECT_TYPE,
926+
error: `The 'required' option is not applicable for ${typeToString(fieldType)}`
927+
};
928+
}
917929
}
918930
}
919931
}

0 commit comments

Comments
 (0)