Merge remote-tracking branch 'parent/main' into upstream-20240112

This commit is contained in:
KMY 2024-01-12 14:48:17 +09:00
commit e65fb9fb51
333 changed files with 2661 additions and 1461 deletions

View file

@ -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

View file

@ -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

View file

@ -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) }

View file

@ -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

View 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

View file

@ -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({

View file

@ -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|

View file

@ -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

View file

@ -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