Skip to content

Commit

Permalink
improve(semval): $ref formatting validation (swagger-api#1656)
Browse files Browse the repository at this point in the history
* Validate $ref formatting via Swagger-Client $$ref meta patches
* Stop falling back to raw $refs
* Add control test for well-formed remote references
  • Loading branch information
shockey authored Feb 3, 2018
1 parent 660485b commit e957a03
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 13 deletions.
44 changes: 31 additions & 13 deletions src/plugins/validate-semantic/validators/refs.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import get from "lodash/get"

export const validateRefHasNoSiblings = () => system => {
return Promise.all([
system.validateSelectors.all$refArtifacts(),
]).then(([nodes]) => {
return system.validateSelectors.all$refArtifacts()
.then((nodes) => {
const immSpecJson = system.specSelectors.specJson()
const specJson = immSpecJson.toJS ? immSpecJson.toJS() : {}

Expand All @@ -28,16 +27,9 @@ export const validateRefHasNoSiblings = () => system => {

// Add warnings for unused definitions
export const validateUnusedDefinitions = () => (system) => {
return Promise.all([
system.validateSelectors.all$refs(),
system.validateSelectors.all$refArtifacts()
]).then(([refs, refArtifacts]) => {
const references = (
(refs.length ? refs : null)
|| (refArtifacts.length ? refArtifacts : null)
|| []
).map(node => node.node)

return system.validateSelectors.all$refArtifacts()
.then((nodes) => {
const references = nodes.map(node => node.node)
const errors = []

system.specSelectors.definitions()
Expand All @@ -55,3 +47,29 @@ export const validateUnusedDefinitions = () => (system) => {
return errors
})
}

export const validateRefPathFormatting = () => (system) => {
return system.validateSelectors.all$refArtifacts()
.then((refArtifacts) => {

const errors = []
refArtifacts.forEach((node) => {
const value = node.node
if(typeof value === "string") {
// eslint-disable-next-line no-unused-vars
const [refUrl, refPath] = value.split("#")

if(!refPath || refPath[0] !== "/") {
errors.push({
// $ref instead of $$ref
path: [...node.path.slice(0, -1), "$ref"],
message: "$ref paths must begin with `#/`",
level: "error"
})
}
}
})

return errors
})
}
48 changes: 48 additions & 0 deletions test/plugins/validate-semantic/refs.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,54 @@ describe("validation plugin - semantic - refs", function() {
})
})

})
describe("Malformed $ref values", () => {
it("should return an error when a JSON pointer lacks a leading `#/`", () => {
const spec = {
paths: {
"/CoolPath": {
$ref: "#myObj/abc"
}
},
myObj: {
abc: {
type: "string"
}
}
}

return validateHelper(spec)
.then(system => {
const allErrors = system.errSelectors.allErrors().toJS()
expect(allErrors.length).toEqual(1)
const firstError = allErrors[0]
expect(firstError.message).toMatch("$ref paths must begin with `#/`")
expect(firstError.level).toEqual("error")
expect(firstError.path).toEqual(["paths", "/CoolPath", "$ref"])
})
})

it("should return no errors when a JSON pointer is a well-formed remote reference", () => {
const spec = {
paths: {
"/CoolPath": {
$ref: "http://google.com#/myObj/abc"
}
},
myObj: {
abc: {
type: "string"
}
}
}

return validateHelper(spec)
.then(system => {
const allErrors = system.errSelectors.allErrors().toJS()
expect(allErrors).toEqual([])
})
})

})
describe.skip("Refs are restricted in specific areas of a spec", () => {
describe("Response $refs", () => {
Expand Down

0 comments on commit e957a03

Please sign in to comment.