Skip to content

Commit 396ccb1

Browse files
author
eddgrant
committed
TRG-1096: Calculate redirects as relative paths when site is configured to use relative links.
1 parent 671dd75 commit 396ccb1

File tree

6 files changed

+95
-26
lines changed

6 files changed

+95
-26
lines changed

lib/govuk_tech_docs/path_helpers.rb

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
require "uri"
22
module GovukTechDocs
33
module PathHelpers
4-
# Some useful notes from https://www.rubydoc.info/github/middleman/middleman/Middleman/Sitemap/Resource#url-instance_method :
5-
# 'resource.path' is "The source path of this resource (relative to the source directory, without template extensions)."
6-
# 'resource.destination_path', which is: "The output path in the build directory for this resource."
7-
# 'resource.url' is based on 'resource.destination_path', but is further tweaked to optionally strip the index file and prefixed with any :http_prefix.
8-
9-
# Calculates the path to the sought resource, taking in to account whether the site has been configured
4+
# Calculates the path to the sought #resource, taking in to account whether the site has been configured
105
# to generate relative or absolute links.
116
# Identifies whether the sought resource is an internal or external target: External targets are returned untouched. Path calculation is performed for internal targets.
127
# Works for both "Middleman::Sitemap::Resource" resources and plain strings (which may be passed from the site configuration when generating header links).
138
#
14-
# @param [Object] config
15-
# @param [Object] resource
16-
# @param [Object] current_page
9+
# Some useful notes from label[https://www.rubydoc.info/github/middleman/middleman/Middleman/Sitemap/Resource#url-instance_method] :
10+
# * 'resource.path' is "The source path of this resource (relative to the source directory, without template extensions)."
11+
# * 'resource.destination_path', which is: "The output path in the build directory for this resource."
12+
# * 'resource.url' is based on 'resource.destination_path', but is further tweaked to optionally strip the index file and prefixed with any :http_prefix.
13+
#
14+
# @param [Object] config from Middleman::ConfigContext
15+
# @param [Middleman::Sitemap::Resource, String] resource
16+
# @param [Middleman::Sitemap::Resource, String] current_page
1717
def get_path_to_resource(config, resource, current_page)
18+
current_page_path = current_page.is_a?(Middleman::Sitemap::Resource) ? current_page.path : current_page
19+
1820
if resource.is_a?(Middleman::Sitemap::Resource)
19-
config[:relative_links] ? get_resource_path_relative_to_current_page(config, current_page.path, resource.path) : resource.url
21+
config[:relative_links] ? get_resource_path_relative_to_current_page(config, current_page_path, resource.path) : resource.url
2022
elsif external_url?(resource)
2123
resource
2224
elsif config[:relative_links]
23-
get_resource_path_relative_to_current_page(config, current_page.path, resource)
25+
get_resource_path_relative_to_current_page(config, current_page_path, resource)
2426
else
2527
resource
2628
end

lib/govuk_tech_docs/redirects.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
require "govuk_tech_docs/path_helpers"
2+
require "ostruct"
3+
14
module GovukTechDocs
25
class Redirects
6+
include GovukTechDocs::PathHelpers
7+
38
LEADING_SLASH = %r{\A/}
49

510
def initialize(context)
@@ -11,7 +16,7 @@ def redirects
1116

1217
all_redirects.map do |from, to|
1318
# Middleman needs paths without leading slashes
14-
[from.sub(LEADING_SLASH, ""), { to: to.sub(LEADING_SLASH, "") }]
19+
[from.sub(LEADING_SLASH, ""), { to: get_path_to_resource(@context.config, to.sub(LEADING_SLASH, ""), from.sub(LEADING_SLASH, "")) }]
1520
end
1621
end
1722

