Merge pull request #2837 from ClearlyClaire/glitch-soc/merge-upstream

Merge upstream changes up to b716248fc5
This commit is contained in:
Claire 2024-09-07 10:16:46 +02:00 committed by GitHub
commit 9dcc6808d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
174 changed files with 786 additions and 612 deletions

View file

@ -1,6 +1,7 @@
[production] [production]
defaults defaults
> 0.2% > 0.2%
firefox >= 78
ios >= 15.6 ios >= 15.6
not dead not dead
not OperaMini all not OperaMini all

1
.github/codecov.yml vendored
View file

@ -1,3 +1,4 @@
annotations: false
comment: false # Do not leave PR comments comment: false # Do not leave PR comments
coverage: coverage:
status: status:

View file

@ -10,35 +10,35 @@ GIT
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
actioncable (7.1.3.4) actioncable (7.1.4)
actionpack (= 7.1.3.4) actionpack (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
nio4r (~> 2.0) nio4r (~> 2.0)
websocket-driver (>= 0.6.1) websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
actionmailbox (7.1.3.4) actionmailbox (7.1.4)
actionpack (= 7.1.3.4) actionpack (= 7.1.4)
activejob (= 7.1.3.4) activejob (= 7.1.4)
activerecord (= 7.1.3.4) activerecord (= 7.1.4)
activestorage (= 7.1.3.4) activestorage (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
mail (>= 2.7.1) mail (>= 2.7.1)
net-imap net-imap
net-pop net-pop
net-smtp net-smtp
actionmailer (7.1.3.4) actionmailer (7.1.4)
actionpack (= 7.1.3.4) actionpack (= 7.1.4)
actionview (= 7.1.3.4) actionview (= 7.1.4)
activejob (= 7.1.3.4) activejob (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
net-imap net-imap
net-pop net-pop
net-smtp net-smtp
rails-dom-testing (~> 2.2) rails-dom-testing (~> 2.2)
actionpack (7.1.3.4) actionpack (7.1.4)
actionview (= 7.1.3.4) actionview (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
nokogiri (>= 1.8.5) nokogiri (>= 1.8.5)
racc racc
rack (>= 2.2.4) rack (>= 2.2.4)
@ -46,15 +46,15 @@ GEM
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2) rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6) rails-html-sanitizer (~> 1.6)
actiontext (7.1.3.4) actiontext (7.1.4)
actionpack (= 7.1.3.4) actionpack (= 7.1.4)
activerecord (= 7.1.3.4) activerecord (= 7.1.4)
activestorage (= 7.1.3.4) activestorage (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
globalid (>= 0.6.0) globalid (>= 0.6.0)
nokogiri (>= 1.8.5) nokogiri (>= 1.8.5)
actionview (7.1.3.4) actionview (7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
builder (~> 3.1) builder (~> 3.1)
erubi (~> 1.11) erubi (~> 1.11)
rails-dom-testing (~> 2.2) rails-dom-testing (~> 2.2)
@ -64,22 +64,22 @@ GEM
activemodel (>= 4.1) activemodel (>= 4.1)
case_transform (>= 0.2) case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3) jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (7.1.3.4) activejob (7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (7.1.3.4) activemodel (7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
activerecord (7.1.3.4) activerecord (7.1.4)
activemodel (= 7.1.3.4) activemodel (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
timeout (>= 0.4.0) timeout (>= 0.4.0)
activestorage (7.1.3.4) activestorage (7.1.4)
actionpack (= 7.1.3.4) actionpack (= 7.1.4)
activejob (= 7.1.3.4) activejob (= 7.1.4)
activerecord (= 7.1.3.4) activerecord (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
marcel (~> 1.0) marcel (~> 1.0)
activesupport (7.1.3.4) activesupport (7.1.4)
base64 base64
bigdecimal bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
@ -638,20 +638,20 @@ GEM
rackup (1.0.0) rackup (1.0.0)
rack (< 3) rack (< 3)
webrick webrick
rails (7.1.3.4) rails (7.1.4)
actioncable (= 7.1.3.4) actioncable (= 7.1.4)
actionmailbox (= 7.1.3.4) actionmailbox (= 7.1.4)
actionmailer (= 7.1.3.4) actionmailer (= 7.1.4)
actionpack (= 7.1.3.4) actionpack (= 7.1.4)
actiontext (= 7.1.3.4) actiontext (= 7.1.4)
actionview (= 7.1.3.4) actionview (= 7.1.4)
activejob (= 7.1.3.4) activejob (= 7.1.4)
activemodel (= 7.1.3.4) activemodel (= 7.1.4)
activerecord (= 7.1.3.4) activerecord (= 7.1.4)
activestorage (= 7.1.3.4) activestorage (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
bundler (>= 1.15.0) bundler (>= 1.15.0)
railties (= 7.1.3.4) railties (= 7.1.4)
rails-controller-testing (1.0.5) rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1) actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1)
@ -666,9 +666,9 @@ GEM
rails-i18n (7.0.9) rails-i18n (7.0.9)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8) railties (>= 6.0.0, < 8)
railties (7.1.3.4) railties (7.1.4)
actionpack (= 7.1.3.4) actionpack (= 7.1.4)
activesupport (= 7.1.3.4) activesupport (= 7.1.4)
irb irb
rackup (>= 1.0.0) rackup (>= 1.0.0)
rake (>= 12.2) rake (>= 12.2)
@ -857,7 +857,7 @@ GEM
unf (~> 0.1.0) unf (~> 0.1.0)
tzinfo (2.0.6) tzinfo (2.0.6)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
tzinfo-data (1.2024.1) tzinfo-data (1.2024.2)
tzinfo (>= 1.0.0) tzinfo (>= 1.0.0)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext

View file

@ -13,7 +13,7 @@ module Admin
redirect_to admin_account_path(@account_moderation_note.target_account_id), notice: I18n.t('admin.account_moderation_notes.created_msg') redirect_to admin_account_path(@account_moderation_note.target_account_id), notice: I18n.t('admin.account_moderation_notes.created_msg')
else else
@account = @account_moderation_note.target_account @account = @account_moderation_note.target_account
@moderation_notes = @account.targeted_moderation_notes.latest @moderation_notes = @account.targeted_moderation_notes.chronological.includes(:account)
@warnings = @account.strikes.custom.latest @warnings = @account.strikes.custom.latest
render 'admin/accounts/show' render 'admin/accounts/show'

View file

@ -33,7 +33,7 @@ module Admin
@deletion_request = @account.deletion_request @deletion_request = @account.deletion_request
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account) @account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
@moderation_notes = @account.targeted_moderation_notes.latest @moderation_notes = @account.targeted_moderation_notes.chronological.includes(:account)
@warnings = @account.strikes.includes(:target_account, :account, :appeal).latest @warnings = @account.strikes.includes(:target_account, :account, :appeal).latest
@domain_block = DomainBlock.rule_for(@account.domain) @domain_block = DomainBlock.rule_for(@account.domain)
end end

View file

@ -7,17 +7,12 @@ module Admin
layout 'admin' layout 'admin'
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
after_action :verify_authorized after_action :verify_authorized
private private
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -7,12 +7,12 @@ module Admin
def index def index
authorize :dashboard, :index? authorize :dashboard, :index?
@pending_appeals_count = Appeal.pending.async_count
@pending_reports_count = Report.unresolved.async_count
@pending_tags_count = Tag.pending_review.async_count
@pending_users_count = User.pending.async_count
@system_checks = Admin::SystemCheck.perform(current_user) @system_checks = Admin::SystemCheck.perform(current_user)
@time_period = (29.days.ago.to_date...Time.now.utc.to_date) @time_period = (29.days.ago.to_date...Time.now.utc.to_date)
@pending_users_count = User.pending.count
@pending_reports_count = Report.unresolved.count
@pending_tags_count = Tag.pending_review.count
@pending_appeals_count = Appeal.pending.count
end end
end end
end end

View file

@ -21,7 +21,7 @@ module Admin
redirect_to after_create_redirect_path, notice: I18n.t('admin.report_notes.created_msg') redirect_to after_create_redirect_path, notice: I18n.t('admin.report_notes.created_msg')
else else
@report_notes = @report.notes.includes(:account).order(id: :desc) @report_notes = @report.notes.chronological.includes(:account)
@action_logs = @report.history.includes(:target) @action_logs = @report.history.includes(:target)
@form = Admin::StatusBatchAction.new @form = Admin::StatusBatchAction.new
@statuses = @report.statuses.with_includes @statuses = @report.statuses.with_includes

View file

@ -13,7 +13,7 @@ module Admin
authorize @report, :show? authorize @report, :show?
@report_note = @report.notes.new @report_note = @report.notes.new
@report_notes = @report.notes.includes(:account).order(id: :desc) @report_notes = @report.notes.chronological.includes(:account)
@action_logs = @report.history.includes(:target) @action_logs = @report.history.includes(:target)
@form = Admin::StatusBatchAction.new @form = Admin::StatusBatchAction.new
@statuses = @report.statuses.with_includes @statuses = @report.statuses.with_includes

View file

@ -11,7 +11,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create] before_action :configure_sign_up_params, only: [:create]
before_action :set_sessions, only: [:edit, :update] before_action :set_sessions, only: [:edit, :update]
before_action :set_strikes, only: [:edit, :update] before_action :set_strikes, only: [:edit, :update]
before_action :set_body_classes, only: [:new, :create, :edit, :update]
before_action :require_not_suspended!, only: [:update] before_action :require_not_suspended!, only: [:update]
before_action :set_cache_headers, only: [:edit, :update] before_action :set_cache_headers, only: [:edit, :update]
before_action :set_rules, only: :new before_action :set_rules, only: :new
@ -104,10 +103,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
private private
def set_body_classes
@body_classes = 'admin' if %w(edit update).include?(action_name)
end
def set_invite def set_invite
@invite = begin @invite = begin
invite = Invite.find_by(code: invite_code) if invite_code.present? invite = Invite.find_by(code: invite_code) if invite_code.present?

View file

@ -20,7 +20,7 @@ module AccountControllerConcern
webfinger_account_link, webfinger_account_link,
actor_url_link, actor_url_link,
] ]
) ).to_s
end end
def webfinger_account_link def webfinger_account_link

View file

@ -19,7 +19,7 @@ module Api::Pagination
links = [] links = []
links << [next_path, [%w(rel next)]] if next_path links << [next_path, [%w(rel next)]] if next_path
links << [prev_path, [%w(rel prev)]] if prev_path links << [prev_path, [%w(rel prev)]] if prev_path
response.headers['Link'] = LinkHeader.new(links) unless links.empty? response.headers['Link'] = LinkHeader.new(links).to_s unless links.empty?
end end
def require_valid_pagination_options! def require_valid_pagination_options!

View file

@ -7,16 +7,11 @@ class Disputes::BaseController < ApplicationController
skip_before_action :require_functional! skip_before_action :require_functional!
before_action :set_body_classes
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_cache_headers before_action :set_cache_headers
private private
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -6,7 +6,6 @@ class Filters::StatusesController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_filter before_action :set_filter
before_action :set_status_filters before_action :set_status_filters
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
PER_PAGE = 20 PER_PAGE = 20
@ -42,10 +41,6 @@ class Filters::StatusesController < ApplicationController
'remove' if params[:remove] 'remove' if params[:remove]
end end
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -5,7 +5,6 @@ class FiltersController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_filter, only: [:edit, :update, :destroy] before_action :set_filter, only: [:edit, :update, :destroy]
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
def index def index
@ -52,10 +51,6 @@ class FiltersController < ApplicationController
params.require(:custom_filter).permit(:title, :expires_in, :filter_action, context: [], keywords_attributes: [:id, :keyword, :whole_word, :_destroy]) params.require(:custom_filter).permit(:title, :expires_in, :filter_action, context: [], keywords_attributes: [:id, :keyword, :whole_word, :_destroy])
end end
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -6,7 +6,6 @@ class InvitesController < ApplicationController
layout 'admin' layout 'admin'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
def index def index
@ -47,10 +46,6 @@ class InvitesController < ApplicationController
params.require(:invite).permit(:max_uses, :expires_in, :autofollow, :comment) params.require(:invite).permit(:max_uses, :expires_in, :autofollow, :comment)
end end
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -19,9 +19,7 @@ class MediaController < ApplicationController
redirect_to @media_attachment.file.url(:original) redirect_to @media_attachment.file.url(:original)
end end
def player def player; end
@body_classes = 'player'
end
private private

View file

@ -6,7 +6,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
before_action :store_current_location before_action :store_current_location
before_action :authenticate_resource_owner! before_action :authenticate_resource_owner!
before_action :require_not_suspended!, only: :destroy before_action :require_not_suspended!, only: :destroy
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
before_action :set_last_used_at_by_app, only: :index, unless: -> { request.format == :json } before_action :set_last_used_at_by_app, only: :index, unless: -> { request.format == :json }
@ -23,10 +22,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
private private
def set_body_classes
@body_classes = 'admin'
end
def store_current_location def store_current_location
store_location_for(:user, request.url) store_location_for(:user, request.url)
end end

View file

@ -6,7 +6,6 @@ class RelationshipsController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_accounts, only: :show before_action :set_accounts, only: :show
before_action :set_relationships, only: :show before_action :set_relationships, only: :show
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship? helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship?
@ -68,10 +67,6 @@ class RelationshipsController < ApplicationController
end end
end end
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -4,15 +4,10 @@ class Settings::BaseController < ApplicationController
layout 'admin' layout 'admin'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
private private
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -4,7 +4,6 @@ class SeveredRelationshipsController < ApplicationController
layout 'admin' layout 'admin'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
before_action :set_event, only: [:following, :followers] before_action :set_event, only: [:following, :followers]
@ -51,10 +50,6 @@ class SeveredRelationshipsController < ApplicationController
account.local? ? account.local_username_and_domain : account.acct account.local? ? account.local_username_and_domain : account.acct
end end
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -4,13 +4,6 @@ class SharesController < ApplicationController
layout 'modal' layout 'modal'
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_body_classes
def show; end def show; end
private
def set_body_classes
@body_classes = 'modal-layout compose-standalone'
end
end end

View file

@ -5,7 +5,6 @@ class StatusesCleanupController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!
before_action :set_policy before_action :set_policy
before_action :set_body_classes
before_action :set_cache_headers before_action :set_cache_headers
def show; end def show; end
@ -34,10 +33,6 @@ class StatusesCleanupController < ApplicationController
params.require(:account_statuses_cleanup_policy).permit(:enabled, :min_status_age, :keep_direct, :keep_pinned, :keep_polls, :keep_media, :keep_self_fav, :keep_self_bookmark, :min_favs, :min_reblogs) params.require(:account_statuses_cleanup_policy).permit(:enabled, :min_status_age, :keep_direct, :keep_pinned, :keep_polls, :keep_media, :keep_self_fav, :keep_self_bookmark, :min_favs, :min_reblogs)
end end
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers def set_cache_headers
response.cache_control.replace(private: true, no_store: true) response.cache_control.replace(private: true, no_store: true)
end end

