diff --git a/docs/lib/url_generator.js b/docs/lib/url_generator.js index 3b29f8e0ee..0f688e1844 100644 --- a/docs/lib/url_generator.js +++ b/docs/lib/url_generator.js @@ -10,6 +10,9 @@ const errors = require('request-promise/errors') const startsWithHttpRe = /^http/ const everythingAfterHashRe = /(#.+)/ +// cache validations +const cache = {} + function isExternalHref (str) { return startsWithHttpRe.test(str) } @@ -166,15 +169,36 @@ function validateLocalFile (sidebar, href, source, render) { } function validateAndGetUrl (sidebar, href, source, render) { + // do we already have a cache for this href? + const cachedValue = cache[href] + + // if we got it, return it! + if (cachedValue) { + return Promise.resolve(cachedValue) + } + if (isExternalHref(href)) { + // cache this now even though + // we haven't validated it yet + // because it will just fail later + cache[href] = href + return validateExternalUrl(href, source) .return(href) } return validateLocalFile(sidebar, href, source, render) + .then((pathToFile) => { + // cache this once its been locally resolved + cache[href] = pathToFile + + return pathToFile + }) } module.exports = { + cache, + normalizeNestedPaths, findFileBySource, diff --git a/docs/test/unit/url_generator_spec.coffee b/docs/test/unit/url_generator_spec.coffee index 75fe1b04ad..cad2ee6fd4 100644 --- a/docs/test/unit/url_generator_spec.coffee +++ b/docs/test/unit/url_generator_spec.coffee @@ -95,15 +95,6 @@ describe "lib/url_generator", -> expect(err.message).to.include("Could not find a valid doc file in the sidebar.yml for: foo") context ".validateAndGetUrl", -> - it "verifies external url", -> - nock("https://www.google.com") - .get("/") - .reply(200) - - urlGenerator.validateAndGetUrl(data, "https://www.google.com") - .then (url) -> - expect(url).to.eq("https://www.google.com") - it "fails when external returns non 2xx", -> nock("https://www.google.com") .get("/") @@ -115,7 +106,7 @@ describe "lib/url_generator", -> .catch (err) -> expect(err.message).to.include("Request to: https://www.google.com failed. (Status Code 500)") - it "verifies local file", -> + it "verifies local file and caches subsequent requests", -> markdown = "## Notes\nfoobarbaz" render = (str) -> @@ -129,6 +120,12 @@ describe "lib/url_generator", -> .then (pathToFile) -> expect(pathToFile).to.eq("/api/commands/and.html#notes") + urlGenerator.validateAndGetUrl(data, "and#notes", "", render) + .then (pathToFile) -> + expect(pathToFile).to.eq("/api/commands/and.html#notes") + + expect(fs.readFile).to.be.calledOnce + it "verifies external url with anchor href matching hash", -> nock("https://www.google.com") .get("/") @@ -137,6 +134,11 @@ describe "lib/url_generator", -> urlGenerator.validateAndGetUrl(data, "https://www.google.com/#assertions") .then (url) -> expect(url).to.eq("https://www.google.com/#assertions") + + urlGenerator.validateAndGetUrl(data, "https://www.google.com/#assertions") + .then (url) -> + expect(url).to.eq("https://www.google.com/#assertions") + it "fails when hash is not present in response", -> nock("https://www.google.com") .get("/") @@ -175,3 +177,10 @@ describe "lib/url_generator", -> "" ].forEach (msg) -> expect(err.message).to.include(msg) + + it "resolves cached values in a promise", -> + urlGenerator.cache["foo"] = "bar" + + urlGenerator.validateAndGetUrl(data, "foo") + .then (url) -> + expect(url).to.eq("bar")