Merge commit '121443c0fca383268b8022c048dd137994785aff' into glitch-soc/main

Conflicts:
- `.rubocop_todo.yml`:
  Upstream regenerated this file, glitch-soc had a specific ignore.
This commit is contained in:
Claire
2023-08-13 18:47:15 +02:00
194 changed files with 3931 additions and 2110 deletions

View File

@@ -57,6 +57,30 @@ describe 'blocking domains through the moderation interface' do
end
end
context 'when suspending a subdomain of an already-silenced domain' do
it 'presents a confirmation screen before suspending the domain' do
domain_block = Fabricate(:domain_block, domain: 'example.com', severity: 'silence')
visit new_admin_domain_block_path
fill_in 'domain_block_domain', with: 'subdomain.example.com'
select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity'
click_on I18n.t('admin.domain_blocks.new.create')
# It presents a confirmation screen
expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'subdomain.example.com'))
# Confirming creates the block
click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm')
expect(DomainBlock.where(domain: 'subdomain.example.com', severity: 'suspend')).to exist
# And leaves the previous block alone
expect(domain_block.reload.severity).to eq 'silence'
expect(domain_block.reload.domain).to eq 'example.com'
end
end
context 'when editing a domain block' do
it 'presents a confirmation screen before suspending the domain' do
domain_block = Fabricate(:domain_block, domain: 'example.com', severity: 'silence')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

View File

@@ -49,11 +49,7 @@ describe Admin::SystemCheck::ElasticsearchCheck do
end
context 'when running version is missing' do
before do
client = instance_double(Elasticsearch::Transport::Client)
allow(client).to receive(:info).and_raise(Elasticsearch::Transport::Transport::Error)
allow(Chewy).to receive(:client).and_return(client)
end
before { stub_elasticsearch_error }
it 'returns false' do
expect(check.pass?).to be false
@@ -86,6 +82,8 @@ describe Admin::SystemCheck::ElasticsearchCheck do
end
context 'when running version is missing' do
before { stub_elasticsearch_error }
it 'sends class name symbol to message instance' do
allow(Admin::SystemCheck::Message).to receive(:new)
.with(:elasticsearch_running_check)
@@ -97,4 +95,10 @@ describe Admin::SystemCheck::ElasticsearchCheck do
end
end
end
def stub_elasticsearch_error
client = instance_double(Elasticsearch::Transport::Client)
allow(client).to receive(:info).and_raise(Elasticsearch::Transport::Transport::Error)
allow(Chewy).to receive(:client).and_return(client)
end
end

View File

@@ -3,33 +3,31 @@
require 'rails_helper'
RSpec.describe LinkDetailsExtractor do
subject { described_class.new(original_url, html, html_charset) }
subject { described_class.new(original_url, html, nil) }
let(:original_url) { '' }
let(:html) { '' }
let(:html_charset) { nil }
let(:original_url) { 'https://example.com/dog.html?tracking=123' }
describe '#canonical_url' do
let(:original_url) { 'https://foo.com/article?bar=baz123' }
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(:html) { '<!doctype html><link rel="canonical" href="https://bar.com/different-article" />' }
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 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" />' }
let(:url) { 'null' }
it 'ignores the canonical URLs' do
expect(subject.canonical_url).to eq original_url
@@ -37,46 +35,103 @@ RSpec.describe LinkDetailsExtractor do
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(:original_url) { 'https://example.com/page.html' }
context 'when 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
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',
},
}.to_json
end
shared_examples 'structured data' do
describe '#title' do
it 'returns the title from structured data' do
expect(subject.title).to eq 'Foo'
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 'Bar'
expect(subject.description).to eq "A dog's tale"
end
end
describe '#provider_name' do
it 'returns the provider name from structured data' do
expect(subject.provider_name).to eq 'Baz'
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 'Hoge'
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
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
@@ -85,76 +140,152 @@ RSpec.describe LinkDetailsExtractor do
<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"
}
}
]
}
invalid LD+JSON
</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/"
}
}
#{ld_json}
</script>
</body>
</html>
HTML
describe '#title' do
it 'returns the title from structured data' do
expect(subject.title).to eq 'Foo'
end
end
include_examples 'structured data'
end
describe '#description' do
it 'returns the description from structured data' do
expect(subject.description).to eq 'Bar'
end
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
describe '#provider_name' do
it 'returns the provider name from structured data' do
expect(subject.provider_name).to eq 'Baz'
end
end
include_examples 'structured data'
end
describe '#author_name' do
it 'returns the author name from structured data' do
expect(subject.author_name).to eq 'Hoge'
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

View File