View file

@ -56,7 +56,9 @@ class StatusesController < ApplicationController
end end
def set_link_headers def set_link_headers
response.headers['Link'] = LinkHeader.new([[ActivityPub::TagManager.instance.uri_for(@status), [%w(rel alternate), %w(type application/activity+json)]]]) response.headers['Link'] = LinkHeader.new(
[[ActivityPub::TagManager.instance.uri_for(@status), [%w(rel alternate), %w(type application/activity+json)]]]
).to_s
end end
def set_status def set_status

View file

@ -159,6 +159,7 @@ module ApplicationHelper
def body_classes def body_classes
output = body_class_string.split output = body_class_string.split
output << content_for(:body_classes)
output << "flavour-#{current_flavour.parameterize}" output << "flavour-#{current_flavour.parameterize}"
output << "skin-#{current_skin.parameterize}" output << "skin-#{current_skin.parameterize}"
output << 'system-font' if current_account&.user&.setting_system_font_ui output << 'system-font' if current_account&.user&.setting_system_font_ui

View file

@ -1,6 +1,6 @@
{ {
"about.blocks": "Moderoidut palvelimet", "about.blocks": "Moderoidut palvelimet",
"about.contact": "Yhteydenotto:", "about.contact": "Yhteystiedot:",
"about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.", "about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.",
"about.domain_blocks.no_reason_available": "Syy ei ole tiedossa", "about.domain_blocks.no_reason_available": "Syy ei ole tiedossa",
"about.domain_blocks.preamble": "Mastodonin avulla voi yleensä tarkastella minkä tahansa fediversumiin kuuluvan palvelimen sisältöä ja olla yhteyksissä eri palvelinten käyttäjien kanssa. Nämä poikkeukset koskevat yksin tätä palvelinta.", "about.domain_blocks.preamble": "Mastodonin avulla voi yleensä tarkastella minkä tahansa fediversumiin kuuluvan palvelimen sisältöä ja olla yhteyksissä eri palvelinten käyttäjien kanssa. Nämä poikkeukset koskevat yksin tätä palvelinta.",
@ -304,7 +304,7 @@
"filter_modal.select_filter.title": "Suodata tämä julkaisu", "filter_modal.select_filter.title": "Suodata tämä julkaisu",
"filter_modal.title.status": "Suodata julkaisu", "filter_modal.title.status": "Suodata julkaisu",
"filter_warning.matches_filter": "Vastaa suodatinta ”{title}”", "filter_warning.matches_filter": "Vastaa suodatinta ”{title}”",
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {Ei keneltäkään, jonka} one {1 käyttäjältä, jonka} other {# käyttäjältä, jotka}} saatat tuntea", "filtered_notifications_banner.pending_requests": "{count, plural, =0 {Ei keneltäkään, jonka} one {Yhdeltä käyttäjältä, jonka} other {# käyttäjältä, jotka}} saatat tuntea",
"filtered_notifications_banner.title": "Suodatetut ilmoitukset", "filtered_notifications_banner.title": "Suodatetut ilmoitukset",
"firehose.all": "Kaikki", "firehose.all": "Kaikki",
"firehose.local": "Tämä palvelin", "firehose.local": "Tämä palvelin",
@ -370,7 +370,7 @@
"home.show_announcements": "Näytä tiedotteet", "home.show_announcements": "Näytä tiedotteet",
"ignore_notifications_modal.disclaimer": "Mastodon ei voi ilmoittaa käyttäjille, että olet sivuuttanut heidän ilmoituksensa. Ilmoitusten sivuuttaminen ei lopeta itse viestien lähetystä.", "ignore_notifications_modal.disclaimer": "Mastodon ei voi ilmoittaa käyttäjille, että olet sivuuttanut heidän ilmoituksensa. Ilmoitusten sivuuttaminen ei lopeta itse viestien lähetystä.",
"ignore_notifications_modal.filter_instead": "Suodata sen sijaan", "ignore_notifications_modal.filter_instead": "Suodata sen sijaan",
"ignore_notifications_modal.filter_to_act_users": "Voit silti hyväksyä, hylätä tai raportoida käyttäjiä", "ignore_notifications_modal.filter_to_act_users": "Voit kuitenkin yhä hyväksyä, hylätä tai raportoida käyttäjiä",
"ignore_notifications_modal.filter_to_avoid_confusion": "Suodatus auttaa välttämään mahdollisia sekaannuksia", "ignore_notifications_modal.filter_to_avoid_confusion": "Suodatus auttaa välttämään mahdollisia sekaannuksia",
"ignore_notifications_modal.filter_to_review_separately": "Voit käydä suodatettuja ilmoituksia läpi erikseen", "ignore_notifications_modal.filter_to_review_separately": "Voit käydä suodatettuja ilmoituksia läpi erikseen",
"ignore_notifications_modal.ignore": "Sivuuta ilmoitukset", "ignore_notifications_modal.ignore": "Sivuuta ilmoitukset",

View file

@ -97,6 +97,8 @@
"block_modal.title": "An bhfuil fonn ort an t-úsáideoir a bhlocáil?", "block_modal.title": "An bhfuil fonn ort an t-úsáideoir a bhlocáil?",
"block_modal.you_wont_see_mentions": "Ní fheicfidh tú postálacha a luann iad.", "block_modal.you_wont_see_mentions": "Ní fheicfidh tú postálacha a luann iad.",
"boost_modal.combo": "Is féidir leat {combo} a bhrú chun é seo a scipeáil an chéad uair eile", "boost_modal.combo": "Is féidir leat {combo} a bhrú chun é seo a scipeáil an chéad uair eile",
"boost_modal.reblog": "An post a threisiú?",
"boost_modal.undo_reblog": "An deireadh a chur le postáil?",
"bundle_column_error.copy_stacktrace": "Cóipeáil tuairisc earráide", "bundle_column_error.copy_stacktrace": "Cóipeáil tuairisc earráide",
"bundle_column_error.error.body": "Ní féidir an leathanach a iarradh a sholáthar. Seans gurb amhlaidh mar gheall ar fhabht sa chód, nó mar gheall ar mhíréireacht leis an mbrabhsálaí.", "bundle_column_error.error.body": "Ní féidir an leathanach a iarradh a sholáthar. Seans gurb amhlaidh mar gheall ar fhabht sa chód, nó mar gheall ar mhíréireacht leis an mbrabhsálaí.",
"bundle_column_error.error.title": "Ó, níl sé sin go maith!", "bundle_column_error.error.title": "Ó, níl sé sin go maith!",
@ -467,6 +469,7 @@
"mute_modal.you_wont_see_mentions": "Ní fheicfidh tú postálacha a luann iad.", "mute_modal.you_wont_see_mentions": "Ní fheicfidh tú postálacha a luann iad.",
"mute_modal.you_wont_see_posts": "Is féidir leo do phoist a fheiceáil go fóill, ach ní fheicfidh tú a gcuid postanna.", "mute_modal.you_wont_see_posts": "Is féidir leo do phoist a fheiceáil go fóill, ach ní fheicfidh tú a gcuid postanna.",
"navigation_bar.about": "Maidir le", "navigation_bar.about": "Maidir le",
"navigation_bar.administration": "Riarachán",
"navigation_bar.advanced_interface": "Oscail i gcomhéadan gréasáin chun cinn", "navigation_bar.advanced_interface": "Oscail i gcomhéadan gréasáin chun cinn",
"navigation_bar.blocks": "Cuntais bhactha", "navigation_bar.blocks": "Cuntais bhactha",
"navigation_bar.bookmarks": "Leabharmharcanna", "navigation_bar.bookmarks": "Leabharmharcanna",
@ -483,6 +486,7 @@
"navigation_bar.follows_and_followers": "Ag leanúint agus do do leanúint", "navigation_bar.follows_and_followers": "Ag leanúint agus do do leanúint",
"navigation_bar.lists": "Liostaí", "navigation_bar.lists": "Liostaí",
"navigation_bar.logout": "Logáil Amach", "navigation_bar.logout": "Logáil Amach",
"navigation_bar.moderation": "Measarthacht",
"navigation_bar.mutes": "Úsáideoirí balbhaithe", "navigation_bar.mutes": "Úsáideoirí balbhaithe",
"navigation_bar.opened_in_classic_interface": "Osclaítear poist, cuntais agus leathanaigh shonracha eile de réir réamhshocraithe sa chomhéadan gréasáin clasaiceach.", "navigation_bar.opened_in_classic_interface": "Osclaítear poist, cuntais agus leathanaigh shonracha eile de réir réamhshocraithe sa chomhéadan gréasáin clasaiceach.",
"navigation_bar.personal": "Pearsanta", "navigation_bar.personal": "Pearsanta",

View file

@ -48,7 +48,7 @@
"account.moved_to": "У {name} теперь новый аккаунт:", "account.moved_to": "У {name} теперь новый аккаунт:",
"account.mute": "Игнорировать @{name}", "account.mute": "Игнорировать @{name}",
"account.mute_notifications_short": "Отключить уведомления", "account.mute_notifications_short": "Отключить уведомления",
"account.mute_short": "Немой", "account.mute_short": "Глохни!",
"account.muted": "Игнорируется", "account.muted": "Игнорируется",
"account.mutual": "Взаимно", "account.mutual": "Взаимно",
"account.no_bio": "Описание не предоставлено.", "account.no_bio": "Описание не предоставлено.",

View file

@ -75,6 +75,8 @@ class Account < ApplicationRecord
DISPLAY_NAME_LENGTH_LIMIT = (ENV['MAX_DISPLAY_NAME_CHARS'] || 30).to_i DISPLAY_NAME_LENGTH_LIMIT = (ENV['MAX_DISPLAY_NAME_CHARS'] || 30).to_i
NOTE_LENGTH_LIMIT = (ENV['MAX_BIO_CHARS'] || 500).to_i NOTE_LENGTH_LIMIT = (ENV['MAX_BIO_CHARS'] || 500).to_i
AUTOMATED_ACTOR_TYPES = %w(Application Service).freeze
include Attachmentable # Load prior to Avatar & Header concerns include Attachmentable # Load prior to Avatar & Header concerns
include Account::Associations include Account::Associations
@ -127,7 +129,8 @@ class Account < ApplicationRecord
scope :without_silenced, -> { where(silenced_at: nil) } scope :without_silenced, -> { where(silenced_at: nil) }
scope :without_instance_actor, -> { where.not(id: INSTANCE_ACTOR_ID) } scope :without_instance_actor, -> { where.not(id: INSTANCE_ACTOR_ID) }
scope :recent, -> { reorder(id: :desc) } scope :recent, -> { reorder(id: :desc) }
scope :bots, -> { where(actor_type: %w(Application Service)) } scope :bots, -> { where(actor_type: AUTOMATED_ACTOR_TYPES) }
scope :non_automated, -> { where.not(actor_type: AUTOMATED_ACTOR_TYPES) }
scope :groups, -> { where(actor_type: 'Group') } scope :groups, -> { where(actor_type: 'Group') }
scope :alphabetic, -> { order(domain: :asc, username: :asc) } scope :alphabetic, -> { order(domain: :asc, username: :asc) }
scope :matches_uri_prefix, ->(value) { where(arel_table[:uri].matches("#{sanitize_sql_like(value)}/%", false, true)).or(where(uri: value)) } scope :matches_uri_prefix, ->(value) { where(arel_table[:uri].matches("#{sanitize_sql_like(value)}/%", false, true)).or(where(uri: value)) }
@ -183,7 +186,7 @@ class Account < ApplicationRecord
end end
def bot? def bot?
%w(Application Service).include? actor_type AUTOMATED_ACTOR_TYPES.include?(actor_type)
end end
def instance_actor? def instance_actor?

View file

@ -18,7 +18,7 @@ class AccountModerationNote < ApplicationRecord
belongs_to :account belongs_to :account
belongs_to :target_account, class_name: 'Account' belongs_to :target_account, class_name: 'Account'
scope :latest, -> { reorder('created_at DESC') } scope :chronological, -> { reorder(id: :asc) }
validates :content, presence: true, length: { maximum: CONTENT_SIZE_LIMIT } validates :content, presence: true, length: { maximum: CONTENT_SIZE_LIMIT }
end end

View file

@ -73,6 +73,14 @@ class Admin::AccountAction
end end
end end
def disabled_types_for_account(account)
if account.suspended?
%w(silence suspend)
elsif account.silenced?
%w(silence)
end
end
def i18n_scope def i18n_scope
:activerecord :activerecord
end end

View file

@ -18,7 +18,7 @@ class ReportNote < ApplicationRecord
belongs_to :account belongs_to :account
belongs_to :report, inverse_of: :notes, touch: true belongs_to :report, inverse_of: :notes, touch: true
scope :latest, -> { reorder(created_at: :desc) } scope :chronological, -> { reorder(id: :asc) }
validates :content, presence: true, length: { maximum: CONTENT_SIZE_LIMIT } validates :content, presence: true, length: { maximum: CONTENT_SIZE_LIMIT }
end end

View file

@ -1,6 +1,13 @@
- content_for :page_title do - content_for :page_title do
= t('admin.account_actions.title', acct: @account.pretty_acct) = t('admin.account_actions.title', acct: @account.pretty_acct)
- if @account.suspended?
.flash-message.alert
= t('admin.account_actions.already_suspended')
- elsif @account.silenced?
.flash-message.warn
= t('admin.account_actions.already_silenced')
= simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f| = simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f|
= f.input :report_id, = f.input :report_id,
as: :hidden as: :hidden
@ -9,6 +16,7 @@
= f.input :type, = f.input :type,
as: :radio_buttons, as: :radio_buttons,
collection: Admin::AccountAction.types_for_account(@account), collection: Admin::AccountAction.types_for_account(@account),
disabled: Admin::AccountAction.disabled_types_for_account(@account),
hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.pretty_acct), hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.pretty_acct),
include_blank: false, include_blank: false,
label_method: ->(type) { account_action_type_label(type) }, label_method: ->(type) { account_action_type_label(type) },

View file

@ -56,19 +56,19 @@
.dashboard__item .dashboard__item
= link_to admin_reports_path, class: 'dashboard__quick-access' do = link_to admin_reports_path, class: 'dashboard__quick-access' do
%span= t('admin.dashboard.pending_reports_html', count: @pending_reports_count) %span= t('admin.dashboard.pending_reports_html', count: @pending_reports_count.value)
= material_symbol 'chevron_right' = material_symbol 'chevron_right'
= link_to admin_accounts_path(status: 'pending'), class: 'dashboard__quick-access' do = link_to admin_accounts_path(status: 'pending'), class: 'dashboard__quick-access' do
%span= t('admin.dashboard.pending_users_html', count: @pending_users_count) %span= t('admin.dashboard.pending_users_html', count: @pending_users_count.value)
= material_symbol 'chevron_right' = material_symbol 'chevron_right'
= link_to admin_trends_tags_path(status: 'pending_review'), class: 'dashboard__quick-access' do = link_to admin_trends_tags_path(status: 'pending_review'), class: 'dashboard__quick-access' do
%span= t('admin.dashboard.pending_tags_html', count: @pending_tags_count) %span= t('admin.dashboard.pending_tags_html', count: @pending_tags_count.value)
= material_symbol 'chevron_right' = material_symbol 'chevron_right'
= link_to admin_disputes_appeals_path(status: 'pending'), class: 'dashboard__quick-access' do = link_to admin_disputes_appeals_path(status: 'pending'), class: 'dashboard__quick-access' do
%span= t('admin.dashboard.pending_appeals_html', count: @pending_appeals_count) %span= t('admin.dashboard.pending_appeals_html', count: @pending_appeals_count.value)
= material_symbol 'chevron_right' = material_symbol 'chevron_right'
.dashboard__item .dashboard__item
= react_admin_component :dimension, = react_admin_component :dimension,

View file

@ -17,21 +17,27 @@
.report-actions__item__button .report-actions__item__button
= form.button t('admin.reports.delete_and_resolve'), = form.button t('admin.reports.delete_and_resolve'),
name: :delete, name: :delete,
class: 'button button--destructive' class: 'button button--destructive',
disabled: statuses.empty?,
title: statuses.empty? ? t('admin.reports.actions_no_posts') : ''
.report-actions__item__description .report-actions__item__description
= t('admin.reports.actions.delete_description_html') = t('admin.reports.actions.delete_description_html')
.report-actions__item .report-actions__item
.report-actions__item__button .report-actions__item__button
= form.button t('admin.accounts.silence'), = form.button t('admin.accounts.silence'),
name: :silence, name: :silence,
class: 'button button--destructive' class: 'button button--destructive',
disabled: report.target_account.silenced? || report.target_account.suspended?,
title: report.target_account.silenced? ? t('admin.account_actions.already_silenced') : ''
.report-actions__item__description .report-actions__item__description
= t('admin.reports.actions.silence_description_html') = t('admin.reports.actions.silence_description_html')
.report-actions__item .report-actions__item
.report-actions__item__button .report-actions__item__button
= form.button t('admin.accounts.suspend'), = form.button t('admin.accounts.suspend'),
name: :suspend, name: :suspend,
class: 'button button--destructive' class: 'button button--destructive',
disabled: report.target_account.suspended?,
title: report.target_account.suspended? ? t('admin.account_actions.already_suspended') : ''
.report-actions__item__description .report-actions__item__description
= t('admin.reports.actions.suspend_description_html') = t('admin.reports.actions.suspend_description_html')
.report-actions__item .report-actions__item

View file

@ -7,7 +7,8 @@
collection: UserRole.assignable, collection: UserRole.assignable,
include_blank: I18n.t('admin.accounts.change_role.no_role'), include_blank: I18n.t('admin.accounts.change_role.no_role'),
label_method: :name, label_method: :name,
wrapper: :with_block_label wrapper: :with_block_label,
hint: safe_join([I18n.t('simple_form.hints.user.role'), ' ', link_to(I18n.t('admin.accounts.change_role.edit_roles'), admin_roles_path)])
.actions .actions
= f.button :button, = f.button :button,

View file

@ -3,6 +3,8 @@
= flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous' = flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous'
= flavoured_javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous' = flavoured_javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :body_classes, 'admin'
- content_for :content do - content_for :content do
.admin-wrapper .admin-wrapper
.sidebar-wrapper .sidebar-wrapper

View file

@ -1,6 +1,8 @@
- content_for :header_tags do - content_for :header_tags do
= flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous' = flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous'
- content_for :body_classes, 'modal-layout compose-standalone'
- content_for :content do - content_for :content do
- if user_signed_in? && !@hide_header - if user_signed_in? && !@hide_header
.account-header .account-header

View file

@ -2,6 +2,8 @@
= render_initial_state = render_initial_state
= flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous' = flavoured_javascript_pack_tag 'public', crossorigin: 'anonymous'
- content_for :body_classes, 'player'
:ruby :ruby
meta = @media_attachment.file.meta || {} meta = @media_attachment.file.meta || {}

View file

@ -38,8 +38,4 @@ Rails.application.configure do
config.active_record.encryption.key_derivation_salt = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT') config.active_record.encryption.key_derivation_salt = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT')
config.active_record.encryption.primary_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY') config.active_record.encryption.primary_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY')
config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
# TODO: https://github.com/rails/rails/issues/50604#issuecomment-1880990392
# Remove after updating to Rails 7.1.4
ActiveRecord::Encryption.configure(**config.active_record.encryption)
end end

