mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FIX: Handle sites with more than 1 JSON-LD element (#17095)
A followup to #17007
This commit is contained in:
@@ -12,32 +12,25 @@ module Onebox
|
|||||||
private
|
private
|
||||||
|
|
||||||
def extract(doc)
|
def extract(doc)
|
||||||
extracted_json = extract_json_from(doc)
|
return {} if Onebox::Helpers::blank?(doc)
|
||||||
parsed_json = parse_json(extracted_json)
|
|
||||||
|
doc.css('script[type="application/ld+json"]').each do |element|
|
||||||
|
parsed_json = parse_json(element.text)
|
||||||
|
|
||||||
extracted =
|
|
||||||
case parsed_json["@type"]
|
case parsed_json["@type"]
|
||||||
when MOVIE_JSON_LD_TYPE
|
when MOVIE_JSON_LD_TYPE
|
||||||
Onebox::Movie.new(parsed_json)
|
return Onebox::Movie.new(parsed_json).to_h
|
||||||
else
|
|
||||||
{}
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
extracted.to_h
|
{}
|
||||||
end
|
|
||||||
|
|
||||||
def extract_json_from(doc)
|
|
||||||
return {} if Onebox::Helpers::blank?(doc)
|
|
||||||
json_ld = doc.search('script[type="application/ld+json"]').text
|
|
||||||
return {} if Onebox::Helpers::blank?(json_ld)
|
|
||||||
json_ld
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_json(json)
|
def parse_json(json)
|
||||||
begin
|
begin
|
||||||
JSON[json]
|
JSON[json]
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
Discourse.warn_exception(e, message: "Error parsing JSON-LD json: #{json}")
|
Discourse.warn_exception(e, message: "Error parsing JSON-LD: #{json}")
|
||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,27 +7,26 @@ describe Onebox::JsonLd do
|
|||||||
invalid_json = "{\"@type\":invalid-json}"
|
invalid_json = "{\"@type\":invalid-json}"
|
||||||
doc = Nokogiri::HTML("<script type=\"application/ld+json\">#{invalid_json}</script>")
|
doc = Nokogiri::HTML("<script type=\"application/ld+json\">#{invalid_json}</script>")
|
||||||
Discourse.expects(:warn_exception).with(
|
Discourse.expects(:warn_exception).with(
|
||||||
instance_of(JSON::ParserError), { message: "Error parsing JSON-LD json: #{invalid_json}" }
|
instance_of(JSON::ParserError), { message: "Error parsing JSON-LD: #{invalid_json}" }
|
||||||
)
|
)
|
||||||
|
|
||||||
json_ld = described_class.new(doc)
|
json_ld = described_class.new(doc)
|
||||||
|
|
||||||
expect(json_ld.data).to eq({})
|
expect(json_ld.data).to eq({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an empty hash if there is no json_ld script tag' do
|
it 'returns an empty hash if there is no JSON-LD script tag' do
|
||||||
doc = Nokogiri::HTML("<script type=\"something else\"></script>")
|
doc = Nokogiri::HTML("<script type=\"something else\"></script>")
|
||||||
json_ld = described_class.new(doc)
|
json_ld = described_class.new(doc)
|
||||||
expect(json_ld.data).to eq({})
|
expect(json_ld.data).to eq({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an empty hash if there is no json_ld data' do
|
it 'returns an empty hash if there is no JSON-LD data' do
|
||||||
doc = Nokogiri::HTML("<script type=\"application/ld+json\"></script>")
|
doc = Nokogiri::HTML("<script type=\"application/ld+json\"></script>")
|
||||||
json_ld = described_class.new(doc)
|
json_ld = described_class.new(doc)
|
||||||
expect(json_ld.data).to eq({})
|
expect(json_ld.data).to eq({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns an empty hash if the type of JSONLD data is not Movie' do
|
it 'returns an empty hash if the type of JSON-LD data is not Movie' do
|
||||||
doc = Nokogiri::HTML("<script type=\"application/ld+json\">{\"@type\":\"Something Else\",\"aggregateRating\":{\"@type\":\"AggregateRating\",\"ratingCount\":806928,\"bestRating\":10,\"worstRating\":1}}</script>")
|
doc = Nokogiri::HTML("<script type=\"application/ld+json\">{\"@type\":\"Something Else\",\"aggregateRating\":{\"@type\":\"AggregateRating\",\"ratingCount\":806928,\"bestRating\":10,\"worstRating\":1}}</script>")
|
||||||
json_ld = described_class.new(doc)
|
json_ld = described_class.new(doc)
|
||||||
expect(json_ld.data).to eq({})
|
expect(json_ld.data).to eq({})
|
||||||
@@ -39,6 +38,15 @@ describe Onebox::JsonLd do
|
|||||||
expect(json_ld.data).to eq(expected_movie_hash)
|
expect(json_ld.data).to eq(expected_movie_hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'does not fail when there is more than one JSON-LD element' do
|
||||||
|
doc = Nokogiri::HTML(onebox_response('imdb'))
|
||||||
|
doc.css("body")[0] << "<script type=\"application/ld+json\">{\"@context\":\"http://schema.org\",\"@type\":\"WebPage\",\"url\":\"https:\/\/imdb.com\",\"description\":\"Movies\"}</script>"
|
||||||
|
Discourse.expects(:warn_exception).never
|
||||||
|
|
||||||
|
json_ld = described_class.new(doc)
|
||||||
|
expect(json_ld.data).to eq(expected_movie_hash)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def expected_movie_hash
|
def expected_movie_hash
|
||||||
|
|||||||
Reference in New Issue
Block a user