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

This commit is contained in:
KMY 2024-11-13 08:17:38 +09:00
commit 910eafda63
177 changed files with 1625 additions and 659 deletions

View file

@ -13,7 +13,7 @@ RSpec.describe Admin::SystemCheck::DatabaseSchemaCheck do
context 'when database needs migration' do
before do
context = instance_double(ActiveRecord::MigrationContext, needs_migration?: true)
allow(ActiveRecord::Base.connection).to receive(:migration_context).and_return(context)
allow(ActiveRecord::Base.connection_pool).to receive(:migration_context).and_return(context)
end
it 'returns false' do
@ -24,7 +24,7 @@ RSpec.describe Admin::SystemCheck::DatabaseSchemaCheck do
context 'when database does not need migration' do
before do
context = instance_double(ActiveRecord::MigrationContext, needs_migration?: false)
allow(ActiveRecord::Base.connection).to receive(:migration_context).and_return(context)
allow(ActiveRecord::Base.connection_pool).to receive(:migration_context).and_return(context)
end
it 'returns true' do

View file

@ -27,9 +27,10 @@ RSpec.describe Admin::SystemCheck::SoftwareVersionCheck do
context 'when checks are disabled' do
around do |example|
ClimateControl.modify UPDATE_CHECK_URL: '' do
example.run
end
original = Rails.configuration.x.mastodon.software_update_url
Rails.configuration.x.mastodon.software_update_url = ''
example.run
Rails.configuration.x.mastodon.software_update_url = original
end
it 'returns true' do

View file

@ -380,16 +380,16 @@ RSpec.describe FeedManager do
end
describe '#push_to_list' do
let(:owner) { Fabricate(:account, username: 'owner') }
let(:list_owner) { Fabricate(:account, username: 'list_owner') }
let(:alice) { Fabricate(:account, username: 'alice') }
let(:bob) { Fabricate(:account, username: 'bob') }
let(:eve) { Fabricate(:account, username: 'eve') }
let(:list) { Fabricate(:list, account: owner) }
let(:list) { Fabricate(:list, account: list_owner) }
before do
owner.follow!(alice)
owner.follow!(bob)
owner.follow!(eve)
list_owner.follow!(alice)
list_owner.follow!(bob)
list_owner.follow!(eve)
list.accounts << alice
list.accounts << bob
@ -414,7 +414,7 @@ RSpec.describe FeedManager do
end
it 'pushes statuses that are replies to list owner' do
status = Fabricate(:status, text: 'Hello world', account: owner)
status = Fabricate(:status, text: 'Hello world', account: list_owner)
reply = Fabricate(:status, text: 'Nay', thread: status, account: bob)
expect(subject.push_to_list(list, reply)).to be true
end
@ -437,7 +437,7 @@ RSpec.describe FeedManager do
end
it 'pushes statuses that are replies to list owner' do
status = Fabricate(:status, text: 'Hello world', account: owner)
status = Fabricate(:status, text: 'Hello world', account: list_owner)
reply = Fabricate(:status, text: 'Nay', thread: status, account: bob)
expect(subject.push_to_list(list, reply)).to be true
end
@ -466,7 +466,7 @@ RSpec.describe FeedManager do
end
it 'pushes statuses that are replies to list owner' do
status = Fabricate(:status, text: 'Hello world', account: owner)
status = Fabricate(:status, text: 'Hello world', account: list_owner)
reply = Fabricate(:status, text: 'Nay', thread: status, account: bob)
expect(subject.push_to_list(list, reply)).to be true
end

View file

@ -1206,14 +1206,6 @@ RSpec.describe Account do
end
end
describe 'silenced' do
it 'returns an array of accounts who are silenced' do
silenced_account = Fabricate(:account, silenced: true)
_account = Fabricate(:account, silenced: false)
expect(described_class.silenced).to contain_exactly(silenced_account)
end
end
describe 'searchable' do
let!(:suspended_local) { Fabricate(:account, suspended: true, username: 'suspended_local') }
let!(:suspended_remote) { Fabricate(:account, suspended: true, domain: 'example.org', username: 'suspended_remote') }

View file

