Merge commit '420ffdfb6259740602d4ce727ed5c60432c776a5' into glitch-soc/merge-upstream
commit
399fbf97de
|
@ -613,7 +613,7 @@ GEM
|
|||
activesupport (>= 3.0.0)
|
||||
raabro (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (2.2.12)
|
||||
rack (2.2.13)
|
||||
rack-attack (6.7.0)
|
||||
rack (>= 1.0, < 4)
|
||||
rack-cors (2.0.2)
|
||||
|
|
|
@ -14,7 +14,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
|
|||
@account = current_account
|
||||
UpdateAccountService.new.call(@account, account_params, raise_error: true)
|
||||
current_user.update(user_params) if user_params
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
render json: @account, serializer: REST::CredentialAccountSerializer
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
render json: ValidationErrorFormatter.new(e).as_json, status: 422
|
||||
|
|
|
@ -7,7 +7,7 @@ class Api::V1::Profile::AvatarsController < Api::BaseController
|
|||
def destroy
|
||||
@account = current_account
|
||||
UpdateAccountService.new.call(@account, { avatar: nil }, raise_error: true)
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
render json: @account, serializer: REST::CredentialAccountSerializer
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ class Api::V1::Profile::HeadersController < Api::BaseController
|
|||
def destroy
|
||||
@account = current_account
|
||||
UpdateAccountService.new.call(@account, { header: nil }, raise_error: true)
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
render json: @account, serializer: REST::CredentialAccountSerializer
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ module Settings
|
|||
def destroy
|
||||
if valid_picture?
|
||||
if UpdateAccountService.new.call(@account, { @picture => nil, "#{@picture}_remote_url" => '' })
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
redirect_to settings_profile_path, notice: I18n.t('generic.changes_saved_msg'), status: 303
|
||||
else
|
||||
redirect_to settings_profile_path
|
||||
|
|
|
@ -8,7 +8,7 @@ class Settings::PrivacyController < Settings::BaseController
|
|||
def update
|
||||
if UpdateAccountService.new.call(@account, account_params.except(:settings))
|
||||
current_user.update!(settings_attributes: account_params[:settings])
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
redirect_to settings_privacy_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
render :show
|
||||
|
|
|
@ -9,7 +9,7 @@ class Settings::ProfilesController < Settings::BaseController
|
|||
|
||||
def update
|
||||
if UpdateAccountService.new.call(@account, account_params)
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
redirect_to settings_profile_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
@account.build_fields
|
||||
|
|
|
@ -8,7 +8,7 @@ class Settings::VerificationsController < Settings::BaseController
|
|||
|
||||
def update
|
||||
if UpdateAccountService.new.call(@account, account_params)
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
redirect_to settings_verification_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
render :show
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
|
@ -28,28 +28,30 @@ export const ActionBar = () => {
|
|||
const dispatch = useDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const handleLogoutClick = useCallback(() => {
|
||||
dispatch(openModal({ modalType: 'CONFIRM_LOG_OUT' }));
|
||||
}, [dispatch]);
|
||||
const menu = useMemo(() => {
|
||||
const handleLogoutClick = () => {
|
||||
dispatch(openModal({ modalType: 'CONFIRM_LOG_OUT' }));
|
||||
};
|
||||
|
||||
let menu = [];
|
||||
|
||||
menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' });
|
||||
menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' });
|
||||
menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
|
||||
menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' });
|
||||
menu.push({ text: intl.formatMessage(messages.bookmarks), to: '/bookmarks' });
|
||||
menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' });
|
||||
menu.push({ text: intl.formatMessage(messages.followed_tags), to: '/followed_tags' });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
|
||||
menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
|
||||
menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
|
||||
menu.push({ text: intl.formatMessage(messages.filters), href: '/filters' });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.logout), action: handleLogoutClick });
|
||||
return ([
|
||||
{ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' },
|
||||
{ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' },
|
||||
{ text: intl.formatMessage(messages.pins), to: '/pinned' },
|
||||
null,
|
||||
{ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' },
|
||||
{ text: intl.formatMessage(messages.favourites), to: '/favourites' },
|
||||
{ text: intl.formatMessage(messages.bookmarks), to: '/bookmarks' },
|
||||
{ text: intl.formatMessage(messages.lists), to: '/lists' },
|
||||
{ text: intl.formatMessage(messages.followed_tags), to: '/followed_tags' },
|
||||
null,
|
||||
{ text: intl.formatMessage(messages.mutes), to: '/mutes' },
|
||||
{ text: intl.formatMessage(messages.blocks), to: '/blocks' },
|
||||
{ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' },
|
||||
{ text: intl.formatMessage(messages.filters), href: '/filters' },
|
||||
null,
|
||||
{ text: intl.formatMessage(messages.logout), action: handleLogoutClick },
|
||||
]);
|
||||
}, [intl, dispatch]);
|
||||
|
||||
return (
|
||||
<DropdownMenuContainer
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::UpdateDistributionWorker < ActivityPub::RawDistributionWorker
|
||||
DEBOUNCE_DELAY = 5.seconds
|
||||
|
||||
sidekiq_options queue: 'push', lock: :until_executed, lock_ttl: 1.day.to_i
|
||||
|
||||
# Distribute an profile update to servers that might have a copy
|
||||
|
|
|
@ -34,11 +34,11 @@ require_relative '../lib/paperclip/transcoder'
|
|||
require_relative '../lib/paperclip/type_corrector'
|
||||
require_relative '../lib/paperclip/response_with_limit_adapter'
|
||||
require_relative '../lib/terrapin/multi_pipe_extensions'
|
||||
require_relative '../lib/mastodon/middleware/public_file_server'
|
||||
require_relative '../lib/mastodon/middleware/socket_cleanup'
|
||||
require_relative '../lib/mastodon/snowflake'
|
||||
require_relative '../lib/mastodon/feature'
|
||||
require_relative '../lib/mastodon/version'
|
||||
require_relative '../lib/mastodon/rack_middleware'
|
||||
require_relative '../lib/public_file_server_middleware'
|
||||
require_relative '../lib/devise/strategies/two_factor_ldap_authenticatable'
|
||||
require_relative '../lib/devise/strategies/two_factor_pam_authenticatable'
|
||||
require_relative '../lib/elasticsearch/client_extensions'
|
||||
|
@ -88,9 +88,9 @@ module Mastodon
|
|||
# We use our own middleware for this
|
||||
config.public_file_server.enabled = false
|
||||
|
||||
config.middleware.use PublicFileServerMiddleware if Rails.env.local? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true'
|
||||
config.middleware.use Mastodon::Middleware::PublicFileServer if Rails.env.local? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true'
|
||||
config.middleware.use Rack::Attack
|
||||
config.middleware.use Mastodon::RackMiddleware
|
||||
config.middleware.use Mastodon::Middleware::SocketCleanup
|
||||
|
||||
config.before_configuration do
|
||||
require 'mastodon/redis_configuration'
|
||||
|
|
|
@ -10,3 +10,5 @@ shared:
|
|||
version:
|
||||
metadata: <%= ['glitch', ENV.fetch('MASTODON_VERSION_METADATA', nil)].compact_blank.join('.') %>
|
||||
prerelease: <%= ENV.fetch('MASTODON_VERSION_PRERELEASE', nil) %>
|
||||
test:
|
||||
experimental_features: <%= [ENV.fetch('EXPERIMENTAL_FEATURES', nil), 'testing_only'].compact.join(',') %>
|
||||
|
|
|
@ -19,8 +19,8 @@ module Mastodon::Feature
|
|||
super
|
||||
end
|
||||
|
||||
def respond_to_missing?(name)
|
||||
name.to_s.end_with?('_enabled?')
|
||||
def respond_to_missing?(name, include_all = false)
|
||||
name.to_s.end_with?('_enabled?') || super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'action_dispatch/middleware/static'
|
||||
|
||||
module Mastodon
|
||||
module Middleware
|
||||
class PublicFileServer
|
||||
SERVICE_WORKER_TTL = 7.days.to_i
|
||||
CACHE_TTL = 28.days.to_i
|
||||
|
||||
def initialize(app)
|
||||
@app = app
|
||||
@file_handler = ActionDispatch::FileHandler.new(Rails.application.paths['public'].first)
|
||||
end
|
||||
|
||||
def call(env)
|
||||
file = @file_handler.attempt(env)
|
||||
|
||||
# If the request is not a static file, move on!
|
||||
return @app.call(env) if file.nil?
|
||||
|
||||
status, headers, response = file
|
||||
|
||||
# Set cache headers on static files. Some paths require different cache headers
|
||||
headers['Cache-Control'] = begin
|
||||
request_path = env['REQUEST_PATH']
|
||||
|
||||
if request_path.start_with?('/sw.js')
|
||||
"public, max-age=#{SERVICE_WORKER_TTL}, must-revalidate"
|
||||
elsif request_path.start_with?(paperclip_root_url)
|
||||
"public, max-age=#{CACHE_TTL}, immutable"
|
||||
else
|
||||
"public, max-age=#{CACHE_TTL}, must-revalidate"
|
||||
end
|
||||
end
|
||||
|
||||
# Override the default CSP header set by the CSP middleware
|
||||
headers['Content-Security-Policy'] = "default-src 'none'; form-action 'none'" if request_path.start_with?(paperclip_root_url)
|
||||
|
||||
headers['X-Content-Type-Options'] = 'nosniff'
|
||||
|
||||
[status, headers, response]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def paperclip_root_url
|
||||
ENV.fetch('PAPERCLIP_ROOT_URL', '/system')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Mastodon
|
||||
module Middleware
|
||||
class SocketCleanup
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@app.call(env)
|
||||
ensure
|
||||
clean_up_sockets!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def clean_up_sockets!
|
||||
clean_up_redis_socket!
|
||||
clean_up_statsd_socket!
|
||||
end
|
||||
|
||||
def clean_up_redis_socket!
|
||||
RedisConnection.pool.checkin if Thread.current[:redis]
|
||||
Thread.current[:redis] = nil
|
||||
end
|
||||
|
||||
def clean_up_statsd_socket!
|
||||
Thread.current[:statsd_socket]&.close
|
||||
Thread.current[:statsd_socket] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Mastodon::RackMiddleware
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@app.call(env)
|
||||
ensure
|
||||
clean_up_sockets!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def clean_up_sockets!
|
||||
clean_up_redis_socket!
|
||||
clean_up_statsd_socket!
|
||||
end
|
||||
|
||||
def clean_up_redis_socket!
|
||||
RedisConnection.pool.checkin if Thread.current[:redis]
|
||||
Thread.current[:redis] = nil
|
||||
end
|
||||
|
||||
def clean_up_statsd_socket!
|
||||
Thread.current[:statsd_socket]&.close
|
||||
Thread.current[:statsd_socket] = nil
|
||||
end
|
||||
end
|
|
@ -1,48 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'action_dispatch/middleware/static'
|
||||
|
||||
class PublicFileServerMiddleware
|
||||
SERVICE_WORKER_TTL = 7.days.to_i
|
||||
CACHE_TTL = 28.days.to_i
|
||||
|
||||
def initialize(app)
|
||||
@app = app
|
||||
@file_handler = ActionDispatch::FileHandler.new(Rails.application.paths['public'].first)
|
||||
end
|
||||
|
||||
def call(env)
|
||||
file = @file_handler.attempt(env)
|
||||
|
||||
# If the request is not a static file, move on!
|
||||
return @app.call(env) if file.nil?
|
||||
|
||||
status, headers, response = file
|
||||
|
||||
# Set cache headers on static files. Some paths require different cache headers
|
||||
headers['Cache-Control'] = begin
|
||||
request_path = env['REQUEST_PATH']
|
||||
|
||||
if request_path.start_with?('/sw.js')
|
||||
"public, max-age=#{SERVICE_WORKER_TTL}, must-revalidate"
|
||||
elsif request_path.start_with?(paperclip_root_url)
|
||||
"public, max-age=#{CACHE_TTL}, immutable"
|
||||
else
|
||||
"public, max-age=#{CACHE_TTL}, must-revalidate"
|
||||
end
|
||||
end
|
||||
|
||||
# Override the default CSP header set by the CSP middleware
|
||||
headers['Content-Security-Policy'] = "default-src 'none'; form-action 'none'" if request_path.start_with?(paperclip_root_url)
|
||||
|
||||
headers['X-Content-Type-Options'] = 'nosniff'
|
||||
|
||||
[status, headers, response]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def paperclip_root_url
|
||||
ENV.fetch('PAPERCLIP_ROOT_URL', '/system')
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::Settings::BrandingController do
|
||||
render_views
|
||||
|
||||
describe 'When signed in as an admin' do
|
||||
before do
|
||||
sign_in Fabricate(:admin_user), scope: :user
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
it 'cannot create a setting value for a non-admin key' do
|
||||
expect(Setting.new_setting_key).to be_blank
|
||||
|
||||
patch :update, params: { form_admin_settings: { new_setting_key: 'New key value' } }
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(400)
|
||||
expect(Setting.new_setting_key).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,28 +3,23 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Mastodon::Feature do
|
||||
around do |example|
|
||||
original_value = Rails.configuration.x.mastodon.experimental_features
|
||||
Rails.configuration.x.mastodon.experimental_features = 'fasp,fetch_all_replies'
|
||||
example.run
|
||||
Rails.configuration.x.mastodon.experimental_features = original_value
|
||||
end
|
||||
|
||||
describe '::fasp_enabled?' do
|
||||
subject { described_class.fasp_enabled? }
|
||||
|
||||
it { is_expected.to be true }
|
||||
end
|
||||
|
||||
describe '::fetch_all_replies_enabled?' do
|
||||
subject { described_class.fetch_all_replies_enabled? }
|
||||
describe '::testing_only_enabled?' do
|
||||
subject { described_class.testing_only_enabled? }
|
||||
|
||||
it { is_expected.to be true }
|
||||
end
|
||||
|
||||
describe '::unspecified_feature_enabled?' do
|
||||
subject { described_class.unspecified_feature_enabled? }
|
||||
context 'when example is not tagged with a feature' do
|
||||
subject { described_class.unspecified_feature_enabled? }
|
||||
|
||||
it { is_expected.to be false }
|
||||
it { is_expected.to be false }
|
||||
end
|
||||
|
||||
context 'when example is tagged with a feature', feature: 'unspecified_feature' do
|
||||
subject { described_class.unspecified_feature_enabled? }
|
||||
|
||||
it { is_expected.to be true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Admin Settings Branding' do
|
||||
describe 'When signed in as an admin' do
|
||||
before { sign_in Fabricate(:admin_user) }
|
||||
|
||||
describe 'PUT /admin/settings/branding' do
|
||||
it 'cannot create a setting value for a non-admin key' do
|
||||
expect { put admin_settings_branding_path, params: { form_admin_settings: { new_setting_key: 'New key value' } } }
|
||||
.to_not change(Setting, :new_setting_key).from(nil)
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(400)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -53,8 +53,6 @@ RSpec.describe 'credentials API' do
|
|||
patch '/api/v1/accounts/update_credentials', headers: headers, params: params
|
||||
end
|
||||
|
||||
before { allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async) }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
avatar: fixture_file_upload('avatar.gif', 'image/gif'),
|
||||
|
@ -113,7 +111,7 @@ RSpec.describe 'credentials API' do
|
|||
})
|
||||
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to have_received(:perform_async).with(user.account_id)
|
||||
.to have_enqueued_sidekiq_job(user.account_id)
|
||||
end
|
||||
|
||||
def expect_account_updates
|
||||
|
|
|
@ -15,10 +15,6 @@ RSpec.describe 'Deleting profile images' do
|
|||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'DELETE /api/v1/profile' do
|
||||
before do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
context 'when deleting an avatar' do
|
||||
context 'with wrong scope' do
|
||||
before do
|
||||
|
@ -38,7 +34,8 @@ RSpec.describe 'Deleting profile images' do
|
|||
account.reload
|
||||
expect(account.avatar).to_not exist
|
||||
expect(account.header).to exist
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to have_enqueued_sidekiq_job(account.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -61,7 +58,8 @@ RSpec.describe 'Deleting profile images' do
|
|||
account.reload
|
||||
expect(account.avatar).to exist
|
||||
expect(account.header).to_not exist
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to have_enqueued_sidekiq_job(account.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.before(:example, :feature) do |example|
|
||||
feature = example.metadata[:feature]
|
||||
allow(Mastodon::Feature).to receive(:"#{feature}_enabled?").and_return(true)
|
||||
end
|
||||
end
|
|
@ -22,7 +22,11 @@ module ProfileStories
|
|||
def as_a_logged_in_user
|
||||
as_a_registered_user
|
||||
visit new_user_session_path
|
||||
expect(page)
|
||||
.to have_title(I18n.t('auth.login'))
|
||||
fill_in_auth_details(email, password)
|
||||
expect(page)
|
||||
.to have_css('.app-holder')
|
||||
end
|
||||
|
||||
def as_a_logged_in_admin
|
||||
|
|
|
@ -5,21 +5,15 @@ require 'rails_helper'
|
|||
RSpec.describe 'NewStatuses', :inline_jobs, :js, :streaming do
|
||||
include ProfileStories
|
||||
|
||||
subject { page }
|
||||
|
||||
let(:email) { 'test@example.com' }
|
||||
let(:password) { 'password' }
|
||||
let(:confirmed_at) { Time.zone.now }
|
||||
let(:finished_onboarding) { true }
|
||||
|
||||
before do
|
||||
as_a_logged_in_user
|
||||
visit root_path
|
||||
end
|
||||
before { as_a_logged_in_user }
|
||||
|
||||
it 'can be posted' do
|
||||
expect(subject).to have_css('div.app-holder')
|
||||
|
||||
visit_homepage
|
||||
status_text = 'This is a new status!'
|
||||
|
||||
within('.compose-form') do
|
||||
|
@ -27,12 +21,12 @@ RSpec.describe 'NewStatuses', :inline_jobs, :js, :streaming do
|
|||
click_on 'Post'
|
||||
end
|
||||
|
||||
expect(subject).to have_css('.status__content__text', text: status_text)
|
||||
expect(page)
|
||||
.to have_css('.status__content__text', text: status_text)
|
||||
end
|
||||
|
||||
it 'can be posted again' do
|
||||
expect(subject).to have_css('div.app-holder')
|
||||
|
||||
visit_homepage
|
||||
status_text = 'This is a second status!'
|
||||
|
||||
within('.compose-form') do
|
||||
|
@ -40,6 +34,15 @@ RSpec.describe 'NewStatuses', :inline_jobs, :js, :streaming do
|
|||
click_on 'Post'
|
||||
end
|
||||
|
||||
expect(subject).to have_css('.status__content__text', text: status_text)
|
||||
expect(page)
|
||||
.to have_css('.status__content__text', text: status_text)
|
||||
end
|
||||
|
||||
def visit_homepage
|
||||
visit root_path
|
||||
|
||||
expect(page)
|
||||
.to have_css('div.app-holder')
|
||||
.and have_css('form.compose-form')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,5 +40,7 @@ RSpec.describe 'report interface', :attachment_processing, :js, :streaming do
|
|||
within '.report-actions' do
|
||||
click_on I18n.t('admin.reports.mark_as_resolved')
|
||||
end
|
||||
expect(page)
|
||||
.to have_content(I18n.t('admin.reports.resolved_msg'))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,8 +11,6 @@ RSpec.describe 'Settings Privacy' do
|
|||
before { user.account.update(discoverable: false) }
|
||||
|
||||
context 'with a successful update' do
|
||||
before { allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async) }
|
||||
|
||||
it 'updates user profile information' do
|
||||
# View settings page
|
||||
visit settings_privacy_path
|
||||
|
@ -29,14 +27,13 @@ RSpec.describe 'Settings Privacy' do
|
|||
.to have_content(I18n.t('privacy.title'))
|
||||
.and have_content(success_message)
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to have_received(:perform_async).with(user.account.id)
|
||||
.to have_enqueued_sidekiq_job(user.account.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a failed update' do
|
||||
before do
|
||||
allow(UpdateAccountService).to receive(:new).and_return(failing_update_service)
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
it 'updates user profile information' do
|
||||
|
@ -54,7 +51,7 @@ RSpec.describe 'Settings Privacy' do
|
|||
expect(page)
|
||||
.to have_content(I18n.t('privacy.title'))
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to_not have_received(:perform_async)
|
||||
.to_not have_enqueued_sidekiq_job(anything)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -7,7 +7,6 @@ RSpec.describe 'Settings profile page' do
|
|||
let(:account) { user.account }
|
||||
|
||||
before do
|
||||
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
|
||||
sign_in user
|
||||
end
|
||||
|
||||
|
@ -24,7 +23,7 @@ RSpec.describe 'Settings profile page' do
|
|||
.to change { account.reload.display_name }.to('New name')
|
||||
.and(change { account.reload.avatar.instance.avatar_file_name }.from(nil).to(be_present))
|
||||
expect(ActivityPub::UpdateDistributionWorker)
|
||||
.to have_received(:perform_async).with(account.id)
|
||||
.to have_enqueued_sidekiq_job(account.id)
|
||||
end
|
||||
|
||||
def display_name_field
|
||||
|
|
Loading…
Reference in New Issue