@squiz/dx-json-schema-lib 1.2.13-alpha.2 → 1.2.13-alpha.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/jest.config.ts +7 -0
  3. package/lib/JsonValidationService.d.ts +4 -6
  4. package/lib/JsonValidationService.js +90 -28
  5. package/lib/JsonValidationService.js.map +1 -1
  6. package/lib/JsonValidationService.spec.js +276 -65
  7. package/lib/JsonValidationService.spec.js.map +1 -1
  8. package/lib/errors/SchemaValidationError.d.ts +1 -1
  9. package/lib/errors/SchemaValidationError.js +8 -1
  10. package/lib/errors/SchemaValidationError.js.map +1 -1
  11. package/lib/formatted-text/v1/formattedText.d.ts +18 -16
  12. package/lib/formatted-text/v1/formattedText.json +59 -88
  13. package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.d.ts +8 -0
  14. package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.js +21 -0
  15. package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.js.map +1 -0
  16. package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.d.ts +1 -0
  17. package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.js +52 -0
  18. package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.js.map +1 -0
  19. package/lib/index.d.ts +1 -0
  20. package/lib/index.js +1 -0
  21. package/lib/index.js.map +1 -1
  22. package/lib/manifest/v1/Draft-07.json +155 -0
  23. package/lib/manifest/v1/DxComponentInputSchema.json +11 -8
  24. package/lib/manifest/v1/DxComponentInputSchema.spec.js +23 -9
  25. package/lib/manifest/v1/DxComponentInputSchema.spec.js.map +1 -1
  26. package/lib/manifest/v1/__test__/schemas/badFunctionInputComponent.json +2 -1
  27. package/lib/manifest/v1/__test__/schemas/badNestedFunctionInput.json +2 -1
  28. package/lib/manifest/v1/__test__/schemas/nonObjectFunctionInputComponent.json +2 -1
  29. package/lib/manifest/v1/__test__/schemas/validComponentJson.json +48 -0
  30. package/lib/manifest/v1/v1.d.ts +5 -7
  31. package/lib/manifest/v1/v1.spec.js +22 -3
  32. package/lib/manifest/v1/v1.spec.js.map +1 -1
  33. package/package.json +4 -3
  34. package/src/JsonValidationService.spec.ts +379 -70
  35. package/src/JsonValidationService.ts +112 -34
  36. package/src/errors/SchemaValidationError.ts +10 -2
  37. package/src/formatted-text/v1/formattedText.json +65 -89
  38. package/src/formatted-text/v1/formattedText.ts +19 -17
  39. package/src/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.ts +58 -0
  40. package/src/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.ts +36 -0
  41. package/src/index.ts +1 -0
  42. package/src/manifest/v1/Draft-07.json +155 -0
  43. package/src/manifest/v1/DxComponentInputSchema.json +11 -8
  44. package/src/manifest/v1/DxComponentInputSchema.spec.ts +63 -35
  45. package/src/manifest/v1/__test__/schemas/badFunctionInputComponent.json +2 -1
  46. package/src/manifest/v1/__test__/schemas/badNestedFunctionInput.json +2 -1
  47. package/src/manifest/v1/__test__/schemas/nonObjectFunctionInputComponent.json +2 -1
  48. package/src/manifest/v1/__test__/schemas/validComponentJson.json +48 -0
  49. package/src/manifest/v1/v1.spec.ts +37 -3
  50. package/src/manifest/v1/v1.ts +5 -7
  51. package/tsconfig.json +3 -1
  52. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.2.13-alpha.3](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.2.2...v1.2.13-alpha.3) (2023-01-16)
7
+
8
+ **Note:** Version bump only for package @squiz/dx-json-schema-lib
9
+
6
10
  ## [1.2.13-alpha.2](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.2.2...v1.2.13-alpha.2) (2023-01-13)
7
11
 
8
12
  **Note:** Version bump only for package @squiz/dx-json-schema-lib
package/jest.config.ts CHANGED
@@ -7,6 +7,7 @@ configFunc();
7
7
  const config: Config = {
8
8
  preset: 'ts-jest',
9
9
  testEnvironment: 'node',
10
+
10
11
  testPathIgnorePatterns: [
11
12
  '<rootDir>/lib/',
12
13
  '<rootDir>/cdk.out/',
@@ -15,6 +16,12 @@ const config: Config = {
15
16
  '.*\\.integration\\.spec\\.ts$',
16
17
  ],
17
18
  maxWorkers: '80%',
19
+
20
+ globals: {
21
+ 'ts-jest': {
22
+ diagnostics: false,
23
+ },
24
+ },
18
25
  };
19
26
 
20
27
  export default config;
@@ -1,9 +1,7 @@
1
- import Ajv, { AnySchemaObject, SchemaObject } from 'ajv';
1
+ import { JSONSchema } from 'json-schema-library';
2
2
  export declare class JsonValidationService {
3
- ajv: Ajv;
4
- constructor();
5
3
  validateManifest(manifest: unknown, version: 'v1'): true;
6
- validateContentSchema(contentSchema: AnySchemaObject): true;
7
- validateComponentInput(functionInputSchema: SchemaObject, inputValue: unknown): true;
8
- private doValidate;
4
+ validateContentSchema(contentSchema: JSONSchema): true;
5
+ validateComponentInput(functionInputSchema: JSONSchema, inputValue: unknown): true;
6
+ private processValidationResult;
9
7
  }
@@ -4,50 +4,112 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.JsonValidationService = void 0;
7
- const ajv_1 = __importDefault(require("ajv"));
8
- const ajv_formats_1 = __importDefault(require("ajv-formats"));
9
- const better_ajv_errors_1 = __importDefault(require("better-ajv-errors"));
10
7
  const DxComponentInputSchema_json_1 = __importDefault(require("./manifest/v1/DxComponentInputSchema.json"));
11
8
  const DxComponentIcons_json_1 = __importDefault(require("./manifest/v1/DxComponentIcons.json"));
12
9
  const DxContentMetaSchema_json_1 = __importDefault(require("./manifest/v1/DxContentMetaSchema.json"));
10
+ const Draft_07_json_1 = __importDefault(require("./manifest/v1/Draft-07.json"));
11
+ const formattedText_json_1 = __importDefault(require("./formatted-text/v1/formattedText.json"));
13
12
  const v1_json_1 = __importDefault(require("./manifest/v1/v1.json"));
14
13
  const SchemaValidationError_1 = require("./errors/SchemaValidationError");
14
+ const json_schema_library_1 = require("json-schema-library");
15
+ const json_schema_library_2 = require("json-schema-library");
16
+ const defaultConfig = {
17
+ ...json_schema_library_2.draft07Config,
18
+ errors: {
19
+ ...json_schema_library_2.draft07Config.errors,
20
+ enumError(data) {
21
+ let values = '[]';
22
+ if (data.values && Array.isArray(data.values)) {
23
+ if (data.values.length < 5) {
24
+ values = `[${data.values.join(', ')}]`;
25
+ }
26
+ else {
27
+ const firstFiveValues = data.values.slice(0, 5);
28
+ values = `[${firstFiveValues.join(', ')}, ... ${data.values.length - 5} more]`;
29
+ }
30
+ }
31
+ return {
32
+ type: 'error',
33
+ name: 'EnumError',
34
+ code: 'enum-error',
35
+ message: `Expected given value \`${data.value}\` in ${data.pointer}\` to be one of \`${values}\``,
36
+ data,
37
+ };
38
+ },
39
+ anyOfError(data) {
40
+ let value = `Value \`${data.value}\` at`;
41
+ if (typeof data.value == 'object') {
42
+ value = 'Object at';
43
+ }
44
+ if (Array.isArray(data.value)) {
45
+ value = 'Array at';
46
+ }
47
+ return {
48
+ type: 'error',
49
+ name: 'AnyOfError',
50
+ code: 'any-of-error',
51
+ message: `${value} \`${data.pointer}\` does not match any schema`,
52
+ data,
53
+ };
54
+ },
55
+ },
56
+ };
57
+ const FTSchema = new json_schema_library_1.Draft07(formattedText_json_1.default);
58
+ const ComponentInputSchema = new json_schema_library_1.Draft({
59
+ ...defaultConfig,
60
+ resolveRef(schema, rootSchema) {
61
+ const resolvedSchema = json_schema_library_2.draft07Config.resolveRef(schema, rootSchema);
62
+ if (!resolvedSchema) {
63
+ return resolvedSchema;
64
+ }
65
+ if (resolvedSchema.type === 'FormattedText') {
66
+ return FTSchema.rootSchema;
67
+ }
68
+ else if (Array.isArray(resolvedSchema.type) && resolvedSchema.type.includes('FormattedText')) {
69
+ return {
70
+ ...schema,
71
+ ...FTSchema.rootSchema,
72
+ type: resolvedSchema.type.filter((t) => t !== 'FormattedText').concat(formattedText_json_1.default.type),
73
+ };
74
+ }
75
+ else {
76
+ return resolvedSchema;
77
+ }
78
+ },
79
+ }, DxComponentInputSchema_json_1.default);
80
+ ComponentInputSchema.addRemoteSchema('DxComponentInputSchema.json/DxContentMetaSchema.json', DxContentMetaSchema_json_1.default);
81
+ const v1Schema = new json_schema_library_1.Draft07(v1_json_1.default, defaultConfig);
82
+ v1Schema.addRemoteSchema('DxComponentInputSchema.json/DxContentMetaSchema.json', DxContentMetaSchema_json_1.default);
83
+ v1Schema.addRemoteSchema('/DxComponentInputSchema.json', ComponentInputSchema.getSchema());
84
+ v1Schema.addRemoteSchema('/DxComponentIcons.json', DxComponentIcons_json_1.default);
85
+ v1Schema.addRemoteSchema('http://json-schema.org/draft-07/schema', Draft_07_json_1.default);
86
+ v1Schema.addRemoteSchema('http://json-schema.org/draft-07/schema#', Draft_07_json_1.default);
87
+ const ContentSchemaSchema = new json_schema_library_1.Draft07(DxComponentInputSchema_json_1.default, defaultConfig);
88
+ ContentSchemaSchema.addRemoteSchema('DxComponentInputSchema.json/DxContentMetaSchema.json', DxContentMetaSchema_json_1.default);
15
89
  class JsonValidationService {
16
- constructor() {
17
- this.ajv = new ajv_1.default({
18
- strict: true,
19
- schemas: { DxContentMetaSchema: DxContentMetaSchema_json_1.default, v1: v1_json_1.default, DxComponentIcons: DxComponentIcons_json_1.default, DxComponentInputSchema: DxComponentInputSchema_json_1.default },
20
- allowUnionTypes: true,
21
- allErrors: true,
22
- formats: {
23
- 'multi-line': true,
24
- },
25
- });
26
- (0, ajv_formats_1.default)(this.ajv);
27
- }
28
90
  validateManifest(manifest, version) {
29
91
  switch (version) {
30
- case 'v1':
31
- return this.doValidate(v1_json_1.default, manifest);
92
+ case 'v1': {
93
+ const validationResult = v1Schema.validate(manifest);
94
+ return this.processValidationResult(validationResult);
95
+ }
32
96
  default:
33
- throw new Error('Invalid manifest version');
97
+ throw new SchemaValidationError_1.SchemaValidationError('Invalid manifest version');
34
98
  }
35
99
  }
36
100
  validateContentSchema(contentSchema) {
37
- // This schema matches the input definition in the manifest
38
- return this.doValidate(DxComponentInputSchema_json_1.default, contentSchema);
101
+ return this.processValidationResult(ContentSchemaSchema.validate(contentSchema));
39
102
  }
40
103
  validateComponentInput(functionInputSchema, inputValue) {
41
- return this.doValidate(functionInputSchema, inputValue);
104
+ const inputSchema = ComponentInputSchema.compileSchema(functionInputSchema);
105
+ const errors = ComponentInputSchema.validate(inputValue, inputSchema);
106
+ return this.processValidationResult(errors);
42
107
  }
43
- doValidate(schema, value) {
44
- const result = this.ajv.validate(schema, value);
45
- if (!result) {
46
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
47
- const betterErrors = (0, better_ajv_errors_1.default)(schema, value, this.ajv.errors, { format: 'js' });
48
- throw new SchemaValidationError_1.SchemaValidationError(betterErrors);
108
+ processValidationResult(errors) {
109
+ if (errors.length > 0) {
110
+ throw new SchemaValidationError_1.SchemaValidationError(errors.map((a) => a.message).join(',\n'));
49
111
  }
50
- return result;
112
+ return true;
51
113
  }
52
114
  }
53
115
  exports.JsonValidationService = JsonValidationService;
@@ -1 +1 @@
1
- {"version":3,"file":"JsonValidationService.js","sourceRoot":"","sources":["../src/JsonValidationService.ts"],"names":[],"mappings":";;;;;;AAAA,8CAAyD;AACzD,8DAAqC;AACrC,0EAAgD;AAEhD,4GAA+E;AAC/E,gGAAmE;AACnE,sGAAyE;AACzE,oEAAuC;AACvC,0EAAuE;AAEvE,MAAa,qBAAqB;IAEhC;QACE,IAAI,CAAC,GAAG,GAAG,IAAI,aAAG,CAAC;YACjB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,EAAE,mBAAmB,EAAnB,kCAAmB,EAAE,EAAE,EAAF,iBAAE,EAAE,gBAAgB,EAAhB,+BAAgB,EAAE,sBAAsB,EAAtB,qCAAsB,EAAE;YAC9E,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,IAAI;YACf,OAAO,EAAE;gBACP,YAAY,EAAE,IAAI;aACnB;SACF,CAAC,CAAC;QAEH,IAAA,qBAAU,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,gBAAgB,CAAC,QAAiB,EAAE,OAAa;QAC/C,QAAQ,OAAO,EAAE;YACf,KAAK,IAAI;gBACP,OAAO,IAAI,CAAC,UAAU,CAAC,iBAAE,EAAE,QAAQ,CAAC,CAAC;YAEvC;gBACE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;SAC/C;IACH,CAAC;IAED,qBAAqB,CAAC,aAA8B;QAClD,2DAA2D;QAC3D,OAAO,IAAI,CAAC,UAAU,CAAC,qCAAsB,EAAE,aAAa,CAAC,CAAC;IAChE,CAAC;IAED,sBAAsB,CAAC,mBAAiC,EAAE,UAAmB;QAC3E,OAAO,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;IAC1D,CAAC;IAEO,UAAU,CAAC,MAA6B,EAAE,KAAc;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,EAAE;YACX,oEAAoE;YACpE,MAAM,YAAY,GAAG,IAAA,2BAAe,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACxF,MAAM,IAAI,6CAAqB,CAAC,YAAY,CAAC,CAAC;SAC/C;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA3CD,sDA2CC"}
1
+ {"version":3,"file":"JsonValidationService.js","sourceRoot":"","sources":["../src/JsonValidationService.ts"],"names":[],"mappings":"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"}
@@ -6,12 +6,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const JsonValidationService_1 = require("./JsonValidationService");
7
7
  const SchemaValidationError_1 = require("./errors/SchemaValidationError");
8
8
  const validComponent_json_1 = __importDefault(require("./manifest/v1/__test__/schemas/validComponent.json"));
9
+ const validComponentJson_json_1 = __importDefault(require("./manifest/v1/__test__/schemas/validComponentJson.json"));
10
+ // eslint-disable-next-line @typescript-eslint/ban-types
11
+ function expectToThrowErrorMatchingTypeAndMessage(received, errorType, message) {
12
+ let error = null;
13
+ try {
14
+ received();
15
+ }
16
+ catch (e) {
17
+ error = e;
18
+ }
19
+ expect(error).toBeDefined();
20
+ expect(error === null || error === void 0 ? void 0 : error.message).toEqual(message);
21
+ expect(error).toBeInstanceOf(errorType);
22
+ }
9
23
  describe('JsonValidationService', () => {
10
- let jsonValidationService;
11
- beforeEach(() => {
12
- jsonValidationService = new JsonValidationService_1.JsonValidationService();
13
- });
24
+ const jsonValidationService = new JsonValidationService_1.JsonValidationService();
14
25
  describe('validateManifest', () => {
26
+ it('should return true for a valid JSON endpoint manifest', () => {
27
+ const result = jsonValidationService.validateManifest(validComponentJson_json_1.default, 'v1');
28
+ expect(result).toBe(true);
29
+ });
15
30
  it('should return true for a valid manifest', () => {
16
31
  const result = jsonValidationService.validateManifest(validComponent_json_1.default, 'v1');
17
32
  expect(result).toBe(true);
@@ -19,17 +34,14 @@ describe('JsonValidationService', () => {
19
34
  it('should throw a SchemaValidationError for an invalid manifest', () => {
20
35
  const invalidManifest = { ...validComponent_json_1.default };
21
36
  delete invalidManifest.name;
22
- expect(() => {
23
- jsonValidationService.validateManifest(invalidManifest, 'v1');
24
- }).toThrow(SchemaValidationError_1.SchemaValidationError);
25
- expect(() => {
37
+ expectToThrowErrorMatchingTypeAndMessage(() => {
26
38
  jsonValidationService.validateManifest(invalidManifest, 'v1');
27
- }).toMatchInlineSnapshot(`[Function]`);
39
+ }, SchemaValidationError_1.SchemaValidationError, `failed validation: The required property \`name\` is missing at \`#\``);
28
40
  });
29
41
  it('should throw an error for an invalid manifest version', () => {
30
- expect(() => {
42
+ expectToThrowErrorMatchingTypeAndMessage(() => {
31
43
  jsonValidationService.validateManifest(validComponent_json_1.default, 'invalid-version');
32
- }).toThrow(Error);
44
+ }, SchemaValidationError_1.SchemaValidationError, 'failed validation: Invalid manifest version');
33
45
  });
34
46
  });
35
47
  describe('validateContentSchema', () => {
@@ -44,8 +56,7 @@ describe('JsonValidationService', () => {
44
56
  const result = jsonValidationService.validateContentSchema(contentSchema);
45
57
  expect(result).toBe(true);
46
58
  });
47
- // TODO DEVX-658
48
- it.skip('should return false for an invalid content schema, where the required property is missed from a child object', () => {
59
+ it('should return false for an invalid content schema, where the required property is missed from a child object', () => {
49
60
  const contentSchema = {
50
61
  type: 'object',
51
62
  properties: {
@@ -58,9 +69,9 @@ describe('JsonValidationService', () => {
58
69
  },
59
70
  required: ['my-input'],
60
71
  };
61
- expect(() => {
72
+ expectToThrowErrorMatchingTypeAndMessage(() => {
62
73
  jsonValidationService.validateContentSchema(contentSchema);
63
- }).toThrow(SchemaValidationError_1.SchemaValidationError);
74
+ }, SchemaValidationError_1.SchemaValidationError, 'failed validation: The required property `required` is missing at `#/properties/my-input`');
64
75
  });
65
76
  it('should throw a SchemaValidationError for an invalid content schema, top level type must be object', () => {
66
77
  const contentSchema = {
@@ -73,70 +84,270 @@ describe('JsonValidationService', () => {
73
84
  required: ['my-input'],
74
85
  },
75
86
  };
76
- expect(() => {
87
+ expectToThrowErrorMatchingTypeAndMessage(() => {
77
88
  jsonValidationService.validateContentSchema(contentSchema);
78
- }).toThrow(SchemaValidationError_1.SchemaValidationError);
89
+ }, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected value at \`#/type\` to be \`object\`, but value given is \`array\``);
79
90
  });
80
- // TODO DEVX-658
81
- it.skip('should throw a SchemaValidationError for an invalid content schema missing the required property', () => {
91
+ it('should throw a SchemaValidationError for an invalid content schema missing the required property', () => {
82
92
  const contentSchema = {
83
93
  type: 'object',
84
94
  properties: {
85
95
  'my-input': { type: 'number' },
86
96
  },
87
97
  };
88
- expect(() => {
98
+ expectToThrowErrorMatchingTypeAndMessage(() => {
89
99
  jsonValidationService.validateContentSchema(contentSchema);
90
- }).toThrow(SchemaValidationError_1.SchemaValidationError);
100
+ }, SchemaValidationError_1.SchemaValidationError, 'failed validation: The required property `required` is missing at `#`');
91
101
  });
92
102
  });
93
103
  describe('validateComponentInput', () => {
94
- const functionInputSchema = {
95
- type: 'object',
96
- properties: {
97
- 'my-input': { type: 'number' },
98
- },
99
- required: ['my-input'],
100
- };
101
- it('should return true for valid input values', () => {
102
- const inputValue = {
103
- 'my-input': 123,
104
- };
105
- const result = jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
106
- expect(result).toBe(true);
107
- });
108
- it('should throw a SchemaValidationError for invalid input type', () => {
109
- const inputValue = {
110
- 'my-input': '123',
111
- };
112
- expect(() => {
113
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
114
- }).toThrow(SchemaValidationError_1.SchemaValidationError);
115
- expect(() => {
116
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
117
- }).toMatchInlineSnapshot(`[Function]`);
118
- });
119
- it('should throw a SchemaValidationError for invalid input missing properties', () => {
120
- const inputValue = {};
121
- expect(() => {
122
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
123
- }).toThrow(SchemaValidationError_1.SchemaValidationError);
124
- expect(() => {
125
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
126
- }).toMatchInlineSnapshot(`[Function]`);
104
+ describe('FormattedText input', () => {
105
+ it('should handle type as an array', () => {
106
+ const functionInputSchema = {
107
+ type: 'object',
108
+ properties: {
109
+ 'my-input': { type: ['number', 'string'] },
110
+ },
111
+ required: ['my-input'],
112
+ };
113
+ expect(jsonValidationService.validateComponentInput(functionInputSchema, {
114
+ 'my-input': 'formattedText',
115
+ })).toEqual(true);
116
+ expect(jsonValidationService.validateComponentInput(functionInputSchema, {
117
+ 'my-input': 123,
118
+ })).toEqual(true);
119
+ });
120
+ it('should handle type is an array of both string and FormattedText', () => {
121
+ const formattedText = [
122
+ {
123
+ tag: 'p',
124
+ type: 'tag',
125
+ children: [
126
+ { type: 'text', value: 'This is some ' },
127
+ { type: 'text', value: 'Link to asset 12345' },
128
+ { type: 'text', value: ' with an image ' },
129
+ { type: 'text', value: '.' },
130
+ ],
131
+ },
132
+ ];
133
+ const functionInputSchema = {
134
+ type: 'object',
135
+ properties: {
136
+ 'my-input': { type: ['FormattedText', 'string'] },
137
+ },
138
+ required: ['my-input'],
139
+ };
140
+ expect(jsonValidationService.validateComponentInput(functionInputSchema, {
141
+ 'my-input': formattedText,
142
+ })).toEqual(true);
143
+ expect(jsonValidationService.validateComponentInput(functionInputSchema, {
144
+ 'my-input': 'hello',
145
+ })).toEqual(true);
146
+ });
147
+ it('should return true if input is formatted text', () => {
148
+ const functionInputSchema = {
149
+ type: 'object',
150
+ properties: {
151
+ 'my-input': { type: 'FormattedText' },
152
+ },
153
+ required: ['my-input'],
154
+ };
155
+ const formattedText = [
156
+ {
157
+ tag: 'p',
158
+ type: 'tag',
159
+ children: [
160
+ { type: 'text', value: 'This is some ' },
161
+ { type: 'text', value: 'Link to asset 12345' },
162
+ { type: 'text', value: ' with an image ' },
163
+ { type: 'text', value: '.' },
164
+ ],
165
+ },
166
+ ];
167
+ const inputValue = {
168
+ 'my-input': formattedText,
169
+ };
170
+ expect(jsonValidationService.validateComponentInput(functionInputSchema, inputValue)).toEqual(true);
171
+ });
172
+ it('should throw an error if the FormattedText input is not formatted text', () => {
173
+ const functionInputSchema = {
174
+ type: 'object',
175
+ properties: {
176
+ 'my-input': { type: 'FormattedText' },
177
+ },
178
+ required: ['my-input'],
179
+ };
180
+ const inputValue = {
181
+ 'my-input': 123,
182
+ };
183
+ expectToThrowErrorMatchingTypeAndMessage(() => {
184
+ jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
185
+ }, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected \`123\` (number) in \`#/my-input\` to be of type \`array\``);
186
+ });
187
+ it('should throw an error if the FormattedText input is invalid formatted text', () => {
188
+ const functionInputSchema = {
189
+ type: 'object',
190
+ properties: {
191
+ 'my-input': { type: 'FormattedText' },
192
+ },
193
+ required: ['my-input'],
194
+ };
195
+ const inputValue = {
196
+ 'my-input': {
197
+ something: 'aa',
198
+ },
199
+ };
200
+ expectToThrowErrorMatchingTypeAndMessage(() => {
201
+ jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
202
+ }, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected \`[object Object]\` (object) in \`#/my-input\` to be of type \`array\``);
203
+ });
204
+ it('should throw an error if the FormattedText input is invalid formatted text (deeply nested)', () => {
205
+ const functionInputSchema = {
206
+ type: 'object',
207
+ properties: {
208
+ 'my-input': { type: 'FormattedText' },
209
+ },
210
+ required: ['my-input'],
211
+ };
212
+ const formattedText = [
213
+ {
214
+ tag: 'p',
215
+ type: 'tag',
216
+ children: [
217
+ { type: 'text', value: 'This is some ' },
218
+ { type: 'text', value: 'Link to asset 12345' },
219
+ { type: 'text', value: ' with an image ' },
220
+ { type: 'text', value: 123 },
221
+ { type: 'text', value: '.' },
222
+ ],
223
+ },
224
+ ];
225
+ const inputValue = {
226
+ 'my-input': formattedText,
227
+ };
228
+ expectToThrowErrorMatchingTypeAndMessage(() => {
229
+ jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
230
+ }, SchemaValidationError_1.SchemaValidationError, 'failed validation: Object at `#/my-input/0` does not match any schema');
231
+ });
232
+ it('should validate an array of formatted texts', () => {
233
+ const formattedText = [
234
+ {
235
+ tag: 'p',
236
+ type: 'tag',
237
+ children: [{ type: 'text', value: 'hello' }],
238
+ },
239
+ ];
240
+ const schema = {
241
+ type: 'object',
242
+ properties: {
243
+ arr: {
244
+ type: 'array',
245
+ items: { type: 'FormattedText' },
246
+ },
247
+ },
248
+ };
249
+ const value = {
250
+ arr: [formattedText],
251
+ };
252
+ expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
253
+ });
254
+ it('should throw an error if the FormattedText input is invalid formatted text (deeply, deeply nested)', () => {
255
+ const formattedText = [
256
+ {
257
+ tag: 'p',
258
+ type: 'tag',
259
+ children: [{ type: 'text', value: 'hello' }],
260
+ },
261
+ ];
262
+ const inputValue = {
263
+ 'my-input': formattedText,
264
+ deep: {
265
+ arr: [
266
+ {
267
+ prop: formattedText,
268
+ formattedTextArray: [formattedText, formattedText, { bad: 'data' }],
269
+ },
270
+ ],
271
+ },
272
+ };
273
+ const functionInputSchema = {
274
+ type: 'object',
275
+ properties: {
276
+ 'my-input': { type: 'FormattedText' },
277
+ deep: {
278
+ type: 'object',
279
+ properties: {
280
+ arr: {
281
+ type: 'array',
282
+ items: {
283
+ type: 'object',
284
+ required: ['prop', 'formattedTextArray'],
285
+ properties: {
286
+ prop: 'FormattedText',
287
+ formattedTextArray: {
288
+ type: 'array',
289
+ items: {
290
+ type: 'FormattedText',
291
+ },
292
+ },
293
+ },
294
+ },
295
+ },
296
+ },
297
+ required: ['arr'],
298
+ },
299
+ },
300
+ required: ['my-input', 'deep'],
301
+ };
302
+ expectToThrowErrorMatchingTypeAndMessage(() => {
303
+ jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
304
+ }, SchemaValidationError_1.SchemaValidationError, 'failed validation: Expected `[object Object]` (object) in `#/deep/arr/0/formattedTextArray/2` to be of type `array`');
305
+ });
127
306
  });
128
- // TODO DEVX-658
129
- it.skip('should throw a SchemaValidationError for invalid input additional properties', () => {
130
- const inputValue = {
131
- 'my-input': 123,
132
- 'my-input-2': 123,
307
+ describe('standard inputs', () => {
308
+ const functionInputSchema = {
309
+ type: 'object',
310
+ properties: {
311
+ 'my-input': { type: 'number' },
312
+ },
313
+ required: ['my-input'],
133
314
  };
134
- expect(() => {
135
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
136
- }).toThrow(SchemaValidationError_1.SchemaValidationError);
137
- expect(() => {
138
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
139
- }).toMatchInlineSnapshot();
315
+ it('should return true for valid input values', () => {
316
+ const inputValue = {
317
+ 'my-input': 123,
318
+ };
319
+ const result = jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
320
+ expect(result).toBe(true);
321
+ });
322
+ it('should throw a SchemaValidationError for invalid input type', () => {
323
+ const inputValue = {
324
+ 'my-input': '123',
325
+ };
326
+ expectToThrowErrorMatchingTypeAndMessage(() => {
327
+ jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
328
+ }, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected \`123\` (string) in \`#/my-input\` to be of type \`number\``);
329
+ });
330
+ it('should throw a SchemaValidationError for invalid input missing properties', () => {
331
+ const inputValue = {};
332
+ expectToThrowErrorMatchingTypeAndMessage(() => {
333
+ jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
334
+ }, SchemaValidationError_1.SchemaValidationError, `failed validation: The required property \`my-input\` is missing at \`#\``);
335
+ });
336
+ it('should throw a SchemaValidationError with a truncated enum value list if there are more than 5 enum options', () => {
337
+ expectToThrowErrorMatchingTypeAndMessage(() => {
338
+ jsonValidationService.validateComponentInput({ type: 'object', properties: { enum: { type: 'string', enum: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] } } }, { enum: 'z' });
339
+ }, SchemaValidationError_1.SchemaValidationError, 'failed validation: Expected given value `z` in #/enum` to be one of `[a, b, c, d, e, ... 2 more]`');
340
+ });
341
+ // TODO DEVX-658
342
+ it.skip('should throw a SchemaValidationError for invalid input additional properties', () => {
343
+ const inputValue = {
344
+ 'my-input': 123,
345
+ 'my-input-2': 123,
346
+ };
347
+ expect(() => {
348
+ jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
349
+ }).toThrowErrorMatchingInlineSnapshot();
350
+ });
140
351
  });
141
352
  });
142
353
  });