-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
We will use this service in the next commit, splitting up the responsibility for generating the HTML from fetching content/metadata and generating the HTML.
- Loading branch information
Showing
2 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
89 changes: 89 additions & 0 deletions
89
...engines/content_block_manager/app/services/content_block_manager/generate_preview_html.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
require "net/http" | ||
require "json" | ||
require "uri" | ||
|
||
module ContentBlockManager | ||
class GeneratePreviewHtml | ||
include ContentBlockManager::Engine.routes.url_helpers | ||
|
||
def initialize(content_id:, content_block_edition:, base_path:) | ||
@content_id = content_id | ||
@content_block_edition = content_block_edition | ||
@base_path = base_path | ||
end | ||
|
||
def call | ||
uri = URI(frontend_path) | ||
nokogiri_html = html_snapshot_from_frontend(uri) | ||
update_local_link_paths(nokogiri_html) | ||
add_draft_style(nokogiri_html) | ||
replace_existing_content_blocks(nokogiri_html).to_s | ||
end | ||
|
||
private | ||
|
||
BLOCK_STYLE = "background-color: yellow;".freeze | ||
ERROR_HTML = "<html><body><p>Preview not found</p></body></html>".freeze | ||
|
||
attr_reader :content_block_edition, :content_id, :base_path | ||
|
||
def frontend_path | ||
frontend_base_path + base_path | ||
end | ||
|
||
def frontend_base_path | ||
Rails.env.development? ? Plek.external_url_for("government-frontend") : Plek.website_root | ||
end | ||
|
||
def html_snapshot_from_frontend(uri) | ||
begin | ||
raw_html = Net::HTTP.get(uri) | ||
rescue StandardError | ||
raw_html = ERROR_HTML | ||
end | ||
Nokogiri::HTML.parse(raw_html) | ||
end | ||
|
||
def update_local_link_paths(nokogiri_html) | ||
url = content_block_manager_content_block_host_content_preview_path(id: content_block_edition.id, host_content_id: content_id) | ||
nokogiri_html.css("a").each do |link| | ||
next if link[:href].start_with?("//") || link[:href].start_with?("http") | ||
|
||
link[:href] = "#{url}?base_path=#{link[:href]}" | ||
link[:target] = "_parent" | ||
end | ||
|
||
nokogiri_html | ||
end | ||
|
||
def add_draft_style(nokogiri_html) | ||
nokogiri_html.css("body").each do |body| | ||
body["class"] ||= "" | ||
body["class"] += " draft" | ||
end | ||
nokogiri_html | ||
end | ||
|
||
def replace_existing_content_blocks(nokogiri_html) | ||
replace_blocks(nokogiri_html) | ||
style_blocks(nokogiri_html) | ||
nokogiri_html | ||
end | ||
|
||
def replace_blocks(nokogiri_html) | ||
content_block_spans(nokogiri_html).each do |span| | ||
span.replace content_block_edition.render | ||
end | ||
end | ||
|
||
def style_blocks(nokogiri_html) | ||
content_block_spans(nokogiri_html).each do |span| | ||
span["style"] = BLOCK_STYLE | ||
end | ||
end | ||
|
||
def content_block_spans(nokogiri_html) | ||
nokogiri_html.css("span[data-content-id=\"#{@content_block_edition.document.content_id}\"]") | ||
end | ||
end | ||
end |
92 changes: 92 additions & 0 deletions
92
lib/engines/content_block_manager/test/unit/app/services/generate_preview_html_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
require "test_helper" | ||
|
||
class ContentBlockManager::GeneratePreviewHtmlTest < ActiveSupport::TestCase | ||
extend Minitest::Spec::DSL | ||
include ContentBlockManager::Engine.routes.url_helpers | ||
include TextAssertions | ||
|
||
let(:host_content_id) { SecureRandom.uuid } | ||
let(:preview_content_id) { SecureRandom.uuid } | ||
let(:host_title) { "Test" } | ||
let(:host_base_path) { "/test" } | ||
let(:uri_mock) { mock } | ||
let(:fake_frontend_response) do | ||
"<body class=\"govuk-body\"><p>test</p><span class=\"content-embed content-embed__content_block_email_address\" data-content-block=\"\" data-document-type=\"content_block_email_address\" data-content-id=\"#{preview_content_id}\">[email protected]</span></body>" | ||
end | ||
let(:block_render) do | ||
"<span class=\"content-embed content-embed__content_block_email_address\" data-content-block=\"\" data-document-type=\"content_block_email_address\" data-content-id=\"#{preview_content_id}\">[email protected]</span>" | ||
end | ||
let(:block_render_with_style) do | ||
"<span class=\"content-embed content-embed__content_block_email_address\" data-content-block=\"\" data-document-type=\"content_block_email_address\" data-content-id=\"#{preview_content_id}\" style=\"background-color: yellow;\">[email protected]</span>" | ||
end | ||
let(:expected_html) do | ||
"<body class=\"govuk-body draft\"><p>test</p>#{block_render_with_style}</body>" | ||
end | ||
let(:error_html) do | ||
"<html><body class=\" draft\"><p>Preview not found</p></body></html>" | ||
end | ||
let(:document) do | ||
build(:content_block_document, :email_address, content_id: preview_content_id) | ||
end | ||
let(:block_to_preview) do | ||
build(:content_block_edition, :email_address, document:, details: { "email_address" => "[email protected]" }, id: 1) | ||
end | ||
|
||
it "returns the preview html" do | ||
Net::HTTP.expects(:get).with(URI(Plek.website_root + host_base_path)).returns(fake_frontend_response) | ||
|
||
expected_content = Nokogiri::HTML.parse(expected_html).to_s | ||
|
||
actual_content = ContentBlockManager::GeneratePreviewHtml.new( | ||
content_id: host_content_id, | ||
content_block_edition: block_to_preview, | ||
base_path: host_base_path, | ||
).call | ||
|
||
assert_equal expected_content, actual_content | ||
end | ||
|
||
it "shows an error template when the request to the frontend throws an error" do | ||
exception = StandardError.new("Something went wrong") | ||
Net::HTTP.expects(:get).with(URI(Plek.website_root + host_base_path)).raises(exception) | ||
|
||
expected_content = Nokogiri::HTML.parse(error_html).to_s | ||
|
||
actual_content = ContentBlockManager::GeneratePreviewHtml.new( | ||
content_id: host_content_id, | ||
content_block_edition: block_to_preview, | ||
base_path: host_base_path, | ||
).call | ||
|
||
assert_equal expected_content, actual_content | ||
end | ||
|
||
it "updates any link paths" do | ||
fake_frontend_response = " | ||
<a href='/foo'>Internal link</a> | ||
<a href='https://example.com'>External link</a> | ||
<a href='//example.com'>Protocol relative link</a> | ||
" | ||
Net::HTTP.expects(:get).with(URI(Plek.website_root + host_base_path)).returns(fake_frontend_response) | ||
|
||
actual_content = ContentBlockManager::GeneratePreviewHtml.new( | ||
content_id: host_content_id, | ||
content_block_edition: block_to_preview, | ||
base_path: host_base_path, | ||
).call | ||
|
||
url = content_block_manager_content_block_host_content_preview_path(id: block_to_preview.id, host_content_id:) | ||
|
||
expected_content = Nokogiri::HTML.parse(" | ||
<html> | ||
<body class=' draft'> | ||
<a href='#{url}?base_path=/foo' target='_parent'>Internal link</a> | ||
<a href='https://example.com'>External link</a> | ||
<a href='//example.com'>Protocol relative link</a> | ||
</body> | ||
</html> | ||
").to_s | ||
|
||
assert_equal_ignoring_whitespace actual_content.to_s, expected_content | ||
end | ||
end |