@@ -6,7 +6,7 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
describe 'local?' do
subject { media_attachment.local? }
let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url) }
let(:media_attachment) { described_class.new(remote_url: remote_url) }
context 'when remote_url is blank' do
let(:remote_url) { '' }
@@ -28,7 +28,7 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
describe 'needs_redownload?' do
subject { media_attachment.needs_redownload? }
let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url, file: file) }
let(:media_attachment) { described_class.new(remote_url: remote_url, file: file) }
context 'when file is blank' do
let(:file) { nil }
@@ -64,11 +64,11 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
end
describe '#to_param' do
let(:media_attachment) { Fabricate(:media_attachment, shortcode: shortcode) }
let(:shortcode) { nil }
let(:media_attachment) { Fabricate.build(:media_attachment, shortcode: shortcode, id: id) }
context 'when media attachment has a shortcode' do
let(:shortcode) { 'foo' }
let(:id) { 123 }
it 'returns shortcode' do
expect(media_attachment.to_param).to eq shortcode
@@ -77,9 +77,10 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
context 'when media attachment does not have a shortcode' do
let(:shortcode) { nil }
let(:id) { 123 }
it 'returns string representation of id' do
expect(media_attachment.to_param).to eq media_attachment.id.to_s
expect(media_attachment.to_param).to eq id.to_s
end
end
end
@@ -89,38 +90,33 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
media.destroy
end
it 'saves media attachment' do
it 'saves media attachment with correct file metadata' do
expect(media.persisted?).to be true
expect(media.file).to_not be_nil
end
it 'completes processing' do
# completes processing
expect(media.processing_complete?).to be true
end
it 'sets type' do
# sets type
expect(media.type).to eq 'image'
end
it 'sets content type' do
# sets content type
expect(media.file_content_type).to eq content_type
end
it 'sets file extension' do
# sets file extension
expect(media.file_file_name).to end_with extension
end
it 'strips original file name' do
it 'saves media attachment with correct size metadata' do
# strips original file name
expect(media.file_file_name).to_not start_with '600x400'
end
it 'sets meta for original' do
# sets meta for original
expect(media.file.meta['original']['width']).to eq 600
expect(media.file.meta['original']['height']).to eq 400
expect(media.file.meta['original']['aspect']).to eq 1.5
end
it 'sets meta for thumbnail' do
# sets meta for thumbnail
expect(media.file.meta['small']['width']).to eq 588
expect(media.file.meta['small']['height']).to eq 392
expect(media.file.meta['small']['aspect']).to eq 1.5
@@ -128,54 +124,48 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
end
describe 'jpeg' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('600x400.jpeg')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.jpeg')) }
it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg'
end
describe 'png' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('600x400.png')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.png')) }
it_behaves_like 'static 600x400 image', 'image/png', '.png'
end
describe 'webp' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('600x400.webp')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.webp')) }
it_behaves_like 'static 600x400 image', 'image/webp', '.webp'
end
describe 'avif' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('600x400.avif')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.avif')) }
it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg'
end
describe 'heic' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('600x400.heic')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.heic')) }
it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg'
end
describe 'base64-encoded image' do
let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('600x400.jpeg').read)}" }
let(:media) { described_class.create(account: Fabricate(:account), file: base64_attachment) }
let(:media) { Fabricate(:media_attachment, file: base64_attachment) }
it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg'
end
describe 'animated gif' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('avatar.gif')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('avatar.gif')) }
it 'sets type to gifv' do
it 'sets correct file metadata' do
expect(media.type).to eq 'gifv'
end
it 'converts original file to mp4' do
expect(media.file_content_type).to eq 'video/mp4'
end
it 'sets meta' do
expect(media.file.meta['original']['width']).to eq 128
expect(media.file.meta['original']['height']).to eq 128
end
@@ -189,17 +179,11 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
fixtures.each do |fixture|
context fixture[:filename] do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture(fixture[:filename])) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture(fixture[:filename])) }
it 'sets type to image' do
it 'sets correct file metadata' do
expect(media.type).to eq 'image'
end
it 'leaves original file as-is' do
expect(media.file_content_type).to eq 'image/gif'
end
it 'sets meta' do
expect(media.file.meta['original']['width']).to eq fixture[:width]
expect(media.file.meta['original']['height']).to eq fixture[:height]
expect(media.file.meta['original']['aspect']).to eq fixture[:aspect]
@@ -209,31 +193,19 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
end
describe 'ogg with cover art' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('boop.ogg')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('boop.ogg')) }
it 'detects it as an audio file' do
it 'sets correct file metadata' do
expect(media.type).to eq 'audio'
end
it 'sets meta for the duration' do
expect(media.file.meta['original']['duration']).to be_within(0.05).of(0.235102)
end
it 'extracts thumbnail' do
expect(media.thumbnail.present?).to be true
end
it 'extracts colors from thumbnail' do
expect(media.file.meta['colors']['background']).to eq '#3088d4'
end
it 'gives the file a random name' do
expect(media.file_file_name).to_not eq 'boop.ogg'
end
end
describe 'mp3 with large cover art' do
let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('boop.mp3')) }
let(:media) { Fabricate(:media_attachment, file: attachment_fixture('boop.mp3')) }
it 'detects it as an audio file' do
expect(media.type).to eq 'audio'
@@ -253,34 +225,36 @@ RSpec.describe MediaAttachment, paperclip_processing: true do
end
it 'is invalid without file' do
media = described_class.new(account: Fabricate(:account))
media = described_class.new
expect(media.valid?).to be false
expect(media).to model_have_error_on_field(:file)
end
describe 'size limit validation' do
it 'rejects video files that are too large' do
stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes
stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte
expect { described_class.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm')) }.to raise_error(ActiveRecord::RecordInvalid)
expect { Fabricate(:media_attachment, file: attachment_fixture('attachment.webm')) }.to raise_error(ActiveRecord::RecordInvalid)
end
it 'accepts video files that are small enough' do
stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte
stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes
media = described_class.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm'))
media = Fabricate(:media_attachment, file: attachment_fixture('attachment.webm'))
expect(media.valid?).to be true
end
it 'rejects image files that are too large' do
stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte
stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes
expect { described_class.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) }.to raise_error(ActiveRecord::RecordInvalid)
expect { Fabricate(:media_attachment, file: attachment_fixture('attachment.jpg')) }.to raise_error(ActiveRecord::RecordInvalid)
end
it 'accepts image files that are small enough' do
stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes
stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte
media = described_class.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg'))
media = Fabricate(:media_attachment, file: attachment_fixture('attachment.jpg'))
expect(media.valid?).to be true
end
end

View File

@@ -161,6 +161,12 @@ RSpec.describe BulkImportRowService do
end
include_examples 'common behavior'
it 'does not create a new list' do
account.follow!(target_account)
expect { subject.call(import_row) }.to_not(change { List.where(title: 'my list').count })
end
end
end
end