Merge branch 'master' into glitch-soc/merge-upstream
Conflicts: - Gemfile.lock - app/controllers/accounts_controller.rb - app/controllers/admin/dashboard_controller.rb - app/controllers/follower_accounts_controller.rb - app/controllers/following_accounts_controller.rb - app/controllers/remote_follow_controller.rb - app/controllers/stream_entries_controller.rb - app/controllers/tags_controller.rb - app/javascript/packs/public.js - app/lib/sanitize_config.rb - app/models/account.rb - app/models/form/admin_settings.rb - app/models/media_attachment.rb - app/models/stream_entry.rb - app/models/user.rb - app/serializers/initial_state_serializer.rb - app/services/batched_remove_status_service.rb - app/services/post_status_service.rb - app/services/process_mentions_service.rb - app/services/reblog_service.rb - app/services/remove_status_service.rb - app/views/admin/settings/edit.html.haml - config/locales/simple_form.pl.yml - config/settings.yml - docker-compose.yml
This commit is contained in:
@@ -143,12 +143,6 @@ RSpec.describe ActivityPub::TagManager do
|
||||
expect(subject.uri_to_resource(OStatus::TagManager.instance.uri_for(status), Status)).to eq status
|
||||
end
|
||||
|
||||
it 'returns the local status for OStatus StreamEntry URL' do
|
||||
status = Fabricate(:status)
|
||||
stream_entry_url = account_stream_entry_url(status.account, status.stream_entry)
|
||||
expect(subject.uri_to_resource(stream_entry_url, Status)).to eq status
|
||||
end
|
||||
|
||||
it 'returns the remote status by matching URI without fragment part' do
|
||||
status = Fabricate(:status, uri: 'https://example.com/123')
|
||||
expect(subject.uri_to_resource('https://example.com/123#456', Status)).to eq status
|
||||
|
||||
@@ -32,11 +32,11 @@ describe LanguageDetector do
|
||||
expect(result).to eq 'Our website is and also'
|
||||
end
|
||||
|
||||
it 'strips #hashtags from strings before detection' do
|
||||
string = 'Hey look at all the #animals and #fish'
|
||||
it 'converts #hashtags back to normal text before detection' do
|
||||
string = 'Hey look at all the #animals and #FishAndChips'
|
||||
|
||||
result = described_class.instance.send(:prepare_text, string)
|
||||
expect(result).to eq 'Hey look at all the and'
|
||||
expect(result).to eq 'Hey look at all the animals and fish and chips'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,5 +14,9 @@ describe Sanitize::Config do
|
||||
it 'keeps ul' do
|
||||
expect(Sanitize.fragment('<p>Check out:</p><ul><li>Foo</li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><ul><li>Foo</li><li>Bar</li></ul>'
|
||||
end
|
||||
|
||||
it 'keep links in lists' do
|
||||
expect(Sanitize.fragment('<p>Check out:</p><ul><li><a href="https://joinmastodon.org" rel="nofollow noopener" target="_blank">joinmastodon.org</a></li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><p><a href="https://joinmastodon.org" rel="nofollow noopener" target="_blank">joinmastodon.org</a><br>Bar</p>'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
160
spec/lib/spam_check_spec.rb
Normal file
160
spec/lib/spam_check_spec.rb
Normal file
@@ -0,0 +1,160 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe SpamCheck do
|
||||
let!(:sender) { Fabricate(:account) }
|
||||
let!(:alice) { Fabricate(:account, username: 'alice') }
|
||||
let!(:bob) { Fabricate(:account, username: 'bob') }
|
||||
|
||||
def status_with_html(text, options = {})
|
||||
status = PostStatusService.new.call(sender, { text: text }.merge(options))
|
||||
status.update_columns(text: Formatter.instance.format(status), local: false)
|
||||
status
|
||||
end
|
||||
|
||||
describe '#hashable_text' do
|
||||
it 'removes mentions from HTML for remote statuses' do
|
||||
status = status_with_html('@alice Hello')
|
||||
expect(described_class.new(status).hashable_text).to eq 'hello'
|
||||
end
|
||||
|
||||
it 'removes mentions from text for local statuses' do
|
||||
status = PostStatusService.new.call(alice, text: "Hey @#{sender.username}, how are you?")
|
||||
expect(described_class.new(status).hashable_text).to eq 'hey , how are you?'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#insufficient_data?' do
|
||||
it 'returns true when there is no text' do
|
||||
status = status_with_html('@alice')
|
||||
expect(described_class.new(status).insufficient_data?).to be true
|
||||
end
|
||||
|
||||
it 'returns false when there is text' do
|
||||
status = status_with_html('@alice h')
|
||||
expect(described_class.new(status).insufficient_data?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#digest' do
|
||||
it 'returns a string' do
|
||||
status = status_with_html('@alice Hello world')
|
||||
expect(described_class.new(status).digest).to be_a String
|
||||
end
|
||||
end
|
||||
|
||||
describe '#spam?' do
|
||||
it 'returns false for a unique status' do
|
||||
status = status_with_html('@alice Hello')
|
||||
expect(described_class.new(status).spam?).to be false
|
||||
end
|
||||
|
||||
it 'returns false for different statuses to the same recipient' do
|
||||
status1 = status_with_html('@alice Hello')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@alice Are you available to talk?')
|
||||
expect(described_class.new(status2).spam?).to be false
|
||||
end
|
||||
|
||||
it 'returns false for statuses with different content warnings' do
|
||||
status1 = status_with_html('@alice Are you available to talk?')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@alice Are you available to talk?', spoiler_text: 'This is a completely different matter than what I was talking about previously, I swear!')
|
||||
expect(described_class.new(status2).spam?).to be false
|
||||
end
|
||||
|
||||
it 'returns false for different statuses to different recipients' do
|
||||
status1 = status_with_html('@alice How is it going?')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@bob Are you okay?')
|
||||
expect(described_class.new(status2).spam?).to be false
|
||||
end
|
||||
|
||||
it 'returns false for very short different statuses to different recipients' do
|
||||
status1 = status_with_html('@alice 🙄')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@bob Huh?')
|
||||
expect(described_class.new(status2).spam?).to be false
|
||||
end
|
||||
|
||||
it 'returns false for statuses with no text' do
|
||||
status1 = status_with_html('@alice')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@bob')
|
||||
expect(described_class.new(status2).spam?).to be false
|
||||
end
|
||||
|
||||
it 'returns true for duplicate statuses to the same recipient' do
|
||||
status1 = status_with_html('@alice Hello')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@alice Hello')
|
||||
expect(described_class.new(status2).spam?).to be true
|
||||
end
|
||||
|
||||
it 'returns true for duplicate statuses to different recipients' do
|
||||
status1 = status_with_html('@alice Hello')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@bob Hello')
|
||||
expect(described_class.new(status2).spam?).to be true
|
||||
end
|
||||
|
||||
it 'returns true for nearly identical statuses with random numbers' do
|
||||
source_text = 'Sodium, atomic number 11, was first isolated by Humphry Davy in 1807. A chemical component of salt, he named it Na in honor of the saltiest region on earth, North America.'
|
||||
status1 = status_with_html('@alice ' + source_text + ' 1234')
|
||||
described_class.new(status1).remember!
|
||||
status2 = status_with_html('@bob ' + source_text + ' 9568')
|
||||
expect(described_class.new(status2).spam?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#skip?' do
|
||||
it 'returns true when the sender is already silenced' do
|
||||
status = status_with_html('@alice Hello')
|
||||
sender.silence!
|
||||
expect(described_class.new(status).skip?).to be true
|
||||
end
|
||||
|
||||
it 'returns true when the mentioned person follows the sender' do
|
||||
status = status_with_html('@alice Hello')
|
||||
alice.follow!(sender)
|
||||
expect(described_class.new(status).skip?).to be true
|
||||
end
|
||||
|
||||
it 'returns false when even one mentioned person doesn\'t follow the sender' do
|
||||
status = status_with_html('@alice @bob Hello')
|
||||
alice.follow!(sender)
|
||||
expect(described_class.new(status).skip?).to be false
|
||||
end
|
||||
|
||||
it 'returns true when the sender is replying to a status that mentions the sender' do
|
||||
parent = PostStatusService.new.call(alice, text: "Hey @#{sender.username}, how are you?")
|
||||
status = status_with_html('@alice @bob Hello', thread: parent)
|
||||
expect(described_class.new(status).skip?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#remember!' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#flag!' do
|
||||
let!(:status1) { status_with_html('@alice General Kenobi you are a bold one') }
|
||||
let!(:status2) { status_with_html('@alice @bob General Kenobi, you are a bold one') }
|
||||
|
||||
before do
|
||||
described_class.new(status1).remember!
|
||||
described_class.new(status2).flag!
|
||||
end
|
||||
|
||||
it 'silences the account' do
|
||||
expect(sender.silenced?).to be true
|
||||
end
|
||||
|
||||
it 'creates a report about the account' do
|
||||
expect(sender.targeted_reports.unresolved.count).to eq 1
|
||||
end
|
||||
|
||||
it 'attaches both matching statuses to the report' do
|
||||
expect(sender.targeted_reports.first.status_ids).to include(status1.id, status2.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -25,15 +25,6 @@ describe StatusFinder do
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a stream entry url' do
|
||||
let(:stream_entry) { Fabricate(:stream_entry) }
|
||||
let(:url) { account_stream_entry_url(stream_entry.account, stream_entry) }
|
||||
|
||||
it 'finds the stream entry' do
|
||||
expect(subject.status).to eq(stream_entry.status)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a remote url even if id exists on local' do
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:url) { "https://example.com/users/test/statuses/#{status.id}" }
|
||||
|
||||
@@ -119,46 +119,4 @@ RSpec.describe TagManager do
|
||||
expect(TagManager.instance.same_acct?('username', 'incorrect@Cb6E6126.nGrOk.Io')).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#url_for' do
|
||||
let(:alice) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
subject { TagManager.instance.url_for(target) }
|
||||
|
||||
context 'activity object' do
|
||||
let(:target) { Fabricate(:status, account: alice, reblog: Fabricate(:status)).stream_entry }
|
||||
|
||||
it 'returns the unique tag for status' do
|
||||
expect(target.object_type).to eq :activity
|
||||
is_expected.to eq "https://cb6e6126.ngrok.io/@alice/#{target.id}"
|
||||
end
|
||||
end
|
||||
|
||||
context 'comment object' do
|
||||
let(:target) { Fabricate(:status, account: alice, reply: true) }
|
||||
|
||||
it 'returns the unique tag for status' do
|
||||
expect(target.object_type).to eq :comment
|
||||
is_expected.to eq "https://cb6e6126.ngrok.io/@alice/#{target.id}"
|
||||
end
|
||||
end
|
||||
|
||||
context 'note object' do
|
||||
let(:target) { Fabricate(:status, account: alice, reply: false, thread: nil) }
|
||||
|
||||
it 'returns the unique tag for status' do
|
||||
expect(target.object_type).to eq :note
|
||||
is_expected.to eq "https://cb6e6126.ngrok.io/@alice/#{target.id}"
|
||||
end
|
||||
end
|
||||
|
||||
context 'person object' do
|
||||
let(:target) { alice }
|
||||
|
||||
it 'returns the URL for account' do
|
||||
expect(target.object_type).to eq :person
|
||||
is_expected.to eq 'https://cb6e6126.ngrok.io/@alice'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user