@ -0,0 +1,42 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe BulkImport do
describe 'Associations' do
it { is_expected.to belong_to(:account).required }
it { is_expected.to have_many(:rows).class_name('BulkImportRow').inverse_of(:bulk_import).dependent(:delete_all) }
end
describe 'Validations' do
subject { Fabricate.build :bulk_import }
it { is_expected.to validate_presence_of(:type) }
end
describe 'Scopes' do
describe '.archival_completed' do
let!(:old_import) { Fabricate :bulk_import, created_at: 1.month.ago }
let!(:new_import) { Fabricate :bulk_import, created_at: 1.day.ago }
it 'returns imports which have passed the archive window period' do
expect(described_class.archival_completed)
.to include(old_import)
.and not_include(new_import)
end
end
describe '.confirmation_missed' do
let!(:old_unconfirmed_import) { Fabricate :bulk_import, created_at: 1.week.ago, state: :unconfirmed }
let!(:old_scheduled_import) { Fabricate :bulk_import, created_at: 1.week.ago, state: :scheduled }
let!(:new_unconfirmed_import) { Fabricate :bulk_import, created_at: 1.minute.ago, state: :unconfirmed }
it 'returns imports which have passed the confirmation window without confirming' do
expect(described_class.confirmation_missed)
.to include(old_unconfirmed_import)
.and not_include(old_scheduled_import)
.and not_include(new_unconfirmed_import)
end
end
end
end

View file

@ -3,10 +3,10 @@
require 'rails_helper'
RSpec.describe Account::Interactions do
let(:account) { Fabricate(:account, username: 'account') }
let(:account) { Fabricate(:account) }
let(:account_id) { account.id }
let(:account_ids) { [account_id] }
let(:target_account) { Fabricate(:account, username: 'target') }
let(:target_account) { Fabricate(:account) }
let(:target_account_id) { target_account.id }
let(:target_account_ids) { [target_account_id] }
let(:follower_account) { Fabricate(:account, username: 'follower') }

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Account::Sensitizes do
describe 'Scopes' do
describe '.sensitized' do
let(:sensitized_account) { Fabricate :account, sensitized_at: 2.days.ago }
before { Fabricate :account, sensitized_at: false }
it 'returns an array of accounts who are sensitized' do
expect(Account.sensitized)
.to contain_exactly(sensitized_account)
end
end
end
end

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Account::Silences do
describe 'Scopes' do
describe '.silenced' do
let(:silenced_account) { Fabricate :account, silenced: true }
before { Fabricate :account, silenced: false }
it 'returns an array of accounts who are silenced' do
expect(Account.silenced)
.to contain_exactly(silenced_account)
end
end
end
end

View file

@ -32,7 +32,7 @@ end
STREAMING_PORT = ENV.fetch('TEST_STREAMING_PORT', '4020')
ENV['STREAMING_API_BASE_URL'] = "http://localhost:#{STREAMING_PORT}"
require File.expand_path('../config/environment', __dir__)
require_relative '../config/environment'
abort('The Rails environment is running in production mode!') if Rails.env.production?

View file

@ -44,6 +44,7 @@ RSpec.describe 'Credentials' do
expect(response.parsed_body)
.to not_include(client_id: be_present)
.and not_include(client_secret: be_present)
.and not_include(client_secret_expires_at: be_present)
end
end

View file

@ -42,6 +42,7 @@ RSpec.describe 'Apps' do
id: app.id.to_s,
client_id: app.uid,
client_secret: app.secret,
client_secret_expires_at: 0,
name: client_name,
website: website,
scopes: ['read', 'write'],

View file

@ -0,0 +1,39 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ActivityPub::ActorSerializer do
subject { serialized_record_json(record, described_class) }
describe '#type' do
context 'with the instance actor' do
let(:record) { Account.find(Account::INSTANCE_ACTOR_ID) }
it { is_expected.to include('type' => 'Application') }
end
context 'with an application actor' do
let(:record) { Fabricate :account, actor_type: 'Application' }
it { is_expected.to include('type' => 'Service') }
end
context 'with a service actor' do
let(:record) { Fabricate :account, actor_type: 'Service' }
it { is_expected.to include('type' => 'Service') }
end
context 'with a Group actor' do
let(:record) { Fabricate :account, actor_type: 'Group' }
it { is_expected.to include('type' => 'Group') }
end
context 'with a Person actor' do
let(:record) { Fabricate :account, actor_type: 'Person' }
it { is_expected.to include('type' => 'Person') }
end
end
end

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ActivityPub::AddSerializer do
describe '.serializer_for' do
subject { described_class.serializer_for(model, {}) }
context 'with a Status model' do
let(:model) { Status.new }
it { is_expected.to eq(described_class::UriSerializer) }
end
context 'with a FeaturedTag model' do
let(:model) { FeaturedTag.new }
it { is_expected.to eq(ActivityPub::HashtagSerializer) }
end
context 'with an Array' do
let(:model) { [] }
it { is_expected.to eq(ActiveModel::Serializer::CollectionSerializer) }
end
end
end

