# frozen_string_literal: true require 'rails_helper' RSpec.describe LinkDetailsExtractor do subject { described_class.new(original_url, html, html_charset) } let(:original_url) { '' } let(:html) { '' } let(:html_charset) { nil } describe '#canonical_url' do let(:original_url) { 'https://foo.com/article?bar=baz123' } context 'when canonical URL points to another host' do let(:html) { '<!doctype html><link rel="canonical" href="https://bar.com/different-article" />' } it 'ignores the canonical URLs' do expect(subject.canonical_url).to eq original_url end end context 'when canonical URL points to the same host' do let(:html) { '<!doctype html><link rel="canonical" href="https://foo.com/article" />' } it 'ignores the canonical URLs' do expect(subject.canonical_url).to eq 'https://foo.com/article' end end context 'when canonical URL is set to "null"' do let(:html) { '<!doctype html><link rel="canonical" href="null" />' } it 'ignores the canonical URLs' do expect(subject.canonical_url).to eq original_url end end end context 'when structured data is present' do let(:original_url) { 'https://example.com/page.html' } context 'and is wrapped in CDATA tags' do let(:html) { <<~HTML } <!doctype html> <html> <head> <script type="application/ld+json"> //<![CDATA[ {"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"https://example.com/page.html","headline":"Foo","datePublished":"2022-01-31T19:53:00+00:00","url":"https://example.com/page.html","description":"Bar","author":{"@type":"Person","name":"Hoge"},"publisher":{"@type":"Organization","name":"Baz"}} //]]> </script> </head> </html> HTML describe '#title' do it 'returns the title from structured data' do expect(subject.title).to eq 'Foo' end end describe '#description' do it 'returns the description from structured data' do expect(subject.description).to eq 'Bar' end end describe '#provider_name' do it 'returns the provider name from structured data' do expect(subject.provider_name).to eq 'Baz' end end describe '#author_name' do it 'returns the author name from structured data' do expect(subject.author_name).to eq 'Hoge' end end end context 'but the first tag is invalid JSON' do let(:html) { <<~HTML } <!doctype html> <html> <body> <script type="application/ld+json"> { "@context":"https://schema.org", "@type":"ItemList", "url":"https://example.com/page.html", "name":"Foo", "description":"Bar" }, { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement":[ { "@type":"ListItem", "position":1, "item":{ "@id":"https://www.example.com", "name":"Baz" } } ] } </script> <script type="application/ld+json"> { "@context":"https://schema.org", "@type":"NewsArticle", "mainEntityOfPage": { "@type":"WebPage", "@id": "http://example.com/page.html" }, "headline": "Foo", "description": "Bar", "datePublished": "2022-01-31T19:46:00+00:00", "author": { "@type": "Organization", "name": "Hoge" }, "publisher": { "@type": "NewsMediaOrganization", "name":"Baz", "url":"https://example.com/" } } </script> </body> </html> HTML describe '#title' do it 'returns the title from structured data' do expect(subject.title).to eq 'Foo' end end describe '#description' do it 'returns the description from structured data' do expect(subject.description).to eq 'Bar' end end describe '#provider_name' do it 'returns the provider name from structured data' do expect(subject.provider_name).to eq 'Baz' end end describe '#author_name' do it 'returns the author name from structured data' do expect(subject.author_name).to eq 'Hoge' end end end end end