Reviewed-on: #413 Co-authored-by: miteruzo <miteruzo@naver.com> Co-committed-by: miteruzo <miteruzo@naver.com>
このコミットはPull リクエスト #413 でマージされました.
このコミットが含まれているのは:
@@ -0,0 +1,123 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe PostMetadataFetcher do
|
||||
Response = Struct.new(:body)
|
||||
|
||||
def fetch_with_published_time(value, url: 'https://example.com/video')
|
||||
html = <<~HTML
|
||||
<html><head>
|
||||
<meta property="article:published_time" content="#{ value }">
|
||||
</head></html>
|
||||
HTML
|
||||
uri = URI.parse(url)
|
||||
allow(Preview::UrlSafety).to receive(:validate).with(url).and_return([uri, ['8.8.8.8']])
|
||||
allow(Preview::HttpFetcher).to receive(:fetch).and_return(Response.new(html))
|
||||
allow(Preview::HtmlMetadataExtractor).to receive(:extract)
|
||||
.and_return(title: 'title', image_url: nil)
|
||||
|
||||
described_class.fetch(url)
|
||||
end
|
||||
|
||||
it 'builds ranges explicitly for year, month, and day precision' do
|
||||
year = fetch_with_published_time('2024')
|
||||
month = fetch_with_published_time('2024-02')
|
||||
day = fetch_with_published_time('2024-02-03')
|
||||
|
||||
expect(year).to include(
|
||||
original_created_from: Time.zone.local(2024, 1, 1).iso8601,
|
||||
original_created_before: Time.zone.local(2025, 1, 1).iso8601
|
||||
)
|
||||
expect(month).to include(
|
||||
original_created_from: Time.zone.local(2024, 2, 1).iso8601,
|
||||
original_created_before: Time.zone.local(2024, 3, 1).iso8601
|
||||
)
|
||||
expect(day).to include(
|
||||
original_created_from: Time.zone.local(2024, 2, 3).iso8601,
|
||||
original_created_before: Time.zone.local(2024, 2, 4).iso8601
|
||||
)
|
||||
end
|
||||
|
||||
it 'rounds second and fractional-second timestamps down to one-minute ranges' do
|
||||
result = fetch_with_published_time('2024-02-03T12:34:56.123+02:30')
|
||||
|
||||
expect(Time.iso8601(result.fetch(:original_created_from)))
|
||||
.to eq(Time.iso8601('2024-02-03T12:34:00+02:30'))
|
||||
expect(
|
||||
Time.iso8601(result.fetch(:original_created_before)) -
|
||||
Time.iso8601(result.fetch(:original_created_from))
|
||||
).to eq(60)
|
||||
expect(result.fetch(:original_created_from)).not_to include('.')
|
||||
end
|
||||
|
||||
it 'treats hour-precision timestamps as one-hour ranges with and without offsets' do
|
||||
offset_result = fetch_with_published_time('2024-02-03T12+02:30')
|
||||
local_result = fetch_with_published_time('2024-02-03T12')
|
||||
|
||||
expect(Time.iso8601(offset_result.fetch(:original_created_from)))
|
||||
.to eq(Time.iso8601('2024-02-03T12:00:00+02:30'))
|
||||
expect(
|
||||
Time.iso8601(offset_result.fetch(:original_created_before)) -
|
||||
Time.iso8601(offset_result.fetch(:original_created_from))
|
||||
).to eq(3600)
|
||||
expect(local_result.fetch(:original_created_from)).to eq('2024-02-03T12:00:00Z')
|
||||
expect(local_result.fetch(:original_created_before)).to eq('2024-02-03T13:00:00Z')
|
||||
end
|
||||
|
||||
it 'adds platform tags for known video URLs' do
|
||||
result = fetch_with_published_time('2024', url: 'https://youtu.be/abc123')
|
||||
|
||||
expect(result.fetch(:tags)).to eq('動画 YouTube')
|
||||
end
|
||||
|
||||
it 'returns nil dates for an invalid timestamp' do
|
||||
result = fetch_with_published_time('not-a-time')
|
||||
|
||||
expect(result.fetch(:original_created_from)).to be_nil
|
||||
expect(result.fetch(:original_created_before)).to be_nil
|
||||
end
|
||||
|
||||
it 'returns nil dates for an invalid timestamp second value' do
|
||||
result = fetch_with_published_time('2024-02-03T12:34:99Z')
|
||||
|
||||
expect(result.fetch(:original_created_from)).to be_nil
|
||||
expect(result.fetch(:original_created_before)).to be_nil
|
||||
end
|
||||
|
||||
it 'returns nil dates for invalid calendar dates and invalid hour values' do
|
||||
invalid_day = fetch_with_published_time('2024-02-31T12:00Z')
|
||||
invalid_leap = fetch_with_published_time('2023-02-29T12:00Z')
|
||||
invalid_hour = fetch_with_published_time('2024-02-29T24:00Z')
|
||||
|
||||
[invalid_day, invalid_leap, invalid_hour].each do |result|
|
||||
expect(result.fetch(:original_created_from)).to be_nil
|
||||
expect(result.fetch(:original_created_before)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it 'accepts a valid leap-day timestamp at minute precision' do
|
||||
result = fetch_with_published_time('2024-02-29T12:34Z')
|
||||
|
||||
expect(result.fetch(:original_created_from)).to eq('2024-02-29T12:34:00Z')
|
||||
expect(result.fetch(:original_created_before)).to eq('2024-02-29T12:35:00Z')
|
||||
end
|
||||
|
||||
it 'serialises metadata duration as the same seconds string contract used by forms' do
|
||||
html = <<~HTML
|
||||
<html><head>
|
||||
<meta property="article:published_time" content="2024-02-03T12:34:56.123+02:30">
|
||||
<meta property="og:video:duration" content="2.5">
|
||||
</head></html>
|
||||
HTML
|
||||
uri = URI.parse('https://example.com/video')
|
||||
allow(Preview::UrlSafety).to receive(:validate)
|
||||
.with('https://example.com/video')
|
||||
.and_return([uri, ['8.8.8.8']])
|
||||
allow(Preview::HttpFetcher).to receive(:fetch).and_return(Response.new(html))
|
||||
allow(Preview::HtmlMetadataExtractor).to receive(:extract)
|
||||
.and_return(title: 'title', image_url: nil)
|
||||
|
||||
result = described_class.fetch('https://example.com/video')
|
||||
|
||||
expect(result.fetch(:duration)).to eq('2.5')
|
||||
end
|
||||
end
|
||||
新しい課題から参照
ユーザをブロックする