View file

@ -25,6 +25,8 @@ en:
admin: admin:
account_actions: account_actions:
action: Perform action action: Perform action
already_silenced: This account has already been silenced.
already_suspended: This account has already been suspended.
title: Perform moderation action on %{acct} title: Perform moderation action on %{acct}
account_moderation_notes: account_moderation_notes:
create: Leave note create: Leave note
@ -46,6 +48,7 @@ en:
title: Change email for %{username} title: Change email for %{username}
change_role: change_role:
changed_msg: Role successfully changed! changed_msg: Role successfully changed!
edit_roles: Manage user roles
label: Change role label: Change role
no_role: No role no_role: No role
title: Change role for %{username} title: Change role for %{username}
@ -602,6 +605,7 @@ en:
suspend_description_html: The account and all its contents will be inaccessible and eventually deleted, and interacting with it will be impossible. Reversible within 30 days. Closes all reports against this account. suspend_description_html: The account and all its contents will be inaccessible and eventually deleted, and interacting with it will be impossible. Reversible within 30 days. Closes all reports against this account.
actions_description_html: Decide which action to take to resolve this report. If you take a punitive action against the reported account, an email notification will be sent to them, except when the <strong>Spam</strong> category is selected. actions_description_html: Decide which action to take to resolve this report. If you take a punitive action against the reported account, an email notification will be sent to them, except when the <strong>Spam</strong> category is selected.
actions_description_remote_html: Decide which action to take to resolve this report. This will only affect how <strong>your</strong> server communicates with this remote account and handle its content. actions_description_remote_html: Decide which action to take to resolve this report. This will only affect how <strong>your</strong> server communicates with this remote account and handle its content.
actions_no_posts: This report doesn't have any associated posts to delete
add_to_report: Add more to report add_to_report: Add more to report
already_suspended_badges: already_suspended_badges:
local: Already suspended on this server local: Already suspended on this server

View file

@ -442,9 +442,9 @@ fi:
create: Lisää verkkotunnus create: Lisää verkkotunnus
resolve: Selvitä verkkotunnus resolve: Selvitä verkkotunnus
title: Estä uusi sähköpostiverkkotunnus title: Estä uusi sähköpostiverkkotunnus
no_email_domain_block_selected: Sähköpostin verkkotunnuksia ei muutettu, koska yhtään ei ollut valittuna no_email_domain_block_selected: Sähköpostiverkkotunnusten estoja ei muutettu; yhtäkään ei ollut valittu
not_permitted: Ei sallittu not_permitted: Ei sallittu
resolved_dns_records_hint_html: Verkkotunnuksen nimi määräytyy seuraaviin MX-verkkotunnuksiin, jotka ovat viime kädessä vastuussa sähköpostin vastaanottamisesta. MX-verkkotunnuksen estäminen estää rekisteröitymisen mistä tahansa sähköpostiosoitteesta, joka käyttää samaa MX-verkkotunnusta, vaikka näkyvä verkkotunnuksen nimi olisikin erilainen. <strong>Varo estämästä suuria sähköpostin palveluntarjoajia.</strong> resolved_dns_records_hint_html: Verkkotunnusnimi kytkeytyy seuraaviin MX-verkkotunnuksiin, jotka ovat viime kädessä vastuussa sähköpostin vastaanottamisesta. MX-verkkotunnuksen estäminen estää rekisteröitymisen mistä tahansa sähköpostiosoitteesta, joka käyttää samaa MX-verkkotunnusta, vaikka näkyvä verkkotunnuksen nimi olisikin erilainen. <strong>Varo estämästä suuria sähköpostipalvelujen tarjoajia.</strong>
resolved_through_html: Ratkaistu verkkotunnuksen %{domain} kautta resolved_through_html: Ratkaistu verkkotunnuksen %{domain} kautta
title: Estetyt sähköpostiverkkotunnukset title: Estetyt sähköpostiverkkotunnukset
export_domain_allows: export_domain_allows:
@ -600,7 +600,7 @@ fi:
resolve_description_html: Ilmoitettua tiliä kohtaan ei ryhdytä toimiin, varoitusta ei kirjata ja raportti suljetaan. resolve_description_html: Ilmoitettua tiliä kohtaan ei ryhdytä toimiin, varoitusta ei kirjata ja raportti suljetaan.
silence_description_html: Tili näkyy vain niille, jotka jo seuraavat sitä tai etsivät sen manuaalisesti, mikä rajoittaa merkittävästi sen tavoitettavuutta. Voidaan perua milloin vain. Sulkee kaikki tiliin kohdistuvat raportit. silence_description_html: Tili näkyy vain niille, jotka jo seuraavat sitä tai etsivät sen manuaalisesti, mikä rajoittaa merkittävästi sen tavoitettavuutta. Voidaan perua milloin vain. Sulkee kaikki tiliin kohdistuvat raportit.
suspend_description_html: Tili ja mikään sen sisältö eivät ole käytettävissä, ja lopulta ne poistetaan ja vuorovaikutus tilin kanssa on mahdotonta. Peruttavissa 30 päivän ajan. Sulkee kaikki tiliin kohdistuvat raportit. suspend_description_html: Tili ja mikään sen sisältö eivät ole käytettävissä, ja lopulta ne poistetaan ja vuorovaikutus tilin kanssa on mahdotonta. Peruttavissa 30 päivän ajan. Sulkee kaikki tiliin kohdistuvat raportit.
actions_description_html: Päätä, mihin toimiin ryhdyt tämän raportin ratkaisemiseksi. Jos ryhdyt rangaistustoimeen ilmoitettua tiliä kohtaan, hänelle lähetetään sähköposti-ilmoitus, paitsi jos <strong>Roskaposti</strong>-luokka on valittuna. actions_description_html: Päätä, mihin toimiin ryhdyt tämän raportin ratkaisemiseksi. Jos ryhdyt rangaistustoimeen ilmoitettua tiliä kohtaan, hänelle lähetetään sähköpostitse ilmoitus asiasta, paitsi jos valittuna on <strong>Roskaposti</strong>-luokka.
actions_description_remote_html: Päätä, mihin toimiin ryhdyt tämän raportin ratkaisemiseksi. Tämä vaikuttaa vain siihen, miten <strong>sinun</strong> palvelimesi viestii tämän etätilin kanssa ja käsittelee sen sisältöä. actions_description_remote_html: Päätä, mihin toimiin ryhdyt tämän raportin ratkaisemiseksi. Tämä vaikuttaa vain siihen, miten <strong>sinun</strong> palvelimesi viestii tämän etätilin kanssa ja käsittelee sen sisältöä.
add_to_report: Lisää raporttiin add_to_report: Lisää raporttiin
already_suspended_badges: already_suspended_badges:
@ -977,7 +977,7 @@ fi:
used_by_over_week: used_by_over_week:
one: Käyttänyt yksi käyttäjä viimeisen viikon aikana one: Käyttänyt yksi käyttäjä viimeisen viikon aikana
other: Käyttänyt %{count} käyttäjää viimeisen viikon aikana other: Käyttänyt %{count} käyttäjää viimeisen viikon aikana
title: Suositukset ja trendit title: Suositukset ja suuntaukset
trending: Trendaus trending: Trendaus
warning_presets: warning_presets:
add_new: Lisää uusi add_new: Lisää uusi
@ -1135,7 +1135,7 @@ fi:
security: Turvallisuus security: Turvallisuus
set_new_password: Aseta uusi salasana set_new_password: Aseta uusi salasana
setup: setup:
email_below_hint_html: Tarkista roskapostikansiosi tai pyydä uusi viesti. Voit korjata sähköpostiosoitteesi, jos se oli väärin. email_below_hint_html: Tarkista roskapostikansiosi tai pyydä uusi viesti. Voit myös korjata sähköpostiosoitteesi tarvittaessa.
email_settings_hint_html: Napsauta lähettämäämme linkkiä vahvistaaksesi osoitteen %{email}. Odotamme täällä. email_settings_hint_html: Napsauta lähettämäämme linkkiä vahvistaaksesi osoitteen %{email}. Odotamme täällä.
link_not_received: Etkö saanut linkkiä? link_not_received: Etkö saanut linkkiä?
new_confirmation_instructions_sent: Saat pian uuden vahvistuslinkin sisältävän sähköpostiviestin! new_confirmation_instructions_sent: Saat pian uuden vahvistuslinkin sisältävän sähköpostiviestin!
@ -1195,8 +1195,8 @@ fi:
caches: Muiden palvelinten välimuistiinsa tallentamaa sisältöä voi säilyä caches: Muiden palvelinten välimuistiinsa tallentamaa sisältöä voi säilyä
data_removal: Julkaisusi ja muut tietosi poistetaan pysyvästi data_removal: Julkaisusi ja muut tietosi poistetaan pysyvästi
email_change_html: Voit <a href="%{path}">muuttaa sähköpostiosoitettasi</a> poistamatta tiliäsi email_change_html: Voit <a href="%{path}">muuttaa sähköpostiosoitettasi</a> poistamatta tiliäsi
email_contact_html: Jos ei saavu perille, voit pyytää apua sähköpostilla <a href="mailto:%{email}">%{email}</a> email_contact_html: Mikäli viesti ei vieläkään saavu perille, voit pyytää apua sähköpostitse osoitteella <a href="mailto:%{email}">%{email}</a>
email_reconfirmation_html: Jos et saa vahvistuksen sähköpostia, niin voit <a href="%{path}">pyytää sitä uudelleen</a> email_reconfirmation_html: Jos et saa vahvistussähköpostiviestiä, voit <a href="%{path}">pyytää sitä uudelleen</a>
irreversible: Et voi palauttaa tiliäsi etkä aktivoida sitä uudelleen irreversible: Et voi palauttaa tiliäsi etkä aktivoida sitä uudelleen
more_details_html: Tarkempia tietoja saat <a href="%{terms_path}">tietosuojakäytännöstämme</a>. more_details_html: Tarkempia tietoja saat <a href="%{terms_path}">tietosuojakäytännöstämme</a>.
username_available: Käyttäjänimesi tulee saataville uudelleen username_available: Käyttäjänimesi tulee saataville uudelleen

View file

