Merge remote-tracking branch 'parent/main' into upstream-20240112
This commit is contained in:
commit
e65fb9fb51
333 changed files with 2661 additions and 1461 deletions
|
@ -521,9 +521,11 @@ RSpec.describe Account do
|
|||
|
||||
results = account.excluded_from_timeline_account_ids
|
||||
expect(results.size).to eq 3
|
||||
expect(results).to include(block.target_account.id)
|
||||
expect(results).to include(mute.target_account.id)
|
||||
expect(results).to include(block_by.account.id)
|
||||
expect(results).to include(
|
||||
block.target_account.id,
|
||||
mute.target_account.id,
|
||||
block_by.account.id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1218,4 +1220,27 @@ RSpec.describe Account do
|
|||
expect(subject.reload.followers_count).to eq 15
|
||||
end
|
||||
end
|
||||
|
||||
describe '.followable_by' do
|
||||
context 'with follows and follow requests' do
|
||||
let!(:account) { Fabricate(:account) }
|
||||
let!(:eligible_account) { Fabricate(:account) }
|
||||
let!(:following_account) { Fabricate(:account) }
|
||||
let!(:follow_requested_account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
Fabricate :follow, account: account, target_account: following_account
|
||||
Fabricate :follow_request, account: account, target_account: follow_requested_account
|
||||
end
|
||||
|
||||
it 'returns accounts not already following or requested to follow' do
|
||||
results = described_class.followable_by(account)
|
||||
|
||||
expect(results)
|
||||
.to include(eligible_account)
|
||||
.and not_include(following_account)
|
||||
.and not_include(follow_requested_account)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,7 +46,7 @@ RSpec.describe Admin::AccountAction do
|
|||
expect(target_account).to be_suspended
|
||||
end
|
||||
|
||||
it 'queues Admin::SuspensionWorker by 1', :sidekiq_fake do
|
||||
it 'queues Admin::SuspensionWorker by 1' do
|
||||
expect do
|
||||
subject
|
||||
end.to change { Admin::SuspensionWorker.jobs.size }.by 1
|
||||
|
|
|
@ -25,22 +25,6 @@ describe Announcement do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#without_muted' do
|
||||
let!(:announcement) { Fabricate(:announcement) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:muted_announcement) { Fabricate(:announcement) }
|
||||
|
||||
before do
|
||||
Fabricate(:announcement_mute, account: account, announcement: muted_announcement)
|
||||
end
|
||||
|
||||
it 'returns the announcements not muted by the account' do
|
||||
results = described_class.without_muted(account)
|
||||
expect(results).to include(announcement)
|
||||
expect(results).to_not include(muted_announcement)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with timestamped announcements' do
|
||||
let!(:adam_announcement) { Fabricate(:announcement, starts_at: 100.days.ago, scheduled_at: 10.days.ago, published_at: 10.days.ago, ends_at: 5.days.from_now) }
|
||||
let!(:brenda_announcement) { Fabricate(:announcement, starts_at: 10.days.ago, scheduled_at: 100.days.ago, published_at: 10.days.ago, ends_at: 5.days.from_now) }
|
||||
|
@ -129,32 +113,6 @@ describe Announcement do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#time_range?' do
|
||||
it 'returns false when starts_at and ends_at are missing' do
|
||||
record = Fabricate.build(:announcement, starts_at: nil, ends_at: nil)
|
||||
|
||||
expect(record.time_range?).to be(false)
|
||||
end
|
||||
|
||||
it 'returns false when starts_at is present and ends_at is missing' do
|
||||
record = Fabricate.build(:announcement, starts_at: 5.days.from_now, ends_at: nil)
|
||||
|
||||
expect(record.time_range?).to be(false)
|
||||
end
|
||||
|
||||
it 'returns false when starts_at is missing and ends_at is present' do
|
||||
record = Fabricate.build(:announcement, starts_at: nil, ends_at: 5.days.from_now)
|
||||
|
||||
expect(record.time_range?).to be(false)
|
||||
end
|
||||
|
||||
it 'returns true when starts_at and ends_at are present' do
|
||||
record = Fabricate.build(:announcement, starts_at: 5.days.from_now, ends_at: 10.days.from_now)
|
||||
|
||||
expect(record.time_range?).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reactions' do
|
||||
context 'with announcement_reactions present' do
|
||||
let!(:account) { Fabricate(:account) }
|
||||
|
|
|
@ -124,12 +124,23 @@ RSpec.describe CustomEmoji do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'pre_validation' do
|
||||
let(:custom_emoji) { Fabricate(:custom_emoji, domain: 'wWw.MaStOdOn.CoM') }
|
||||
describe 'Normalizations' do
|
||||
describe 'downcase domain value' do
|
||||
context 'with a mixed case domain value' do
|
||||
it 'normalizes the value to downcased' do
|
||||
custom_emoji = Fabricate.build(:custom_emoji, domain: 'wWw.MaStOdOn.CoM')
|
||||
|
||||
it 'downcases' do
|
||||
custom_emoji.valid?
|
||||
expect(custom_emoji.domain).to eq('www.mastodon.com')
|
||||
expect(custom_emoji.domain).to eq('www.mastodon.com')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a nil domain value' do
|
||||
it 'leaves the value as nil' do
|
||||
custom_emoji = Fabricate.build(:custom_emoji, domain: nil)
|
||||
|
||||
expect(custom_emoji.domain).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
35
spec/models/custom_filter_spec.rb
Normal file
35
spec/models/custom_filter_spec.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CustomFilter do
|
||||
describe 'Validations' do
|
||||
it 'requires presence of title' do
|
||||
record = described_class.new(title: '')
|
||||
record.valid?
|
||||
|
||||
expect(record).to model_have_error_on_field(:title)
|
||||
end
|
||||
|
||||
it 'requires presence of context' do
|
||||
record = described_class.new(context: nil)
|
||||
record.valid?
|
||||
|
||||
expect(record).to model_have_error_on_field(:context)
|
||||
end
|
||||
|
||||
it 'requires non-empty of context' do
|
||||
record = described_class.new(context: [])
|
||||
record.valid?
|
||||
|
||||
expect(record).to model_have_error_on_field(:context)
|
||||
end
|
||||
|
||||
it 'requires valid context value' do
|
||||
record = described_class.new(context: ['invalid'])
|
||||
record.valid?
|
||||
|
||||
expect(record).to model_have_error_on_field(:context)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@ describe FriendDomain do
|
|||
end
|
||||
|
||||
describe '#follow!' do
|
||||
it 'call inbox' do
|
||||
it 'call inbox', :sidekiq_inline do
|
||||
friend.update(active_state: :accepted, passive_state: :accepted)
|
||||
friend.follow!
|
||||
expect(friend.active_follow_activity_id).to_not be_nil
|
||||
|
@ -27,7 +27,7 @@ describe FriendDomain do
|
|||
end
|
||||
|
||||
describe '#unfollow!' do
|
||||
it 'call inbox' do
|
||||
it 'call inbox', :sidekiq_inline do
|
||||
friend.update(active_follow_activity_id: 'ohagi', active_state: :accepted, passive_state: :accepted)
|
||||
friend.unfollow!
|
||||
expect(friend.active_follow_activity_id).to be_nil
|
||||
|
@ -46,7 +46,7 @@ describe FriendDomain do
|
|||
end
|
||||
|
||||
describe '#accept!' do
|
||||
it 'call inbox' do
|
||||
it 'call inbox', :sidekiq_inline do
|
||||
friend.update(passive_follow_activity_id: 'ohagi', active_state: :accepted, passive_state: :pending)
|
||||
friend.accept!
|
||||
expect(friend.they_are_accepted?).to be true
|
||||
|
@ -61,7 +61,7 @@ describe FriendDomain do
|
|||
end
|
||||
|
||||
describe '#reject!' do
|
||||
it 'call inbox' do
|
||||
it 'call inbox', :sidekiq_inline do
|
||||
friend.update(passive_follow_activity_id: 'ohagi', active_state: :accepted, passive_state: :pending)
|
||||
friend.reject!
|
||||
expect(friend.they_are_rejected?).to be true
|
||||
|
@ -76,7 +76,7 @@ describe FriendDomain do
|
|||
end
|
||||
|
||||
describe '#delete!' do
|
||||
it 'call inbox' do
|
||||
it 'call inbox', :sidekiq_inline do
|
||||
friend.update(active_state: :pending)
|
||||
friend.destroy
|
||||
expect(a_request(:post, 'https://foo.bar/inbox').with(body: hash_including({
|
||||
|
|
|
@ -58,6 +58,88 @@ RSpec.describe Notification do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'Setting account from activity_type' do
|
||||
context 'when activity_type is a Status' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
status = Fabricate(:status)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Status', activity: status)
|
||||
|
||||
expect(notification.from_account).to eq(status.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is a Follow' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
follow = Fabricate(:follow)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Follow', activity: follow)
|
||||
|
||||
expect(notification.from_account).to eq(follow.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is a Favourite' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
favourite = Fabricate(:favourite)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Favourite', activity: favourite)
|
||||
|
||||
expect(notification.from_account).to eq(favourite.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is a FollowRequest' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
follow_request = Fabricate(:follow_request)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'FollowRequest', activity: follow_request)
|
||||
|
||||
expect(notification.from_account).to eq(follow_request.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is a Poll' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
poll = Fabricate(:poll)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Poll', activity: poll)
|
||||
|
||||
expect(notification.from_account).to eq(poll.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is a Report' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
report = Fabricate(:report)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Report', activity: report)
|
||||
|
||||
expect(notification.from_account).to eq(report.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is a Mention' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
mention = Fabricate(:mention)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Mention', activity: mention)
|
||||
|
||||
expect(notification.from_account).to eq(mention.status.account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when activity_type is an Account' do
|
||||
it 'sets the notification from_account correctly' do
|
||||
account = Fabricate(:account)
|
||||
|
||||
notification = Fabricate.build(:notification, activity_type: 'Account', account: account)
|
||||
|
||||
expect(notification.account).to eq(account)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.preload_cache_collection_target_statuses' do
|
||||
subject do
|
||||
described_class.preload_cache_collection_target_statuses(notifications) do |target_statuses|
|
||||
|
|
|
@ -13,189 +13,65 @@ RSpec.describe Setting do
|
|||
end
|
||||
|
||||
describe '.[]' do
|
||||
let(:key) { 'key' }
|
||||
let(:cache_key) { 'cache-key' }
|
||||
let(:cache_value) { 'cache-value' }
|
||||
|
||||
before do
|
||||
allow(described_class).to receive(:rails_initialized?).and_return(rails_initialized)
|
||||
allow(described_class).to receive(:cache_key).with(key).and_return(cache_key)
|
||||
end
|
||||
|
||||
let(:key) { 'key' }
|
||||
|
||||
context 'when rails_initialized? is falsey' do
|
||||
let(:rails_initialized) { false }
|
||||
|
||||
it 'calls RailsSettings::Base#[]' do
|
||||
allow(RailsSettings::Base).to receive(:[]).with(key)
|
||||
|
||||
described_class[key]
|
||||
|
||||
expect(RailsSettings::Base).to have_received(:[]).with(key)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when rails_initialized? is truthy' do
|
||||
context 'when Rails.cache does not exists' do
|
||||
before do
|
||||
allow(RailsSettings::Base).to receive(:cache_key).with(key, nil).and_return(cache_key)
|
||||
allow(described_class).to receive(:default_settings).and_return(default_settings)
|
||||
|
||||
Fabricate(:setting, var: key, value: 42) if save_setting
|
||||
|
||||
Rails.cache.delete(cache_key)
|
||||
end
|
||||
|
||||
let(:rails_initialized) { true }
|
||||
let(:cache_key) { 'cache-key' }
|
||||
let(:cache_value) { 'cache-value' }
|
||||
let(:default_value) { 'default_value' }
|
||||
let(:default_settings) { { key => default_value } }
|
||||
let(:save_setting) { true }
|
||||
|
||||
it 'calls not RailsSettings::Base#[]' do
|
||||
allow(RailsSettings::Base).to receive(:[]).with(key)
|
||||
|
||||
described_class[key]
|
||||
|
||||
expect(RailsSettings::Base).to_not have_received(:[]).with(key)
|
||||
end
|
||||
|
||||
context 'when Rails.cache does not exists' do
|
||||
before do
|
||||
allow(RailsSettings::Settings).to receive(:object).with(key).and_return(object)
|
||||
allow(described_class).to receive(:default_settings).and_return(default_settings)
|
||||
settings_double = instance_double(Settings::ScopedSettings, thing_scoped: records)
|
||||
allow(Settings::ScopedSettings).to receive(:new).and_return(settings_double)
|
||||
Rails.cache.delete(cache_key)
|
||||
end
|
||||
|
||||
let(:object) { nil }
|
||||
let(:default_value) { 'default_value' }
|
||||
let(:default_settings) { { key => default_value } }
|
||||
let(:records) { [Fabricate(:setting, var: key, value: nil)] }
|
||||
|
||||
it 'calls RailsSettings::Settings.object' do
|
||||
allow(RailsSettings::Settings).to receive(:object).with(key)
|
||||
|
||||
described_class[key]
|
||||
|
||||
expect(RailsSettings::Settings).to have_received(:object).with(key)
|
||||
end
|
||||
|
||||
context 'when RailsSettings::Settings.object returns truthy' do
|
||||
let(:object) { db_val }
|
||||
let(:db_val) { instance_double(described_class, value: 'db_val') }
|
||||
|
||||
context 'when default_value is a Hash' do
|
||||
let(:default_value) { { default_value: 'default_value' } }
|
||||
|
||||
it 'calls default_value.with_indifferent_access.merge!' do
|
||||
indifferent_hash = instance_double(Hash, merge!: nil)
|
||||
allow(default_value).to receive(:with_indifferent_access).and_return(indifferent_hash)
|
||||
|
||||
described_class[key]
|
||||
|
||||
expect(default_value).to have_received(:with_indifferent_access)
|
||||
expect(indifferent_hash).to have_received(:merge!).with(db_val.value)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default_value is not a Hash' do
|
||||
let(:default_value) { 'default_value' }
|
||||
|
||||
it 'returns db_val.value' do
|
||||
expect(described_class[key]).to be db_val.value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when RailsSettings::Settings.object returns falsey' do
|
||||
let(:object) { nil }
|
||||
|
||||
it 'returns default_settings[key]' do
|
||||
expect(described_class[key]).to be default_settings[key]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when Rails.cache exists' do
|
||||
before do
|
||||
Rails.cache.write(cache_key, cache_value)
|
||||
end
|
||||
|
||||
it 'does not query the database' do
|
||||
context 'when the setting has been saved to database' do
|
||||
it 'returns the value from database' do
|
||||
callback = double
|
||||
allow(callback).to receive(:call)
|
||||
|
||||
ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do
|
||||
described_class[key]
|
||||
expect(described_class[key]).to eq 42
|
||||
end
|
||||
expect(callback).to_not have_received(:call)
|
||||
end
|
||||
|
||||
it 'returns the cached value' do
|
||||
expect(described_class[key]).to eq cache_value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.all_as_records' do
|
||||
before do
|
||||
settings_double = instance_double(Settings::ScopedSettings, thing_scoped: records)
|
||||
allow(Settings::ScopedSettings).to receive(:new).and_return(settings_double)
|
||||
allow(described_class).to receive(:default_settings).and_return(default_settings)
|
||||
end
|
||||
|
||||
let(:key) { 'key' }
|
||||
let(:default_value) { 'default_value' }
|
||||
let(:default_settings) { { key => default_value } }
|
||||
let(:original_setting) { Fabricate(:setting, var: key, value: nil) }
|
||||
let(:records) { [original_setting] }
|
||||
|
||||
it 'returns a Hash' do
|
||||
expect(described_class.all_as_records).to be_a Hash
|
||||
end
|
||||
|
||||
context 'when records includes Setting with var as the key' do
|
||||
let(:records) { [original_setting] }
|
||||
|
||||
it 'includes the original Setting' do
|
||||
setting = described_class.all_as_records[key]
|
||||
expect(setting).to eq original_setting
|
||||
end
|
||||
end
|
||||
|
||||
context 'when records includes nothing' do
|
||||
let(:records) { [] }
|
||||
|
||||
context 'when default_value is not a Hash' do
|
||||
it 'includes Setting with value of default_value' do
|
||||
setting = described_class.all_as_records[key]
|
||||
|
||||
expect(setting).to be_a described_class
|
||||
expect(setting).to have_attributes(var: key)
|
||||
expect(setting).to have_attributes(value: 'default_value')
|
||||
expect(callback).to have_received(:call)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default_value is a Hash' do
|
||||
let(:default_value) { { 'foo' => 'fuga' } }
|
||||
context 'when the setting has not been saved to database' do
|
||||
let(:save_setting) { false }
|
||||
|
||||
it 'returns {}' do
|
||||
expect(described_class.all_as_records).to eq({})
|
||||
it 'returns default_settings[key]' do
|
||||
expect(described_class[key]).to be default_settings[key]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.default_settings' do
|
||||
subject { described_class.default_settings }
|
||||
|
||||
before do
|
||||
allow(RailsSettings::Default).to receive(:enabled?).and_return(enabled)
|
||||
end
|
||||
|
||||
context 'when RailsSettings::Default.enabled? is false' do
|
||||
let(:enabled) { false }
|
||||
|
||||
it 'returns {}' do
|
||||
expect(subject).to eq({})
|
||||
context 'when Rails.cache exists' do
|
||||
before do
|
||||
Rails.cache.write(cache_key, cache_value)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when RailsSettings::Settings.enabled? is true' do
|
||||
let(:enabled) { true }
|
||||
it 'does not query the database' do
|
||||
callback = double
|
||||
allow(callback).to receive(:call)
|
||||
ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do
|
||||
described_class[key]
|
||||
end
|
||||
expect(callback).to_not have_received(:call)
|
||||
end
|
||||
|
||||
it 'returns instance of RailsSettings::Default' do
|
||||
expect(subject).to be_a RailsSettings::Default
|
||||
it 'returns the cached value' do
|
||||
expect(described_class[key]).to eq cache_value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,27 +38,53 @@ RSpec.describe User do
|
|||
user.save(validate: false)
|
||||
expect(user.valid?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
it 'cleans out invalid locale' do
|
||||
user = Fabricate.build(:user, locale: 'toto')
|
||||
expect(user.valid?).to be true
|
||||
expect(user.locale).to be_nil
|
||||
describe 'Normalizations' do
|
||||
describe 'locale' do
|
||||
it 'preserves valid locale' do
|
||||
user = Fabricate.build(:user, locale: 'en')
|
||||
|
||||
expect(user.locale).to eq('en')
|
||||
end
|
||||
|
||||
it 'cleans out invalid locale' do
|
||||
user = Fabricate.build(:user, locale: 'toto')
|
||||
|
||||
expect(user.locale).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it 'cleans out invalid timezone' do
|
||||
user = Fabricate.build(:user, time_zone: 'toto')
|
||||
expect(user.valid?).to be true
|
||||
expect(user.time_zone).to be_nil
|
||||
describe 'time_zone' do
|
||||
it 'preserves valid timezone' do
|
||||
user = Fabricate.build(:user, time_zone: 'UTC')
|
||||
|
||||
expect(user.time_zone).to eq('UTC')
|
||||
end
|
||||
|
||||
it 'cleans out invalid timezone' do
|
||||
user = Fabricate.build(:user, time_zone: 'toto')
|
||||
|
||||
expect(user.time_zone).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it 'cleans out empty string from languages' do
|
||||
user = Fabricate.build(:user, chosen_languages: [''])
|
||||
user.valid?
|
||||
expect(user.chosen_languages).to be_nil
|
||||
describe 'languages' do
|
||||
it 'preserves valid options for languages' do
|
||||
user = Fabricate.build(:user, chosen_languages: ['en', 'fr', ''])
|
||||
|
||||
expect(user.chosen_languages).to eq(['en', 'fr'])
|
||||
end
|
||||
|
||||
it 'cleans out empty string from languages' do
|
||||
user = Fabricate.build(:user, chosen_languages: [''])
|
||||
|
||||
expect(user.chosen_languages).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'scopes' do
|
||||
describe 'scopes', :sidekiq_inline do
|
||||
describe 'recent' do
|
||||
it 'returns an array of recent users ordered by id' do
|
||||
first_user = Fabricate(:user)
|
||||
|
@ -452,7 +478,7 @@ RSpec.describe User do
|
|||
expect(user.confirmed_at).to be_present
|
||||
end
|
||||
|
||||
it 'delivers mails' do
|
||||
it 'delivers mails', :sidekiq_inline do
|
||||
expect(ActionMailer::Base.deliveries.count).to eq 2
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue