From 6b396e7c4a073af639c55cd0b7dbfd8dd99a39a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Pablo=20Caballero?= Date: Fri, 23 Jul 2021 17:04:39 -0300 Subject: [PATCH] Fixed issue #473. Enum works properly now --- src/js/Node.js | 7 +- test/Node.test.js | 187 ++++++++++++++++++++++++++++++++++++++++++ test/test_enum.html | 62 ++++++++++++++ test/test_enum_2.html | 123 +++++++++++++++++++++++++++ 4 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 test/test_enum.html create mode 100644 test/test_enum_2.html diff --git a/src/js/Node.js b/src/js/Node.js index aabf1ee01..73957e59e 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -4482,7 +4482,12 @@ Node._findSchema = (topLevelSchema, schemaRefs, path, currentSchema = topLevelSc if (schemaUrl in schemaRefs) { const referencedSchema = schemaRefs[schemaUrl] const reference = { $ref: '#/'.concat(relativePath) } - return Node._findSchema(referencedSchema, schemaRefs, nextPath, reference) + let auxNextPath = [] + auxNextPath.push(nextKey) + if(nextPath.length > 0) { + auxNextPath.push(...nextPath) + } + return Node._findSchema(referencedSchema, schemaRefs, auxNextPath, reference) } else { throw Error(`Unable to resolve reference ${ref}`) } diff --git a/test/Node.test.js b/test/Node.test.js index 70b43298f..26957a233 100644 --- a/test/Node.test.js +++ b/test/Node.test.js @@ -77,6 +77,69 @@ describe('Node', () => { ) }) + it('should find referenced schema within multi-level object properties', () => { + const schema = { + type: 'object', + properties: { + aProperty: { + "$ref": "second_schema#/definitions/some_def" + } + } + } + const schemaRefs = { + second_schema: { + definitions: { + some_def: { + type: 'object', + properties: { + enumProp: { + enum: [1, 2, 3] + } + } + } + } + } + } + let path = ['aProperty', 'enumProp'] + let expected_schema = { + enum: [1, 2, 3] + } + assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expected_schema) + }) + + it('should find array referenced schema within multi-level object properties', () => { + const schema = { + type: 'object', + properties: { + aProperty: { + type: "array", + items: { + "$ref": "second_schema#/definitions/some_def" + } + } + } + } + const schemaRefs = { + "second_schema": { + "definitions": { + "some_def": { + type: 'object', + properties: { + enumProp: { + enum: [1, 2, 3] + } + } + } + } + } + } + let path = ['aProperty', 0, 'enumProp'] + let expected_schema = { + enum: [1, 2, 3] + } + assert.deepStrictEqual(Node._findSchema(schema, schemaRefs, path), expected_schema) + }) + it('should return null for path that has no schema', () => { const schema = { type: 'object', @@ -152,6 +215,121 @@ describe('Node', () => { const path = ['foo'] assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema) }) + + it('should find a referenced schema property', () => { + const schema = { + type: 'object', + properties: { + foo: { + $ref: 'foo' + } + } + } + const fooSchema = { + type: 'object', + properties: { + levelTwo: { + type: 'string' + } + } + } + const path = ['foo', 'levelTwo'] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.properties.levelTwo) + }) + + it('should find a referenced schema definition', () => { + const schema = { + type: 'object', + properties: { + foo: { + type: "array", + items: { + "$ref": "foo#/definitions/some_def" + } + } + } + } + const fooSchema = { + "definitions": { + "some_def": { + type: 'object', + properties: { + propA: { + type: 'string' + }, + propB: { + type: 'string' + } + } + } + } + } + const path = ['foo', 0] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.definitions.some_def) + }) + + it('should find a referenced schema definition 2', () => { + const schema = { + type: 'object', + properties: { + foo: { + type: "array", + items: { + "$ref": "foo#/definitions/some_def" + } + } + } + } + const fooSchema = { + definitions: { + some_def: { + type: 'object', + properties: { + propA: { + type: 'string' + }, + propB: { + type: 'string' + } + } + } + } + } + const path = ['foo', 0, 'propA'] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.definitions.some_def.properties.propA) + }) + + it('should find a referenced schema definition 3', () => { + const schema = { + type: 'object', + properties: { + foo: { + type: "array", + items: { + "$ref": "foo#/definitions/some_def" + } + } + } + } + const fooSchema = { + "definitions": { + "some_def": { + type: 'object', + properties: { + propA: { + type: 'object', + properties: { + propA1: { type: 'boolean' } + } + }, + propB: { type: 'string' } + } + } + } + } + const path = ['foo', 0, 'propA', 'propA1'] + assert.strictEqual(Node._findSchema(schema, { foo: fooSchema }, path), fooSchema.definitions.some_def.properties.propA.properties.propA1) + }) }) describe('with $ref to internal definition', () => { @@ -423,4 +601,13 @@ describe('Node', () => { }) }) }) + describe('_findEnum', () => { + it('should find enum', () => { + const schema = { + type: 'object', + enum: [1, 2, 3] + } + assert.strictEqual(Node._findEnum(schema), schema.enum) + }) + }) }) diff --git a/test/test_enum.html b/test/test_enum.html new file mode 100644 index 000000000..399f88d3b --- /dev/null +++ b/test/test_enum.html @@ -0,0 +1,62 @@ + + + + JSONEditor | template + enums + + + + + + + + +
+ + + + diff --git a/test/test_enum_2.html b/test/test_enum_2.html new file mode 100644 index 000000000..6f27f033f --- /dev/null +++ b/test/test_enum_2.html @@ -0,0 +1,123 @@ + + + + JSONEditor | template + enums + + + + + + + +

Demonstrates a template with JSON schema validation. To use: click the context menu of the first or second employee, click insert or append, click "Employee".

+

See github issue #473

+ +
+ + + +