Merge remote-tracking branch 'parent/main' into upstream-20231124
This commit is contained in:
commit
c5e4020922
206 changed files with 1987 additions and 965 deletions
|
@ -45,7 +45,7 @@ describe Admin::InvitesController do
|
|||
|
||||
describe 'POST #deactivate_all' do
|
||||
it 'expires all invites, then redirects to admin_invites_path' do
|
||||
invites = Fabricate.times(2, :invite, expires_at: nil)
|
||||
invites = Fabricate.times(1, :invite, expires_at: nil)
|
||||
|
||||
post :deactivate_all
|
||||
|
||||
|
|
|
@ -19,5 +19,17 @@ describe Api::V1::Accounts::FamiliarFollowersController do
|
|||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
context 'when there are duplicate account IDs in the params' do
|
||||
let(:account_a) { Fabricate(:account) }
|
||||
let(:account_b) { Fabricate(:account) }
|
||||
|
||||
it 'removes duplicate account IDs from params' do
|
||||
account_ids = [account_a, account_b, account_b, account_a, account_a].map { |a| a.id.to_s }
|
||||
get :index, params: { id: account_ids }
|
||||
|
||||
expect(body_as_json.pluck(:id)).to eq [account_a.id.to_s, account_b.id.to_s]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Admin::DimensionsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'returns http success' do
|
||||
post :create, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Admin::MeasuresController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'returns http success' do
|
||||
post :create, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Admin::RetentionController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'returns http success' do
|
||||
post :create, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::CustomEmojisController do
|
||||
render_views
|
||||
|
||||
describe 'GET #index' do
|
||||
before do
|
||||
Fabricate(:custom_emoji)
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::EndorsementsController do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns 200' do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Instances::ActivityController do
|
||||
describe 'GET #show' do
|
||||
it 'returns 200' do
|
||||
get :show
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
context 'with !Setting.activity_api_enabled' do
|
||||
it 'returns 404' do
|
||||
Setting.activity_api_enabled = false
|
||||
|
||||
get :show
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Instances::DomainBlocksController do
|
||||
render_views
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
Setting.show_domain_blocks = 'all'
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Instances::ExtendedDescriptionsController do
|
||||
render_views
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::Instances::PeersController do
|
||||
describe 'GET #index' do
|
||||
it 'returns 200' do
|
||||
get :index
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
context 'with !Setting.peers_api_enabled' do
|
||||
it 'returns 404' do
|
||||
Setting.peers_api_enabled = false
|
||||
|
||||
get :index
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Instances::PrivacyPoliciesController do
|
||||
render_views
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Instances::RulesController do
|
||||
render_views
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Instances::TranslationLanguagesController do
|
||||
describe 'GET #show' do
|
||||
context 'when no translation service is configured' do
|
||||
it 'returns empty language matrix', :aggregate_failures do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to eq({})
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a translation service is configured' do
|
||||
before do
|
||||
service = instance_double(TranslationService::DeepL, languages: { nil => %w(en de), 'en' => ['de'] })
|
||||
allow(TranslationService).to receive_messages(configured?: true, configured: service)
|
||||
end
|
||||
|
||||
it 'returns language matrix', :aggregate_failures do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to eq({ und: %w(en de), en: ['de'] })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::InstancesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::PreferencesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::ScheduledStatusesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,13 +9,7 @@ describe Api::V1::Statuses::ReblogsController do
|
|||
let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:statuses', application: app) }
|
||||
|
||||
context 'with an oauth token' do
|
||||
around do |example|
|
||||
Sidekiq::Testing.fake! do
|
||||
example.run
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an oauth token', :sidekiq_fake do
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V2::InstancesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -38,12 +38,10 @@ describe Settings::ExportsController do
|
|||
expect(response).to redirect_to(settings_export_path)
|
||||
end
|
||||
|
||||
it 'queues BackupWorker job by 1' do
|
||||
Sidekiq::Testing.fake! do
|
||||
expect do
|
||||
post :create
|
||||
end.to change(BackupWorker.jobs, :size).by(1)
|
||||
end
|
||||
it 'queues BackupWorker job by 1', :sidekiq_fake do
|
||||
expect do
|
||||
post :create
|
||||
end.to change(BackupWorker.jobs, :size).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,11 +28,5 @@ describe Settings::Preferences::AppearanceController do
|
|||
|
||||
expect(response).to redirect_to(settings_preferences_appearance_path)
|
||||
end
|
||||
|
||||
it 'renders show on failure' do
|
||||
put :update, params: { user: { locale: 'fake option' } }
|
||||
|
||||
expect(response).to render_template('preferences/appearance/show')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
74
spec/controllers/settings/privacy_controller_spec.rb
Normal file
74
spec/controllers/settings/privacy_controller_spec.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::PrivacyController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
let(:account) { user.account }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and have_attributes(
|
||||
headers: include(
|
||||
'Cache-Control' => 'private, no-store'
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
context 'when update succeeds' do
|
||||
before do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
it 'updates the user profile' do
|
||||
put :update, params: { account: { discoverable: '1', settings: { indexable: '1' } } }
|
||||
|
||||
expect(account.reload.discoverable)
|
||||
.to be(true)
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(settings_privacy_path)
|
||||
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to have_received(:perform_async).with(account.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when update fails' do
|
||||
before do
|
||||
allow(UpdateAccountService).to receive(:new).and_return(failing_update_service)
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
it 'updates the user profile' do
|
||||
put :update, params: { account: { discoverable: '1', settings: { indexable: '1' } } }
|
||||
|
||||
expect(response)
|
||||
.to render_template(:show)
|
||||
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to_not have_received(:perform_async)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def failing_update_service
|
||||
instance_double(UpdateAccountService, call: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
29
spec/controllers/settings/verifications_controller_spec.rb
Normal file
29
spec/controllers/settings/verifications_controller_spec.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::VerificationsController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success with private cache control headers', :aggregate_failures do
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and have_attributes(
|
||||
headers: include(
|
||||
'Cache-Control' => 'private, no-store'
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,4 +3,5 @@
|
|||
Fabricator(:scheduled_status) do
|
||||
account { Fabricate.build(:account) }
|
||||
scheduled_at { 20.hours.from_now }
|
||||
params { {} }
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
stub_request(:get, 'http://example.com/emojib.png').to_return(body: attachment_fixture('emojo.png'), headers: { 'Content-Type' => 'application/octet-stream' })
|
||||
end
|
||||
|
||||
describe 'processing posts received out of order' do
|
||||
describe 'processing posts received out of order', :sidekiq_fake do
|
||||
let(:follower) { Fabricate(:account, username: 'bob') }
|
||||
|
||||
let(:object_json) do
|
||||
|
@ -78,13 +78,6 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
follower.follow!(sender)
|
||||
end
|
||||
|
||||
around do |example|
|
||||
Sidekiq::Testing.fake! do
|
||||
example.run
|
||||
Sidekiq::Worker.clear_all
|
||||
end
|
||||
end
|
||||
|
||||
it 'correctly processes posts and inserts them in timelines', :aggregate_failures do
|
||||
# Simulate a temporary failure preventing from fetching the parent post
|
||||
stub_request(:get, object_json[:id]).to_return(status: 500)
|
||||
|
|
|
@ -465,7 +465,7 @@ describe Mastodon::CLI::Accounts do
|
|||
end
|
||||
|
||||
describe '#approve' do
|
||||
let(:total_users) { 10 }
|
||||
let(:total_users) { 4 }
|
||||
|
||||
before do
|
||||
Form::AdminSettings.new(registrations_mode: 'approved').save
|
||||
|
@ -482,7 +482,7 @@ describe Mastodon::CLI::Accounts do
|
|||
|
||||
context 'with --number option' do
|
||||
context 'when the number is positive' do
|
||||
let(:options) { { number: 3 } }
|
||||
let(:options) { { number: 2 } }
|
||||
|
||||
it 'approves the earliest n pending registrations' do
|
||||
cli.invoke(:approve, nil, options)
|
||||
|
@ -779,6 +779,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:arguments) { [account_example_com_a.acct, account_example_com_b.acct] }
|
||||
|
||||
before do
|
||||
# NOTE: `Account.find_remote` is stubbed so that `Account#reset_avatar!`
|
||||
# can be stubbed on the individual accounts.
|
||||
allow(Account).to receive(:find_remote).with(account_example_com_a.username, account_example_com_a.domain).and_return(account_example_com_a)
|
||||
allow(Account).to receive(:find_remote).with(account_example_com_b.username, account_example_com_b.domain).and_return(account_example_com_b)
|
||||
allow(Account).to receive(:find_remote).with(account_example_net.username, account_example_net.domain).and_return(account_example_net)
|
||||
|
@ -978,11 +980,10 @@ describe Mastodon::CLI::Accounts do
|
|||
end
|
||||
|
||||
context 'when --all option is provided' do
|
||||
let(:accounts) { Fabricate.times(3, :account) }
|
||||
let(:options) { { all: true } }
|
||||
let!(:accounts) { Fabricate.times(2, :account) }
|
||||
let(:options) { { all: true } }
|
||||
|
||||
before do
|
||||
allow(Account).to receive(:local).and_return(Account.where(id: accounts.map(&:id)))
|
||||
cli.options = { all: true }
|
||||
end
|
||||
|
||||
|
@ -1269,7 +1270,7 @@ describe Mastodon::CLI::Accounts do
|
|||
end
|
||||
|
||||
context 'when the given username is found' do
|
||||
let(:total_relationships) { 10 }
|
||||
let(:total_relationships) { 3 }
|
||||
let!(:accounts) { Fabricate.times(total_relationships, :account) }
|
||||
|
||||
context 'with --follows option' do
|
||||
|
@ -1324,8 +1325,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { followers: true, follows: true } }
|
||||
|
||||
before do
|
||||
accounts.first(6).each { |account| account.follow!(target_account) }
|
||||
accounts.last(4).each { |account| target_account.follow!(account) }
|
||||
accounts.first(2).each { |account| account.follow!(target_account) }
|
||||
accounts.last(1).each { |account| target_account.follow!(account) }
|
||||
end
|
||||
|
||||
it 'resets all "followers" relationships from the target account' do
|
||||
|
@ -1363,7 +1364,7 @@ describe Mastodon::CLI::Accounts do
|
|||
let!(:group_account) { Fabricate(:account, actor_type: 'Group', domain: 'example.com') }
|
||||
let!(:mentioned_account) { Fabricate(:account, domain: 'example.com') }
|
||||
let!(:prunable_accounts) do
|
||||
Fabricate.times(3, :account, domain: 'example.com', bot: false, suspended_at: nil, silenced_at: nil)
|
||||
Fabricate.times(2, :account, domain: 'example.com', bot: false, suspended_at: nil, silenced_at: nil)
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -1581,8 +1582,7 @@ describe Mastodon::CLI::Accounts do
|
|||
|
||||
context 'when the specified account is redirecting to a different target account' do
|
||||
before do
|
||||
allow(Account).to receive(:find_local).with(source_account.username).and_return(source_account)
|
||||
allow(source_account).to receive(:moved_to_account_id).and_return(-1)
|
||||
source_account.update(moved_to_account: Fabricate(:account))
|
||||
end
|
||||
|
||||
it 'exits with an error message' do
|
||||
|
@ -1597,9 +1597,8 @@ describe Mastodon::CLI::Accounts do
|
|||
let(:options) { { target: target_account.acct, force: true } }
|
||||
|
||||
before do
|
||||
source_account.update(moved_to_account: Fabricate(:account))
|
||||
target_account.aliases.create!(acct: source_account.acct)
|
||||
allow(Account).to receive(:find_local).with(source_account.username).and_return(source_account)
|
||||
allow(source_account).to receive(:moved_to_account_id).and_return(-1)
|
||||
end
|
||||
|
||||
it_behaves_like 'a successful migration'
|
||||
|
|
|
@ -83,12 +83,14 @@ RSpec.describe AdminMailer do
|
|||
|
||||
describe '.new_trends' do
|
||||
let(:recipient) { Fabricate(:account, username: 'Snurf') }
|
||||
let(:links) { [] }
|
||||
let(:statuses) { [] }
|
||||
let(:tags) { [] }
|
||||
let(:mail) { described_class.with(recipient: recipient).new_trends(links, tags, statuses) }
|
||||
let(:link) { Fabricate(:preview_card, trendable: true, language: 'en') }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
let(:mail) { described_class.with(recipient: recipient).new_trends([link], [tag], [status]) }
|
||||
|
||||
before do
|
||||
PreviewCardTrend.create!(preview_card: link)
|
||||
StatusTrend.create!(status: status, account: Fabricate(:account))
|
||||
recipient.user.update(locale: :en)
|
||||
end
|
||||
|
||||
|
@ -99,6 +101,9 @@ RSpec.describe AdminMailer do
|
|||
.and(deliver_from('notifications@localhost'))
|
||||
.and(have_subject('New trends up for review on cb6e6126.ngrok.io'))
|
||||
.and(have_body_text('The following items need a review before they can be displayed publicly'))
|
||||
.and(have_body_text(ActivityPub::TagManager.instance.url_for(status)))
|
||||
.and(have_body_text(link.title))
|
||||
.and(have_body_text(tag.display_name))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,16 @@
|
|||
# Preview all emails at http://localhost:3000/rails/mailers/admin_mailer
|
||||
|
||||
class AdminMailerPreview < ActionMailer::Preview
|
||||
# Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_report
|
||||
def new_report
|
||||
AdminMailer.with(recipient: Account.first).new_report(Report.first)
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_appeal
|
||||
def new_appeal
|
||||
AdminMailer.with(recipient: Account.first).new_appeal(Appeal.first)
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_pending_account
|
||||
def new_pending_account
|
||||
AdminMailer.with(recipient: Account.first).new_pending_account(User.pending.first)
|
||||
|
@ -18,8 +28,13 @@ class AdminMailerPreview < ActionMailer::Preview
|
|||
AdminMailer.with(recipient: Account.first).new_trends(PreviewCard.joins(:trend).limit(3), Tag.limit(3), Status.joins(:trend).where(reblog_of_id: nil).limit(3))
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_appeal
|
||||
def new_appeal
|
||||
AdminMailer.with(recipient: Account.first).new_appeal(Appeal.first)
|
||||
# Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_software_updates
|
||||
def new_software_updates
|
||||
AdminMailer.with(recipient: Account.first).new_software_updates
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_critical_software_updates
|
||||
def new_critical_software_updates
|
||||
AdminMailer.with(recipient: Account.first).new_critical_software_updates
|
||||
end
|
||||
end
|
||||
|
|
|
@ -651,10 +651,11 @@ RSpec.describe Account do
|
|||
expect(results).to eq [match]
|
||||
end
|
||||
|
||||
it 'limits by 10 by default' do
|
||||
11.times.each { Fabricate(:account, display_name: 'Display Name') }
|
||||
it 'limits via constant by default' do
|
||||
stub_const('AccountSearch::DEFAULT_LIMIT', 1)
|
||||
2.times.each { Fabricate(:account, display_name: 'Display Name') }
|
||||
results = described_class.search_for('display')
|
||||
expect(results.size).to eq 10
|
||||
expect(results.size).to eq 1
|
||||
end
|
||||
|
||||
it 'accepts arbitrary limits' do
|
||||
|
@ -743,6 +744,33 @@ RSpec.describe Account do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when limiting search to follower accounts' do
|
||||
it 'accepts ?, \, : and space as delimiter' do
|
||||
match = Fabricate(
|
||||
:account,
|
||||
display_name: 'A & l & i & c & e',
|
||||
username: 'username',
|
||||
domain: 'example.com'
|
||||
)
|
||||
match.follow!(account)
|
||||
|
||||
results = described_class.advanced_search_for('A?l\i:c e', account, limit: 10, follower: true)
|
||||
expect(results).to eq [match]
|
||||
end
|
||||
|
||||
it 'does not return non-follower accounts' do
|
||||
Fabricate(
|
||||
:account,
|
||||
display_name: 'A & l & i & c & e',
|
||||
username: 'username',
|
||||
domain: 'example.com'
|
||||
)
|
||||
|
||||
results = described_class.advanced_search_for('A?l\i:c e', account, limit: 10, follower: true)
|
||||
expect(results).to eq []
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not return suspended users' do
|
||||
Fabricate(
|
||||
:account,
|
||||
|
@ -795,9 +823,10 @@ RSpec.describe Account do
|
|||
end
|
||||
|
||||
it 'limits by 10 by default' do
|
||||
11.times { Fabricate(:account, display_name: 'Display Name') }
|
||||
stub_const('AccountSearch::DEFAULT_LIMIT', 1)
|
||||
2.times { Fabricate(:account, display_name: 'Display Name') }
|
||||
results = described_class.advanced_search_for('display', account)
|
||||
expect(results.size).to eq 10
|
||||
expect(results.size).to eq 1
|
||||
end
|
||||
|
||||
it 'accepts arbitrary limits' do
|
||||
|
|
|
@ -280,10 +280,10 @@ RSpec.describe AccountStatusesCleanupPolicy do
|
|||
let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) }
|
||||
|
||||
before do
|
||||
4.times { faved_primary.increment_count!(:favourites_count) }
|
||||
5.times { faved_secondary.increment_count!(:favourites_count) }
|
||||
4.times { reblogged_primary.increment_count!(:reblogs_count) }
|
||||
5.times { reblogged_secondary.increment_count!(:reblogs_count) }
|
||||
faved_primary.status_stat.update(favourites_count: 4)
|
||||
faved_secondary.status_stat.update(favourites_count: 5)
|
||||
reblogged_primary.status_stat.update(reblogs_count: 4)
|
||||
reblogged_secondary.status_stat.update(reblogs_count: 5)
|
||||
end
|
||||
|
||||
context 'when passed a max_id' do
|
||||
|
|
|
@ -46,12 +46,10 @@ RSpec.describe Admin::AccountAction do
|
|||
expect(target_account).to be_suspended
|
||||
end
|
||||
|
||||
it 'queues Admin::SuspensionWorker by 1' do
|
||||
Sidekiq::Testing.fake! do
|
||||
expect do
|
||||
subject
|
||||
end.to change { Admin::SuspensionWorker.jobs.size }.by 1
|
||||
end
|
||||
it 'queues Admin::SuspensionWorker by 1', :sidekiq_fake do
|
||||
expect do
|
||||
subject
|
||||
end.to change { Admin::SuspensionWorker.jobs.size }.by 1
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -40,35 +40,34 @@ RSpec.describe StatusPin do
|
|||
expect(described_class.new(account: account, status: status).save).to be false
|
||||
end
|
||||
|
||||
max_pins = 5
|
||||
it 'does not allow pins above the max' do
|
||||
account = Fabricate(:account)
|
||||
status = []
|
||||
context 'with a pin limit' do
|
||||
before { stub_const('StatusPinValidator::PIN_LIMIT', 2) }
|
||||
|
||||
(max_pins + 1).times do |i|
|
||||
status[i] = Fabricate(:status, account: account)
|
||||
it 'does not allow pins above the max' do
|
||||
account = Fabricate(:account)
|
||||
|
||||
Fabricate.times(StatusPinValidator::PIN_LIMIT, :status_pin, account: account)
|
||||
|
||||
pin = described_class.new(account: account, status: Fabricate(:status, account: account))
|
||||
expect(pin.save)
|
||||
.to be(false)
|
||||
|
||||
expect(pin.errors[:base])
|
||||
.to contain_exactly(I18n.t('statuses.pin_errors.limit'))
|
||||
end
|
||||
|
||||
max_pins.times do |i|
|
||||
expect(described_class.new(account: account, status: status[i]).save).to be true
|
||||
it 'allows pins above the max for remote accounts' do
|
||||
account = Fabricate(:account, domain: 'remote.test', username: 'bob', url: 'https://remote.test/')
|
||||
|
||||
Fabricate.times(StatusPinValidator::PIN_LIMIT, :status_pin, account: account)
|
||||
|
||||
pin = described_class.new(account: account, status: Fabricate(:status, account: account))
|
||||
expect(pin.save)
|
||||
.to be(true)
|
||||
|
||||
expect(pin.errors[:base])
|
||||
.to be_empty
|
||||
end
|
||||
|
||||
expect(described_class.new(account: account, status: status[max_pins]).save).to be false
|
||||
end
|
||||
|
||||
it 'allows pins above the max for remote accounts' do
|
||||
account = Fabricate(:account, domain: 'remote.test', username: 'bob', url: 'https://remote.test/')
|
||||
status = []
|
||||
|
||||
(max_pins + 1).times do |i|
|
||||
status[i] = Fabricate(:status, account: account)
|
||||
end
|
||||
|
||||
max_pins.times do |i|
|
||||
expect(described_class.new(account: account, status: status[i]).save).to be true
|
||||
end
|
||||
|
||||
expect(described_class.new(account: account, status: status[max_pins]).save).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,12 +27,6 @@ RSpec.describe User do
|
|||
expect(user).to model_have_error_on_field(:account)
|
||||
end
|
||||
|
||||
it 'is invalid without a valid locale' do
|
||||
user = Fabricate.build(:user, locale: 'toto')
|
||||
user.valid?
|
||||
expect(user).to model_have_error_on_field(:locale)
|
||||
end
|
||||
|
||||
it 'is invalid without a valid email' do
|
||||
user = Fabricate.build(:user, email: 'john@')
|
||||
user.valid?
|
||||
|
@ -45,6 +39,18 @@ RSpec.describe User do
|
|||
expect(user.valid?).to be true
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
it 'cleans out empty string from languages' do
|
||||
user = Fabricate.build(:user, chosen_languages: [''])
|
||||
user.valid?
|
||||
|
|
|
@ -60,7 +60,9 @@ RSpec.configure do |config|
|
|||
# By default, skip the elastic search integration specs
|
||||
config.filter_run_excluding search: true
|
||||
|
||||
config.fixture_path = Rails.root.join('spec', 'fixtures')
|
||||
config.fixture_paths = [
|
||||
Rails.root.join('spec', 'fixtures'),
|
||||
]
|
||||
config.use_transactional_fixtures = true
|
||||
config.order = 'random'
|
||||
config.infer_spec_type_from_file_location!
|
||||
|
@ -93,6 +95,13 @@ RSpec.configure do |config|
|
|||
self.use_transactional_tests = true
|
||||
end
|
||||
|
||||
config.around(:each, :sidekiq_fake) do |example|
|
||||
Sidekiq::Testing.fake! do
|
||||
example.run
|
||||
Sidekiq::Worker.clear_all
|
||||
end
|
||||
end
|
||||
|
||||
config.before :each, type: :cli do
|
||||
stub_stdout
|
||||
stub_reset_connection_pools
|
||||
|
|
|
@ -79,6 +79,22 @@ describe 'GET /api/v1/accounts/relationships' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when there are duplicate IDs in the params' do
|
||||
let(:params) { { id: [simon.id, lewis.id, lewis.id, lewis.id, simon.id] } }
|
||||
|
||||
it 'removes duplicate account IDs from params' do
|
||||
subject
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_an(Enumerable)
|
||||
.and have_attributes(
|
||||
size: 2,
|
||||
first: include(simon_item),
|
||||
second: include(lewis_item)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def simon_item
|
||||
{
|
||||
id: simon.id.to_s,
|
||||
|
|
35
spec/requests/api/v1/admin/dimensions_spec.rb
Normal file
35
spec/requests/api/v1/admin/dimensions_spec.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin Dimensions' do
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
describe 'GET /api/v1/admin/dimensions' do
|
||||
context 'when not authorized' do
|
||||
it 'returns http forbidden' do
|
||||
post '/api/v1/admin/dimensions', params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with correct scope' do
|
||||
let(:scopes) { 'admin:read' }
|
||||
|
||||
it 'returns http success and status json' do
|
||||
post '/api/v1/admin/dimensions', params: { account_id: account.id, limit: 2 }, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_an(Array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -35,7 +35,7 @@ RSpec.describe 'Domain Allows' do
|
|||
end
|
||||
|
||||
context 'when there are allowed domains' do
|
||||
let!(:domain_allows) { Fabricate.times(5, :domain_allow) }
|
||||
let!(:domain_allows) { Fabricate.times(2, :domain_allow) }
|
||||
let(:expected_response) do
|
||||
domain_allows.map do |domain_allow|
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ RSpec.describe 'Domain Allows' do
|
|||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 2 } }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'returns only the requested number of allowed domains' do
|
||||
subject
|
||||
|
|
35
spec/requests/api/v1/admin/measures_spec.rb
Normal file
35
spec/requests/api/v1/admin/measures_spec.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin Measures' do
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
describe 'GET /api/v1/admin/measures' do
|
||||
context 'when not authorized' do
|
||||
it 'returns http forbidden' do
|
||||
post '/api/v1/admin/measures', params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with correct scope' do
|
||||
let(:scopes) { 'admin:read' }
|
||||
|
||||
it 'returns http success and status json' do
|
||||
post '/api/v1/admin/measures', params: { account_id: account.id, limit: 2 }, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_an(Array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
35
spec/requests/api/v1/admin/retention_spec.rb
Normal file
35
spec/requests/api/v1/admin/retention_spec.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin Retention' do
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
describe 'GET /api/v1/admin/retention' do
|
||||
context 'when not authorized' do
|
||||
it 'returns http forbidden' do
|
||||
post '/api/v1/admin/retention', params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with correct scope' do
|
||||
let(:scopes) { 'admin:read' }
|
||||
|
||||
it 'returns http success and status json' do
|
||||
post '/api/v1/admin/retention', params: { account_id: account.id, limit: 2 }, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_an(Array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -14,7 +14,7 @@ RSpec.describe 'Bookmarks' do
|
|||
end
|
||||
|
||||
let(:params) { {} }
|
||||
let!(:bookmarks) { Fabricate.times(3, :bookmark, account: user.account) }
|
||||
let!(:bookmarks) { Fabricate.times(2, :bookmark, account: user.account) }
|
||||
|
||||
let(:expected_response) do
|
||||
bookmarks.map do |bookmark|
|
||||
|
@ -37,7 +37,7 @@ RSpec.describe 'Bookmarks' do
|
|||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 2 } }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'paginates correctly', :aggregate_failures do
|
||||
subject
|
||||
|
|
45
spec/requests/api/v1/custom_emojis_spec.rb
Normal file
45
spec/requests/api/v1/custom_emojis_spec.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Custom Emojis' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/custom_emojis' do
|
||||
before do
|
||||
Fabricate(:custom_emoji, domain: nil, disabled: false, visible_in_picker: true)
|
||||
end
|
||||
|
||||
context 'when logged out' do
|
||||
it 'returns http success and json' do
|
||||
get api_v1_custom_emojis_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and have_attributes(
|
||||
first: include(shortcode: 'coolcat')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when logged in' do
|
||||
it 'returns http success and json' do
|
||||
get api_v1_custom_emojis_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and have_attributes(
|
||||
first: include(shortcode: 'coolcat')
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
61
spec/requests/api/v1/endorsements_spec.rb
Normal file
61
spec/requests/api/v1/endorsements_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Endorsements' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/endorsements' do
|
||||
context 'when not authorized' do
|
||||
it 'returns http unauthorized' do
|
||||
get api_v1_endorsements_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with wrong scope' do
|
||||
before do
|
||||
get api_v1_endorsements_path, headers: headers
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:accounts'
|
||||
end
|
||||
|
||||
context 'with correct scope' do
|
||||
let(:scopes) { 'read:accounts' }
|
||||
|
||||
context 'with endorsed accounts' do
|
||||
let!(:account_pin) { Fabricate(:account_pin, account: user.account) }
|
||||
|
||||
it 'returns http success and accounts json' do
|
||||
get api_v1_endorsements_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and have_attributes(
|
||||
first: include(acct: account_pin.target_account.acct)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without endorsed accounts without json' do
|
||||
it 'returns http success' do
|
||||
get api_v1_endorsements_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to_not be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -14,7 +14,7 @@ RSpec.describe 'Favourites' do
|
|||
end
|
||||
|
||||
let(:params) { {} }
|
||||
let!(:favourites) { Fabricate.times(3, :favourite, account: user.account) }
|
||||
let!(:favourites) { Fabricate.times(2, :favourite, account: user.account) }
|
||||
|
||||
let(:expected_response) do
|
||||
favourites.map do |favourite|
|
||||
|
@ -37,7 +37,7 @@ RSpec.describe 'Favourites' do
|
|||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 2 } }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'returns only the requested number of favourites' do
|
||||
subject
|
||||
|
|
|
@ -32,7 +32,7 @@ RSpec.describe 'FeaturedTags' do
|
|||
end
|
||||
|
||||
context 'when the requesting user has no featured tag' do
|
||||
before { Fabricate.times(3, :featured_tag) }
|
||||
before { Fabricate(:featured_tag) }
|
||||
|
||||
it 'returns an empty body' do
|
||||
get '/api/v1/featured_tags', headers: headers
|
||||
|
@ -44,7 +44,7 @@ RSpec.describe 'FeaturedTags' do
|
|||
end
|
||||
|
||||
context 'when the requesting user has featured tags' do
|
||||
let!(:user_featured_tags) { Fabricate.times(5, :featured_tag, account: user.account) }
|
||||
let!(:user_featured_tags) { Fabricate.times(1, :featured_tag, account: user.account) }
|
||||
|
||||
it 'returns only the featured tags belonging to the requesting user' do
|
||||
get '/api/v1/featured_tags', headers: headers
|
||||
|
|
|
@ -13,7 +13,7 @@ RSpec.describe 'Follow requests' do
|
|||
get '/api/v1/follow_requests', headers: headers, params: params
|
||||
end
|
||||
|
||||
let(:accounts) { Fabricate.times(5, :account) }
|
||||
let(:accounts) { Fabricate.times(2, :account) }
|
||||
let(:params) { {} }
|
||||
|
||||
let(:expected_response) do
|
||||
|
@ -40,7 +40,7 @@ RSpec.describe 'Follow requests' do
|
|||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 2 } }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'returns only the requested number of follow requests' do
|
||||
subject
|
||||
|
|
|
@ -13,7 +13,7 @@ RSpec.describe 'Followed tags' do
|
|||
get '/api/v1/followed_tags', headers: headers, params: params
|
||||
end
|
||||
|
||||
let!(:tag_follows) { Fabricate.times(5, :tag_follow, account: user.account) }
|
||||
let!(:tag_follows) { Fabricate.times(2, :tag_follow, account: user.account) }
|
||||
let(:params) { {} }
|
||||
|
||||
let(:expected_response) do
|
||||
|
@ -41,7 +41,7 @@ RSpec.describe 'Followed tags' do
|
|||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 3 } }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'returns only the requested number of follow tags' do
|
||||
subject
|
||||
|
@ -58,7 +58,7 @@ RSpec.describe 'Followed tags' do
|
|||
it 'sets the correct pagination header for the next path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq(api_v1_followed_tags_url(limit: params[:limit], max_id: tag_follows[2].id))
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq(api_v1_followed_tags_url(limit: params[:limit], max_id: tag_follows.last.id))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
37
spec/requests/api/v1/instance_spec.rb
Normal file
37
spec/requests/api/v1/instance_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Instances' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/instance' do
|
||||
context 'when not logged in' do
|
||||
it 'returns http success and json' do
|
||||
get api_v1_instance_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and include(title: 'Mastodon')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when logged in' do
|
||||
it 'returns http success and json' do
|
||||
get api_v1_instance_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and include(title: 'Mastodon')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
40
spec/requests/api/v1/instances/activity_spec.rb
Normal file
40
spec/requests/api/v1/instances/activity_spec.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Activity' do
|
||||
describe 'GET /api/v1/instance/activity' do
|
||||
around do |example|
|
||||
original = Setting.activity_api_enabled
|
||||
example.run
|
||||
Setting.activity_api_enabled = original
|
||||
end
|
||||
|
||||
context 'with activity api enabled' do
|
||||
before { Setting.activity_api_enabled = true }
|
||||
|
||||
it 'returns http success' do
|
||||
get api_v1_instance_activity_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and(be_an(Array))
|
||||
.and(have_attributes(size: Api::V1::Instances::ActivityController::WEEKS_OF_ACTIVITY))
|
||||
end
|
||||
end
|
||||
|
||||
context 'with activity api diabled' do
|
||||
before { Setting.activity_api_enabled = false }
|
||||
|
||||
it 'returns not found' do
|
||||
get api_v1_instance_activity_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
55
spec/requests/api/v1/instances/domain_blocks_spec.rb
Normal file
55
spec/requests/api/v1/instances/domain_blocks_spec.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Domain Blocks' do
|
||||
describe 'GET /api/v1/instance/domain_blocks' do
|
||||
around do |example|
|
||||
original = Setting.show_domain_blocks
|
||||
example.run
|
||||
Setting.show_domain_blocks = original
|
||||
end
|
||||
|
||||
before do
|
||||
Fabricate(:domain_block)
|
||||
end
|
||||
|
||||
context 'with domain blocks set to all' do
|
||||
before { Setting.show_domain_blocks = 'all' }
|
||||
|
||||
it 'returns http success' do
|
||||
get api_v1_instance_domain_blocks_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and(be_an(Array))
|
||||
.and(have_attributes(size: 1))
|
||||
end
|
||||
end
|
||||
|
||||
context 'with domain blocks set to users' do
|
||||
before { Setting.show_domain_blocks = 'users' }
|
||||
|
||||
it 'returns http not found' do
|
||||
get api_v1_instance_domain_blocks_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with domain blocks set to disabled' do
|
||||
before { Setting.show_domain_blocks = 'disabled' }
|
||||
|
||||
it 'returns http not found' do
|
||||
get api_v1_instance_domain_blocks_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
spec/requests/api/v1/instances/extended_descriptions_spec.rb
Normal file
18
spec/requests/api/v1/instances/extended_descriptions_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Extended Descriptions' do
|
||||
describe 'GET /api/v1/instance/extended_description' do
|
||||
it 'returns http success' do
|
||||
get api_v1_instance_extended_description_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and include(:content)
|
||||
end
|
||||
end
|
||||
end
|
38
spec/requests/api/v1/instances/peers_spec.rb
Normal file
38
spec/requests/api/v1/instances/peers_spec.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Peers' do
|
||||
describe 'GET /api/v1/instance/peers' do
|
||||
around do |example|
|
||||
original = Setting.peers_api_enabled
|
||||
example.run
|
||||
Setting.peers_api_enabled = original
|
||||
end
|
||||
|
||||
context 'with peers api enabled' do
|
||||
before { Setting.peers_api_enabled = true }
|
||||
|
||||
it 'returns http success' do
|
||||
get api_v1_instance_peers_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_an(Array)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with peers api diabled' do
|
||||
before { Setting.peers_api_enabled = false }
|
||||
|
||||
it 'returns http not found' do
|
||||
get api_v1_instance_peers_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
spec/requests/api/v1/instances/privacy_policies_spec.rb
Normal file
18
spec/requests/api/v1/instances/privacy_policies_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Privacy Policy' do
|
||||
describe 'GET /api/v1/instance/privacy_policy' do
|
||||
it 'returns http success' do
|
||||
get api_v1_instance_privacy_policy_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and include(:content)
|
||||
end
|
||||
end
|
||||
end
|
17
spec/requests/api/v1/instances/rules_spec.rb
Normal file
17
spec/requests/api/v1/instances/rules_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Rules' do
|
||||
describe 'GET /api/v1/instance/rules' do
|
||||
it 'returns http success' do
|
||||
get api_v1_instance_rules_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_an(Array)
|
||||
end
|
||||
end
|
||||
end
|
43
spec/requests/api/v1/instances/translation_languages_spec.rb
Normal file
43
spec/requests/api/v1/instances/translation_languages_spec.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Translation Languages' do
|
||||
describe 'GET /api/v1/instances/translation_languages' do
|
||||
context 'when no translation service is configured' do
|
||||
it 'returns empty language matrix', :aggregate_failures do
|
||||
get api_v1_instance_translation_languages_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to eq({})
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a translation service is configured' do
|
||||
before { configure_translation_service }
|
||||
|
||||
it 'returns language matrix', :aggregate_failures do
|
||||
get api_v1_instance_translation_languages_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to eq({ und: %w(en de), en: ['de'] })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def configure_translation_service
|
||||
allow(TranslationService).to receive_messages(configured?: true, configured: service_double)
|
||||
end
|
||||
|
||||
def service_double
|
||||
instance_double(TranslationService::DeepL, languages: { nil => %w(en de), 'en' => ['de'] })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -15,7 +15,7 @@ RSpec.describe 'Accounts' do
|
|||
|
||||
let(:params) { { limit: 0 } }
|
||||
let(:list) { Fabricate(:list, account: user.account) }
|
||||
let(:accounts) { Fabricate.times(3, :account) }
|
||||
let(:accounts) { Fabricate.times(2, :account) }
|
||||
|
||||
let(:expected_response) do
|
||||
accounts.map do |account|
|
||||
|
|
|
@ -13,7 +13,7 @@ RSpec.describe 'Mutes' do
|
|||
get '/api/v1/mutes', headers: headers, params: params
|
||||
end
|
||||
|
||||
let!(:mutes) { Fabricate.times(3, :mute, account: user.account) }
|
||||
let!(:mutes) { Fabricate.times(2, :mute, account: user.account) }
|
||||
let(:params) { {} }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:mutes'
|
||||
|
@ -33,7 +33,7 @@ RSpec.describe 'Mutes' do
|
|||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 2 } }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'returns only the requested number of muted accounts' do
|
||||
subject
|
||||
|
@ -46,8 +46,8 @@ RSpec.describe 'Mutes' do
|
|||
|
||||
headers = response.headers['Link']
|
||||
|
||||
expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_mutes_url(limit: params[:limit], since_id: mutes[2].id.to_s))
|
||||
expect(headers.find_link(%w(rel next)).href).to eq(api_v1_mutes_url(limit: params[:limit], max_id: mutes[1].id.to_s))
|
||||
expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_mutes_url(limit: params[:limit], since_id: mutes.last.id.to_s))
|
||||
expect(headers.find_link(%w(rel next)).href).to eq(api_v1_mutes_url(limit: params[:limit], max_id: mutes.last.id.to_s))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -72,8 +72,8 @@ RSpec.describe 'Mutes' do
|
|||
|
||||
body = body_as_json
|
||||
|
||||
expect(body.size).to eq 2
|
||||
expect(body[0][:id]).to eq mutes[2].target_account_id.to_s
|
||||
expect(body.size).to eq 1
|
||||
expect(body[0][:id]).to eq mutes[1].target_account_id.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ RSpec.describe 'Notifications' do
|
|||
end
|
||||
|
||||
before do
|
||||
Fabricate.times(3, :notification, account: user.account)
|
||||
Fabricate(:notification, account: user.account)
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:notifications'
|
||||
|
|
42
spec/requests/api/v1/preferences_spec.rb
Normal file
42
spec/requests/api/v1/preferences_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Preferences' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/preferences' do
|
||||
context 'when not authorized' do
|
||||
it 'returns http unauthorized' do
|
||||
get api_v1_preferences_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with wrong scope' do
|
||||
before do
|
||||
get api_v1_preferences_path, headers: headers
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:accounts'
|
||||
end
|
||||
|
||||
context 'with correct scope' do
|
||||
let(:scopes) { 'read:accounts' }
|
||||
|
||||
it 'returns http success' do
|
||||
get api_v1_preferences_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
61
spec/requests/api/v1/scheduled_status_spec.rb
Normal file
61
spec/requests/api/v1/scheduled_status_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Scheduled Statuses' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/scheduled_statuses' do
|
||||
context 'when not authorized' do
|
||||
it 'returns http unauthorized' do
|
||||
get api_v1_scheduled_statuses_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with wrong scope' do
|
||||
before do
|
||||
get api_v1_scheduled_statuses_path, headers: headers
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:statuses'
|
||||
end
|
||||
|
||||
context 'with correct scope' do
|
||||
let(:scopes) { 'read:statuses' }
|
||||
|
||||
context 'without scheduled statuses' do
|
||||
it 'returns http success without json' do
|
||||
get api_v1_scheduled_statuses_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to_not be_present
|
||||
end
|
||||
end
|
||||
|
||||
context 'with scheduled statuses' do
|
||||
let!(:scheduled_status) { Fabricate(:scheduled_status, account: user.account) }
|
||||
|
||||
it 'returns http success and status json' do
|
||||
get api_v1_scheduled_statuses_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and have_attributes(
|
||||
first: include(id: scheduled_status.id.to_s)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -70,19 +70,13 @@ RSpec.describe 'Favourites' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/statuses/:status_id/unfavourite' do
|
||||
describe 'POST /api/v1/statuses/:status_id/unfavourite', :sidekiq_fake do
|
||||
subject do
|
||||
post "/api/v1/statuses/#{status.id}/unfavourite", headers: headers
|
||||
end
|
||||
|
||||
let(:status) { Fabricate(:status) }
|
||||
|
||||
around do |example|
|
||||
Sidekiq::Testing.fake! do
|
||||
example.run
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:favourites'
|
||||
|
||||
context 'with public status' do
|
||||
|
|
|
@ -245,7 +245,7 @@ describe '/api/v1/statuses' do
|
|||
context 'when exceeding rate limit' do
|
||||
before do
|
||||
rate_limiter = RateLimiter.new(user.account, family: :statuses)
|
||||
300.times { rate_limiter.record! }
|
||||
RateLimiter::FAMILIES[:statuses][:limit].times { rate_limiter.record! }
|
||||
end
|
||||
|
||||
it 'returns rate limit headers', :aggregate_failures do
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe 'Filters' do
|
|||
get '/api/v2/filters', headers: headers
|
||||
end
|
||||
|
||||
let!(:filters) { Fabricate.times(3, :custom_filter, account: user.account) }
|
||||
let!(:filters) { Fabricate.times(2, :custom_filter, account: user.account) }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:filters'
|
||||
it_behaves_like 'unauthorized for invalid token'
|
37
spec/requests/api/v2/instance_spec.rb
Normal file
37
spec/requests/api/v2/instance_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Instances' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v2/instance' do
|
||||
context 'when logged out' do
|
||||
it 'returns http success and json' do
|
||||
get api_v2_instance_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and include(title: 'Mastodon')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when logged in' do
|
||||
it 'returns http success and json' do
|
||||
get api_v2_instance_path, headers: headers
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_present
|
||||
.and include(title: 'Mastodon')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,10 +9,82 @@ RSpec.describe 'Media API', :paperclip_processing do
|
|||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'POST /api/v2/media' do
|
||||
it 'returns http success' do
|
||||
post '/api/v2/media', headers: headers, params: { file: fixture_file_upload('attachment-jpg.123456_abcd', 'image/jpeg') }
|
||||
expect(File.exist?(user.account.media_attachments.first.file.path(:small))).to be true
|
||||
expect(response).to have_http_status(200)
|
||||
context 'when small media format attachment is processed immediately' do
|
||||
let(:params) { { file: fixture_file_upload('attachment-jpg.123456_abcd', 'image/jpeg') } }
|
||||
|
||||
it 'returns http success' do
|
||||
post '/api/v2/media', headers: headers, params: params
|
||||
|
||||
expect(File.exist?(user.account.media_attachments.first.file.path(:small)))
|
||||
.to be true
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_a(Hash)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when large format media attachment has not been processed' do
|
||||
let(:params) { { file: fixture_file_upload('attachment.webm', 'video/webm') } }
|
||||
|
||||
it 'returns http accepted' do
|
||||
post '/api/v2/media', headers: headers, params: params
|
||||
|
||||
expect(File.exist?(user.account.media_attachments.first.file.path(:small)))
|
||||
.to be true
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(202)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_a(Hash)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when paperclip errors occur' do
|
||||
let(:media_attachments) { double }
|
||||
let(:params) { { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } }
|
||||
|
||||
before do
|
||||
allow(User).to receive(:find).with(token.resource_owner_id).and_return(user)
|
||||
allow(user.account).to receive(:media_attachments).and_return(media_attachments)
|
||||
end
|
||||
|
||||
context 'when imagemagick cannot identify the file type' do
|
||||
before do
|
||||
allow(media_attachments).to receive(:create!).and_raise(Paperclip::Errors::NotIdentifiedByImageMagickError)
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
post '/api/v2/media', headers: headers, params: params
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(422)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_a(Hash)
|
||||
.and include(error: /File type/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a generic error' do
|
||||
before do
|
||||
allow(media_attachments).to receive(:create!).and_raise(Paperclip::Error)
|
||||
end
|
||||
|
||||
it 'returns http 500' do
|
||||
post '/api/v2/media', headers: headers, params: params
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(500)
|
||||
|
||||
expect(body_as_json)
|
||||
.to be_a(Hash)
|
||||
.and include(error: /processing/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
30
spec/requests/remote_interaction_helper_spec.rb
Normal file
30
spec/requests/remote_interaction_helper_spec.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Remote Interaction Helper' do
|
||||
describe 'GET /remote_interaction_helper' do
|
||||
it 'returns http success' do
|
||||
get remote_interaction_helper_path
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(200)
|
||||
.and render_template(:index, layout: 'helper_frame')
|
||||
.and have_attributes(
|
||||
headers: include(
|
||||
'X-Frame-Options' => 'SAMEORIGIN',
|
||||
'Referrer-Policy' => 'no-referrer',
|
||||
'Content-Security-Policy' => expected_csp_headers
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expected_csp_headers
|
||||
<<~CSP.squish
|
||||
default-src 'none'; frame-ancestors 'self'; form-action 'none'; script-src 'self' https://cb6e6126.ngrok.io 'wasm-unsafe-eval'; connect-src https:
|
||||
CSP
|
||||
end
|
||||
end
|
|
@ -12,14 +12,7 @@ RSpec.describe BulkImportService do
|
|||
import.update(total_items: import.rows.count)
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
around do |example|
|
||||
Sidekiq::Testing.fake! do
|
||||
example.run
|
||||
Sidekiq::Worker.clear_all
|
||||
end
|
||||
end
|
||||
|
||||
describe '#call', :sidekiq_fake do
|
||||
context 'when importing follows' do
|
||||
let(:import_type) { 'following' }
|
||||
let(:overwrite) { false }
|
||||
|
|
|
@ -111,7 +111,7 @@ RSpec.describe UpdateStatusService, type: :service do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when poll changes' do
|
||||
context 'when poll changes', :sidekiq_fake do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let!(:status) { Fabricate(:status, text: 'Foo', account: account, poll_attributes: { options: %w(Foo Bar), account: account, multiple: false, hide_totals: false, expires_at: 7.days.from_now }) }
|
||||
let!(:poll) { status.poll }
|
||||
|
@ -120,9 +120,7 @@ RSpec.describe UpdateStatusService, type: :service do
|
|||
before do
|
||||
status.update(poll: poll)
|
||||
VoteService.new.call(voter, poll, [0])
|
||||
Sidekiq::Testing.fake! do
|
||||
subject.call(status, status.account_id, text: 'Foo', poll: { options: %w(Bar Baz Foo), expires_in: 5.days.to_i })
|
||||
end
|
||||
subject.call(status, status.account_id, text: 'Foo', poll: { options: %w(Bar Baz Foo), expires_in: 5.days.to_i })
|
||||
end
|
||||
|
||||
it 'updates poll' do
|
||||
|
|
|
@ -159,12 +159,9 @@ describe MoveWorker do
|
|||
|
||||
describe '#perform' do
|
||||
context 'when both accounts are distant' do
|
||||
it 'calls UnfollowFollowWorker' do
|
||||
Sidekiq::Testing.fake! do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, false)
|
||||
Sidekiq::Worker.drain_all
|
||||
end
|
||||
it 'calls UnfollowFollowWorker', :sidekiq_fake do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, false)
|
||||
end
|
||||
|
||||
include_examples 'common tests'
|
||||
|
@ -173,12 +170,9 @@ describe MoveWorker do
|
|||
context 'when target account is local' do
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
|
||||
it 'calls UnfollowFollowWorker' do
|
||||
Sidekiq::Testing.fake! do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, true)
|
||||
Sidekiq::Worker.clear_all
|
||||
end
|
||||
it 'calls UnfollowFollowWorker', :sidekiq_fake do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, true)
|
||||
end
|
||||
|
||||
include_examples 'common tests'
|
||||
|
|
|
@ -10,13 +10,7 @@ describe PollExpirationNotifyWorker do
|
|||
let(:remote?) { false }
|
||||
let(:poll_vote) { Fabricate(:poll_vote, poll: poll) }
|
||||
|
||||
describe '#perform' do
|
||||
around do |example|
|
||||
Sidekiq::Testing.fake! do
|
||||
example.run
|
||||
end
|
||||
end
|
||||
|
||||
describe '#perform', :sidekiq_fake do
|
||||
it 'runs without error for missing record' do
|
||||
expect { worker.perform(nil) }.to_not raise_error
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue