Relativize absolute links to the instance on export
This commit is contained in:
@@ -20,7 +20,7 @@ class Account::DataTransfer::ActionText::RichTextRecordSet < Account::DataTransf
|
||||
end
|
||||
|
||||
def export_record(rich_text)
|
||||
data = rich_text.as_json.merge("body" => convert_sgids_to_gids(rich_text.body))
|
||||
data = rich_text.as_json.merge("body" => transform_body_for_export(rich_text.body))
|
||||
zip.add_file "data/action_text_rich_texts/#{rich_text.id}.json", data.to_json
|
||||
end
|
||||
|
||||
@@ -54,9 +54,14 @@ class Account::DataTransfer::ActionText::RichTextRecordSet < Account::DataTransf
|
||||
check_associations_dont_exist(data)
|
||||
end
|
||||
|
||||
def convert_sgids_to_gids(content)
|
||||
def transform_body_for_export(content)
|
||||
return nil if content.blank?
|
||||
|
||||
html = convert_sgids_to_gids(content)
|
||||
relativize_urls(html)
|
||||
end
|
||||
|
||||
def convert_sgids_to_gids(content)
|
||||
content.send(:attachment_nodes).each do |node|
|
||||
sgid = SignedGlobalID.parse(node["sgid"], for: ::ActionText::Attachable::LOCATOR_NAME)
|
||||
|
||||
@@ -75,6 +80,25 @@ class Account::DataTransfer::ActionText::RichTextRecordSet < Account::DataTransf
|
||||
content.fragment.source.to_html
|
||||
end
|
||||
|
||||
def relativize_urls(html)
|
||||
host = Rails.application.routes.default_url_options[:host]
|
||||
return html unless host
|
||||
|
||||
fragment = Nokogiri::HTML.fragment(html)
|
||||
|
||||
fragment.css("a[href]").each do |link|
|
||||
uri = URI.parse(link["href"]) rescue nil
|
||||
|
||||
if uri.respond_to?(:host) && uri.host == host
|
||||
link["href"] = uri.path
|
||||
link["href"] += "?#{uri.query}" if uri.query
|
||||
link["href"] += "##{uri.fragment}" if uri.fragment
|
||||
end
|
||||
end
|
||||
|
||||
fragment.to_html
|
||||
end
|
||||
|
||||
def transform_body_for_import(body)
|
||||
return body if body.blank?
|
||||
|
||||
@@ -112,7 +136,7 @@ class Account::DataTransfer::ActionText::RichTextRecordSet < Account::DataTransf
|
||||
if match
|
||||
path = match.post_match.presence || "/"
|
||||
valid_path = Rails.application.routes.recognize_path(path) rescue nil
|
||||
link["href"] = "#{account.slug}#{remaining_path}" if valid_path
|
||||
link["href"] = "#{account.slug}#{path}" if valid_path
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -117,4 +117,57 @@ class Account::DataTransfer::ActionText::RichTextRecordSetTest < ActiveSupport::
|
||||
|
||||
assert_equal html, result
|
||||
end
|
||||
|
||||
test "relativize_urls strips instance host from absolute URLs" do
|
||||
with_default_url_host("fizzy.example.com") do
|
||||
record_set = Account::DataTransfer::ActionText::RichTextRecordSet.new(accounts(:"37s"))
|
||||
|
||||
html = %(<p>See <a href="https://fizzy.example.com/123/cards/42">card</a></p>)
|
||||
result = record_set.send(:relativize_urls, html)
|
||||
|
||||
assert_includes result, %(/123/cards/42)
|
||||
assert_not_includes result, "fizzy.example.com"
|
||||
end
|
||||
end
|
||||
|
||||
test "relativize_urls preserves query and fragment" do
|
||||
with_default_url_host("fizzy.example.com") do
|
||||
record_set = Account::DataTransfer::ActionText::RichTextRecordSet.new(accounts(:"37s"))
|
||||
|
||||
html = %(<p><a href="https://fizzy.example.com/123/cards/42?tab=comments#comment_1">link</a></p>)
|
||||
result = record_set.send(:relativize_urls, html)
|
||||
|
||||
assert_includes result, "/123/cards/42?tab=comments#comment_1"
|
||||
assert_not_includes result, "fizzy.example.com"
|
||||
end
|
||||
end
|
||||
|
||||
test "relativize_urls leaves external URLs alone" do
|
||||
with_default_url_host("fizzy.example.com") do
|
||||
record_set = Account::DataTransfer::ActionText::RichTextRecordSet.new(accounts(:"37s"))
|
||||
|
||||
html = %(<p><a href="https://github.com/some/repo">link</a></p>)
|
||||
result = record_set.send(:relativize_urls, html)
|
||||
|
||||
assert_includes result, "https://github.com/some/repo"
|
||||
end
|
||||
end
|
||||
|
||||
test "relativize_urls is a no-op when host is not configured" do
|
||||
record_set = Account::DataTransfer::ActionText::RichTextRecordSet.new(accounts(:"37s"))
|
||||
|
||||
html = %(<p><a href="https://fizzy.example.com/123/cards/42">link</a></p>)
|
||||
result = record_set.send(:relativize_urls, html)
|
||||
|
||||
assert_includes result, "https://fizzy.example.com/123/cards/42"
|
||||
end
|
||||
|
||||
private
|
||||
def with_default_url_host(host)
|
||||
original = Rails.application.routes.default_url_options[:host]
|
||||
Rails.application.routes.default_url_options[:host] = host
|
||||
yield
|
||||
ensure
|
||||
Rails.application.routes.default_url_options[:host] = original
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user