Skip to content

Commit

Permalink
fix(core): deal with unqualified date times in local offsets (#553)
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Roberts <[email protected]>
  • Loading branch information
mttrbrts authored Jan 6, 2023
1 parent 60012cf commit 20315ea
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 78 deletions.
2 changes: 1 addition & 1 deletion packages/concerto-cli/lib/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class Commands {
const factory = new Factory(modelManager);
const serializer = new Serializer(factory, modelManager);

const object = serializer.fromJSON(json);
const object = serializer.fromJSON(json, options);
return JSON.stringify(serializer.toJSON(object, options));
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/concerto-core/lib/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class Serializer {
parameters.resourceStack = new TypedStack(resource);
parameters.modelManager = this.modelManager;
parameters.factory = this.factory;
const populator = new JSONPopulator(options.acceptResourcesForRelationships === true, options.ergo === true, options.utcOffset);
const populator = new JSONPopulator(options.acceptResourcesForRelationships === true, options.ergo === true, options.utcOffset, options.strictQualifiedDateTimes === true);
classDeclaration.accept(populator, parameters);

// validate the resource against the model
Expand Down
14 changes: 11 additions & 3 deletions packages/concerto-core/lib/serializer/jsonpopulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,13 @@ class JSONPopulator {
* place of relationships, false by default.
* @param {boolean} [ergo] target ergo.
* @param {number} [utcOffset] - UTC Offset for DateTime values.
* @param {number} [strictQualifiedDateTimes] - Only allow fully-qualified date-times with offsets.
*/
constructor(acceptResourcesForRelationships, ergo, utcOffset) {
constructor(acceptResourcesForRelationships, ergo, utcOffset, strictQualifiedDateTimes) {
this.acceptResourcesForRelationships = acceptResourcesForRelationships;
this.ergo = ergo;
this.utcOffset = utcOffset || 0; // Defaults to UTC
this.strictQualifiedDateTimes = strictQualifiedDateTimes;
}

/**
Expand Down Expand Up @@ -256,10 +258,16 @@ class JSONPopulator {
result = json;
} else if (typeof json !== 'string') {
throw new ValidationException(`Expected value at path \`${path}\` to be of type \`${field.getType()}\``);
} else {
} else if (!this.strictQualifiedDateTimes){
result = dayjs.utc(json).utcOffset(this.utcOffset);
} else if (this.strictQualifiedDateTimes){
if (json.match(/^((?:(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}(?:\.\d+)?))(Z|[+-]\d{2}:\d{2}))$/)){
result = dayjs.utc(json);
} else {
throw new ValidationException(`Expected value at path \`${path}\` to be of type \`${field.getType()}\` with format YYYY-MM-DDTHH:mm:ss[Z]`);
}
}
if (!result.isValid()) {
if (!result || !result.isValid()) {
throw new ValidationException(`Expected value at path \`${path}\` to be of type \`${field.getType()}\``);
}
}
Expand Down
1 change: 0 additions & 1 deletion packages/concerto-core/test/concerto.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,5 @@ describe('concerto', () => {
concerto.validate(obj);
}).should.throw(/The class "org.accordproject.test.Person" is abstract and should not contain an instance./);
});

});
});
266 changes: 196 additions & 70 deletions packages/concerto-core/test/serializer.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/concerto-core/test/serializer/jsongenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ describe('JSONGenerator', () => {

beforeEach(() => {
sandbox = sinon.createSandbox();
jsonGenerator = new JSONGenerator();
jsonGenerator = new JSONGenerator(null, null, null, null, null, 'Z');
ergoJsonGenerator = new JSONGenerator(null,null,null,null,true);
ergoJsonGeneratorId = new JSONGenerator(null,null,null,true,true);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ declare class JSONPopulator {
* place of relationships, false by default.
* @param {boolean} [ergo] target ergo.
* @param {number} [utcOffset] - UTC Offset for DateTime values.
* @param {number} [strictQualifiedDateTimes] - Only allow fully-qualified date-times with offsets.
*/
constructor(acceptResourcesForRelationships?: boolean, ergo?: boolean, utcOffset?: number);
constructor(acceptResourcesForRelationships?: boolean, ergo?: boolean, utcOffset?: number, strictQualifiedDateTimes?: number);
acceptResourcesForRelationships: boolean;
ergo: boolean;
utcOffset: number;
strictQualifiedDateTimes: number;
/**
* Visitor design pattern
* @param {Object} thing - the object being visited
Expand Down

0 comments on commit 20315ea

Please sign in to comment.