@ -132,6 +132,7 @@ fr-CA:
resubscribe: Se réabonner resubscribe: Se réabonner
role: Rôle role: Rôle
search: Rechercher search: Rechercher
search_same_email_domain: Autres utilisateurs avec le même domaine de courriel
search_same_ip: Autres utilisateur·rice·s avec la même IP search_same_ip: Autres utilisateur·rice·s avec la même IP
security: Sécurité security: Sécurité
security_measures: security_measures:
@ -1428,6 +1429,7 @@ fr-CA:
media_attachments: media_attachments:
validations: validations:
images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images
not_found: Média %{ids} introuvable ou déjà attaché à un autre message
not_ready: Impossible de joindre les fichiers en cours de traitement. Réessayez dans un instant ! not_ready: Impossible de joindre les fichiers en cours de traitement. Réessayez dans un instant !
too_many: Impossible de joindre plus de 4 fichiers too_many: Impossible de joindre plus de 4 fichiers
migrations: migrations:

View file

@ -132,6 +132,7 @@ fr:
resubscribe: Se réabonner resubscribe: Se réabonner
role: Rôle role: Rôle
search: Rechercher search: Rechercher
search_same_email_domain: Autres utilisateurs avec le même domaine de courriel
search_same_ip: Autres utilisateur·rice·s avec la même IP search_same_ip: Autres utilisateur·rice·s avec la même IP
security: Sécurité security: Sécurité
security_measures: security_measures:
@ -1428,6 +1429,7 @@ fr:
media_attachments: media_attachments:
validations: validations:
images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images
not_found: Média %{ids} introuvable ou déjà attaché à un autre message
not_ready: Impossible de joindre les fichiers en cours de traitement. Réessayez dans un instant ! not_ready: Impossible de joindre les fichiers en cours de traitement. Réessayez dans un instant !
too_many: Impossible de joindre plus de 4 fichiers too_many: Impossible de joindre plus de 4 fichiers
migrations: migrations:

View file

@ -1454,6 +1454,7 @@ fy:
media_attachments: media_attachments:
validations: validations:
images_and_video: In fideo kin net oan in berjocht mei ôfbyldingen keppele wurde images_and_video: In fideo kin net oan in berjocht mei ôfbyldingen keppele wurde
not_found: Media %{ids} net fûn of al tafoege oan in oar berjocht
not_ready: Kin gjin bestannen tafoegje dyt noch net ferwurke binne. Probearje it letter opnij! not_ready: Kin gjin bestannen tafoegje dyt noch net ferwurke binne. Probearje it letter opnij!
too_many: Der kinne net mear as 4 ôfbyldingen tafoege wurde too_many: Der kinne net mear as 4 ôfbyldingen tafoege wurde
migrations: migrations:

View file

@ -1532,6 +1532,7 @@ ga:
media_attachments: media_attachments:
validations: validations:
images_and_video: Ní féidir físeán a cheangal le postáil a bhfuil íomhánna ann cheana féin images_and_video: Ní féidir físeán a cheangal le postáil a bhfuil íomhánna ann cheana féin
not_found: Meán %{ids} gan aimsiú nó ceangailte le postáil eile cheana
not_ready: Ní féidir comhaid nach bhfuil próiseáil críochnaithe acu a cheangal. Bain triail eile as i gceann nóiméad! not_ready: Ní féidir comhaid nach bhfuil próiseáil críochnaithe acu a cheangal. Bain triail eile as i gceann nóiméad!
too_many: Ní féidir níos mó ná 4 chomhad a cheangal too_many: Ní féidir níos mó ná 4 chomhad a cheangal
migrations: migrations:

View file

@ -1506,6 +1506,7 @@ gd:
media_attachments: media_attachments:
validations: validations:
images_and_video: Chan urrainn dhut video a cheangal ri post sa bheil dealbh mu thràth images_and_video: Chan urrainn dhut video a cheangal ri post sa bheil dealbh mu thràth
not_found: Cha deach na meadhanan %{ids} a lorg no chaidh an ceangal ri post eile mu thràth
not_ready: Chan urrainn dhuinn faidhlichean a cheangal ris nach eil air am pròiseasadh fhathast. Feuch ris a-rithist an ceann greis! not_ready: Chan urrainn dhuinn faidhlichean a cheangal ris nach eil air am pròiseasadh fhathast. Feuch ris a-rithist an ceann greis!
too_many: Chan urrainn dhut barrachd air 4 faidhlichean a ceangal ris too_many: Chan urrainn dhut barrachd air 4 faidhlichean a ceangal ris
migrations: migrations:

View file

@ -203,7 +203,7 @@ pt-BR:
disable_sign_in_token_auth_user: Desativar autenticação via Token de Email para Usuário disable_sign_in_token_auth_user: Desativar autenticação via Token de Email para Usuário
disable_user: Desativar usuário disable_user: Desativar usuário
enable_custom_emoji: Ativar emoji personalizado enable_custom_emoji: Ativar emoji personalizado
enable_sign_in_token_auth_user: Desativar autenticação via token por e-mail para o usuário enable_sign_in_token_auth_user: Ativar autenticação via Token de Email para Usuário
enable_user: Ativar usuário enable_user: Ativar usuário
memorialize_account: Converter conta em memorial memorialize_account: Converter conta em memorial
promote_user: Promover usuário promote_user: Promover usuário
@ -442,6 +442,7 @@ pt-BR:
create: Adicionar domínio create: Adicionar domínio
resolve: Resolver domínio resolve: Resolver domínio
title: Bloquear novo domínio de e-mail title: Bloquear novo domínio de e-mail
no_email_domain_block_selected: Nenhum bloco de domínio de email foi alterado, pois, nenhum foi selecionado
not_permitted: Não permitido not_permitted: Não permitido
resolved_dns_records_hint_html: O nome de domínio é associado aos seguintes domínios MX, que são responsáveis por aceitar e-mails. Ao bloquear um domínio MX, você bloqueará as inscrições de qualquer endereço de e-mail que use o mesmo domínio MX, mesmo que o nome de domínio visível seja diferente. <strong>Tenha cuidado para não bloquear os principais provedores de e-mail.</strong> resolved_dns_records_hint_html: O nome de domínio é associado aos seguintes domínios MX, que são responsáveis por aceitar e-mails. Ao bloquear um domínio MX, você bloqueará as inscrições de qualquer endereço de e-mail que use o mesmo domínio MX, mesmo que o nome de domínio visível seja diferente. <strong>Tenha cuidado para não bloquear os principais provedores de e-mail.</strong>
resolved_through_html: Resolvido através de %{domain} resolved_through_html: Resolvido através de %{domain}
@ -1440,6 +1441,13 @@ pt-BR:
action: Sim, cancelar subscrição action: Sim, cancelar subscrição
complete: Desinscrito complete: Desinscrito
confirmation_html: Tem certeza que deseja cancelar a assinatura de %{type} para Mastodon no %{domain} para o seu endereço de e-mail %{email}? Você sempre pode se inscrever novamente nas <a href="%{settings_path}">configurações de notificação de email</a>. confirmation_html: Tem certeza que deseja cancelar a assinatura de %{type} para Mastodon no %{domain} para o seu endereço de e-mail %{email}? Você sempre pode se inscrever novamente nas <a href="%{settings_path}">configurações de notificação de email</a>.
emails:
notification_emails:
favourite: emails de notificação favoritos
follow: seguir emails de notificação
follow_request: emails de seguidores pendentes
mention: emails de notificação de menções
reblog: emails de notificação de boosts
resubscribe_html: Se você cancelou sua inscrição por engano, você pode se inscrever novamente em suas <a href="%{settings_path}"> configurações de notificações por e-mail</a>. resubscribe_html: Se você cancelou sua inscrição por engano, você pode se inscrever novamente em suas <a href="%{settings_path}"> configurações de notificações por e-mail</a>.
success_html: Você não mais receberá %{type} no Mastodon em %{domain} ao seu endereço de e-mail %{email}. success_html: Você não mais receberá %{type} no Mastodon em %{domain} ao seu endereço de e-mail %{email}.
title: Cancelar inscrição title: Cancelar inscrição

View file

@ -130,7 +130,7 @@ en:
name: You can only change the casing of the letters, for example, to make it more readable name: You can only change the casing of the letters, for example, to make it more readable
user: user:
chosen_languages: When checked, only posts in selected languages will be displayed in public timelines chosen_languages: When checked, only posts in selected languages will be displayed in public timelines
role: The role controls which permissions the user has role: The role controls which permissions the user has.
user_role: user_role:
color: Color to be used for the role throughout the UI, as RGB in hex format color: Color to be used for the role throughout the UI, as RGB in hex format
highlighted: This makes the role publicly visible highlighted: This makes the role publicly visible

View file

@ -81,6 +81,7 @@ fr-CA:
bootstrap_timeline_accounts: Ces comptes seront épinglés en tête de liste des recommandations pour les nouveaux utilisateurs. bootstrap_timeline_accounts: Ces comptes seront épinglés en tête de liste des recommandations pour les nouveaux utilisateurs.
closed_registrations_message: Affiché lorsque les inscriptions sont fermées closed_registrations_message: Affiché lorsque les inscriptions sont fermées
custom_css: Vous pouvez appliquer des styles personnalisés sur la version Web de Mastodon. custom_css: Vous pouvez appliquer des styles personnalisés sur la version Web de Mastodon.
favicon: WEBP, PNG, GIF ou JPG. Remplace la favicon Mastodon par défaut avec une icône personnalisée.
mascot: Remplace l'illustration dans l'interface Web avancée. mascot: Remplace l'illustration dans l'interface Web avancée.
media_cache_retention_period: Les fichiers médias des messages publiés par des utilisateurs distants sont mis en cache sur votre serveur. Lorsque cette valeur est positive, les médias sont supprimés au terme du nombre de jours spécifié. Si les données des médias sont demandées après leur suppression, elles seront téléchargées à nouveau, dans la mesure où le contenu source est toujours disponible. En raison des restrictions concernant la fréquence à laquelle les cartes de prévisualisation des liens interrogent des sites tiers, il est recommandé de fixer cette valeur à au moins 14 jours, faute de quoi les cartes de prévisualisation des liens ne seront pas mises à jour à la demande avant cette échéance. media_cache_retention_period: Les fichiers médias des messages publiés par des utilisateurs distants sont mis en cache sur votre serveur. Lorsque cette valeur est positive, les médias sont supprimés au terme du nombre de jours spécifié. Si les données des médias sont demandées après leur suppression, elles seront téléchargées à nouveau, dans la mesure où le contenu source est toujours disponible. En raison des restrictions concernant la fréquence à laquelle les cartes de prévisualisation des liens interrogent des sites tiers, il est recommandé de fixer cette valeur à au moins 14 jours, faute de quoi les cartes de prévisualisation des liens ne seront pas mises à jour à la demande avant cette échéance.
peers_api_enabled: Une liste de noms de domaine que ce serveur a rencontrés dans le fédiverse. Aucune donnée indiquant si vous vous fédérez ou non avec un serveur particulier n'est incluse ici, seulement l'information que votre serveur connaît un autre serveur. Cette option est utilisée par les services qui collectent des statistiques sur la fédération en général. peers_api_enabled: Une liste de noms de domaine que ce serveur a rencontrés dans le fédiverse. Aucune donnée indiquant si vous vous fédérez ou non avec un serveur particulier n'est incluse ici, seulement l'information que votre serveur connaît un autre serveur. Cette option est utilisée par les services qui collectent des statistiques sur la fédération en général.

View file

@ -81,6 +81,7 @@ fr:
bootstrap_timeline_accounts: Ces comptes seront épinglés en tête de liste des recommandations pour les nouveaux utilisateurs. bootstrap_timeline_accounts: Ces comptes seront épinglés en tête de liste des recommandations pour les nouveaux utilisateurs.
closed_registrations_message: Affiché lorsque les inscriptions sont fermées closed_registrations_message: Affiché lorsque les inscriptions sont fermées
custom_css: Vous pouvez appliquer des styles personnalisés sur la version Web de Mastodon. custom_css: Vous pouvez appliquer des styles personnalisés sur la version Web de Mastodon.
favicon: WEBP, PNG, GIF ou JPG. Remplace la favicon Mastodon par défaut avec une icône personnalisée.
mascot: Remplace l'illustration dans l'interface Web avancée. mascot: Remplace l'illustration dans l'interface Web avancée.
media_cache_retention_period: Les fichiers médias des messages publiés par des utilisateurs distants sont mis en cache sur votre serveur. Lorsque cette valeur est positive, les médias sont supprimés au terme du nombre de jours spécifié. Si les données des médias sont demandées après leur suppression, elles seront téléchargées à nouveau, dans la mesure où le contenu source est toujours disponible. En raison des restrictions concernant la fréquence à laquelle les cartes de prévisualisation des liens interrogent des sites tiers, il est recommandé de fixer cette valeur à au moins 14 jours, faute de quoi les cartes de prévisualisation des liens ne seront pas mises à jour à la demande avant cette échéance. media_cache_retention_period: Les fichiers médias des messages publiés par des utilisateurs distants sont mis en cache sur votre serveur. Lorsque cette valeur est positive, les médias sont supprimés au terme du nombre de jours spécifié. Si les données des médias sont demandées après leur suppression, elles seront téléchargées à nouveau, dans la mesure où le contenu source est toujours disponible. En raison des restrictions concernant la fréquence à laquelle les cartes de prévisualisation des liens interrogent des sites tiers, il est recommandé de fixer cette valeur à au moins 14 jours, faute de quoi les cartes de prévisualisation des liens ne seront pas mises à jour à la demande avant cette échéance.
peers_api_enabled: Une liste de noms de domaine que ce serveur a rencontrés dans le fédiverse. Aucune donnée indiquant si vous vous fédérez ou non avec un serveur particulier n'est incluse ici, seulement l'information que votre serveur connaît un autre serveur. Cette option est utilisée par les services qui collectent des statistiques sur la fédération en général. peers_api_enabled: Une liste de noms de domaine que ce serveur a rencontrés dans le fédiverse. Aucune donnée indiquant si vous vous fédérez ou non avec un serveur particulier n'est incluse ici, seulement l'information que votre serveur connaît un autre serveur. Cette option est utilisée par les services qui collectent des statistiques sur la fédération en général.

View file

@ -1428,6 +1428,7 @@ zh-CN:
media_attachments: media_attachments:
validations: validations:
images_and_video: 无法在嘟文中同时插入视频和图片 images_and_video: 无法在嘟文中同时插入视频和图片
not_found: 未发现媒体%{ids} 或已附在另一条嘟文中
not_ready: 不能附加还在处理中的文件。请稍后再试! not_ready: 不能附加还在处理中的文件。请稍后再试!
too_many: 最多只能添加 4 张图片 too_many: 最多只能添加 4 张图片
migrations: migrations:

View file

