Skip to content

Commit

Permalink
Fix problem cannot resolve relative references (swagger-api#984)
Browse files Browse the repository at this point in the history
* Fix many issues

* Fix failed tests

* Add backward compatibility to resolve()

* Remove debug log
  • Loading branch information
buunguyen authored Mar 30, 2017
1 parent 9035699 commit 4e2dff3
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 10 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"deps_check_dir": ".deps_check"
},
"scripts": {
"build": "NODE_ENV=production webpack -p --config ./webpack.config.js && NODE_ENV=production webpack -p --config ./webpack.bundle.config.js ",
"build": "NODE_ENV=production webpack -p --config ./webpack.config.js",
"build-bundle": "NODE_ENV=production webpack -p --config ./webpack.bundle.config.js",
"watch": "webpack --config webpack.config.js --watch --progress",
"test": "NODE_ENV=test node --debug ./node_modules/.bin/_mocha --recursive --compilers js:babel-core/register",
"inspector": "node-debug",
Expand Down
12 changes: 8 additions & 4 deletions src/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,23 @@ export function clearCache() {
plugins.refs.clearCache()
}

export default function resolve({http, fetch, spec, url, mode, allowMetaPatches = true}) {
export default function resolve({http, fetch, spec, url, baseDoc, mode, allowMetaPatches = true}) {
// @TODO Swagger-UI uses baseDoc instead of url, this is to allow both
// need to fix and pick one.
baseDoc = baseDoc || url

// Provide a default fetch implementation
// TODO fetch should be removed, and http used instead
http = fetch || http || Http

if (!spec) {
// We create a spec, that has a single $ref to the url
// This is how we'll resolve it based on a URL only
spec = {$ref: url}
spec = {$ref: baseDoc}
}
else {
// Store the spec into the url provided, to cache it
plugins.refs.docCache[url] = spec
plugins.refs.docCache[baseDoc] = spec
}

// Build a json-fetcher ( ie: give it a URL and get json out )
Expand All @@ -47,7 +51,7 @@ export default function resolve({http, fetch, spec, url, mode, allowMetaPatches
// mapSpec is where the hard work happens, see https://github.com/swagger-api/specmap for more details
return mapSpec({
spec,
context: {baseDoc: url},
context: {baseDoc},
plugins: plugs,
allowMetaPatches // allows adding .meta patches, which include adding `$$ref`s to the spec
}).then(normalizeSwagger)
Expand Down
4 changes: 2 additions & 2 deletions src/specmap/lib/context-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default class ContextTree {
const children = branch.children

if (!children[token] && ensureExists) {
children[token] = createNode()
children[token] = createNode(null, branch)
}

return children[token]
Expand All @@ -79,7 +79,7 @@ function createNode(value, parent) {
function updateNode(node, value, parent) {
node.value = value || {}
node.protoValue = parent
? Object.assign(Object.create(parent.protoValue), node.value)
? {...parent.protoValue, ...node.value}
: node.value

Object.keys(node.children).forEach((prop) => {
Expand Down
2 changes: 1 addition & 1 deletion src/specmap/lib/refs.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const plugin = {
}

const patch = lib.replace(parent, promOrVal, {$$ref: ref})
if (basePath) {
if (basePath && basePath !== baseDoc) {
return [patch, lib.context(parent, {baseDoc: basePath})]
}

Expand Down
7 changes: 6 additions & 1 deletion test/index-authorizations.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('(instance) #execute', function () {
client.execute({http, operationId: 'getPets'})
expect(http.calls.length).toEqual(1)
expect(http.calls[0].arguments[0]).toEqual({
credentials: 'same-origin',
headers: {},
method: 'GET',
url: '/pet'
Expand Down Expand Up @@ -50,6 +51,7 @@ describe('(instance) #execute', function () {
client.execute({http, operationId: 'getPets'})
expect(http.calls.length).toEqual(1)
expect(http.calls[0].arguments[0]).toEqual({
credentials: 'same-origin',
headers: {
authorization: 'Basic Zm9vOmJhcg=='
},
Expand Down Expand Up @@ -87,6 +89,7 @@ describe('(instance) #execute', function () {
client.execute({http, operationId: 'getPets'})
expect(http.calls.length).toEqual(1)
expect(http.calls[0].arguments[0]).toEqual({
credentials: 'same-origin',
headers: {
petKey: 'fooBar'
},
Expand Down Expand Up @@ -124,6 +127,7 @@ describe('(instance) #execute', function () {
client.execute({http, operationId: 'getPets'})
expect(http.calls.length).toEqual(1)
expect(http.calls[0].arguments[0]).toEqual({
credentials: 'same-origin',
headers: { },
method: 'GET',
url: '/pet?petKey=barFoo'
Expand Down Expand Up @@ -161,6 +165,7 @@ describe('(instance) #execute', function () {
client.execute({http, operationId: 'getPets'})
expect(http.calls.length).toEqual(1)
expect(http.calls[0].arguments[0]).toEqual({
credentials: 'same-origin',
headers: {
authorization: 'Bearer one two'
},
Expand Down Expand Up @@ -198,6 +203,7 @@ describe('(instance) #execute', function () {
client.execute({http, operationId: 'getPets'})
expect(http.calls.length).toEqual(1)
expect(http.calls[0].arguments[0]).toEqual({
credentials: 'same-origin',
headers: {
Auth: 'yup'
},
Expand All @@ -207,4 +213,3 @@ describe('(instance) #execute', function () {
})
})
})

2 changes: 1 addition & 1 deletion test/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('resolver', () => {
xmock().get(url, (req, res) => res.send({one: 1}))

// When
return Swagger.resolve({url, allowMetaPatches: false})
return Swagger.resolve({baseDoc: url, allowMetaPatches: false})
.then(handleResponse)

// Then
Expand Down
7 changes: 7 additions & 0 deletions test/specmap/context-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ describe('ContextTree', function () {
expect(tree.get(['one', 'two']).root).toEqual('rooty')
})

it('should retrieve root after setting a sibling', function () {
const tree = new ContextTree()
tree.set([], {baseDoc: 'rooty'})
tree.set(['one', 'two', 'four'], {two: 2})
expect(tree.get(['one', 'three', 'four']).baseDoc).toEqual('rooty')
})

it('should allow setting the root from contructor and get without arg, returns root', function () {
const tree = new ContextTree({two: 2})
const res = tree.get()
Expand Down

0 comments on commit 4e2dff3

Please sign in to comment.