From aa4430a4748cb514787061dac8fe372a086d91ae Mon Sep 17 00:00:00 2001 From: nickevansuk <2616208+nickevansuk@users.noreply.github.com> Date: Thu, 12 Oct 2023 15:14:40 +0100 Subject: [PATCH 1/4] feature/validate-data-and-id --- .../page/required-property-values-rule.js | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/rules/page/required-property-values-rule.js b/src/rules/page/required-property-values-rule.js index 1b0dbc2..88e92b7 100644 --- a/src/rules/page/required-property-values-rule.js +++ b/src/rules/page/required-property-values-rule.js @@ -13,7 +13,7 @@ const RequiredPropertyValuesRule = class extends RpdeRule { description: 'Validates that the feed properties conform to the correct format', tests: { state: { - description: 'Raises a failure if the state property isn\'t one of "updated" or "deleted"', + description: 'Raises a failure if the `state` property isn\'t one of "updated" or "deleted"', message: 'The [`state` property](https://www.openactive.io/realtime-paged-data-exchange/#-item-) must be of value "updated" or "deleted", but was found to be different in {{count}} items in the feed.', sampleValues: { count: 23, @@ -22,8 +22,18 @@ const RequiredPropertyValuesRule = class extends RpdeRule { severity: ValidationErrorSeverity.FAILURE, type: RpdeErrorType.INVALID_FORMAT, }, + id: { + description: 'Raises a failure if the `id` property isn\'t a string or an integer in any item', + message: 'The [`id` property](https://www.openactive.io/realtime-paged-data-exchange/#-item-) must be a string, but was found to be different in {{count}} items in the feed.', + sampleValues: { + count: 23, + }, + category: ValidationErrorCategory.CONFORMANCE, + severity: ValidationErrorSeverity.FAILURE, + type: RpdeErrorType.INVALID_FORMAT, + }, kind: { - description: 'Raises a failure if the kind property isn\'t a string in any item', + description: 'Raises a failure if the `kind` property isn\'t a string in any item', message: 'The [`kind` property](https://www.openactive.io/realtime-paged-data-exchange/#-item-) must be a string, but was found to be different in {{count}} items in the feed.', sampleValues: { count: 23, @@ -32,6 +42,16 @@ const RequiredPropertyValuesRule = class extends RpdeRule { severity: ValidationErrorSeverity.FAILURE, type: RpdeErrorType.INVALID_FORMAT, }, + data: { + description: 'Raises a failure if the `data` property isn\'t an object in any item', + message: 'The [`data` property](https://www.openactive.io/realtime-paged-data-exchange/#-data-) must be an object, but was found to be different in {{count}} items in the feed.', + sampleValues: { + count: 23, + }, + category: ValidationErrorCategory.CONFORMANCE, + severity: ValidationErrorSeverity.FAILURE, + type: RpdeErrorType.INVALID_FORMAT, + }, item: { description: 'Raises a failure if an item is found that isn\'t an object', message: 'Items must be objects, but were found to be different in {{count}} items in the feed.', @@ -142,6 +162,18 @@ const RequiredPropertyValuesRule = class extends RpdeRule { ) { invalidProps.kind += 1; } + if ( + typeof item.id !== 'undefined' + && typeof item.id !== 'string' && typeof item.id !== 'number' + ) { + invalidProps.id += 1; + } + if ( + typeof item.data !== 'undefined' + && typeof item.data !== 'object' + ) { + invalidProps.data += 1; + } } } From 55bdf3618c550fc063bf7c26614b984b20f7a2a3 Mon Sep 17 00:00:00 2001 From: nickevansuk <2616208+nickevansuk@users.noreply.github.com> Date: Thu, 12 Oct 2023 16:02:25 +0100 Subject: [PATCH 2/4] Fix links --- src/rules/page/required-property-values-rule.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rules/page/required-property-values-rule.js b/src/rules/page/required-property-values-rule.js index 88e92b7..e0ddfcb 100644 --- a/src/rules/page/required-property-values-rule.js +++ b/src/rules/page/required-property-values-rule.js @@ -14,7 +14,7 @@ const RequiredPropertyValuesRule = class extends RpdeRule { tests: { state: { description: 'Raises a failure if the `state` property isn\'t one of "updated" or "deleted"', - message: 'The [`state` property](https://www.openactive.io/realtime-paged-data-exchange/#-item-) must be of value "updated" or "deleted", but was found to be different in {{count}} items in the feed.', + message: 'The [`state` property](https://www.openactive.io/realtime-paged-data-exchange/#-state-) must be of value "updated" or "deleted", but was found to be different in {{count}} items in the feed.', sampleValues: { count: 23, }, @@ -24,7 +24,7 @@ const RequiredPropertyValuesRule = class extends RpdeRule { }, id: { description: 'Raises a failure if the `id` property isn\'t a string or an integer in any item', - message: 'The [`id` property](https://www.openactive.io/realtime-paged-data-exchange/#-item-) must be a string, but was found to be different in {{count}} items in the feed.', + message: 'The [`id` property](https://www.openactive.io/realtime-paged-data-exchange/#-id-) must be a string, but was found to be different in {{count}} items in the feed.', sampleValues: { count: 23, }, @@ -34,7 +34,7 @@ const RequiredPropertyValuesRule = class extends RpdeRule { }, kind: { description: 'Raises a failure if the `kind` property isn\'t a string in any item', - message: 'The [`kind` property](https://www.openactive.io/realtime-paged-data-exchange/#-item-) must be a string, but was found to be different in {{count}} items in the feed.', + message: 'The [`kind` property](https://www.openactive.io/realtime-paged-data-exchange/#-kind-) must be a string, but was found to be different in {{count}} items in the feed.', sampleValues: { count: 23, }, From f9effdfaf0bbee154b0eea7851d1570bef156ae3 Mon Sep 17 00:00:00 2001 From: nickevansuk <2616208+nickevansuk@users.noreply.github.com> Date: Thu, 12 Oct 2023 16:08:47 +0100 Subject: [PATCH 3/4] Add tests --- .../required-property-values-rule.spec.js | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/rules/page/required-property-values-rule.spec.js b/src/rules/page/required-property-values-rule.spec.js index 08bba07..840d623 100644 --- a/src/rules/page/required-property-values-rule.spec.js +++ b/src/rules/page/required-property-values-rule.spec.js @@ -64,6 +64,60 @@ describe('RequiredPropertyValuesRule', () => { } }); + it('should raise an error when the id field is not a string or integer', () => { + json.items[0].id = []; + const node = new RpdeNode( + url, + json, + log, + ); + + rule.validate(node); + + expect(log.addPageError).toHaveBeenCalled(); + expect(log.pages.length).toBe(1); + expect(log.pages[0].errors.length).toBe(1); + for (const error of log.pages[0].errors) { + expect(error.type).toBe(RpdeErrorType.INVALID_FORMAT); + } + }); + + it('should raise an error when the data field is not an object', () => { + json.items[0].data = []; + const node = new RpdeNode( + url, + json, + log, + ); + + rule.validate(node); + + expect(log.addPageError).toHaveBeenCalled(); + expect(log.pages.length).toBe(1); + expect(log.pages[0].errors.length).toBe(1); + for (const error of log.pages[0].errors) { + expect(error.type).toBe(RpdeErrorType.INVALID_FORMAT); + } + }); + + it('should raise an error when the kind field is not a string', () => { + json.items[0].kind = 123; + const node = new RpdeNode( + url, + json, + log, + ); + + rule.validate(node); + + expect(log.addPageError).toHaveBeenCalled(); + expect(log.pages.length).toBe(1); + expect(log.pages[0].errors.length).toBe(1); + for (const error of log.pages[0].errors) { + expect(error.type).toBe(RpdeErrorType.INVALID_FORMAT); + } + }); + it('should raise an error when the items field is not an array', () => { json.items = {}; const node = new RpdeNode( @@ -82,7 +136,7 @@ describe('RequiredPropertyValuesRule', () => { } }); - it('should raise an error when there is an item field that is not an object', () => { + it('should raise an error when there is an items field that is not an object', () => { json.items[0] = 1234; const node = new RpdeNode( url, From 982505a9fb204d8f3e09660d9a6d7b2bfe823ba7 Mon Sep 17 00:00:00 2001 From: nickevansuk <2616208+nickevansuk@users.noreply.github.com> Date: Thu, 12 Oct 2023 16:47:24 +0100 Subject: [PATCH 4/4] Fix failing tests --- .vscode/launch.json | 17 +++++++++++++++++ src/rules/page/required-property-values-rule.js | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f0b054f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Jasmine Tests", + "program": "${workspaceFolder:rpde-validator}/node_modules/jasmine/bin/jasmine.js", + "env": { + "NODE_PATH": "." + } + } +] +} \ No newline at end of file diff --git a/src/rules/page/required-property-values-rule.js b/src/rules/page/required-property-values-rule.js index e0ddfcb..36d5b5c 100644 --- a/src/rules/page/required-property-values-rule.js +++ b/src/rules/page/required-property-values-rule.js @@ -134,6 +134,8 @@ const RequiredPropertyValuesRule = class extends RpdeRule { state: 0, kind: 0, item: 0, + id: 0, + data: 0, }; if (node.data.items instanceof Array) { @@ -170,7 +172,7 @@ const RequiredPropertyValuesRule = class extends RpdeRule { } if ( typeof item.data !== 'undefined' - && typeof item.data !== 'object' + && (typeof item.data !== 'object' || item.data instanceof Array) ) { invalidProps.data += 1; }