View file

@ -0,0 +1,39 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ActivityPub::CollectionSerializer do
describe '.serializer_for' do
subject { described_class.serializer_for(model, {}) }
context 'with a Status model' do
let(:model) { Status.new }
it { is_expected.to eq(ActivityPub::NoteSerializer) }
end
context 'with a FeaturedTag model' do
let(:model) { FeaturedTag.new }
it { is_expected.to eq(ActivityPub::HashtagSerializer) }
end
context 'with an ActivityPub::CollectionPresenter' do
let(:model) { ActivityPub::CollectionPresenter.new }
it { is_expected.to eq(described_class) }
end
context 'with a String' do
let(:model) { '' }
it { is_expected.to eq(described_class::StringSerializer) }
end
context 'with an Array' do
let(:model) { [] }
it { is_expected.to eq(ActiveModel::Serializer::CollectionSerializer) }
end
end
end

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ActivityPub::RemoveSerializer do
describe '.serializer_for' do
subject { described_class.serializer_for(model, {}) }
context 'with a Status model' do
let(:model) { Status.new }
it { is_expected.to eq(described_class::UriSerializer) }
end
context 'with a FeaturedTag model' do
let(:model) { FeaturedTag.new }
it { is_expected.to eq(ActivityPub::HashtagSerializer) }
end
context 'with an Array' do
let(:model) { [] }
it { is_expected.to eq(ActiveModel::Serializer::CollectionSerializer) }
end
end
end

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::AccountRelationshipSeveranceEventSerializer do
subject { serialized_record_json(record, described_class) }
let(:record) { Fabricate.build :account_relationship_severance_event, id: 123 }
describe 'serialization' do
it 'returns expected values' do
expect(subject)
.to include(
'id' => be_a(String).and(eq('123'))
)
end
end
end

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::AccountWarningSerializer do
subject { serialized_record_json(record, described_class) }
let(:record) { Fabricate :account_warning, id: 123, status_ids: [456, 789] }
describe 'serialization' do
it 'returns expected values' do
expect(subject)
.to include(
'id' => be_a(String).and(eq('123')),
'status_ids' => be_a(Array).and(eq(['456', '789']))
)
end
end
end

View file

@ -0,0 +1,25 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::Admin::AccountSerializer do
subject { serialized_record_json(record, described_class) }
describe 'created_by_application_id' do
context 'when account is application-created' do
let(:record) { Fabricate :account, user: Fabricate(:user, created_by_application: application) }
let(:application) { Fabricate :application }
it { is_expected.to include('created_by_application_id' => application.id.to_s) }
end
end
describe 'invited_by_account_id' do
context 'when account was invited' do
let(:record) { Fabricate :account, user: Fabricate(:user, invite: invite) }
let(:invite) { Fabricate :invite }
it { is_expected.to include('invited_by_account_id' => invite.user.account.id.to_s) }
end
end
end

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::Admin::CohortSerializer do
subject { serialized_record_json(record, described_class) }
let(:record) { Admin::Metrics::Retention.new('2024-01-01', '2024-01-02', 'day').cohorts.first }
describe 'serialization' do
it 'returns expected values' do
expect(subject)
.to include(
'data' => be_a(Array),
'period' => /2024-01-01/
)
end
end
end

View file

@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::Admin::WebhookEventSerializer do
describe '.serializer_for' do
subject { described_class.serializer_for(model, {}) }
context 'with an Account model' do
let(:model) { Account.new }
it { is_expected.to eq(REST::Admin::AccountSerializer) }
end
context 'with a Report model' do
let(:model) { Report.new }
it { is_expected.to eq(REST::Admin::ReportSerializer) }
end
context 'with a Status model' do
let(:model) { Status.new }
it { is_expected.to eq(REST::StatusSerializer) }
end
context 'with an Array' do
let(:model) { [] }
it { is_expected.to eq(ActiveModel::Serializer::CollectionSerializer) }
end
end
end

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::AppealSerializer do
subject { serialized_record_json(record, described_class) }
describe 'state' do
context 'when appeal is approved' do
let(:record) { Fabricate.build :appeal, approved_at: 2.days.ago }
it { is_expected.to include('state' => 'approved') }
end
context 'when appeal is rejected' do
let(:record) { Fabricate.build :appeal, rejected_at: 2.days.ago }
it { is_expected.to include('state' => 'rejected') }
end
context 'when appeal is not approved or rejected' do
let(:record) { Fabricate.build :appeal, approved_at: nil, rejected_at: nil }
it { is_expected.to include('state' => 'pending') }
end
end
end

View file

@ -3,15 +3,18 @@
require 'rails_helper'
RSpec.describe REST::CustomEmojiSerializer do
let(:serialization) { serialized_record_json(record, described_class) }
let(:record) do
Fabricate(:custom_emoji, shortcode: 'ohagi', aliases: aliases)
end
subject { serialized_record_json(record, described_class) }
let(:record) { Fabricate.build :custom_emoji, id: 123, category: Fabricate(:custom_emoji_category, name: 'Category Name'), aliases: aliases }
let(:aliases) { [] }
context 'when empty aliases' do
it 'returns normalized aliases' do
expect(serialization['aliases']).to eq []
describe 'serialization' do
it 'returns expected values' do
expect(subject)
.to include(
'category' => be_a(String).and(eq('Category Name')),
'aliases' => be_a(Array).and(eq([]))
)
end
end
@ -19,7 +22,7 @@ RSpec.describe REST::CustomEmojiSerializer do
let(:aliases) { nil }
it 'returns normalized aliases' do
expect(serialization['aliases']).to eq []
expect(subject['aliases']).to eq []
end
end
@ -27,7 +30,7 @@ RSpec.describe REST::CustomEmojiSerializer do
let(:aliases) { [nil] }
it 'returns normalized aliases' do
expect(serialization['aliases']).to eq []
expect(subject['aliases']).to eq []
end
end
@ -35,7 +38,7 @@ RSpec.describe REST::CustomEmojiSerializer do
let(:aliases) { ['neko'] }
it 'returns normalized aliases' do
expect(serialization['aliases']).to eq ['neko']
expect(subject['aliases']).to eq ['neko']
end
end
end

View file

@ -0,0 +1,35 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::ExtendedDescriptionSerializer do
subject { serialized_record_json(record, described_class) }
describe 'serialization' do
context 'with text present' do
let(:record) { ExtendedDescription.new text: 'Hello world', updated_at: Date.new(2024, 1, 1) }
it 'returns expected values' do
expect(subject)
.to include(
'content' => eq(<<~HTML),
<p>Hello world</p>
HTML
'updated_at' => eq('2024-01-01')
)
end
end
context 'with text missing' do
let(:record) { ExtendedDescription.new text: nil, updated_at: Date.new(2024, 1, 1) }
it 'returns expected values' do
expect(subject)
.to include(
'content' => eq(''),
'updated_at' => eq('2024-01-01')
)
end
end
end
end

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe REST::RuleSerializer do
subject { serialized_record_json(record, described_class) }
let(:record) { Fabricate.build :rule, id: 123 }
describe 'serialization' do
it 'returns expected values' do
expect(subject)
.to include(
'id' => be_a(String).and(eq('123'))
)
end
end
end

View file

@ -124,9 +124,10 @@ RSpec.describe SoftwareUpdateCheckService do
context 'when update checking is disabled' do
around do |example|
ClimateControl.modify UPDATE_CHECK_URL: '' do
example.run
end
original = Rails.configuration.x.mastodon.software_update_url
Rails.configuration.x.mastodon.software_update_url = ''
example.run
Rails.configuration.x.mastodon.software_update_url = original
end
before do
@ -148,9 +149,10 @@ RSpec.describe SoftwareUpdateCheckService do
let(:update_check_url) { 'https://api.example.com/update_check' }
around do |example|
ClimateControl.modify UPDATE_CHECK_URL: 'https://api.example.com/update_check' do
example.run
end
original = Rails.configuration.x.mastodon.software_update_url
Rails.configuration.x.mastodon.software_update_url = 'https://api.example.com/update_check'
example.run
Rails.configuration.x.mastodon.software_update_url = original
end
it_behaves_like 'when the feature is enabled'