Merge commit 'f877aa9d70d0d600961989b8e97c0e0ce3ac1db6' into glitch-soc/merge-upstream
Conflicts: - `.github/dependabot.yml`: Upstream made changes, but we had removed it. Discarded upstream changes. - `.rubocop_todo.yml`: Upstream regenerated the file, we had some glitch-soc-specific ignores. - `app/models/account_statuses_filter.rb`: Minor upstream code style change where glitch-soc had slightly different code due to handling of local-only posts. Updated to match upstream's code style. - `app/models/status.rb`: Upstream moved ActiveRecord callback definitions, glitch-soc had an extra one. Moved the definitions as upstream did. - `app/services/backup_service.rb`: Upstream rewrote a lot of the backup service, glitch-soc had changes because of exporting local-only posts. Took upstream changes and added back code to deal with local-only posts. - `config/routes.rb`: Upstream split the file into different files, while glitch-soc had a few extra routes. Extra routes added to `config/routes/settings.rb`, `config/routes/api.rb` and `config/routes/admin.rb` - `db/schema.rb`: Upstream has new migrations, while glitch-soc had an extra migration. Updated the expected serial number to match upstream's. - `lib/mastodon/version.rb`: Upstream added support to set version tags from environment variables, while glitch-soc has an extra `+glitch` tag. Changed the code to support upstream's feature but prepending a `+glitch`. - `spec/lib/activitypub/activity/create_spec.rb`: Minor code style change upstream, while glitch-soc has extra tests due to `directMessage` handling. Applied upstream's changes while keeping glitch-soc's extra tests. - `spec/models/concerns/account_interactions_spec.rb`: Minor code style change upstream, while glitch-soc has extra tests. Applied upstream's changes while keeping glitch-soc's extra tests.
This commit is contained in:
@ -43,7 +43,7 @@ RSpec.describe ActivityPub::Activity::Accept do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a relay' do
|
||||
context 'when given a relay' do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
let!(:relay) { Fabricate(:relay, state: :pending, follow_activity_id: 'https://abc-123/456') }
|
||||
|
@ -39,7 +39,7 @@ RSpec.describe ActivityPub::Activity::Announce do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
context 'a known status' do
|
||||
context 'with known status' do
|
||||
let(:object_json) do
|
||||
ActivityPub::TagManager.instance.uri_for(status)
|
||||
end
|
||||
@ -49,7 +49,7 @@ RSpec.describe ActivityPub::Activity::Announce do
|
||||
end
|
||||
end
|
||||
|
||||
context 'an unknown status' do
|
||||
context 'with unknown status' do
|
||||
let(:object_json) { 'https://example.com/actor/hello-world' }
|
||||
|
||||
it 'creates a reblog by sender of status' do
|
||||
@ -60,7 +60,7 @@ RSpec.describe ActivityPub::Activity::Announce do
|
||||
end
|
||||
end
|
||||
|
||||
context 'self-boost of a previously unknown status with correct attributedTo' do
|
||||
context 'when self-boost of a previously unknown status with correct attributedTo' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: 'https://example.com/actor#bar',
|
||||
@ -76,7 +76,7 @@ RSpec.describe ActivityPub::Activity::Announce do
|
||||
end
|
||||
end
|
||||
|
||||
context 'self-boost of a previously unknown status with correct attributedTo, inlined Collection in audience' do
|
||||
context 'when self-boost of a previously unknown status with correct attributedTo, inlined Collection in audience' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: 'https://example.com/actor#bar',
|
||||
@ -123,7 +123,7 @@ RSpec.describe ActivityPub::Activity::Announce do
|
||||
stub_request(:get, 'https://example.com/actor/hello-world').to_return(body: Oj.dump(unknown_object_json))
|
||||
end
|
||||
|
||||
context 'and the relay is enabled' do
|
||||
context 'when the relay is enabled' do
|
||||
before do
|
||||
relay.update(state: :accepted)
|
||||
subject.perform
|
||||
@ -135,7 +135,7 @@ RSpec.describe ActivityPub::Activity::Announce do
|
||||
end
|
||||
end
|
||||
|
||||
context 'and the relay is disabled' do
|
||||
context 'when the relay is disabled' do
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
|
@ -31,7 +31,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
subject.perform
|
||||
end
|
||||
|
||||
context 'object has been edited' do
|
||||
context 'when object has been edited' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -57,7 +57,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'object has update date equal to creation date' do
|
||||
context 'when object has update date equal to creation date' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -83,7 +83,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'unknown object type' do
|
||||
context 'with an unknown object type' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -97,7 +97,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'standalone' do
|
||||
context 'with a standalone' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -121,7 +121,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'public with explicit public address' do
|
||||
context 'when public with explicit public address' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -139,7 +139,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'public with as:Public' do
|
||||
context 'when public with as:Public' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -157,7 +157,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'public with Public' do
|
||||
context 'when public with Public' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -175,7 +175,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'unlisted with explicit public address' do
|
||||
context 'when unlisted with explicit public address' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -193,7 +193,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'unlisted with as:Public' do
|
||||
context 'when unlisted with as:Public' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -211,7 +211,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'unlisted with Public' do
|
||||
context 'when unlisted with Public' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -229,7 +229,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'private' do
|
||||
context 'when private' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -247,7 +247,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'private with inlined Collection in audience' do
|
||||
context 'when private with inlined Collection in audience' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
@ -269,7 +269,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'limited' do
|
||||
context 'when limited' do
|
||||
let(:recipient) { Fabricate(:account) }
|
||||
|
||||
let(:object_json) do
|
||||
@ -294,7 +294,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'limited when direct message assertion is false' do
|
||||
context 'when directMessage attribute is false' do
|
||||
let(:recipient) { Fabricate(:account) }
|
||||
|
||||
let(:object_json) do
|
||||
@ -311,7 +311,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
it 'creates status with limited visibility' do
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@ -319,7 +319,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'direct' do
|
||||
context 'when direct' do
|
||||
let(:recipient) { Fabricate(:account) }
|
||||
|
||||
let(:object_json) do
|
||||
@ -335,7 +335,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
it 'creates status with direct visibility' do
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
@ -343,7 +343,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'direct when direct message assertion is true' do
|
||||
context 'when directMessage attribute is true' do
|
||||
let(:recipient) { Fabricate(:account) }
|
||||
|
||||
let(:object_json) do
|
||||
@ -364,7 +364,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||
end
|
||||
end
|
||||
|
||||
context 'as a reply' do
|
||||
context 'with a reply' do
|
||||
let(:original_status) { Fabricate(:status) }
|
||||
|
||||
let(:object_json) do
|
||||
|
@ -20,7 +20,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
context 'with no prior follow' do
|
||||
context 'unlocked account' do
|
||||
context 'with an unlocked account' do
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
@ -35,7 +35,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
end
|
||||
end
|
||||
|
||||
context 'silenced account following an unlocked account' do
|
||||
context 'when silenced account following an unlocked account' do
|
||||
before do
|
||||
sender.touch(:silenced_at)
|
||||
subject.perform
|
||||
@ -51,7 +51,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
end
|
||||
end
|
||||
|
||||
context 'unlocked account muting the sender' do
|
||||
context 'with an unlocked account muting the sender' do
|
||||
before do
|
||||
recipient.mute!(sender)
|
||||
subject.perform
|
||||
@ -67,7 +67,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
end
|
||||
end
|
||||
|
||||
context 'locked account' do
|
||||
context 'when locked account' do
|
||||
before do
|
||||
recipient.update(locked: true)
|
||||
subject.perform
|
||||
@ -89,7 +89,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
sender.active_relationships.create!(target_account: recipient, uri: 'bar')
|
||||
end
|
||||
|
||||
context 'unlocked account' do
|
||||
context 'with an unlocked account' do
|
||||
before do
|
||||
subject.perform
|
||||
end
|
||||
@ -103,7 +103,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
end
|
||||
end
|
||||
|
||||
context 'silenced account following an unlocked account' do
|
||||
context 'when silenced account following an unlocked account' do
|
||||
before do
|
||||
sender.touch(:silenced_at)
|
||||
subject.perform
|
||||
@ -118,7 +118,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
end
|
||||
end
|
||||
|
||||
context 'unlocked account muting the sender' do
|
||||
context 'with an unlocked account muting the sender' do
|
||||
before do
|
||||
recipient.mute!(sender)
|
||||
subject.perform
|
||||
@ -133,7 +133,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
end
|
||||
end
|
||||
|
||||
context 'locked account' do
|
||||
context 'when locked account' do
|
||||
before do
|
||||
recipient.update(locked: true)
|
||||
subject.perform
|
||||
@ -154,7 +154,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
sender.follow_requests.create!(target_account: recipient, uri: 'bar')
|
||||
end
|
||||
|
||||
context 'silenced account following an unlocked account' do
|
||||
context 'when silenced account following an unlocked account' do
|
||||
before do
|
||||
sender.touch(:silenced_at)
|
||||
subject.perform
|
||||
@ -170,7 +170,7 @@ RSpec.describe ActivityPub::Activity::Follow do
|
||||
end
|
||||
end
|
||||
|
||||
context 'locked account' do
|
||||
context 'when locked account' do
|
||||
before do
|
||||
recipient.update(locked: true)
|
||||
subject.perform
|
||||
|
@ -27,7 +27,7 @@ RSpec.describe ActivityPub::Activity::Reject do
|
||||
describe '#perform' do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
context 'rejecting a pending follow request by target' do
|
||||
context 'when rejecting a pending follow request by target' do
|
||||
before do
|
||||
Fabricate(:follow_request, account: recipient, target_account: sender)
|
||||
subject.perform
|
||||
@ -42,7 +42,7 @@ RSpec.describe ActivityPub::Activity::Reject do
|
||||
end
|
||||
end
|
||||
|
||||
context 'rejecting a pending follow request by uri' do
|
||||
context 'when rejecting a pending follow request by uri' do
|
||||
before do
|
||||
Fabricate(:follow_request, account: recipient, target_account: sender, uri: 'bar')
|
||||
subject.perform
|
||||
@ -57,7 +57,7 @@ RSpec.describe ActivityPub::Activity::Reject do
|
||||
end
|
||||
end
|
||||
|
||||
context 'rejecting a pending follow request by uri only' do
|
||||
context 'when rejecting a pending follow request by uri only' do
|
||||
let(:object_json) { 'bar' }
|
||||
|
||||
before do
|
||||
@ -74,7 +74,7 @@ RSpec.describe ActivityPub::Activity::Reject do
|
||||
end
|
||||
end
|
||||
|
||||
context 'rejecting an existing follow relationship by target' do
|
||||
context 'when rejecting an existing follow relationship by target' do
|
||||
before do
|
||||
Fabricate(:follow, account: recipient, target_account: sender)
|
||||
subject.perform
|
||||
@ -89,7 +89,7 @@ RSpec.describe ActivityPub::Activity::Reject do
|
||||
end
|
||||
end
|
||||
|
||||
context 'rejecting an existing follow relationship by uri' do
|
||||
context 'when rejecting an existing follow relationship by uri' do
|
||||
before do
|
||||
Fabricate(:follow, account: recipient, target_account: sender, uri: 'bar')
|
||||
subject.perform
|
||||
@ -104,7 +104,7 @@ RSpec.describe ActivityPub::Activity::Reject do
|
||||
end
|
||||
end
|
||||
|
||||
context 'rejecting an existing follow relationship by uri only' do
|
||||
context 'when rejecting an existing follow relationship by uri only' do
|
||||
let(:object_json) { 'bar' }
|
||||
|
||||
before do
|
||||
@ -122,7 +122,7 @@ RSpec.describe ActivityPub::Activity::Reject do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a relay' do
|
||||
context 'when given a relay' do
|
||||
subject { described_class.new(json, sender) }
|
||||
|
||||
let!(:relay) { Fabricate(:relay, state: :pending, follow_activity_id: 'https://abc-123/456') }
|
||||
|
@ -3,43 +3,51 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::Adapter do
|
||||
class TestObject < ActiveModelSerializers::Model
|
||||
attributes :foo
|
||||
end
|
||||
|
||||
class TestWithBasicContextSerializer < ActivityPub::Serializer
|
||||
attributes :foo
|
||||
end
|
||||
|
||||
class TestWithNamedContextSerializer < ActivityPub::Serializer
|
||||
context :security
|
||||
attributes :foo
|
||||
end
|
||||
|
||||
class TestWithNestedNamedContextSerializer < ActivityPub::Serializer
|
||||
attributes :foo
|
||||
|
||||
has_one :virtual_object, key: :baz, serializer: TestWithNamedContextSerializer
|
||||
|
||||
def virtual_object
|
||||
object
|
||||
before do
|
||||
test_object_class = Class.new(ActiveModelSerializers::Model) do
|
||||
attributes :foo
|
||||
end
|
||||
end
|
||||
stub_const('TestObject', test_object_class)
|
||||
|
||||
class TestWithContextExtensionSerializer < ActivityPub::Serializer
|
||||
context_extensions :sensitive
|
||||
attributes :foo
|
||||
end
|
||||
|
||||
class TestWithNestedContextExtensionSerializer < ActivityPub::Serializer
|
||||
context_extensions :manually_approves_followers
|
||||
attributes :foo
|
||||
|
||||
has_one :virtual_object, key: :baz, serializer: TestWithContextExtensionSerializer
|
||||
|
||||
def virtual_object
|
||||
object
|
||||
test_with_basic_context_serializer = Class.new(ActivityPub::Serializer) do
|
||||
attributes :foo
|
||||
end
|
||||
stub_const('TestWithBasicContextSerializer', test_with_basic_context_serializer)
|
||||
|
||||
test_with_named_context_serializer = Class.new(ActivityPub::Serializer) do
|
||||
context :security
|
||||
attributes :foo
|
||||
end
|
||||
stub_const('TestWithNamedContextSerializer', test_with_named_context_serializer)
|
||||
|
||||
test_with_nested_named_context_serializer = Class.new(ActivityPub::Serializer) do
|
||||
attributes :foo
|
||||
|
||||
has_one :virtual_object, key: :baz, serializer: TestWithNamedContextSerializer
|
||||
|
||||
def virtual_object
|
||||
object
|
||||
end
|
||||
end
|
||||
stub_const('TestWithNestedNamedContextSerializer', test_with_nested_named_context_serializer)
|
||||
|
||||
test_with_context_extension_serializer = Class.new(ActivityPub::Serializer) do
|
||||
context_extensions :sensitive
|
||||
attributes :foo
|
||||
end
|
||||
stub_const('TestWithContextExtensionSerializer', test_with_context_extension_serializer)
|
||||
|
||||
test_with_nested_context_extension_serializer = Class.new(ActivityPub::Serializer) do
|
||||
context_extensions :manually_approves_followers
|
||||
attributes :foo
|
||||
|
||||
has_one :virtual_object, key: :baz, serializer: TestWithContextExtensionSerializer
|
||||
|
||||
def virtual_object
|
||||
object
|
||||
end
|
||||
end
|
||||
stub_const('TestWithNestedContextExtensionSerializer', test_with_nested_context_extension_serializer)
|
||||
end
|
||||
|
||||
describe '#serializable_hash' do
|
||||
|
@ -3,22 +3,24 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ConnectionPool::SharedConnectionPool do
|
||||
class MiniConnection
|
||||
attr_reader :site
|
||||
subject { described_class.new(size: 5, timeout: 5) { |site| mini_connection_class.new(site) } }
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
let(:mini_connection_class) do
|
||||
Class.new do
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
subject { described_class.new(size: 5, timeout: 5) { |site| MiniConnection.new(site) } }
|
||||
|
||||
describe '#with' do
|
||||
it 'runs a block with a connection' do
|
||||
block_run = false
|
||||
|
||||
subject.with('foo') do |connection|
|
||||
expect(connection).to be_a MiniConnection
|
||||
expect(connection).to be_a mini_connection_class
|
||||
block_run = true
|
||||
end
|
||||
|
||||
|
@ -3,30 +3,32 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ConnectionPool::SharedTimedStack do
|
||||
class MiniConnection
|
||||
attr_reader :site
|
||||
subject { described_class.new(5) { |site| mini_connection_class.new(site) } }
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
let(:mini_connection_class) do
|
||||
Class.new do
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
subject { described_class.new(5) { |site| MiniConnection.new(site) } }
|
||||
|
||||
describe '#push' do
|
||||
it 'keeps the connection in the stack' do
|
||||
subject.push(MiniConnection.new('foo'))
|
||||
subject.push(mini_connection_class.new('foo'))
|
||||
expect(subject.size).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pop' do
|
||||
it 'returns a connection' do
|
||||
expect(subject.pop('foo')).to be_a MiniConnection
|
||||
expect(subject.pop('foo')).to be_a mini_connection_class
|
||||
end
|
||||
|
||||
it 'returns the same connection that was pushed in' do
|
||||
connection = MiniConnection.new('foo')
|
||||
connection = mini_connection_class.new('foo')
|
||||
subject.push(connection)
|
||||
expect(subject.pop('foo')).to be connection
|
||||
end
|
||||
@ -36,8 +38,8 @@ describe ConnectionPool::SharedTimedStack do
|
||||
end
|
||||
|
||||
it 'repurposes a connection for a different site when maximum amount is reached' do
|
||||
5.times { subject.push(MiniConnection.new('foo')) }
|
||||
expect(subject.pop('bar')).to be_a MiniConnection
|
||||
5.times { subject.push(mini_connection_class.new('foo')) }
|
||||
expect(subject.pop('bar')).to be_a mini_connection_class
|
||||
end
|
||||
end
|
||||
|
||||
@ -47,14 +49,14 @@ describe ConnectionPool::SharedTimedStack do
|
||||
end
|
||||
|
||||
it 'returns false when there are connections on the stack' do
|
||||
subject.push(MiniConnection.new('foo'))
|
||||
subject.push(mini_connection_class.new('foo'))
|
||||
expect(subject.empty?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#size' do
|
||||
it 'returns the number of connections on the stack' do
|
||||
2.times { subject.push(MiniConnection.new('foo')) }
|
||||
2.times { subject.push(mini_connection_class.new('foo')) }
|
||||
expect(subject.size).to eq 2
|
||||
end
|
||||
end
|
||||
|
@ -14,7 +14,7 @@ RSpec.describe EmojiFormatter do
|
||||
|
||||
let(:emojis) { [emoji] }
|
||||
|
||||
context 'given text that is not marked as html-safe' do
|
||||
context 'when given text that is not marked as html-safe' do
|
||||
let(:text) { 'Foo' }
|
||||
|
||||
it 'raises an argument error' do
|
||||
@ -22,7 +22,7 @@ RSpec.describe EmojiFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text with an emoji shortcode at the start' do
|
||||
context 'when given text with an emoji shortcode at the start' do
|
||||
let(:text) { preformat_text(':coolcat: Beep boop') }
|
||||
|
||||
it 'converts the shortcode to an image tag' do
|
||||
@ -30,7 +30,7 @@ RSpec.describe EmojiFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text with an emoji shortcode in the middle' do
|
||||
context 'when given text with an emoji shortcode in the middle' do
|
||||
let(:text) { preformat_text('Beep :coolcat: boop') }
|
||||
|
||||
it 'converts the shortcode to an image tag' do
|
||||
@ -38,7 +38,7 @@ RSpec.describe EmojiFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text with concatenated emoji shortcodes' do
|
||||
context 'when given text with concatenated emoji shortcodes' do
|
||||
let(:text) { preformat_text(':coolcat::coolcat:') }
|
||||
|
||||
it 'does not touch the shortcodes' do
|
||||
@ -46,7 +46,7 @@ RSpec.describe EmojiFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text with an emoji shortcode at the end' do
|
||||
context 'when given text with an emoji shortcode at the end' do
|
||||
let(:text) { preformat_text('Beep boop :coolcat:') }
|
||||
|
||||
it 'converts the shortcode to an image tag' do
|
||||
|
@ -9,7 +9,7 @@ RSpec.describe EntityCache do
|
||||
describe '#emoji' do
|
||||
subject { EntityCache.instance.emoji(shortcodes, domain) }
|
||||
|
||||
context 'called with an empty list of shortcodes' do
|
||||
context 'when called with an empty list of shortcodes' do
|
||||
let(:shortcodes) { [] }
|
||||
let(:domain) { 'example.org' }
|
||||
|
||||
|
@ -27,7 +27,7 @@ RSpec.describe FeedManager do
|
||||
let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') }
|
||||
let(:jeff) { Fabricate(:account, username: 'jeff') }
|
||||
|
||||
context 'for home feed' do
|
||||
context 'with home feed' do
|
||||
it 'returns false for followee\'s status' do
|
||||
status = Fabricate(:status, text: 'Hello world', account: alice)
|
||||
bob.follow!(alice)
|
||||
@ -162,7 +162,7 @@ RSpec.describe FeedManager do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for mentions feed' do
|
||||
context 'with mentions feed' do
|
||||
it 'returns true for status that mentions blocked account' do
|
||||
bob.block!(jeff)
|
||||
status = PostStatusService.new.call(alice, text: 'Hey @jeff')
|
||||
@ -195,7 +195,7 @@ RSpec.describe FeedManager do
|
||||
it 'trims timelines if they will have more than FeedManager::MAX_ITEMS' do
|
||||
account = Fabricate(:account)
|
||||
status = Fabricate(:status)
|
||||
members = FeedManager::MAX_ITEMS.times.map { |count| [count, count] }
|
||||
members = Array.new(FeedManager::MAX_ITEMS) { |count| [count, count] }
|
||||
redis.zadd("feed:home:#{account.id}", members)
|
||||
|
||||
FeedManager.instance.push_to_home(account, status)
|
||||
@ -203,7 +203,7 @@ RSpec.describe FeedManager do
|
||||
expect(redis.zcard("feed:home:#{account.id}")).to eq FeedManager::MAX_ITEMS
|
||||
end
|
||||
|
||||
context 'reblogs' do
|
||||
context 'with reblogs' do
|
||||
it 'saves reblogs of unseen statuses' do
|
||||
account = Fabricate(:account)
|
||||
reblogged = Fabricate(:status)
|
||||
@ -240,7 +240,7 @@ RSpec.describe FeedManager do
|
||||
it 'does not save a new reblog of a recently-reblogged status' do
|
||||
account = Fabricate(:account)
|
||||
reblogged = Fabricate(:status)
|
||||
reblogs = 2.times.map { Fabricate(:status, reblog: reblogged) }
|
||||
reblogs = Array.new(2) { Fabricate(:status, reblog: reblogged) }
|
||||
|
||||
# The first reblog will be accepted
|
||||
FeedManager.instance.push_to_home(account, reblogs.first)
|
||||
@ -269,7 +269,7 @@ RSpec.describe FeedManager do
|
||||
it 'does not save a new reblog of a multiply-reblogged-then-unreblogged status' do
|
||||
account = Fabricate(:account)
|
||||
reblogged = Fabricate(:status)
|
||||
reblogs = 3.times.map { Fabricate(:status, reblog: reblogged) }
|
||||
reblogs = Array.new(3) { Fabricate(:status, reblog: reblogged) }
|
||||
|
||||
# Accept the reblogs
|
||||
FeedManager.instance.push_to_home(account, reblogs[0])
|
||||
@ -285,7 +285,7 @@ RSpec.describe FeedManager do
|
||||
it 'saves a new reblog of a long-ago-reblogged status' do
|
||||
account = Fabricate(:account)
|
||||
reblogged = Fabricate(:status)
|
||||
reblogs = 2.times.map { Fabricate(:status, reblog: reblogged) }
|
||||
reblogs = Array.new(2) { Fabricate(:status, reblog: reblogged) }
|
||||
|
||||
# The first reblog will be accepted
|
||||
FeedManager.instance.push_to_home(account, reblogs.first)
|
||||
@ -466,7 +466,7 @@ RSpec.describe FeedManager do
|
||||
|
||||
it 'leaves a multiply-reblogged status if another reblog was in feed' do
|
||||
reblogged = Fabricate(:status)
|
||||
reblogs = 3.times.map { Fabricate(:status, reblog: reblogged) }
|
||||
reblogs = Array.new(3) { Fabricate(:status, reblog: reblogged) }
|
||||
|
||||
reblogs.each do |reblog|
|
||||
FeedManager.instance.push_to_home(receiver, reblog)
|
||||
|
@ -18,7 +18,7 @@ RSpec.describe HtmlAwareFormatter do
|
||||
context 'when remote' do
|
||||
let(:local) { false }
|
||||
|
||||
context 'given plain text' do
|
||||
context 'when given plain text' do
|
||||
let(:text) { 'Beep boop' }
|
||||
|
||||
it 'keeps the plain text' do
|
||||
@ -26,7 +26,7 @@ RSpec.describe HtmlAwareFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing script tags' do
|
||||
context 'when given text containing script tags' do
|
||||
let(:text) { '<script>alert("Hello")</script>' }
|
||||
|
||||
it 'strips the scripts' do
|
||||
@ -34,7 +34,7 @@ RSpec.describe HtmlAwareFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing malicious classes' do
|
||||
context 'when given text containing malicious classes' do
|
||||
let(:text) { '<span class="mention status__content__spoiler-link">Show more</span>' }
|
||||
|
||||
it 'strips the malicious classes' do
|
||||
|
@ -40,7 +40,7 @@ RSpec.describe LinkDetailsExtractor do
|
||||
context 'when structured data is present' do
|
||||
let(:original_url) { 'https://example.com/page.html' }
|
||||
|
||||
context 'and is wrapped in CDATA tags' do
|
||||
context 'when is wrapped in CDATA tags' do
|
||||
let(:html) { <<~HTML }
|
||||
<!doctype html>
|
||||
<html>
|
||||
@ -79,7 +79,7 @@ RSpec.describe LinkDetailsExtractor do
|
||||
end
|
||||
end
|
||||
|
||||
context 'but the first tag is invalid JSON' do
|
||||
context 'with the first tag is invalid JSON' do
|
||||
let(:html) { <<~HTML }
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
64
spec/lib/mastodon/settings_cli_spec.rb
Normal file
64
spec/lib/mastodon/settings_cli_spec.rb
Normal file
@ -0,0 +1,64 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require 'mastodon/settings_cli'
|
||||
|
||||
RSpec.describe Mastodon::SettingsCLI do
|
||||
describe 'subcommand "registrations"' do
|
||||
let(:cli) { Mastodon::RegistrationsCLI.new }
|
||||
|
||||
before do
|
||||
Setting.registrations_mode = nil
|
||||
end
|
||||
|
||||
describe '#open' do
|
||||
it 'changes "registrations_mode" to "open"' do
|
||||
expect { cli.open }.to change(Setting, :registrations_mode).from(nil).to('open')
|
||||
end
|
||||
|
||||
it 'displays success message' do
|
||||
expect { cli.open }.to output(
|
||||
a_string_including('OK')
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
describe '#approved' do
|
||||
it 'changes "registrations_mode" to "approved"' do
|
||||
expect { cli.approved }.to change(Setting, :registrations_mode).from(nil).to('approved')
|
||||
end
|
||||
|
||||
it 'displays success message' do
|
||||
expect { cli.approved }.to output(
|
||||
a_string_including('OK')
|
||||
).to_stdout
|
||||
end
|
||||
|
||||
context 'with --require-reason' do
|
||||
before do
|
||||
cli.options = { require_reason: true }
|
||||
end
|
||||
|
||||
it 'changes "registrations_mode" to "approved"' do
|
||||
expect { cli.approved }.to change(Setting, :registrations_mode).from(nil).to('approved')
|
||||
end
|
||||
|
||||
it 'sets "require_invite_text" to "true"' do
|
||||
expect { cli.approved }.to change(Setting, :require_invite_text).from(false).to(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#close' do
|
||||
it 'changes "registrations_mode" to "none"' do
|
||||
expect { cli.close }.to change(Setting, :registrations_mode).from(nil).to('none')
|
||||
end
|
||||
|
||||
it 'displays success message' do
|
||||
expect { cli.close }.to output(
|
||||
a_string_including('OK')
|
||||
).to_stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -40,7 +40,7 @@ describe OStatus::TagManager do
|
||||
describe '#uri_for' do
|
||||
subject { OStatus::TagManager.instance.uri_for(target) }
|
||||
|
||||
context 'comment object' do
|
||||
context 'with comment object' do
|
||||
let(:target) { Fabricate(:status, created_at: '2000-01-01T00:00:00Z', reply: true) }
|
||||
|
||||
it 'returns the unique tag for status' do
|
||||
@ -49,7 +49,7 @@ describe OStatus::TagManager do
|
||||
end
|
||||
end
|
||||
|
||||
context 'note object' do
|
||||
context 'with note object' do
|
||||
let(:target) { Fabricate(:status, created_at: '2000-01-01T00:00:00Z', reply: false, thread: nil) }
|
||||
|
||||
it 'returns the unique tag for status' do
|
||||
@ -58,7 +58,7 @@ describe OStatus::TagManager do
|
||||
end
|
||||
end
|
||||
|
||||
context 'person object' do
|
||||
context 'when person object' do
|
||||
let(:target) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
it 'returns the URL for account' do
|
||||
|
@ -33,7 +33,7 @@ describe RequestPool do
|
||||
|
||||
subject
|
||||
|
||||
threads = 20.times.map do |_i|
|
||||
threads = Array.new(20) do |_i|
|
||||
Thread.new do
|
||||
20.times do
|
||||
subject.with('http://example.com') do |http_client|
|
||||
|
@ -20,67 +20,67 @@ describe ScopeTransformer do
|
||||
end
|
||||
end
|
||||
|
||||
context 'for scope "read"' do
|
||||
context 'with scope "read"' do
|
||||
let(:input) { 'read' }
|
||||
|
||||
it_behaves_like 'a scope', nil, 'all', 'read'
|
||||
end
|
||||
|
||||
context 'for scope "write"' do
|
||||
context 'with scope "write"' do
|
||||
let(:input) { 'write' }
|
||||
|
||||
it_behaves_like 'a scope', nil, 'all', 'write'
|
||||
end
|
||||
|
||||
context 'for scope "follow"' do
|
||||
context 'with scope "follow"' do
|
||||
let(:input) { 'follow' }
|
||||
|
||||
it_behaves_like 'a scope', nil, 'follow', 'read/write'
|
||||
end
|
||||
|
||||
context 'for scope "crypto"' do
|
||||
context 'with scope "crypto"' do
|
||||
let(:input) { 'crypto' }
|
||||
|
||||
it_behaves_like 'a scope', nil, 'crypto', 'read/write'
|
||||
end
|
||||
|
||||
context 'for scope "push"' do
|
||||
context 'with scope "push"' do
|
||||
let(:input) { 'push' }
|
||||
|
||||
it_behaves_like 'a scope', nil, 'push', 'read/write'
|
||||
end
|
||||
|
||||
context 'for scope "admin:read"' do
|
||||
context 'with scope "admin:read"' do
|
||||
let(:input) { 'admin:read' }
|
||||
|
||||
it_behaves_like 'a scope', 'admin', 'all', 'read'
|
||||
end
|
||||
|
||||
context 'for scope "admin:write"' do
|
||||
context 'with scope "admin:write"' do
|
||||
let(:input) { 'admin:write' }
|
||||
|
||||
it_behaves_like 'a scope', 'admin', 'all', 'write'
|
||||
end
|
||||
|
||||
context 'for scope "admin:read:accounts"' do
|
||||
context 'with scope "admin:read:accounts"' do
|
||||
let(:input) { 'admin:read:accounts' }
|
||||
|
||||
it_behaves_like 'a scope', 'admin', 'accounts', 'read'
|
||||
end
|
||||
|
||||
context 'for scope "admin:write:accounts"' do
|
||||
context 'with scope "admin:write:accounts"' do
|
||||
let(:input) { 'admin:write:accounts' }
|
||||
|
||||
it_behaves_like 'a scope', 'admin', 'accounts', 'write'
|
||||
end
|
||||
|
||||
context 'for scope "read:accounts"' do
|
||||
context 'with scope "read:accounts"' do
|
||||
let(:input) { 'read:accounts' }
|
||||
|
||||
it_behaves_like 'a scope', nil, 'accounts', 'read'
|
||||
end
|
||||
|
||||
context 'for scope "write:accounts"' do
|
||||
context 'with scope "write:accounts"' do
|
||||
let(:input) { 'write:accounts' }
|
||||
|
||||
it_behaves_like 'a scope', nil, 'accounts', 'write'
|
||||
|
@ -44,7 +44,7 @@ describe StatusCacheHydrator do
|
||||
let(:reblog) { Fabricate(:status) }
|
||||
let(:status) { Fabricate(:status, reblog: reblog) }
|
||||
|
||||
context 'that has been favourited' do
|
||||
context 'when it has been favourited' do
|
||||
before do
|
||||
FavouriteService.new.call(account, reblog)
|
||||
end
|
||||
@ -54,7 +54,7 @@ describe StatusCacheHydrator do
|
||||
end
|
||||
end
|
||||
|
||||
context 'that has been reblogged' do
|
||||
context 'when it has been reblogged' do
|
||||
before do
|
||||
ReblogService.new.call(account, reblog)
|
||||
end
|
||||
@ -64,7 +64,7 @@ describe StatusCacheHydrator do
|
||||
end
|
||||
end
|
||||
|
||||
context 'that has been pinned' do
|
||||
context 'when it has been pinned' do
|
||||
let(:reblog) { Fabricate(:status, account: account) }
|
||||
|
||||
before do
|
||||
@ -76,7 +76,7 @@ describe StatusCacheHydrator do
|
||||
end
|
||||
end
|
||||
|
||||
context 'that has been followed tags' do
|
||||
context 'when it has been followed tags' do
|
||||
let(:followed_tag) { Fabricate(:tag) }
|
||||
|
||||
before do
|
||||
@ -90,7 +90,7 @@ describe StatusCacheHydrator do
|
||||
end
|
||||
end
|
||||
|
||||
context 'that has a poll authored by the user' do
|
||||
context 'when it has a poll authored by the user' do
|
||||
let(:poll) { Fabricate(:poll, account: account) }
|
||||
let(:reblog) { Fabricate(:status, poll: poll, account: account) }
|
||||
|
||||
@ -99,7 +99,7 @@ describe StatusCacheHydrator do
|
||||
end
|
||||
end
|
||||
|
||||
context 'that has been voted in' do
|
||||
context 'when it has been voted in' do
|
||||
let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) }
|
||||
let(:reblog) { Fabricate(:status, poll: poll) }
|
||||
|
||||
@ -112,7 +112,7 @@ describe StatusCacheHydrator do
|
||||
end
|
||||
end
|
||||
|
||||
context 'that matches account filters' do
|
||||
context 'when it matches account filters' do
|
||||
let(:reblog) { Fabricate(:status, text: 'this toot is about that banned word') }
|
||||
|
||||
before do
|
||||
|
@ -4,7 +4,7 @@ require 'rails_helper'
|
||||
|
||||
describe StatusReachFinder do
|
||||
describe '#inboxes' do
|
||||
context 'for a local status' do
|
||||
context 'with a local status' do
|
||||
subject { described_class.new(status) }
|
||||
|
||||
let(:parent_status) { nil }
|
||||
|
@ -8,7 +8,7 @@ RSpec.describe TextFormatter do
|
||||
|
||||
let(:preloaded_accounts) { nil }
|
||||
|
||||
context 'given text containing plain text' do
|
||||
context 'when given text containing plain text' do
|
||||
let(:text) { 'text' }
|
||||
|
||||
it 'paragraphizes the text' do
|
||||
@ -16,7 +16,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing line feeds' do
|
||||
context 'when given text containing line feeds' do
|
||||
let(:text) { "line\nfeed" }
|
||||
|
||||
it 'removes line feeds' do
|
||||
@ -24,7 +24,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing linkable mentions' do
|
||||
context 'when given text containing linkable mentions' do
|
||||
let(:preloaded_accounts) { [Fabricate(:account, username: 'alice')] }
|
||||
let(:text) { '@alice' }
|
||||
|
||||
@ -33,7 +33,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing unlinkable mentions' do
|
||||
context 'when given text containing unlinkable mentions' do
|
||||
let(:preloaded_accounts) { [] }
|
||||
let(:text) { '@alice' }
|
||||
|
||||
@ -42,7 +42,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a stand-alone medium URL' do
|
||||
context 'when given a stand-alone medium URL' do
|
||||
let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -50,7 +50,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a stand-alone google URL' do
|
||||
context 'when given a stand-alone google URL' do
|
||||
let(:text) { 'http://google.com' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -58,7 +58,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a stand-alone URL with a newer TLD' do
|
||||
context 'when given a stand-alone URL with a newer TLD' do
|
||||
let(:text) { 'http://example.gay' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -66,7 +66,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a stand-alone IDN URL' do
|
||||
context 'when given a stand-alone IDN URL' do
|
||||
let(:text) { 'https://nic.みんな/' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -78,7 +78,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with a trailing period' do
|
||||
context 'when given a URL with a trailing period' do
|
||||
let(:text) { 'http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona. ' }
|
||||
|
||||
it 'matches the full URL but not the period' do
|
||||
@ -86,7 +86,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL enclosed with parentheses' do
|
||||
context 'when given a URL enclosed with parentheses' do
|
||||
let(:text) { '(http://google.com/)' }
|
||||
|
||||
it 'matches the full URL but not the parentheses' do
|
||||
@ -94,7 +94,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with a trailing exclamation point' do
|
||||
context 'when given a URL with a trailing exclamation point' do
|
||||
let(:text) { 'http://www.google.com!' }
|
||||
|
||||
it 'matches the full URL but not the exclamation point' do
|
||||
@ -102,7 +102,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with a trailing single quote' do
|
||||
context 'when given a URL with a trailing single quote' do
|
||||
let(:text) { "http://www.google.com'" }
|
||||
|
||||
it 'matches the full URL but not the single quote' do
|
||||
@ -110,7 +110,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with a trailing angle bracket' do
|
||||
context 'when given a URL with a trailing angle bracket' do
|
||||
let(:text) { 'http://www.google.com>' }
|
||||
|
||||
it 'matches the full URL but not the angle bracket' do
|
||||
@ -118,7 +118,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with a query string' do
|
||||
context 'when given a URL with a query string' do
|
||||
context 'with escaped unicode character' do
|
||||
let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' }
|
||||
|
||||
@ -152,7 +152,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with parentheses in it' do
|
||||
context 'when given a URL with parentheses in it' do
|
||||
let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -160,7 +160,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL in quotation marks' do
|
||||
context 'when given a URL in quotation marks' do
|
||||
let(:text) { '"https://example.com/"' }
|
||||
|
||||
it 'does not match the quotation marks' do
|
||||
@ -168,7 +168,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL in angle brackets' do
|
||||
context 'when given a URL in angle brackets' do
|
||||
let(:text) { '<https://example.com/>' }
|
||||
|
||||
it 'does not match the angle brackets' do
|
||||
@ -176,7 +176,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with Japanese path string' do
|
||||
context 'when given a URL with Japanese path string' do
|
||||
let(:text) { 'https://ja.wikipedia.org/wiki/日本' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -184,7 +184,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with Korean path string' do
|
||||
context 'when given a URL with Korean path string' do
|
||||
let(:text) { 'https://ko.wikipedia.org/wiki/대한민국' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -192,7 +192,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with a full-width space' do
|
||||
context 'when given a URL with a full-width space' do
|
||||
let(:text) { 'https://example.com/ abc123' }
|
||||
|
||||
it 'does not match the full-width space' do
|
||||
@ -200,7 +200,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL in Japanese quotation marks' do
|
||||
context 'when given a URL in Japanese quotation marks' do
|
||||
let(:text) { '「[https://example.org/」' }
|
||||
|
||||
it 'does not match the quotation marks' do
|
||||
@ -208,7 +208,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with Simplified Chinese path string' do
|
||||
context 'when given a URL with Simplified Chinese path string' do
|
||||
let(:text) { 'https://baike.baidu.com/item/中华人民共和国' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -216,7 +216,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL with Traditional Chinese path string' do
|
||||
context 'when given a URL with Traditional Chinese path string' do
|
||||
let(:text) { 'https://zh.wikipedia.org/wiki/臺灣' }
|
||||
|
||||
it 'matches the full URL' do
|
||||
@ -224,7 +224,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL containing unsafe code (XSS attack, visible part)' do
|
||||
context 'when given a URL containing unsafe code (XSS attack, visible part)' do
|
||||
let(:text) { 'http://example.com/b<del>b</del>' }
|
||||
|
||||
it 'does not include the HTML in the URL' do
|
||||
@ -236,7 +236,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a URL containing unsafe code (XSS attack, invisible part)' do
|
||||
context 'when given a URL containing unsafe code (XSS attack, invisible part)' do
|
||||
let(:text) { 'http://example.com/blahblahblahblah/a<script>alert("Hello")</script>' }
|
||||
|
||||
it 'does not include the HTML in the URL' do
|
||||
@ -248,7 +248,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing HTML code (script tag)' do
|
||||
context 'when given text containing HTML code (script tag)' do
|
||||
let(:text) { '<script>alert("Hello")</script>' }
|
||||
|
||||
it 'escapes the HTML' do
|
||||
@ -256,7 +256,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing HTML (XSS attack)' do
|
||||
context 'when given text containing HTML (XSS attack)' do
|
||||
let(:text) { %q{<img src="javascript:alert('XSS');">} }
|
||||
|
||||
it 'escapes the HTML' do
|
||||
@ -264,7 +264,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an invalid URL' do
|
||||
context 'when given an invalid URL' do
|
||||
let(:text) { 'http://www\.google\.com' }
|
||||
|
||||
it 'outputs the raw URL' do
|
||||
@ -272,7 +272,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing a hashtag' do
|
||||
context 'when given text containing a hashtag' do
|
||||
let(:text) { '#hashtag' }
|
||||
|
||||
it 'creates a hashtag link' do
|
||||
@ -280,7 +280,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing a hashtag with Unicode chars' do
|
||||
context 'when given text containing a hashtag with Unicode chars' do
|
||||
let(:text) { '#hashtagタグ' }
|
||||
|
||||
it 'creates a hashtag link' do
|
||||
@ -288,7 +288,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text with a stand-alone xmpp: URI' do
|
||||
context 'when given text with a stand-alone xmpp: URI' do
|
||||
let(:text) { 'xmpp:user@instance.com' }
|
||||
|
||||
it 'matches the full URI' do
|
||||
@ -296,7 +296,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text with an xmpp: URI with a query-string' do
|
||||
context 'when given text with an xmpp: URI with a query-string' do
|
||||
let(:text) { 'please join xmpp:muc@instance.com?join right now' }
|
||||
|
||||
it 'matches the full URI' do
|
||||
@ -304,7 +304,7 @@ RSpec.describe TextFormatter do
|
||||
end
|
||||
end
|
||||
|
||||
context 'given text containing a magnet: URI' do
|
||||
context 'when given text containing a magnet: URI' do
|
||||
let(:text) { 'wikipedia gives this example of a magnet uri: magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a' }
|
||||
|
||||
it 'matches the full URI' do
|
||||
|
19
spec/lib/vacuum/imports_vacuum_spec.rb
Normal file
19
spec/lib/vacuum/imports_vacuum_spec.rb
Normal file
@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Vacuum::ImportsVacuum do
|
||||
subject { described_class.new }
|
||||
|
||||
let!(:old_unconfirmed) { Fabricate(:bulk_import, state: :unconfirmed, created_at: 2.days.ago) }
|
||||
let!(:new_unconfirmed) { Fabricate(:bulk_import, state: :unconfirmed, created_at: 10.seconds.ago) }
|
||||
let!(:recent_ongoing) { Fabricate(:bulk_import, state: :in_progress, created_at: 20.minutes.ago) }
|
||||
let!(:recent_finished) { Fabricate(:bulk_import, state: :finished, created_at: 1.day.ago) }
|
||||
let!(:old_finished) { Fabricate(:bulk_import, state: :finished, created_at: 2.months.ago) }
|
||||
|
||||
describe '#perform' do
|
||||
it 'cleans up the expected imports' do
|
||||
expect { subject.perform }.to change { BulkImport.all.pluck(:id) }.from([old_unconfirmed, new_unconfirmed, recent_ongoing, recent_finished, old_finished].map(&:id)).to([new_unconfirmed, recent_ongoing, recent_finished].map(&:id))
|
||||
end
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user