spec/govuk_tech_docs/pages_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
RSpec.describe GovukTechDocs::Pages do
44
describe "#to_json" do
55
it "returns the pages as JSON when using absolute links" do
6-
current_page = double(path: "/api/pages.json")
6+
current_page = create_resource_double(path: "/api/pages.json")
77
sitemap = double(resources: [
88
create_resource_double(url: "/a.html", data: double(title: "A thing", owner_slack: "#2ndline", last_reviewed_on: Date.yesterday, review_in: "0 days")),
99
create_resource_double(url: "/b.html", data: double(title: "B thing", owner_slack: "#2ndline", last_reviewed_on: Date.yesterday, review_in: "2 days")),
@@ -18,7 +18,7 @@
1818
end
1919

2020
it "returns the pages as JSON when using relative links" do
21-
current_page = double(path: "/api/pages.json")
21+
current_page = create_resource_double(path: "/api/pages.json")
2222
sitemap = double(resources: [
2323
create_resource_double(url: "/a.html", path: "/a.html", data: double(title: "A thing", owner_slack: "#2ndline", last_reviewed_on: Date.yesterday, review_in: "0 days")),
2424
create_resource_double(url: "/b/c.html", path: "/b/c.html", data: double(title: "B thing", owner_slack: "#2ndline", last_reviewed_on: Date.yesterday, review_in: "2 days")),

spec/govuk_tech_docs/path_helpers_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
}
2323

2424
current_page_path = "/documentation/introduction/section-one/index.html"
25-
current_page = double("current_page", path: current_page_path)
25+
current_page = create_resource_double(url: current_page_path, path: current_page_path)
2626
resource = create_resource_double(url: resource_url, path: resource_url)
2727
resource_path = get_path_to_resource(config, resource, current_page)
2828

@@ -49,7 +49,7 @@
4949
}
5050

5151
url = "/documentation/introduction/index.html"
52-
current_page = double("current_page", path: current_page_path)
52+
current_page = create_resource_double(url: current_page_path, path: current_page_path)
5353
resource_path = get_path_to_resource(config, url, current_page)
5454

5555
expect(resource_path).to eql("../../../documentation/introduction/index.html")
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
require "govuk_tech_docs/doubles"
2+
3+
RSpec.describe GovukTechDocs::Redirects do
4+
describe "#redirects" do
5+
it "calculates redirects as a relative path from the site root" do
6+
config = {
7+
relative_links: true,
8+
tech_docs: {
9+
redirects: {
10+
# A page has been renamed in an existing folder
11+
"documentation/some-location/old-page.html" => "documentation/some-location/new-page.html",
12+
# A page has been moved between sibling folders
13+
"documentation/old-location/index.html" => "documentation/new-location/index.html",
14+
# A page has been moved and has changed its position in the folder hierarchy
15+
"documentation/some-path/old-location/index.html" => "documentation/new-location/index.html",
16+
# A page has been moved but within some shared common folder hierarchy
17+
"documentation/some-common-path/old-location/index.html" => "documentation/some-common-path/new-location/index.html",
18+
},
19+
},
20+
}
21+
context = double("Middleman::ConfigContext")
22+
allow(context).to receive(:config).and_return config
23+
allow(context).to receive_message_chain(:sitemap, :resources).and_return []
24+
25+
under_test = described_class.new(context)
26+
redirects = under_test.redirects
27+
28+
expect(redirects[0][0]).to eql("documentation/some-location/old-page.html")
29+
expect(redirects[0][1][:to]).to eql("../../documentation/some-location/new-page.html")
30+
31+
expect(redirects[1][0]).to eql("documentation/old-location/index.html")
32+
expect(redirects[1][1][:to]).to eql("../../documentation/new-location/index.html")
33+
34+
expect(redirects[2][0]).to eql("documentation/some-path/old-location/index.html")
35+
expect(redirects[2][1][:to]).to eql("../../../documentation/new-location/index.html")
36+
37+
expect(redirects[3][0]).to eql("documentation/some-common-path/old-location/index.html")
38+
expect(redirects[3][1][:to]).to eql("../../../documentation/some-common-path/new-location/index.html")
39+
end
40+
41+
it "performs no manipulation of redirects when the site is not using relative links" do
42+
old_location = "documentation/old-location/index.html"
43+
new_location = "documentation/new-location/index.html"
44+
config = {
45+
relative_links: false,
46+
tech_docs: {
47+
redirects: {
48+
old_location => new_location,
49+
},
50+
},
51+
}
52+
context = double("Middleman::ConfigContext")
53+
allow(context).to receive(:config).and_return config
54+
allow(context).to receive_message_chain(:sitemap, :resources).and_return []
55+
56+
under_test = described_class.new(context)
57+
redirects = under_test.redirects
58+
59+
expect(redirects[0][0]).to eql(old_location)
60+
expect(redirects[0][1][:to]).to eql(new_location)
61+
end
62+
end
63+
end

spec/table_of_contents/helpers_spec.rb

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require "govuk_tech_docs/doubles"
12
require "spec_helper"
23

34
describe GovukTechDocs::TableOfContents::Helpers do
@@ -224,11 +225,10 @@ def is_a?(klass)
224225
resources[5] = FakeResource.new("/1/5/6/e.html", '<h1 id="heading-one">Heading one</h1><h2 id="heading-two">Heading two</h2>', 60, "Sub page A", resources[0])
225226
resources[0].add_children [resources[1], resources[2], resources[3], resources[4], resources[5]]
226227

227-
current_page = double("current_page",
228-
data: double("page_frontmatter", description: "The description.", title: "The Title"),
229-
url: "/1/2/3/index.html",
230-
path: "/1/2/3/index.html",
231-
metadata: { locals: {} })
228+
current_page = create_resource_double(data: double("page_frontmatter", description: "The description.", title: "The Title"),
229+
url: "/1/2/3/index.html",
230+
path: "/1/2/3/index.html",
231+
metadata: { locals: {} })
232232

233233
current_page_html = '<h1 id="heading-one">Heading one</h1><h2 id="heading-two">Heading two</h2>'
234234

@@ -299,11 +299,10 @@ def is_a?(klass)
299299
resources[2] = FakeResource.new("/prefix/b.html", '<h1 id="heading-one">Heading one</h1><h2 id="heading-two">Heading two</h2>', 20, "Sub page B", resources[0])
300300
resources[0].add_children [resources[1], resources[2]]
301301

302-
current_page = double("current_page",
303-
data: double("page_frontmatter", description: "The description.", title: "The Title"),
304-
url: "/prefix/index.html",
305-
path: "/prefix/index.html",
306-
metadata: { locals: {} })
302+
current_page = create_resource_double(data: double("page_frontmatter", description: "The description.", title: "The Title"),
303+
url: "/prefix/index.html",
304+
path: "/prefix/index.html",
305+
metadata: { locals: {} })
307306

308307
current_page_html = '<h1 id="heading-one">Heading one</h1><h2 id="heading-two">Heading two</h2>'
309308

0 commit comments

Comments
 (0)