@ -502,7 +502,7 @@ module Mastodon::CLI
- not muted/blocked by us - not muted/blocked by us
LONG_DESC LONG_DESC
def prune def prune
query = Account.remote.where.not(actor_type: %i(Application Service)) query = Account.remote.non_automated
query = query.where('NOT EXISTS (SELECT 1 FROM mentions WHERE account_id = accounts.id)') query = query.where('NOT EXISTS (SELECT 1 FROM mentions WHERE account_id = accounts.id)')
query = query.where('NOT EXISTS (SELECT 1 FROM favourites WHERE account_id = accounts.id)') query = query.where('NOT EXISTS (SELECT 1 FROM favourites WHERE account_id = accounts.id)')
query = query.where('NOT EXISTS (SELECT 1 FROM statuses WHERE account_id = accounts.id)') query = query.where('NOT EXISTS (SELECT 1 FROM statuses WHERE account_id = accounts.id)')

View file

@ -31,7 +31,7 @@ RSpec.describe ActivityPub::CollectionsController do
.and have_cacheable_headers .and have_cacheable_headers
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(body_as_json[:orderedItems]) expect(response.parsed_body[:orderedItems])
.to be_an(Array) .to be_an(Array)
.and have_attributes(size: 3) .and have_attributes(size: 3)
.and include(ActivityPub::TagManager.instance.uri_for(private_pinned)) .and include(ActivityPub::TagManager.instance.uri_for(private_pinned))
@ -71,7 +71,7 @@ RSpec.describe ActivityPub::CollectionsController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(body_as_json[:orderedItems]) expect(response.parsed_body[:orderedItems])
.to be_an(Array) .to be_an(Array)
.and have_attributes(size: 3) .and have_attributes(size: 3)
.and include(ActivityPub::TagManager.instance.uri_for(private_pinned)) .and include(ActivityPub::TagManager.instance.uri_for(private_pinned))
@ -94,7 +94,7 @@ RSpec.describe ActivityPub::CollectionsController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Cache-Control']).to include 'private' expect(response.headers['Cache-Control']).to include 'private'
expect(body_as_json[:orderedItems]) expect(response.parsed_body[:orderedItems])
.to be_an(Array) .to be_an(Array)
.and be_empty .and be_empty
end end
@ -110,7 +110,7 @@ RSpec.describe ActivityPub::CollectionsController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Cache-Control']).to include 'private' expect(response.headers['Cache-Control']).to include 'private'
expect(body_as_json[:orderedItems]) expect(response.parsed_body[:orderedItems])
.to be_an(Array) .to be_an(Array)
.and be_empty .and be_empty
end end

View file

@ -34,7 +34,6 @@ RSpec.describe ActivityPub::FollowersSynchronizationsController do
context 'with signature from example.com' do context 'with signature from example.com' do
subject(:response) { get :show, params: { account_username: account.username } } subject(:response) { get :show, params: { account_username: account.username } }
let(:body) { body_as_json }
let(:remote_account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/instance') } let(:remote_account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/instance') }
it 'returns http success and cache control and activity json types and correct items' do it 'returns http success and cache control and activity json types and correct items' do
@ -42,7 +41,7 @@ RSpec.describe ActivityPub::FollowersSynchronizationsController do
expect(response.headers['Cache-Control']).to eq 'max-age=0, private' expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(body[:orderedItems]) expect(response.parsed_body[:orderedItems])
.to be_an(Array) .to be_an(Array)
.and contain_exactly( .and contain_exactly(
follower_example_com_instance_actor.uri, follower_example_com_instance_actor.uri,

View file

@ -19,7 +19,6 @@ RSpec.describe ActivityPub::OutboxesController do
context 'without signature' do context 'without signature' do
subject(:response) { get :show, params: { account_username: account.username, page: page } } subject(:response) { get :show, params: { account_username: account.username, page: page } }
let(:body) { body_as_json }
let(:remote_account) { nil } let(:remote_account) { nil }
context 'with page not requested' do context 'with page not requested' do
@ -32,7 +31,7 @@ RSpec.describe ActivityPub::OutboxesController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Vary']).to be_nil expect(response.headers['Vary']).to be_nil
expect(body[:totalItems]).to eq 4 expect(response.parsed_body[:totalItems]).to eq 4
end end
context 'when account is permanently suspended' do context 'when account is permanently suspended' do
@ -68,9 +67,11 @@ RSpec.describe ActivityPub::OutboxesController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Vary']).to include 'Signature' expect(response.headers['Vary']).to include 'Signature'
expect(body[:orderedItems]).to be_an Array expect(response.parsed_body)
expect(body[:orderedItems].size).to eq 2 .to include(
expect(body[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true orderedItems: be_an(Array).and(have_attributes(size: 2))
)
expect(response.parsed_body[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true
end end
context 'when account is permanently suspended' do context 'when account is permanently suspended' do
@ -110,9 +111,11 @@ RSpec.describe ActivityPub::OutboxesController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Cache-Control']).to eq 'max-age=60, private' expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
expect(body_as_json[:orderedItems]).to be_an Array expect(response.parsed_body)
expect(body_as_json[:orderedItems].size).to eq 2 .to include(
expect(body_as_json[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true orderedItems: be_an(Array).and(have_attributes(size: 2))
)
expect(response.parsed_body[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true
end end
end end
@ -127,9 +130,11 @@ RSpec.describe ActivityPub::OutboxesController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Cache-Control']).to eq 'max-age=60, private' expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
expect(body_as_json[:orderedItems]).to be_an Array expect(response.parsed_body)
expect(body_as_json[:orderedItems].size).to eq 3 .to include(
expect(body_as_json[:orderedItems].all? { |item| targets_public_collection?(item) || targets_followers_collection?(item, account) }).to be true orderedItems: be_an(Array).and(have_attributes(size: 3))
)
expect(response.parsed_body[:orderedItems].all? { |item| targets_public_collection?(item) || targets_followers_collection?(item, account) }).to be true
end end
end end
@ -144,9 +149,10 @@ RSpec.describe ActivityPub::OutboxesController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Cache-Control']).to eq 'max-age=60, private' expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
expect(body_as_json[:orderedItems]) expect(response.parsed_body)
.to be_an(Array) .to include(
.and be_empty orderedItems: be_an(Array).and(be_empty)
)
end end
end end
@ -161,9 +167,10 @@ RSpec.describe ActivityPub::OutboxesController do
expect(response.media_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
expect(response.headers['Cache-Control']).to eq 'max-age=60, private' expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
expect(body_as_json[:orderedItems]) expect(response.parsed_body)
.to be_an(Array) .to include(
.and be_empty orderedItems: be_an(Array).and(be_empty)
)
end end
end end
end end

View file

@ -66,7 +66,7 @@ RSpec.describe ActivityPub::RepliesController do
context 'when status is public' do context 'when status is public' do
let(:parent_visibility) { :public } let(:parent_visibility) { :public }
let(:page_json) { body_as_json[:first] } let(:page_json) { response.parsed_body[:first] }
it 'returns http success and correct media type' do it 'returns http success and correct media type' do
expect(response) expect(response)

View file

@ -55,6 +55,23 @@ RSpec.describe Admin::AccountsController do
describe 'GET #show' do describe 'GET #show' do
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
describe 'account moderation notes' do
let(:account) { Fabricate(:account) }
it 'includes moderation notes' do
note1 = Fabricate(:account_moderation_note, target_account: account)
note2 = Fabricate(:account_moderation_note, target_account: account)
get :show, params: { id: account.id }
expect(response).to have_http_status(200)
moderation_notes = assigns(:moderation_notes).to_a
expect(moderation_notes.size).to be 2
expect(moderation_notes).to eq [note1, note2]
end
end
context 'with a remote account' do context 'with a remote account' do
let(:account) { Fabricate(:account, domain: 'example.com') } let(:account) { Fabricate(:account, domain: 'example.com') }

View file

@ -47,6 +47,24 @@ RSpec.describe Admin::ReportsController do
expect(response.body) expect(response.body)
.to include(report.comment) .to include(report.comment)
end end
describe 'account moderation notes' do
let(:report) { Fabricate(:report) }
it 'includes moderation notes' do
note1 = Fabricate(:report_note, report: report)
note2 = Fabricate(:report_note, report: report)
get :show, params: { id: report }
expect(response).to have_http_status(200)
report_notes = assigns(:report_notes).to_a
expect(report_notes.size).to be 2
expect(report_notes).to eq [note1, note2]
end
end
end end
describe 'POST #resolve' do describe 'POST #resolve' do

View file

@ -402,7 +402,7 @@ RSpec.describe Auth::SessionsController do
end end
it 'instructs the browser to redirect to home, logs the user in, and updates the sign count' do it 'instructs the browser to redirect to home, logs the user in, and updates the sign count' do
expect(body_as_json[:redirect_path]).to eq(root_path) expect(response.parsed_body[:redirect_path]).to eq(root_path)
expect(controller.current_user).to eq user expect(controller.current_user).to eq user

View file

@ -54,17 +54,12 @@ RSpec.describe AccountControllerConcern do
it 'Prepares the account, returns success, and sets link headers' do it 'Prepares the account, returns success, and sets link headers' do
get 'success', params: { account_username: account.username } get 'success', params: { account_username: account.username }
expect(response).to have_http_status(200) expect(response)
expect(response.headers['Link'].to_s).to eq(expected_link_headers) .to have_http_status(200)
.and have_http_link_header('http://test.host/.well-known/webfinger?resource=acct%3Ausername%40cb6e6126.ngrok.io').for(rel: 'lrdd', type: 'application/jrd+json')
.and have_http_link_header('https://cb6e6126.ngrok.io/users/username').for(rel: 'alternate', type: 'application/activity+json')
expect(response.body) expect(response.body)
.to include(account.username) .to include(account.username)
end end
def expected_link_headers
[
'<http://test.host/.well-known/webfinger?resource=acct%3Ausername%40cb6e6126.ngrok.io>; rel="lrdd"; type="application/jrd+json"',
'<https://cb6e6126.ngrok.io/users/username>; rel="alternate"; type="application/activity+json"',
].join(', ')
end
end end
end end

View file

@ -39,8 +39,6 @@ RSpec.describe FollowerAccountsController do
end end
context 'when format is json' do context 'when format is json' do
subject(:body) { response.parsed_body }
let(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } let(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } }
context 'with page' do context 'with page' do
@ -48,15 +46,15 @@ RSpec.describe FollowerAccountsController do
it 'returns followers' do it 'returns followers' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
orderedItems: contain_exactly( orderedItems: contain_exactly(
include(follow_from_bob.account.username), include(follow_from_bob.account.username),
include(follow_from_chris.account.username) include(follow_from_chris.account.username)
) ),
totalItems: eq(2),
partOf: be_present
) )
expect(body['totalItems']).to eq 2
expect(body['partOf']).to be_present
end end
context 'when account is permanently suspended' do context 'when account is permanently suspended' do
@ -86,8 +84,11 @@ RSpec.describe FollowerAccountsController do
it 'returns followers' do it 'returns followers' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body['totalItems']).to eq 2 expect(response.parsed_body)
expect(body['partOf']).to be_blank .to include(
totalItems: eq(2)
)
.and not_include(:partOf)
end end
context 'when account hides their network' do context 'when account hides their network' do
@ -95,15 +96,17 @@ RSpec.describe FollowerAccountsController do
alice.update(hide_collections: true) alice.update(hide_collections: true)
end end
it 'returns followers count' do it 'returns followers count but not any items' do
expect(body['totalItems']).to eq 2 expect(response.parsed_body)
end .to include(
totalItems: eq(2)
it 'does not return items' do )
expect(body['items']).to be_blank .and not_include(
expect(body['orderedItems']).to be_blank :items,
expect(body['first']).to be_blank :orderedItems,
expect(body['last']).to be_blank :first,
:last
)
end end
end end

View file

@ -39,8 +39,6 @@ RSpec.describe FollowingAccountsController do
end end
context 'when format is json' do context 'when format is json' do
subject(:body) { response.parsed_body }
let(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } let(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } }
context 'with page' do context 'with page' do
@ -48,15 +46,15 @@ RSpec.describe FollowingAccountsController do
it 'returns followers' do it 'returns followers' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
orderedItems: contain_exactly( orderedItems: contain_exactly(
include(follow_of_bob.target_account.username), include(follow_of_bob.target_account.username),
include(follow_of_chris.target_account.username) include(follow_of_chris.target_account.username)
) ),
totalItems: eq(2),
partOf: be_present
) )
expect(body['totalItems']).to eq 2
expect(body['partOf']).to be_present
end end
context 'when account is permanently suspended' do context 'when account is permanently suspended' do
@ -86,8 +84,11 @@ RSpec.describe FollowingAccountsController do
it 'returns followers' do it 'returns followers' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body['totalItems']).to eq 2 expect(response.parsed_body)
expect(body['partOf']).to be_blank .to include(
totalItems: eq(2)
)
.and not_include(:partOf)
end end
context 'when account hides their network' do context 'when account hides their network' do
@ -95,15 +96,17 @@ RSpec.describe FollowingAccountsController do
alice.update(hide_collections: true) alice.update(hide_collections: true)
end end
it 'returns followers count' do it 'returns followers count but not any items' do
expect(body['totalItems']).to eq 2 expect(response.parsed_body)
end .to include(
totalItems: eq(2)
it 'does not return items' do )
expect(body['items']).to be_blank .and not_include(
expect(body['orderedItems']).to be_blank :items,
expect(body['first']).to be_blank :orderedItems,
expect(body['last']).to be_blank :first,
:last
)
end end
end end

View file

@ -81,7 +81,7 @@ RSpec.describe StatusesController do
'Content-Type' => include('application/activity+json'), 'Content-Type' => include('application/activity+json'),
'Link' => satisfy { |header| header.to_s.include?('activity+json') } 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
) )
expect(body_as_json) expect(response.parsed_body)
.to include(content: include(status.text)) .to include(content: include(status.text))
end end
end end
@ -186,7 +186,7 @@ RSpec.describe StatusesController do
'Content-Type' => include('application/activity+json'), 'Content-Type' => include('application/activity+json'),
'Link' => satisfy { |header| header.to_s.include?('activity+json') } 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
) )
expect(body_as_json) expect(response.parsed_body)
.to include(content: include(status.text)) .to include(content: include(status.text))
end end
end end
@ -230,7 +230,7 @@ RSpec.describe StatusesController do
'Content-Type' => include('application/activity+json'), 'Content-Type' => include('application/activity+json'),
'Link' => satisfy { |header| header.to_s.include?('activity+json') } 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
) )
expect(body_as_json) expect(response.parsed_body)
.to include(content: include(status.text)) .to include(content: include(status.text))
end end
end end
@ -296,7 +296,7 @@ RSpec.describe StatusesController do
'Content-Type' => include('application/activity+json'), 'Content-Type' => include('application/activity+json'),
'Link' => satisfy { |header| header.to_s.include?('activity+json') } 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
) )
expect(body_as_json) expect(response.parsed_body)
.to include(content: include(status.text)) .to include(content: include(status.text))
end end
end end
@ -387,7 +387,7 @@ RSpec.describe StatusesController do
'Content-Type' => include('application/activity+json'), 'Content-Type' => include('application/activity+json'),
'Link' => satisfy { |header| header.to_s.include?('activity+json') } 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
) )
expect(body_as_json) expect(response.parsed_body)
.to include(content: include(status.text)) .to include(content: include(status.text))
end end
end end
@ -431,7 +431,7 @@ RSpec.describe StatusesController do
'Link' => satisfy { |header| header.to_s.include?('activity+json') } 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
) )
expect(body_as_json) expect(response.parsed_body)
.to include(content: include(status.text)) .to include(content: include(status.text))
end end
end end
@ -497,7 +497,7 @@ RSpec.describe StatusesController do
'Content-Type' => include('application/activity+json'), 'Content-Type' => include('application/activity+json'),
'Link' => satisfy { |header| header.to_s.include?('activity+json') } 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
) )
expect(body_as_json) expect(response.parsed_body)
.to include(content: include(status.text)) .to include(content: include(status.text))
end end
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
Fabricator(:account_moderation_note) do Fabricator(:account_moderation_note) do
content 'MyText' content { Faker::Lorem.sentences }
account { Fabricate.build(:account) } account { Fabricate.build(:account) }
target_account { Fabricate.build(:account) } target_account { Fabricate.build(:account) }
end end

