import expect from "expect" import validateHelper from "../validate-helper.js" describe(`validation plugin - semantic - 2and3 parameters`, () => { describe(`parameters must have unique name + in values`, () => { describe(`direct siblings`, () => { it("should return an error for an invalid Swagger 2 definition", () => { const spec = { swagger: "2.0", "paths": { "/pets": { "parameters": [ { "name": "pathLevel", "in": "query", "description": "tags to filter by", "type": "string" }, { "name": "pathLevel", "in": "query", "description": "tags to filter by", "type": "string" }, ], "get": { "parameters": [ { "name": "opLevel", "in": "query", "description": "tags to filter by", "type": "string" }, { "name": "opLevel", "in": "query", "description": "tags to filter by", "type": "string" }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() const firstError = allErrors[0] const secondError = allErrors[1] expect(allErrors.length).toEqual(2) expect(firstError.path).toEqual(["paths", "/pets", "parameters", "1"]) expect(firstError.message).toEqual("Sibling parameters must have unique name + in values") expect(secondError.path).toEqual(["paths", "/pets", "get", "parameters", "1"]) expect(secondError.message).toEqual("Sibling parameters must have unique name + in values") }) }) it("should return an error for an invalid OpenAPI 3 definition", () => { const spec = { openapi: "3.0.0", "paths": { "/pets": { "parameters": [ { "name": "pathLevel", "in": "query", "description": "tags to filter by", "schema": { "type": "string" } }, { "name": "pathLevel", "in": "query", "description": "tags to filter by", "schema": { "type": "string" } }, ], "get": { "parameters": [ { "name": "opLevel", "in": "query", "description": "tags to filter by", "schema": { "type": "string" } }, { "name": "opLevel", "in": "query", "description": "tags to filter by", "schema": { "type": "string" } }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() const firstError = allErrors[0] const secondError = allErrors[1] expect(allErrors.length).toEqual(2) expect(firstError.path).toEqual(["paths", "/pets", "parameters", "1"]) expect(firstError.message).toEqual("Sibling parameters must have unique name + in values") expect(secondError.path).toEqual(["paths", "/pets", "get", "parameters", "1"]) expect(secondError.message).toEqual("Sibling parameters must have unique name + in values") }) }) it("should return no errors for a valid Swagger 2 definition", () => { const spec = { swagger: "2.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "wags", "in": "query", "description": "wags to filter by", "type": "string" }, { "name": "tags", "in": "query", "description": "tags to filter by", "type": "string" }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return no errors for a valid OpenAPI 3 definition", () => { const spec = { openapi: "3.0.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "wags", "in": "query", "description": "wags to filter by", "type": "string" }, { "name": "tags", "in": "query", "description": "tags to filter by", "type": "string" }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) }) describe(`inherited siblings`, () => { it("should return no errors for a valid Swagger 2 definition due to inheritance", () => { const spec = { swagger: "2.0", parameters: { MyParam: { name: "one", in: "query" } }, "paths": { "/pets": { "parameters": [ { name: "one", in: "query" }, { name: "two", in: "query" } ], "get": { "parameters": [ { name: "two", in: "query" }, { name: "three", in: "query" } ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return no errors for a valid OpenAPI 3 definition due to inheritance", () => { const spec = { openapi: "3.0.0", parameters: { MyParam: { name: "one", in: "query" } }, "paths": { "/pets": { "parameters": [ { name: "one", in: "query" }, { name: "two", in: "query" } ], "get": { "parameters": [ { name: "two", in: "query" }, { name: "three", in: "query" } ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should not return an error for root parameters in Swagger 2", () => { const spec = { swagger: "2.0", parameters: { MyParam: { name: "one", in: "query" } }, "paths": { "/pets": { "parameters": [ { name: "otherParam", in: "query" } ], "get": { "parameters": [ { name: "one", in: "query" } ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should not return an error for root parameters in OpenAPI 3", () => { const spec = { openapi: "3.0.0", parameters: { MyParam: { name: "one", in: "query" } }, "paths": { "/pets": { "parameters": [ { name: "otherParam", in: "query" } ], "get": { "parameters": [ { name: "one", in: "query" } ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return no errors for a valid Swagger 2 definition", () => { const spec = { swagger: "2.0", parameters: { MyParamOne: { name: "one", in: "query" }, MyParamTwo: { name: "anotherParam1", in: "query" }, }, "paths": { "/pets/{one}/{two}": { "parameters": [ { name: "one", in: "path", required: true }, { name: "two", in: "query" }, { name: "anotherParam2", in: "query" }, ], "get": { "parameters": [ { name: "two", in: "path", required: true }, { name: "three", in: "query" }, { name: "anotherParam3", in: "query" }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors).toEqual([]) }) }) it("should return no errors for a valid OpenAPI 3 definition", () => { const spec = { openapi: "3.0.0", parameters: { MyParamOne: { name: "one", in: "query" }, MyParamTwo: { name: "anotherParam1", in: "query" }, }, "paths": { "/pets/{one}/{two}": { "parameters": [ { name: "one", in: "path", required: true }, { name: "two", in: "query" }, { name: "anotherParam2", in: "query" }, ], "get": { "parameters": [ { name: "two", in: "path", required: true }, { name: "three", in: "query" }, { name: "anotherParam3", in: "query" }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) }) }) describe(`parameter defaults must be present in enums`, () => { it("should return an error for an invalid Swagger 2 definition", () => { const spec = { swagger: "2.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "num", "in": "query", "type": "number", enum: [1, 2, 3], default: 0 }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() const firstError = allErrors[0] expect(allErrors.length).toEqual(1) expect(firstError.path).toEqual(["paths", "/pets", "get", "parameters", "0", "default"]) expect(firstError.message).toEqual("Default values must be present in `enum`") }) }) it("should return an error for an invalid OpenAPI 3 definition", () => { const spec = { openapi: "3.0.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "num", "in": "query", "type": "number", schema: { enum: [1, 2, 3], default: 0 } }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() const firstError = allErrors[0] expect(allErrors.length).toEqual(1) expect(firstError.path).toEqual(["paths", "/pets", "get", "parameters", "0", "schema", "default"]) expect(firstError.message).toEqual("Default values must be present in `enum`") }) }) it("should return an error for an invalid OpenAPI 3 definition", () => { const spec = { openapi: "3.0.0", components: { parameters: { MyParam: { "name": "num", "in": "query", "type": "number", schema: { enum: [1, 2, 3], default: 0 } } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() const firstError = allErrors[0] expect(allErrors.length).toEqual(1) expect(firstError.path).toEqual(["components", "parameters", "MyParam", "schema", "default"]) expect(firstError.message).toEqual("Default values must be present in `enum`") }) }) it("should return no errors for a Swagger 2 definition without default set", () => { const spec = { swagger: "2.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "num", "in": "query", "type": "number", enum: [1, 2, 3] }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return no errors for an OpenAPI 3 definition without default set", () => { const spec = { openapi: "3.0.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "num", "in": "query", "type": "number", schema: { enum: [1, 2, 3] } }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return no errors for a Swagger 2 definition without enum set", () => { const spec = { swagger: "2.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "num", "in": "query", "type": "number", default: 0 }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return no errors for an OpenAPI 3 definition without enum set", () => { const spec = { openapi: "3.0.0", "paths": { "/pets": { "get": { "parameters": [ { "name": "num", "in": "query", "type": "number", schema: { default: 0 } }, ] } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) }) describe(`path parameters must be in path definition`, () => { it("should return no errors for a valid Swagger 2 definition", () => { const spec = { swagger: "2.0", info: { "title": "Correct path parameters in path", "version": "1.0.0" }, "paths": { "/foo/{param1}/{param2}/{param3}": { "parameters": [ { name: "param1", in: "path", required: true, type: "string" }, { $ref: "#/parameters/param3" } ], "get": { "parameters": [ { name: "param2", in: "path", required: true, type: "string" } ], responses: { "200": { "description": "ok" } } } } }, parameters: { param3: { name: "param3", in: "path", required: true, type: "string" } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return 2 errors for each path parameter that isn't in the path in spec 2", () => { const spec = { swagger: "2.0", info: { "title": "Unused path parameters in path", "version": "1.0.0" }, "paths": { "/foo": { "parameters": [ { name: "param1", in: "path", required: true, type: "string" } ], "get": { "parameters": [ { name: "param2", in: "path", required: true, type: "string" } ], responses: { "200": { "description": "ok" } } } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(2) const firstError = allErrors[0] expect(firstError.path).toEqual(["paths", "/foo", "parameters", "0","name"]) expect(firstError.message).toEqual(`Path parameter "param1" must have the corresponding {param1} segment in the "/foo" path`) const secondError = allErrors[1] expect(secondError.path).toEqual(["paths", "/foo", "get", "parameters", "0","name"]) expect(secondError.message).toEqual(`Path parameter "param2" must have the corresponding {param2} segment in the "/foo" path`) }) }) it("should return 2 errors for each referenced path parameter that isn't in the path for 2 spec", () => { const spec = { swagger: "2.0", info: { "title": "Unused path parameters in path", "version": "1.0.0" }, "paths": { "/foo/{param1}/{param2}": { "parameters": [ { name: "param1", in: "path", required: true, type: "string" }, { $ref: "#/parameters/param3" } ], "get": { "parameters": [ { name: "param2", in: "path", required: true, type: "string" }, { $ref: "#/parameters/param4" } ], responses: { "200": { "description": "ok" } } } } }, parameters: { param3: { name: "param3", in: "path", required: true, type: "string" }, param4: { name: "param4", in: "path", required: true, type: "string" } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(2) const firstError = allErrors[0] expect(firstError.path).toEqual(["paths", "/foo/{param1}/{param2}", "parameters", "1","name"]) expect(firstError.message).toEqual(`Path parameter "param3" must have the corresponding {param3} segment in the "/foo/{param1}/{param2}" path`) const secondError = allErrors[1] expect(secondError.path).toEqual(["paths", "/foo/{param1}/{param2}","get", "parameters", "1","name"]) expect(secondError.message).toEqual(`Path parameter "param4" must have the corresponding {param4} segment in the "/foo/{param1}/{param2}" path`) }) }) it("should return no errors for a valid Swagger 3 definition", () => { const spec = { swagger: "3.0", info: { "title": "Correct path parameters in path", "version": "1.0.0" }, "paths": { "/foo/{param1}/{param2}/{param3}": { "parameters": [ { name: "param1", in: "path", required: true, type: "string" }, { $ref: "#/parameters/param3" } ], "get": { "parameters": [ { name: "param2", in: "path", required: true, type: "string" } ], responses: { "200": { "description": "ok" } } } } }, components: { parameters: { param3: { name: "param3", in: "path", required: true, type: "string" } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(0) }) }) it("should return 2 errors for each path parameter that isn't in the path in spec 3", () => { const spec = { openapi: "3.0.2", info: { "title": "Unused path parameters in path", "version": "1.0.0" }, "paths": { "/foo": { "parameters": [ { name: "param1", in: "path", required: true, type: "string" } ], "get": { "parameters": [ { name: "param2", in: "path", required: true, type: "string" } ], responses: { "200": { "description": "ok" } } } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(2) const firstError = allErrors[0] expect(firstError.path).toEqual(["paths", "/foo", "parameters", "0","name"]) expect(firstError.message).toEqual(`Path parameter "param1" must have the corresponding {param1} segment in the "/foo" path`) const secondError = allErrors[1] expect(secondError.path).toEqual(["paths", "/foo", "get", "parameters", "0","name"]) expect(secondError.message).toEqual(`Path parameter "param2" must have the corresponding {param2} segment in the "/foo" path`) }) }) it("should return 2 errors for each referenced path parameter that isn't in the path for 3 spec", () => { const spec = { openapi: "3.0.2", info: { "title": "Unused path parameters in path", "version": "1.0.0" }, "paths": { "/foo/{param1}/{param2}": { "parameters": [ { name: "param1", in: "path", required: true, type: "string" }, { $ref: "#/components/parameters/param3" } ], "get": { "parameters": [ { name: "param2", in: "path", required: true, type: "string" }, { $ref: "#/components/parameters/param4" } ], responses: { "200": { "description": "ok" } } } } }, components: { parameters: { param3: { name: "param3", in: "path", required: true, type: "string" }, param4: { name: "param4", in: "path", required: true, type: "string" } } } } return validateHelper(spec) .then(system => { const allErrors = system.errSelectors.allErrors().toJS() expect(allErrors.length).toEqual(2) const firstError = allErrors[0] expect(firstError.path).toEqual(["paths", "/foo/{param1}/{param2}", "parameters", "1","name"]) expect(firstError.message).toEqual(`Path parameter "param3" must have the corresponding {param3} segment in the "/foo/{param1}/{param2}" path`) const secondError = allErrors[1] expect(secondError.path).toEqual(["paths", "/foo/{param1}/{param2}","get", "parameters", "1","name"]) expect(secondError.message).toEqual(`Path parameter "param4" must have the corresponding {param4} segment in the "/foo/{param1}/{param2}" path`) }) }) }) })