donphan/spec/lib/link_details_extractor_spec.rb

303 lines
8.2 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe LinkDetailsExtractor do
subject { described_class.new(original_url, html, nil) }
let(:original_url) { 'https://example.com/dog.html?tracking=123' }
describe '#canonical_url' do
let(:html) { "<!doctype html><link rel='canonical' href='#{url}'>" }
context 'when canonical URL points to the same host' do
let(:url) { 'https://example.com/dog.html' }
it 'ignores the canonical URLs' do
expect(subject.canonical_url).to eq 'https://example.com/dog.html'
end
end
context 'when canonical URL points to another host' do
let(:url) { 'https://different.example.net/dog.html' }
it 'ignores the canonical URLs' do
expect(subject.canonical_url).to eq original_url
end
end
context 'when canonical URL is set to "null"' do
let(:url) { 'null' }
it 'ignores the canonical URLs' do
expect(subject.canonical_url).to eq original_url
end
end
end
context 'when only basic metadata is present' do
let(:html) { <<~HTML }
<!doctype html>
<html lang="en">
<head>
<title>Man bites dog</title>
<meta name="description" content="A dog&#39;s tale">
</head>
</html>
HTML
describe '#title' do
it 'returns the title from title tag' do
expect(subject.title).to eq 'Man bites dog'
end
end
describe '#description' do
it 'returns the description from meta tag' do
expect(subject.description).to eq "A dog's tale"
end
end
describe '#language' do
it 'returns the language from lang attribute' do
expect(subject.language).to eq 'en'
end
end
end
context 'when structured data is present' do
let(:ld_json) do
{
'@context' => 'https://schema.org',
'@type' => 'NewsArticle',
'headline' => 'Man bites dog',
'description' => "A dog's tale",
'datePublished' => '2022-01-31T19:53:00+00:00',
'author' => {
'@type' => 'Organization',
'name' => 'Charlie Brown',
},
'publisher' => {
'@type' => 'NewsMediaOrganization',
'name' => 'Pet News',
'url' => 'https://example.com',
},
'inLanguage' => {
name: 'English',
alternateName: 'en',
},
}.to_json
end
shared_examples 'structured data' do
describe '#title' do
it 'returns the title from structured data' do
expect(subject.title).to eq 'Man bites dog'
end
end
describe '#description' do
it 'returns the description from structured data' do
expect(subject.description).to eq "A dog's tale"
end
end
describe '#published_at' do
it 'returns the publicaton time from structured data' do
expect(subject.published_at).to eq '2022-01-31T19:53:00+00:00'
end
end
describe '#author_name' do
it 'returns the author name from structured data' do
expect(subject.author_name).to eq 'Charlie Brown'
end
end
describe '#provider_name' do
it 'returns the provider name from structured data' do
expect(subject.provider_name).to eq 'Pet News'
end
end
describe '#language' do
it 'returns the language from structured data' do
expect(subject.language).to eq 'en'
end
end
end
context 'when is wrapped in CDATA tags' do
let(:html) { <<~HTML }
<!doctype html>
<html>
<head>
<script type="application/ld+json">
//<![CDATA[
#{ld_json}
//]]>
</script>
</head>
</html>
HTML
include_examples 'structured data'
end
context 'with the first tag is invalid JSON' do
let(:html) { <<~HTML }
<!doctype html>
<html>
<body>
<script type="application/ld+json">
invalid LD+JSON
</script>
<script type="application/ld+json">
#{ld_json}
</script>
</body>
</html>
HTML
include_examples 'structured data'
end
context 'with preceding block of unsupported LD+JSON' do
let(:html) { <<~HTML }
<!doctype html>
<html>
<body>
<script type="application/ld+json">
[
{
"@context": "https://schema.org",
"@type": "ItemList",
"url": "https://example.com/cat.html",
"name": "Man bites cat",
"description": "A cat's tale"
},
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement":[
{
"@type": "ListItem",
"position": 1,
"item": {
"@id": "https://www.example.com",
"name": "Cat News"
}
}
]
}
]
</script>
<script type="application/ld+json">
#{ld_json}
</script>
</body>
</html>
HTML
include_examples 'structured data'
end
context 'with unsupported in same block LD+JSON' do
let(:html) { <<~HTML }
<!doctype html>
<html>
<body>
<script type="application/ld+json">
[
{
"@context": "https://schema.org",
"@type": "ItemList",
"url": "https://example.com/cat.html",
"name": "Man bites cat",
"description": "A cat's tale"
},
#{ld_json}
]
</script>
</body>
</html>
HTML
include_examples 'structured data'
end
end
context 'when Open Graph protocol data is present' do
let(:html) { <<~HTML }
<!doctype html>
<html>
<head>
<meta property="og:url" content="https://example.com/dog.html">
<meta property="og:title" content="Man bites dog">
<meta property="og:description" content="A dog's tale">
<meta property="article:published_time" content="2022-01-31T19:53:00+00:00">
<meta property="og:author" content="Charlie Brown">
<meta property="og:locale" content="en">
<meta property="og:image" content="https://example.com/snoopy.jpg">
<meta property="og:image:alt" content="A good boy">
<meta property="og:site_name" content="Pet News">
</head>
</html>
HTML
describe '#canonical_url' do
it 'returns the URL from Open Graph protocol data' do
expect(subject.canonical_url).to eq 'https://example.com/dog.html'
end
end
describe '#title' do
it 'returns the title from Open Graph protocol data' do
expect(subject.title).to eq 'Man bites dog'
end
end
describe '#description' do
it 'returns the description from Open Graph protocol data' do
expect(subject.description).to eq "A dog's tale"
end
end
describe '#published_at' do
it 'returns the publicaton time from Open Graph protocol data' do
expect(subject.published_at).to eq '2022-01-31T19:53:00+00:00'
end
end
describe '#author_name' do
it 'returns the author name from Open Graph protocol data' do
expect(subject.author_name).to eq 'Charlie Brown'
end
end
describe '#language' do
it 'returns the language from Open Graph protocol data' do
expect(subject.language).to eq 'en'
end
end
describe '#image' do
it 'returns the image from Open Graph protocol data' do
expect(subject.image).to eq 'https://example.com/snoopy.jpg'
end
end
describe '#image:alt' do
it 'returns the image description from Open Graph protocol data' do
expect(subject.image_alt).to eq 'A good boy'
end
end
describe '#provider_name' do
it 'returns the provider name from Open Graph protocol data' do
expect(subject.provider_name).to eq 'Pet News'
end
end
end
end