View file

@ -3,5 +3,5 @@
Fabricator(:report_note) do Fabricator(:report_note) do
report { Fabricate.build(:report) } report { Fabricate.build(:report) }
account { Fabricate.build(:account) } account { Fabricate.build(:account) }
content 'Test Content' content { Faker::Lorem.sentences }
end end

View file

@ -8,7 +8,17 @@ RSpec.describe ApplicationHelper do
before { helper.extend controller_helpers } before { helper.extend controller_helpers }
it 'uses the controller body classes in the result' do it 'uses the controller body classes in the result' do
expect(helper.body_classes).to match(/modal-layout compose-standalone/) expect(helper.body_classes)
.to match(/modal-layout compose-standalone/)
.and match(/flavour-glitch/)
.and match(/skin-default/)
end
it 'includes values set via content_for' do
helper.content_for(:body_classes) { 'admin' }
expect(helper.body_classes)
.to match(/admin/)
end end
private private

View file

@ -0,0 +1,31 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe AccountModerationNote do
describe 'chronological scope' do
it 'returns account moderation notes oldest to newest' do
account = Fabricate(:account)
note1 = Fabricate(:account_moderation_note, target_account: account)
note2 = Fabricate(:account_moderation_note, target_account: account)
expect(account.targeted_moderation_notes.chronological).to eq [note1, note2]
end
end
describe 'validations' do
it 'is invalid if the content is empty' do
report = Fabricate.build(:account_moderation_note, content: '')
expect(report.valid?).to be false
end
it 'is invalid if content is longer than character limit' do
report = Fabricate.build(:account_moderation_note, content: comment_over_limit)
expect(report.valid?).to be false
end
def comment_over_limit
Faker::Lorem.paragraph_by_chars(number: described_class::CONTENT_SIZE_LIMIT * 2)
end
end
end

View file

@ -0,0 +1,31 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ReportNote do
describe 'chronological scope' do
it 'returns report notes oldest to newest' do
report = Fabricate(:report)
note1 = Fabricate(:report_note, report: report)
note2 = Fabricate(:report_note, report: report)
expect(report.notes.chronological).to eq [note1, note2]
end
end
describe 'validations' do
it 'is invalid if the content is empty' do
report = Fabricate.build(:report_note, content: '')
expect(report.valid?).to be false
end
it 'is invalid if content is longer than character limit' do
report = Fabricate.build(:report_note, content: comment_over_limit)
expect(report.valid?).to be false
end
def comment_over_limit
Faker::Lorem.paragraph_by_chars(number: described_class::CONTENT_SIZE_LIMIT * 2)
end
end
end

View file

@ -69,8 +69,7 @@ RSpec.describe 'Accounts show response' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
.and render_template(:show) .and render_template(:show)
.and have_http_link_header(ActivityPub::TagManager.instance.uri_for(account)).for(rel: 'alternate')
expect(response.headers['Link'].to_s).to include ActivityPub::TagManager.instance.uri_for(account)
end end
end end
@ -135,7 +134,7 @@ RSpec.describe 'Accounts show response' do
media_type: eq('application/activity+json') media_type: eq('application/activity+json')
) )
expect(body_as_json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) expect(response.parsed_body).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
end end
context 'with authorized fetch mode' do context 'with authorized fetch mode' do
@ -164,7 +163,7 @@ RSpec.describe 'Accounts show response' do
expect(response.headers['Cache-Control']).to include 'private' expect(response.headers['Cache-Control']).to include 'private'
expect(body_as_json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) expect(response.parsed_body).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
end end
end end
@ -183,7 +182,7 @@ RSpec.describe 'Accounts show response' do
media_type: eq('application/activity+json') media_type: eq('application/activity+json')
) )
expect(body_as_json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) expect(response.parsed_body).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
end end
context 'with authorized fetch mode' do context 'with authorized fetch mode' do
@ -199,7 +198,7 @@ RSpec.describe 'Accounts show response' do
expect(response.headers['Cache-Control']).to include 'private' expect(response.headers['Cache-Control']).to include 'private'
expect(response.headers['Vary']).to include 'Signature' expect(response.headers['Vary']).to include 'Signature'
expect(body_as_json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) expect(response.parsed_body).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary)
end end
end end
end end

View file

@ -20,7 +20,7 @@ RSpec.describe 'credentials API' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json).to include({ expect(response.parsed_body).to include({
source: hash_including({ source: hash_including({
discoverable: false, discoverable: false,
indexable: false, indexable: false,
@ -37,7 +37,7 @@ RSpec.describe 'credentials API' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to include({ expect(response.parsed_body).to include({
locked: true, locked: true,
}) })
end end
@ -93,7 +93,7 @@ RSpec.describe 'credentials API' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json).to include({ expect(response.parsed_body).to include({
source: hash_including({ source: hash_including({
discoverable: true, discoverable: true,
indexable: true, indexable: true,

View file

@ -24,7 +24,7 @@ RSpec.describe 'Accounts Familiar Followers API' do
account_ids = [account_a, account_b, account_b, account_a, account_a].map { |a| a.id.to_s } account_ids = [account_a, account_b, account_b, account_a, account_a].map { |a| a.id.to_s }
get '/api/v1/accounts/familiar_followers', params: { id: account_ids }, headers: headers get '/api/v1/accounts/familiar_followers', params: { id: account_ids }, headers: headers
expect(body_as_json.pluck(:id)).to contain_exactly(account_a.id.to_s, account_b.id.to_s) expect(response.parsed_body.pluck(:id)).to contain_exactly(account_a.id.to_s, account_b.id.to_s)
end end
end end
end end

View file

@ -23,7 +23,7 @@ RSpec.describe 'account featured tags API' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to contain_exactly(a_hash_including({ expect(response.parsed_body).to contain_exactly(a_hash_including({
name: 'bar', name: 'bar',
url: "https://cb6e6126.ngrok.io/@#{account.username}/tagged/bar", url: "https://cb6e6126.ngrok.io/@#{account.username}/tagged/bar",
}), a_hash_including({ }), a_hash_including({
@ -37,7 +37,7 @@ RSpec.describe 'account featured tags API' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to contain_exactly(a_hash_including({ expect(response.parsed_body).to contain_exactly(a_hash_including({
name: 'bar', name: 'bar',
url: "https://cb6e6126.ngrok.io/@#{account.pretty_acct}/tagged/bar", url: "https://cb6e6126.ngrok.io/@#{account.pretty_acct}/tagged/bar",
}), a_hash_including({ }), a_hash_including({

View file

@ -21,8 +21,8 @@ RSpec.describe 'API V1 Accounts FollowerAccounts' do
get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq 2 expect(response.parsed_body.size).to eq 2
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) expect([response.parsed_body[0][:id], response.parsed_body[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
end end
it 'does not return blocked users', :aggregate_failures do it 'does not return blocked users', :aggregate_failures do
@ -30,8 +30,8 @@ RSpec.describe 'API V1 Accounts FollowerAccounts' do
get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq 1 expect(response.parsed_body.size).to eq 1
expect(body_as_json[0][:id]).to eq alice.id.to_s expect(response.parsed_body[0][:id]).to eq alice.id.to_s
end end
context 'when requesting user is blocked' do context 'when requesting user is blocked' do
@ -41,7 +41,7 @@ RSpec.describe 'API V1 Accounts FollowerAccounts' do
it 'hides results' do it 'hides results' do
get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers
expect(body_as_json.size).to eq 0 expect(response.parsed_body.size).to eq 0
end end
end end
@ -52,8 +52,8 @@ RSpec.describe 'API V1 Accounts FollowerAccounts' do
account.mute!(bob) account.mute!(bob)
get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers
expect(body_as_json.size).to eq 2 expect(response.parsed_body.size).to eq 2
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) expect([response.parsed_body[0][:id], response.parsed_body[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
end end
end end
end end

View file

@ -21,8 +21,8 @@ RSpec.describe 'API V1 Accounts FollowingAccounts' do
get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq 2 expect(response.parsed_body.size).to eq 2
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) expect([response.parsed_body[0][:id], response.parsed_body[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
end end
it 'does not return blocked users', :aggregate_failures do it 'does not return blocked users', :aggregate_failures do
@ -30,8 +30,8 @@ RSpec.describe 'API V1 Accounts FollowingAccounts' do
get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq 1 expect(response.parsed_body.size).to eq 1
expect(body_as_json[0][:id]).to eq alice.id.to_s expect(response.parsed_body[0][:id]).to eq alice.id.to_s
end end
context 'when requesting user is blocked' do context 'when requesting user is blocked' do
@ -41,7 +41,7 @@ RSpec.describe 'API V1 Accounts FollowingAccounts' do
it 'hides results' do it 'hides results' do
get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers
expect(body_as_json.size).to eq 0 expect(response.parsed_body.size).to eq 0
end end
end end
@ -52,8 +52,8 @@ RSpec.describe 'API V1 Accounts FollowingAccounts' do
account.mute!(bob) account.mute!(bob)
get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers
expect(body_as_json.size).to eq 2 expect(response.parsed_body.size).to eq 2
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) expect([response.parsed_body[0][:id], response.parsed_body[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
end end
end end
end end

View file

@ -29,7 +29,7 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Enumerable) .to be_an(Enumerable)
.and contain_exactly( .and contain_exactly(
include( include(
@ -50,7 +50,7 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Enumerable) .to be_an(Enumerable)
.and have_attributes( .and have_attributes(
size: 2 size: 2
@ -70,7 +70,7 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Enumerable) .to be_an(Enumerable)
.and have_attributes( .and have_attributes(
size: 3 size: 3
@ -89,7 +89,7 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
it 'removes duplicate account IDs from params' do it 'removes duplicate account IDs from params' do
subject subject
expect(body_as_json) expect(response.parsed_body)
.to be_an(Enumerable) .to be_an(Enumerable)
.and have_attributes( .and have_attributes(
size: 2 size: 2
@ -141,7 +141,7 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
it 'returns JSON with correct data on previously cached requests' do it 'returns JSON with correct data on previously cached requests' do
# Initial request including multiple accounts in params # Initial request including multiple accounts in params
get '/api/v1/accounts/relationships', headers: headers, params: { id: [simon.id, lewis.id] } get '/api/v1/accounts/relationships', headers: headers, params: { id: [simon.id, lewis.id] }
expect(body_as_json) expect(response.parsed_body)
.to have_attributes(size: 2) .to have_attributes(size: 2)
# Subsequent request with different id, should override cache from first request # Subsequent request with different id, should override cache from first request
@ -150,7 +150,7 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Enumerable) .to be_an(Enumerable)
.and have_attributes( .and have_attributes(
size: 1 size: 1
@ -172,7 +172,7 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Enumerable) .to be_an(Enumerable)
.and contain_exactly( .and contain_exactly(
include( include(

View file

@ -41,7 +41,7 @@ RSpec.describe 'API V1 Accounts Statuses' do
it 'returns posts along with self replies', :aggregate_failures do it 'returns posts along with self replies', :aggregate_failures do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to have_attributes(size: 2) .to have_attributes(size: 2)
.and contain_exactly( .and contain_exactly(
include(id: status.id.to_s), include(id: status.id.to_s),
@ -102,7 +102,7 @@ RSpec.describe 'API V1 Accounts Statuses' do
it 'lists the public status only' do it 'lists the public status only' do
get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers
expect(body_as_json) expect(response.parsed_body)
.to contain_exactly( .to contain_exactly(
a_hash_including(id: status.id.to_s) a_hash_including(id: status.id.to_s)
) )
@ -117,7 +117,7 @@ RSpec.describe 'API V1 Accounts Statuses' do
it 'lists both the public and the private statuses' do it 'lists both the public and the private statuses' do
get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers
expect(body_as_json) expect(response.parsed_body)
.to contain_exactly( .to contain_exactly(
a_hash_including(id: status.id.to_s), a_hash_including(id: status.id.to_s),
a_hash_including(id: private_status.id.to_s) a_hash_including(id: private_status.id.to_s)

View file

@ -17,7 +17,7 @@ RSpec.describe '/api/v1/accounts' do
get '/api/v1/accounts', headers: headers, params: { id: [account.id, other_account.id, 123_123] } get '/api/v1/accounts', headers: headers, params: { id: [account.id, other_account.id, 123_123] }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to contain_exactly( expect(response.parsed_body).to contain_exactly(
hash_including(id: account.id.to_s), hash_including(id: account.id.to_s),
hash_including(id: other_account.id.to_s) hash_including(id: other_account.id.to_s)
) )
@ -32,7 +32,7 @@ RSpec.describe '/api/v1/accounts' do
get "/api/v1/accounts/#{account.id}" get "/api/v1/accounts/#{account.id}"
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:id]).to eq(account.id.to_s) expect(response.parsed_body[:id]).to eq(account.id.to_s)
end end
end end
@ -41,7 +41,7 @@ RSpec.describe '/api/v1/accounts' do
get '/api/v1/accounts/1' get '/api/v1/accounts/1'
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
expect(body_as_json[:error]).to eq('Record not found') expect(response.parsed_body[:error]).to eq('Record not found')
end end
end end
@ -57,7 +57,7 @@ RSpec.describe '/api/v1/accounts' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:id]).to eq(account.id.to_s) expect(response.parsed_body[:id]).to eq(account.id.to_s)
end end
it_behaves_like 'forbidden for wrong scope', 'write:statuses' it_behaves_like 'forbidden for wrong scope', 'write:statuses'
@ -80,7 +80,7 @@ RSpec.describe '/api/v1/accounts' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:access_token]).to_not be_blank expect(response.parsed_body[:access_token]).to_not be_blank
user = User.find_by(email: 'hello@world.tld') user = User.find_by(email: 'hello@world.tld')
expect(user).to_not be_nil expect(user).to_not be_nil
@ -114,7 +114,7 @@ RSpec.describe '/api/v1/accounts' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
following: true, following: true,
requested: false requested: false
@ -134,7 +134,7 @@ RSpec.describe '/api/v1/accounts' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
following: false, following: false,
requested: true requested: true
@ -157,7 +157,7 @@ RSpec.describe '/api/v1/accounts' do
it 'changes reblogs option' do it 'changes reblogs option' do
post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { reblogs: true } post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { reblogs: true }
expect(body_as_json).to include({ expect(response.parsed_body).to include({
following: true, following: true,
showing_reblogs: true, showing_reblogs: true,
notifying: false, notifying: false,
@ -167,7 +167,7 @@ RSpec.describe '/api/v1/accounts' do
it 'changes notify option' do it 'changes notify option' do
post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { notify: true } post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { notify: true }
expect(body_as_json).to include({ expect(response.parsed_body).to include({
following: true, following: true,
showing_reblogs: false, showing_reblogs: false,
notifying: true, notifying: true,
@ -177,7 +177,7 @@ RSpec.describe '/api/v1/accounts' do
it 'changes languages option' do it 'changes languages option' do
post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { languages: %w(en es) } post "/api/v1/accounts/#{other_account.id}/follow", headers: headers, params: { languages: %w(en es) }
expect(body_as_json).to include({ expect(response.parsed_body).to include({
following: true, following: true,
showing_reblogs: false, showing_reblogs: false,
notifying: false, notifying: false,

View file

@ -19,7 +19,7 @@ RSpec.describe 'Accounts' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.pluck(:id)).to match_array(expected_results.map { |a| a.id.to_s }) expect(response.parsed_body.pluck(:id)).to match_array(expected_results.map { |a| a.id.to_s })
end end
end end
@ -93,7 +93,7 @@ RSpec.describe 'Accounts' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
end end
@ -112,7 +112,7 @@ RSpec.describe 'Accounts' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including(id: account.id.to_s, username: account.username, email: account.user.email) a_hash_including(id: account.id.to_s, username: account.username, email: account.user.email)
) )
end end

View file

@ -30,7 +30,7 @@ RSpec.describe 'Canonical Email Blocks' do
it 'returns an empty list' do it 'returns an empty list' do
subject subject
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
@ -41,7 +41,7 @@ RSpec.describe 'Canonical Email Blocks' do
it 'returns the correct canonical email hashes' do it 'returns the correct canonical email hashes' do
subject subject
expect(body_as_json.pluck(:canonical_email_hash)).to match_array(expected_email_hashes) expect(response.parsed_body.pluck(:canonical_email_hash)).to match_array(expected_email_hashes)
end end
context 'with limit param' do context 'with limit param' do
@ -50,7 +50,7 @@ RSpec.describe 'Canonical Email Blocks' do
it 'returns only the requested number of canonical email blocks' do it 'returns only the requested number of canonical email blocks' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
@ -62,7 +62,7 @@ RSpec.describe 'Canonical Email Blocks' do
canonical_email_blocks_ids = canonical_email_blocks.pluck(:id).map(&:to_s) canonical_email_blocks_ids = canonical_email_blocks.pluck(:id).map(&:to_s)
expect(body_as_json.pluck(:id)).to match_array(canonical_email_blocks_ids[2..]) expect(response.parsed_body.pluck(:id)).to match_array(canonical_email_blocks_ids[2..])
end end
end end
@ -74,7 +74,7 @@ RSpec.describe 'Canonical Email Blocks' do
canonical_email_blocks_ids = canonical_email_blocks.pluck(:id).map(&:to_s) canonical_email_blocks_ids = canonical_email_blocks.pluck(:id).map(&:to_s)
expect(body_as_json.pluck(:id)).to match_array(canonical_email_blocks_ids[..2]) expect(response.parsed_body.pluck(:id)).to match_array(canonical_email_blocks_ids[..2])
end end
end end
end end
@ -96,7 +96,7 @@ RSpec.describe 'Canonical Email Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
id: eq(canonical_email_block.id.to_s), id: eq(canonical_email_block.id.to_s),
canonical_email_hash: eq(canonical_email_block.canonical_email_hash) canonical_email_hash: eq(canonical_email_block.canonical_email_hash)
@ -142,7 +142,7 @@ RSpec.describe 'Canonical Email Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[0][:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash) expect(response.parsed_body.first[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
end end
end end
@ -151,7 +151,7 @@ RSpec.describe 'Canonical Email Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
end end
@ -173,7 +173,7 @@ RSpec.describe 'Canonical Email Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash) expect(response.parsed_body[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
end end
context 'when the required email param is not provided' do context 'when the required email param is not provided' do
@ -193,7 +193,7 @@ RSpec.describe 'Canonical Email Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:canonical_email_hash]).to eq(params[:canonical_email_hash]) expect(response.parsed_body[:canonical_email_hash]).to eq(params[:canonical_email_hash])
end end
end end
@ -204,7 +204,7 @@ RSpec.describe 'Canonical Email Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash) expect(response.parsed_body[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
end end
end end

View file

@ -27,7 +27,7 @@ RSpec.describe 'Admin Dimensions' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Array) .to be_an(Array)
end end
end end

View file

@ -30,7 +30,7 @@ RSpec.describe 'Domain Allows' do
it 'returns an empty body' do it 'returns an empty body' do
subject subject
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
@ -49,7 +49,7 @@ RSpec.describe 'Domain Allows' do
it 'returns the correct allowed domains' do it 'returns the correct allowed domains' do
subject subject
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
context 'with limit param' do context 'with limit param' do
@ -58,7 +58,7 @@ RSpec.describe 'Domain Allows' do
it 'returns only the requested number of allowed domains' do it 'returns only the requested number of allowed domains' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
end end
@ -79,7 +79,7 @@ RSpec.describe 'Domain Allows' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:domain]).to eq domain_allow.domain expect(response.parsed_body[:domain]).to eq domain_allow.domain
end end
context 'when the requested allowed domain does not exist' do context 'when the requested allowed domain does not exist' do
@ -107,7 +107,7 @@ RSpec.describe 'Domain Allows' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:domain]).to eq 'foo.bar.com' expect(response.parsed_body[:domain]).to eq 'foo.bar.com'
expect(DomainAllow.find_by(domain: 'foo.bar.com')).to be_present expect(DomainAllow.find_by(domain: 'foo.bar.com')).to be_present
end end
end end
@ -140,7 +140,7 @@ RSpec.describe 'Domain Allows' do
it 'returns the existing allowed domain name' do it 'returns the existing allowed domain name' do
subject subject
expect(body_as_json[:domain]).to eq(params[:domain]) expect(response.parsed_body[:domain]).to eq(params[:domain])
end end
end end
end end

View file

@ -30,7 +30,7 @@ RSpec.describe 'Domain Blocks' do
it 'returns an empty list' do it 'returns an empty list' do
subject subject
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
@ -64,7 +64,7 @@ RSpec.describe 'Domain Blocks' do
it 'returns the expected domain blocks' do it 'returns the expected domain blocks' do
subject subject
expect(body_as_json).to match_array(expected_responde) expect(response.parsed_body).to match_array(expected_responde)
end end
context 'with limit param' do context 'with limit param' do
@ -73,7 +73,7 @@ RSpec.describe 'Domain Blocks' do
it 'returns only the requested number of domain blocks' do it 'returns only the requested number of domain blocks' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
end end
@ -94,19 +94,17 @@ RSpec.describe 'Domain Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match( expect(response.parsed_body).to match(
{ id: domain_block.id.to_s,
id: domain_block.id.to_s, domain: domain_block.domain,
domain: domain_block.domain, digest: domain_block.domain_digest,
digest: domain_block.domain_digest, created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'), severity: domain_block.severity.to_s,
severity: domain_block.severity.to_s, reject_media: domain_block.reject_media,
reject_media: domain_block.reject_media, reject_reports: domain_block.reject_reports,
reject_reports: domain_block.reject_reports, private_comment: domain_block.private_comment,
private_comment: domain_block.private_comment, public_comment: domain_block.public_comment,
public_comment: domain_block.public_comment, obfuscate: domain_block.obfuscate
obfuscate: domain_block.obfuscate,
}
) )
end end
@ -134,7 +132,7 @@ RSpec.describe 'Domain Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match a_hash_including( expect(response.parsed_body).to match a_hash_including(
{ {
domain: 'foo.bar.com', domain: 'foo.bar.com',
severity: 'silence', severity: 'silence',
@ -155,7 +153,7 @@ RSpec.describe 'Domain Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match a_hash_including( expect(response.parsed_body).to match a_hash_including(
{ {
domain: 'foo.bar.com', domain: 'foo.bar.com',
severity: 'suspend', severity: 'suspend',
@ -175,7 +173,7 @@ RSpec.describe 'Domain Blocks' do
subject subject
expect(response).to have_http_status(422) expect(response).to have_http_status(422)
expect(body_as_json[:existing_domain_block][:domain]).to eq('foo.bar.com') expect(response.parsed_body[:existing_domain_block][:domain]).to eq('foo.bar.com')
end end
end end
@ -188,7 +186,7 @@ RSpec.describe 'Domain Blocks' do
subject subject
expect(response).to have_http_status(422) expect(response).to have_http_status(422)
expect(body_as_json[:existing_domain_block][:domain]).to eq('bar.com') expect(response.parsed_body[:existing_domain_block][:domain]).to eq('bar.com')
end end
end end
@ -219,7 +217,7 @@ RSpec.describe 'Domain Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match a_hash_including( expect(response.parsed_body).to match a_hash_including(
{ {
id: domain_block.id.to_s, id: domain_block.id.to_s,
domain: domain_block.domain, domain: domain_block.domain,

View file

@ -31,7 +31,7 @@ RSpec.describe 'Email Domain Blocks' do
it 'returns an empty list' do it 'returns an empty list' do
subject subject
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
@ -42,7 +42,7 @@ RSpec.describe 'Email Domain Blocks' do
it 'return the correct blocked email domains' do it 'return the correct blocked email domains' do
subject subject
expect(body_as_json.pluck(:domain)).to match_array(blocked_email_domains) expect(response.parsed_body.pluck(:domain)).to match_array(blocked_email_domains)
end end
context 'with limit param' do context 'with limit param' do
@ -51,7 +51,7 @@ RSpec.describe 'Email Domain Blocks' do
it 'returns only the requested number of email domain blocks' do it 'returns only the requested number of email domain blocks' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
@ -63,7 +63,7 @@ RSpec.describe 'Email Domain Blocks' do
email_domain_blocks_ids = email_domain_blocks.pluck(:id).map(&:to_s) email_domain_blocks_ids = email_domain_blocks.pluck(:id).map(&:to_s)
expect(body_as_json.pluck(:id)).to match_array(email_domain_blocks_ids[2..]) expect(response.parsed_body.pluck(:id)).to match_array(email_domain_blocks_ids[2..])
end end
end end
@ -75,7 +75,7 @@ RSpec.describe 'Email Domain Blocks' do
email_domain_blocks_ids = email_domain_blocks.pluck(:id).map(&:to_s) email_domain_blocks_ids = email_domain_blocks.pluck(:id).map(&:to_s)
expect(body_as_json.pluck(:id)).to match_array(email_domain_blocks_ids[..2]) expect(response.parsed_body.pluck(:id)).to match_array(email_domain_blocks_ids[..2])
end end
end end
end end
@ -97,7 +97,7 @@ RSpec.describe 'Email Domain Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:domain]).to eq(email_domain_block.domain) expect(response.parsed_body[:domain]).to eq(email_domain_block.domain)
end end
end end
@ -125,7 +125,7 @@ RSpec.describe 'Email Domain Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:domain]).to eq(params[:domain]) expect(response.parsed_body[:domain]).to eq(params[:domain])
end end
context 'when domain param is not provided' do context 'when domain param is not provided' do
@ -176,7 +176,7 @@ RSpec.describe 'Email Domain Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
expect(EmailDomainBlock.find_by(id: email_domain_block.id)).to be_nil expect(EmailDomainBlock.find_by(id: email_domain_block.id)).to be_nil
end end

View file

@ -30,7 +30,7 @@ RSpec.describe 'IP Blocks' do
it 'returns an empty body' do it 'returns an empty body' do
subject subject
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
@ -58,7 +58,7 @@ RSpec.describe 'IP Blocks' do
it 'returns the correct blocked ips' do it 'returns the correct blocked ips' do
subject subject
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
context 'with limit param' do context 'with limit param' do
@ -67,7 +67,7 @@ RSpec.describe 'IP Blocks' do
it 'returns only the requested number of ip blocks' do it 'returns only the requested number of ip blocks' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
end end
@ -89,7 +89,7 @@ RSpec.describe 'IP Blocks' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
ip: eq("#{ip_block.ip}/#{ip_block.ip.prefix}"), ip: eq("#{ip_block.ip}/#{ip_block.ip.prefix}"),
severity: eq(ip_block.severity.to_s) severity: eq(ip_block.severity.to_s)
@ -120,7 +120,7 @@ RSpec.describe 'IP Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
ip: eq("#{params[:ip]}/32"), ip: eq("#{params[:ip]}/32"),
severity: eq(params[:severity]), severity: eq(params[:severity]),
@ -185,7 +185,7 @@ RSpec.describe 'IP Blocks' do
.and change_comment_value .and change_comment_value
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match(hash_including({ expect(response.parsed_body).to match(hash_including({
ip: "#{ip_block.ip}/#{ip_block.ip.prefix}", ip: "#{ip_block.ip}/#{ip_block.ip.prefix}",
severity: 'sign_up_requires_approval', severity: 'sign_up_requires_approval',
comment: 'Decreasing severity', comment: 'Decreasing severity',
@ -220,7 +220,7 @@ RSpec.describe 'IP Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
expect(IpBlock.find_by(id: ip_block.id)).to be_nil expect(IpBlock.find_by(id: ip_block.id)).to be_nil
end end

View file

@ -44,7 +44,7 @@ RSpec.describe 'Admin Measures' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Array) .to be_an(Array)
end end
end end

View file

@ -29,7 +29,7 @@ RSpec.describe 'Reports' do
it 'returns an empty list' do it 'returns an empty list' do
subject subject
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
@ -64,7 +64,7 @@ RSpec.describe 'Reports' do
it 'returns all unresolved reports' do it 'returns all unresolved reports' do
subject subject
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
context 'with resolved param' do context 'with resolved param' do
@ -74,7 +74,7 @@ RSpec.describe 'Reports' do
it 'returns only the resolved reports' do it 'returns only the resolved reports' do
subject subject
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
end end
@ -85,7 +85,7 @@ RSpec.describe 'Reports' do
it 'returns all unresolved reports filed by the specified account' do it 'returns all unresolved reports filed by the specified account' do
subject subject
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
end end
@ -96,7 +96,7 @@ RSpec.describe 'Reports' do
it 'returns all unresolved reports targeting the specified account' do it 'returns all unresolved reports targeting the specified account' do
subject subject
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
end end
@ -106,7 +106,7 @@ RSpec.describe 'Reports' do
it 'returns only the requested number of reports' do it 'returns only the requested number of reports' do
subject subject
expect(body_as_json.size).to eq(1) expect(response.parsed_body.size).to eq(1)
end end
end end
end end
@ -126,7 +126,7 @@ RSpec.describe 'Reports' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to include( expect(response.parsed_body).to include(
{ {
id: report.id.to_s, id: report.id.to_s,
action_taken: report.action_taken?, action_taken: report.action_taken?,
@ -159,7 +159,7 @@ RSpec.describe 'Reports' do
report.reload report.reload
expect(body_as_json).to include( expect(response.parsed_body).to include(
{ {
id: report.id.to_s, id: report.id.to_s,
action_taken: report.action_taken?, action_taken: report.action_taken?,

View file

@ -27,7 +27,7 @@ RSpec.describe 'Admin Retention' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_an(Array) .to be_an(Array)
end end
end end

View file

@ -30,7 +30,7 @@ RSpec.describe 'Tags' do
it 'returns an empty list' do it 'returns an empty list' do
subject subject
expect(body_as_json).to be_empty expect(response.parsed_body).to be_empty
end end
end end
@ -47,7 +47,7 @@ RSpec.describe 'Tags' do
it 'returns the expected tags' do it 'returns the expected tags' do
subject subject
tags.each do |tag| tags.each do |tag|
expect(body_as_json.find { |item| item[:id] == tag.id.to_s && item[:name] == tag.name }).to_not be_nil expect(response.parsed_body.find { |item| item[:id] == tag.id.to_s && item[:name] == tag.name }).to_not be_nil
end end
end end
@ -57,7 +57,7 @@ RSpec.describe 'Tags' do
it 'returns only the requested number of tags' do it 'returns only the requested number of tags' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
end end
@ -82,8 +82,8 @@ RSpec.describe 'Tags' do
it 'returns expected tag content' do it 'returns expected tag content' do
subject subject
expect(body_as_json[:id].to_i).to eq(tag.id) expect(response.parsed_body[:id].to_i).to eq(tag.id)
expect(body_as_json[:name]).to eq(tag.name) expect(response.parsed_body[:name]).to eq(tag.name)
end end
context 'when the requested tag does not exist' do context 'when the requested tag does not exist' do
@ -116,8 +116,8 @@ RSpec.describe 'Tags' do
it 'returns updated tag' do it 'returns updated tag' do
subject subject
expect(body_as_json[:id].to_i).to eq(tag.id) expect(response.parsed_body[:id].to_i).to eq(tag.id)
expect(body_as_json[:name]).to eq(tag.name.upcase) expect(response.parsed_body[:name]).to eq(tag.name.upcase)
end end
context 'when the updated display name is invalid' do context 'when the updated display name is invalid' do

View file

@ -44,7 +44,7 @@ RSpec.describe 'Links' do
end end
def expects_correct_link_data def expects_correct_link_data
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including( a_hash_including(
url: preview_card.url, url: preview_card.url,
title: preview_card.title, title: preview_card.title,
@ -98,7 +98,7 @@ RSpec.describe 'Links' do
it 'returns the link data' do it 'returns the link data' do
subject subject
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including( a_hash_including(
url: preview_card.url, url: preview_card.url,
title: preview_card.title, title: preview_card.title,

View file

@ -34,7 +34,7 @@ RSpec.describe 'API V1 Annual Reports' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_present .to be_present
end end
end end

View file

@ -18,7 +18,7 @@ RSpec.describe 'Credentials' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including( a_hash_including(
id: token.application.id.to_s, id: token.application.id.to_s,
name: token.application.name, name: token.application.name,
@ -37,8 +37,8 @@ RSpec.describe 'Credentials' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json[:client_id]).to_not be_present expect(response.parsed_body[:client_id]).to_not be_present
expect(body_as_json[:client_secret]).to_not be_present expect(response.parsed_body[:client_secret]).to_not be_present
end end
end end
@ -56,7 +56,7 @@ RSpec.describe 'Credentials' do
it 'returns the app information correctly' do it 'returns the app information correctly' do
subject subject
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including( a_hash_including(
id: token.application.id.to_s, id: token.application.id.to_s,
name: token.application.name, name: token.application.name,
@ -95,7 +95,7 @@ RSpec.describe 'Credentials' do
it 'returns the error in the json response' do it 'returns the error in the json response' do
subject subject
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including( a_hash_including(
error: 'The access token was revoked' error: 'The access token was revoked'
) )
@ -117,7 +117,7 @@ RSpec.describe 'Credentials' do
it 'returns the error in the json response' do it 'returns the error in the json response' do
subject subject
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including( a_hash_including(
error: 'The access token is invalid' error: 'The access token is invalid'
) )

View file

@ -35,7 +35,7 @@ RSpec.describe 'Apps' do
expect(app.scopes.to_s).to eq scopes expect(app.scopes.to_s).to eq scopes
expect(app.redirect_uris).to eq redirect_uris expect(app.redirect_uris).to eq redirect_uris
expect(body_as_json).to match( expect(response.parsed_body).to match(
a_hash_including( a_hash_including(
id: app.id.to_s, id: app.id.to_s,
client_id: app.uid, client_id: app.uid,
@ -61,7 +61,7 @@ RSpec.describe 'Apps' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(Doorkeeper::Application.find_by(name: client_name)).to be_present expect(Doorkeeper::Application.find_by(name: client_name)).to be_present
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
scopes: Doorkeeper.config.default_scopes.to_a scopes: Doorkeeper.config.default_scopes.to_a
) )
@ -82,7 +82,7 @@ RSpec.describe 'Apps' do
expect(app).to be_present expect(app).to be_present
expect(app.scopes.to_s).to eq 'read' expect(app.scopes.to_s).to eq 'read'
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
scopes: %w(read) scopes: %w(read)
) )
@ -165,7 +165,7 @@ RSpec.describe 'Apps' do
expect(app.redirect_uri).to eq redirect_uris expect(app.redirect_uri).to eq redirect_uris
expect(app.redirect_uris).to eq redirect_uris.split expect(app.redirect_uris).to eq redirect_uris.split
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
redirect_uri: redirect_uris, redirect_uri: redirect_uris,
redirect_uris: redirect_uris.split redirect_uris: redirect_uris.split
@ -187,7 +187,7 @@ RSpec.describe 'Apps' do
expect(app.redirect_uri).to eq redirect_uris.join "\n" expect(app.redirect_uri).to eq redirect_uris.join "\n"
expect(app.redirect_uris).to eq redirect_uris expect(app.redirect_uris).to eq redirect_uris
expect(body_as_json) expect(response.parsed_body)
.to include( .to include(
redirect_uri: redirect_uris.join("\n"), redirect_uri: redirect_uris.join("\n"),
redirect_uris: redirect_uris redirect_uris: redirect_uris

View file

@ -26,7 +26,7 @@ RSpec.describe 'Blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
context 'with limit param' do context 'with limit param' do
@ -35,7 +35,7 @@ RSpec.describe 'Blocks' do
it 'returns only the requested number of blocked accounts' do it 'returns only the requested number of blocked accounts' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
it 'sets correct link header pagination' do it 'sets correct link header pagination' do
@ -55,7 +55,7 @@ RSpec.describe 'Blocks' do
it 'queries the blocks in range according to max_id', :aggregate_failures do it 'queries the blocks in range according to max_id', :aggregate_failures do
subject subject
expect(body_as_json) expect(response.parsed_body)
.to contain_exactly(include(id: blocks.first.target_account.id.to_s)) .to contain_exactly(include(id: blocks.first.target_account.id.to_s))
end end
end end
@ -66,7 +66,7 @@ RSpec.describe 'Blocks' do
it 'queries the blocks in range according to since_id', :aggregate_failures do it 'queries the blocks in range according to since_id', :aggregate_failures do
subject subject
expect(body_as_json) expect(response.parsed_body)
.to contain_exactly(include(id: blocks[2].target_account.id.to_s)) .to contain_exactly(include(id: blocks[2].target_account.id.to_s))
end end
end end

View file

@ -33,7 +33,7 @@ RSpec.describe 'Bookmarks' do
it 'returns the bookmarked statuses' do it 'returns the bookmarked statuses' do
subject subject
expect(body_as_json).to match_array(expected_response) expect(response.parsed_body).to match_array(expected_response)
end end
context 'with limit param' do context 'with limit param' do
@ -42,7 +42,7 @@ RSpec.describe 'Bookmarks' do
it 'paginates correctly', :aggregate_failures do it 'paginates correctly', :aggregate_failures do
subject subject
expect(body_as_json.size) expect(response.parsed_body.size)
.to eq(params[:limit]) .to eq(params[:limit])
expect(response) expect(response)

View file

@ -31,8 +31,8 @@ RSpec.describe 'API V1 Conversations' do
it 'returns conversations', :aggregate_failures do it 'returns conversations', :aggregate_failures do
get '/api/v1/conversations', headers: headers get '/api/v1/conversations', headers: headers
expect(body_as_json.size).to eq 2 expect(response.parsed_body.size).to eq 2
expect(body_as_json[0][:accounts].size).to eq 1 expect(response.parsed_body.first[:accounts].size).to eq 1
end end
context 'with since_id' do context 'with since_id' do
@ -40,7 +40,7 @@ RSpec.describe 'API V1 Conversations' do
it 'returns conversations' do it 'returns conversations' do
get '/api/v1/conversations', params: { since_id: Mastodon::Snowflake.id_at(1.hour.ago, with_random: false) }, headers: headers get '/api/v1/conversations', params: { since_id: Mastodon::Snowflake.id_at(1.hour.ago, with_random: false) }, headers: headers
expect(body_as_json.size).to eq 2 expect(response.parsed_body.size).to eq 2
end end
end end
@ -48,7 +48,7 @@ RSpec.describe 'API V1 Conversations' do
it 'returns no conversation' do it 'returns no conversation' do
get '/api/v1/conversations', params: { since_id: Mastodon::Snowflake.id_at(1.hour.from_now, with_random: false) }, headers: headers get '/api/v1/conversations', params: { since_id: Mastodon::Snowflake.id_at(1.hour.from_now, with_random: false) }, headers: headers
expect(body_as_json.size).to eq 0 expect(response.parsed_body.size).to eq 0
end end
end end
end end

View file

@ -19,7 +19,7 @@ RSpec.describe 'Custom Emojis' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_present .to be_present
.and have_attributes( .and have_attributes(
first: include(shortcode: 'coolcat') first: include(shortcode: 'coolcat')
@ -34,7 +34,7 @@ RSpec.describe 'Custom Emojis' do
expect(response) expect(response)
.to have_http_status(200) .to have_http_status(200)
expect(body_as_json) expect(response.parsed_body)
.to be_present .to be_present
.and have_attributes( .and have_attributes(
first: include(shortcode: 'coolcat') first: include(shortcode: 'coolcat')

View file

@ -82,8 +82,8 @@ RSpec.describe 'Directories API' do
get '/api/v1/directory', headers: headers get '/api/v1/directory', headers: headers
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq(2) expect(response.parsed_body.size).to eq(2)
expect(body_as_json.pluck(:id)).to contain_exactly(eligible_remote_account.id.to_s, local_discoverable_account.id.to_s) expect(response.parsed_body.pluck(:id)).to contain_exactly(eligible_remote_account.id.to_s, local_discoverable_account.id.to_s)
end end
end end
@ -101,8 +101,8 @@ RSpec.describe 'Directories API' do
get '/api/v1/directory', headers: headers, params: { local: '1' } get '/api/v1/directory', headers: headers, params: { local: '1' }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq(1) expect(response.parsed_body.size).to eq(1)
expect(body_as_json.first[:id]).to include(local_account.id.to_s) expect(response.parsed_body.first[:id]).to include(local_account.id.to_s)
expect(response.body).to_not include(remote_account.id.to_s) expect(response.body).to_not include(remote_account.id.to_s)
end end
end end
@ -115,9 +115,9 @@ RSpec.describe 'Directories API' do
get '/api/v1/directory', headers: headers, params: { order: 'active' } get '/api/v1/directory', headers: headers, params: { order: 'active' }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq(2) expect(response.parsed_body.size).to eq(2)
expect(body_as_json.first[:id]).to include(new_stat.account_id.to_s) expect(response.parsed_body.first[:id]).to include(new_stat.account_id.to_s)
expect(body_as_json.second[:id]).to include(old_stat.account_id.to_s) expect(response.parsed_body.second[:id]).to include(old_stat.account_id.to_s)
end end
end end
@ -130,9 +130,9 @@ RSpec.describe 'Directories API' do
get '/api/v1/directory', headers: headers, params: { order: 'new' } get '/api/v1/directory', headers: headers, params: { order: 'new' }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json.size).to eq(2) expect(response.parsed_body.size).to eq(2)
expect(body_as_json.first[:id]).to include(account_new.id.to_s) expect(response.parsed_body.first[:id]).to include(account_new.id.to_s)
expect(body_as_json.second[:id]).to include(account_old.id.to_s) expect(response.parsed_body.second[:id]).to include(account_old.id.to_s)
end end
end end
end end

View file

@ -26,7 +26,7 @@ RSpec.describe 'Domain blocks' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to match_array(blocked_domains) expect(response.parsed_body).to match_array(blocked_domains)
end end
context 'with limit param' do context 'with limit param' do
@ -35,7 +35,7 @@ RSpec.describe 'Domain blocks' do
it 'returns only the requested number of blocked domains' do it 'returns only the requested number of blocked domains' do
subject subject
expect(body_as_json.size).to eq(params[:limit]) expect(response.parsed_body.size).to eq(params[:limit])
end end
end end
end end

View file

@ -111,7 +111,7 @@ RSpec.describe 'Confirmations' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to be false expect(response.parsed_body).to be false
end end
end end
@ -122,7 +122,7 @@ RSpec.describe 'Confirmations' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to be true expect(response.parsed_body).to be true
end end
end end
end end
@ -139,7 +139,7 @@ RSpec.describe 'Confirmations' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to be false expect(response.parsed_body).to be false
end end
end end
@ -150,7 +150,7 @@ RSpec.describe 'Confirmations' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(body_as_json).to be true expect(response.parsed_body).to be true
end end
end end
end end

Some files were not shown because too many files have changed in this diff Show more