diff --git a/.eslintrc.js b/.eslintrc.js index 1150f734d7..5adfa3bd70 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -120,7 +120,6 @@ module.exports = defineConfig({ 'react/jsx-uses-react': 'off', // not needed with new JSX transform 'react/jsx-wrap-multilines': 'error', 'react/no-deprecated': 'off', - 'react/no-unknown-property': 'off', 'react/react-in-jsx-scope': 'off', // not needed with new JSX transform 'react/self-closing-comp': 'error', diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 895dbfbad2..a7998ddfdc 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -50,7 +50,6 @@ matchManagers: ['bundler'], matchPackageNames: [ 'rack', // Needs to be synced with Rails version - 'sprockets', // Requires manual upgrade https://github.com/rails/sprockets/blob/master/UPGRADING.md#guide-to-upgrading-from-sprockets-3x-to-4x 'strong_migrations', // Requires manual upgrade 'sidekiq', // Requires manual upgrade 'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 9564c02dea..d74940ec7f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -112,20 +112,6 @@ Rails/HasAndBelongsToMany: - 'app/models/status.rb' - 'app/models/tag.rb' -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/HasManyOrHasOneDependent: - Exclude: - - 'app/models/concerns/account/counters.rb' - - 'app/models/conversation.rb' - - 'app/models/custom_emoji.rb' - - 'app/models/custom_emoji_category.rb' - - 'app/models/domain_block.rb' - - 'app/models/invite.rb' - - 'app/models/status.rb' - - 'app/models/user.rb' - - 'app/models/web/push_subscription.rb' - # Configuration parameters: Include. # Include: app/controllers/**/*.rb, app/mailers/**/*.rb Rails/LexicallyScopedActionFilter: diff --git a/Gemfile b/Gemfile index d162a78399..300036804b 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ ruby '>= 3.0.0' gem 'puma', '~> 6.3' gem 'rails', '~> 7.1.1' -gem 'sprockets', '~> 3.7.2' +gem 'propshaft' gem 'thor', '~> 1.2' gem 'rack', '~> 2.2.7' @@ -89,7 +89,6 @@ gem 'sidekiq-unique-jobs', '~> 7.1' gem 'sidekiq-bulk', '~> 0.2.0' gem 'simple-navigation', '~> 4.4' gem 'simple_form', '~> 5.2' -gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie' gem 'stoplight', '~> 3.0.1' gem 'strong_migrations', '1.6.4' gem 'tty-prompt', '~> 0.23', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 4e8c607ade..7a7fdb01c4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -175,7 +175,7 @@ GEM blurhash (0.1.7) bootsnap (1.17.0) msgpack (~> 1.2) - brakeman (6.0.1) + brakeman (6.1.0) browser (5.3.1) brpoplpush-redis_script (0.1.3) concurrent-ruby (~> 1.0, >= 1.0.5) @@ -197,7 +197,7 @@ GEM activesupport cbor (0.5.9.6) charlock_holmes (0.7.7) - chewy (7.3.4) + chewy (7.3.5) activesupport (>= 5.2) elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch-dsl @@ -245,7 +245,7 @@ GEM docile (1.4.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - doorkeeper (5.6.7) + doorkeeper (5.6.8) railties (>= 5) dotenv (2.8.1) dotenv-rails (2.8.1) @@ -377,11 +377,11 @@ GEM terminal-table (>= 1.5.1) idn-ruby (0.1.5) io-console (0.6.0) - irb (1.9.1) + irb (1.10.1) rdoc reline (>= 0.3.8) jmespath (1.6.2) - json (2.6.3) + json (2.7.0) json-canonicalization (1.0.0) json-jwt (1.15.3) activesupport (>= 4.2) @@ -484,7 +484,8 @@ GEM nokogiri (1.15.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.1) + oj (3.16.2) + bigdecimal (~> 3.1) omniauth (2.1.1) hashie (>= 3.4.6) rack (>= 2.2.3) @@ -534,6 +535,11 @@ GEM net-smtp premailer (~> 1.7, >= 1.7.9) private_address_check (0.5.0) + propshaft (0.8.0) + actionpack (>= 7.0.0) + activesupport (>= 7.0.0) + rack + railties (>= 7.0.0) psych (5.1.1.1) stringio public_suffix (5.0.4) @@ -608,7 +614,7 @@ GEM link_header (~> 0.0, >= 0.0.8) rdf-normalize (0.6.1) rdf (~> 3.2) - rdoc (6.6.0) + rdoc (6.6.1) psych (>= 4.0.0) redcarpet (3.6.0) redis (4.8.1) @@ -617,7 +623,7 @@ GEM redlock (1.3.2) redis (>= 3.0.0, < 6.0) regexp_parser (2.8.2) - reline (0.4.0) + reline (0.4.1) io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) @@ -656,7 +662,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 8) rspec-support (3.12.1) - rubocop (1.57.2) + rubocop (1.58.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -664,7 +670,7 @@ GEM rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.1, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.30.0) @@ -702,7 +708,7 @@ GEM scenic (1.7.0) activerecord (>= 4.0.0) railties (>= 4.0.0) - selenium-webdriver (4.15.0) + selenium-webdriver (4.16.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) @@ -736,18 +742,11 @@ GEM simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) smart_properties (1.17.0) - sprockets (3.7.2) - concurrent-ruby (~> 1.0) - rack (> 1, < 3) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - sprockets (>= 3.0.0) stackprof (0.2.25) statsd-ruby (1.5.0) stoplight (3.0.2) redlock (~> 1.0) - stringio (3.0.9) + stringio (3.1.0) strong_migrations (1.6.4) activerecord (>= 5.2) swd (1.3.0) @@ -911,6 +910,7 @@ DEPENDENCIES posix-spawn premailer-rails private_address_check (~> 0.5) + propshaft public_suffix (~> 5.0) puma (~> 6.3) pundit (~> 2.3) @@ -949,8 +949,6 @@ DEPENDENCIES simple_form (~> 5.2) simplecov (~> 0.22) simplecov-lcov (~> 0.8) - sprockets (~> 3.7.2) - sprockets-rails (~> 3.4) stackprof stoplight (~> 3.0.1) strong_migrations (= 1.6.4) diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index c81ba32b08..b3c60fcaf4 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -64,7 +64,7 @@ class Api::BaseController < ApplicationController end def doorkeeper_unauthorized_render_options(error: nil) - { json: { error: (error.try(:description) || 'Not authorized') } } + { json: { error: error.try(:description) || 'Not authorized' } } end def doorkeeper_forbidden_render_options(*) diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index 653529316f..be251b4259 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -49,7 +49,7 @@ class Api::V1::AccountsController < Api::BaseController end def mute - MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: (params[:duration]&.to_i || 0)) + MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: params[:duration].to_i) render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships end diff --git a/app/javascript/mastodon/features/interaction_modal/index.jsx b/app/javascript/mastodon/features/interaction_modal/index.jsx index 4f145f9ed2..216c63a7e6 100644 --- a/app/javascript/mastodon/features/interaction_modal/index.jsx +++ b/app/javascript/mastodon/features/interaction_modal/index.jsx @@ -298,9 +298,9 @@ class LoginForm extends React.PureComponent { onFocus={this.handleFocus} onBlur={this.handleBlur} onKeyDown={this.handleKeyDown} - autocomplete='off' - autocapitalize='off' - spellcheck='false' + autoComplete='off' + autoCapitalize='off' + spellCheck='false' /> diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx index 4b0e03a0fd..d1b2a0910b 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx @@ -82,7 +82,7 @@ class NavigationPanel extends Component { {banner && -
rel="me"
neleidžia apsimesti interneto svetainėse, kuriose yra naudotojų sukurto turinio. Vietoj to gali naudoti net nuorodą
puslapio antraštėje esančią žymę a
, tačiau HTML turi būti pasiekiamas nevykdant JavaScript.
hint_html: "Savo tapatybės patvirtinimas Mastodon skirtas visiems. Remiantis atviraisiais žiniatinklio standartais, dabar ir visam laikui nemokamas. Viskas, ko tau reikia, yra asmeninė svetainė, pagal kurią žmonės tave atpažįsta. Kai iš savo profilio pateiksi nuorodą į šią svetainę, patikrinsime, ar svetainėje yra nuoroda į tavo profilį, ir parodysime vizualinį indikatorių."
+ instructions_html: Nukopijuok ir įklijuok toliau pateiktą kodą į savo svetainės HTML. Tada į vieną iš papildomų profilio laukų skirtuke „Redaguoti profilį“ įrašyk savo svetainės adresą ir išsaugok pakeitimus.
verification: Patvirtinimas
verified_links: Tavo patikrintos nuorodos
webauthn_credentials:
create:
error: Kilo problema pridedant saugumo raktą. Bandyk dar kartą.
+ success: Tavo saugumo raktas buvo sėkmingai pridėtas.
+ delete_confirmation: Ar tikrai nori ištrinti šį saugumo raktą?
+ description_html: Jei įjungsi saugumo rakto tapatybės nustatymą, prisijungiant reikės naudoti vieną iš savo saugumo raktų.
+ destroy:
+ error: Kilo problema ištrinant saugumo raktą. Bandyk dar kartą.
+ success: Tavo saugumo raktas buvo sėkmingai ištrintas.
nickname_hint: Įvesk naujojo saugumo rakto slapyvardį
not_enabled: Dar neįjungei WebAuthn
diff --git a/config/locales/ne.yml b/config/locales/ne.yml
new file mode 100644
index 0000000000..db03c5186b
--- /dev/null
+++ b/config/locales/ne.yml
@@ -0,0 +1 @@
+ne:
diff --git a/config/locales/ry.yml b/config/locales/ry.yml
new file mode 100644
index 0000000000..6fe57b65cd
--- /dev/null
+++ b/config/locales/ry.yml
@@ -0,0 +1 @@
+ry:
diff --git a/config/locales/sc.yml b/config/locales/sc.yml
index fa7603f2b1..d92b64783a 100644
--- a/config/locales/sc.yml
+++ b/config/locales/sc.yml
@@ -5,6 +5,7 @@ sc:
contact_missing: No cunfiguradu
contact_unavailable: No a disponimentu
hosted_on: Mastodon allogiadu in %{domain}
+ title: Informatziones
accounts:
follow: Sighi
followers:
@@ -45,6 +46,7 @@ sc:
confirm: Cunfirma
confirmed: Cunfirmadu
confirming: Cunfirmende
+ custom: Personalizadu
delete: Cantzella datos
deleted: Cantzelladu
demote: Degrada
@@ -81,7 +83,9 @@ sc:
moderation:
active: Ativu
all: Totus
+ disabled: Disativadu
pending: De imbiare
+ silenced: Limitadu
suspended: Suspèndidu
title: Moderatzione
moderation_notes: Notas de moderatzione
@@ -112,6 +116,7 @@ sc:
search: Chirca
search_same_email_domain: Àteras persones cun su pròpiu domìniu de posta
search_same_ip: Àteras persones cun sa pròpiu IP
+ security: Seguresa
sensitive: Sensìbile
sensitized: marcadu comente a sensìbile
shared_inbox_url: URL de intrada cumpartzida
@@ -122,6 +127,7 @@ sc:
silenced: Limitadas
statuses: Tuts
subscribe: Sutascrie·ti
+ suspend: Suspensione
suspended: Suspèndidu
suspension_irreversible: Is datos de custu contu sunt istados cantzellados in manera irreversìbile. Podes bogare sa suspensione a su contu pro chi si potzat impreare, ma no at a recuperare datu perunu de is chi teniat in antis.
suspension_reversible_hint_html: Su contu est istadu suspèndidu, e is datos ant a èssere cantzelladu de su totu su %{date}. Finas a tando, su contu si podet ripristinare sena efetu malu perunu. Si boles cantzellare totu is datos de su contu immediatamente ddu podes fàghere inoghe in bassu.
@@ -274,6 +280,7 @@ sc:
updated_msg: Emoji atualizadu
upload: Càrriga
dashboard:
+ media_storage: Immagasinamentu
software: Programmas
space: Impreu de ispàtziu
title: Pannellu
@@ -281,21 +288,28 @@ sc:
add_new: Permite sa federatzione cun domìniu
created_msg: Sa federatzione cun su domìniu est istada permìtida
destroyed_msg: Sa federatzione cun su domìniu no est istada permìtida
+ import: Importatzione
undo: Non permitas sa federatzione cun su domìniu
domain_blocks:
add_new: Agiunghe blocu de domìniu nou
+ confirm_suspension:
+ cancel: Annulla
+ confirm: Suspensione
created_msg: Protzessende su blocu de domìniu
destroyed_msg: Su blocu de domìniu est istadu iscontzadu
domain: Domìniu
edit: Modìfica su blocu de su domìniu
existing_domain_block_html: As giai impostu lìmites prus astrintos a %{name}, ddu dias dèpere isblocare prima.
+ import: Importatzione
new:
create: Crea unu blocu
hint: Su blocu de domìniu no at a impedire sa creatzione de contos noos in sa base de datos, ma ant a èssere aplicados in manera retroativa mètodos de moderatzione ispetzìficos subra custos contos.
severity:
noop: Perunu
+ silence: A sa muda
suspend: Suspensione
title: Blocu de domìniu nou
+ not_permitted: Non tenes su permissu de fàghere custa atzione
obfuscate: Cua su nòmine de domìniu
obfuscate_hint: Cua una parte de su nòmine de domìniu in sa lista si sa visualizatzione de sa lista de domìnios limitados est ativa
private_comment: Cummentu privadu
@@ -326,9 +340,24 @@ sc:
title: Cussìgios de sighidura
unsuppress: Recùpera su cussìgiu de sighidura
instances:
+ back_to_all: Totus
+ back_to_limited: Limitadu
+ back_to_warning: Atentzione
by_domain: Domìniu
+ content_policies:
+ policies:
+ reject_reports: Refuda informes
+ silence: A sa muda
+ suspend: Suspensione
+ dashboard:
+ instance_reports_measure: informes a subra de àtere
+ delivery:
+ all: Totus
delivery_available: Sa cunsigna est a disponimentu
empty: Perunu domìniu agatadu.
+ known_accounts:
+ one: "%{count} contu connòschidu"
+ other: "%{count} contos connòschidos"
moderation:
all: Totus
limited: Limitadas
@@ -390,18 +419,23 @@ sc:
notes:
one: "%{count} nota"
other: "%{count} notas"
+ action_log: Registru de controllu
action_taken_by: Mesuras adotadas dae
are_you_sure: Seguru?
assign_to_self: Assigna a mie
assigned: Moderatzione assignada
by_target_domain: Domìniu de su contu signaladu
+ cancel: Annulla
comment:
none: Perunu
+ confirm: Cunfirma
created_at: Sinnaladu
forwarded: Torradu a imbiare
forwarded_to: Torradu a imbiare a %{domain}
mark_as_resolved: Marca comente a isòrvidu
+ mark_as_sensitive: Signala comente a sensìbile
mark_as_unresolved: Marcare comente a non isòrvidu
+ no_one_assigned: Nemos
notes:
create: Agiunghe una nota
create_and_resolve: Isorve cun una nota
@@ -419,6 +453,15 @@ sc:
unassign: Boga s'assignatzione
unresolved: No isòrvidu
updated_at: Atualizadu
+ view_profile: Visualiza profilu
+ roles:
+ categories:
+ administration: Amministratzione
+ invites: Invitos
+ moderation: Moderatzione
+ delete: Cantzella
+ privileges:
+ administrator: Amministratzione
rules:
add_new: Agiunghe règula
delete: Cantzella
@@ -427,10 +470,26 @@ sc:
empty: Peruna règula de serbidore definida ancora.
title: Règulas de su serbidore
settings:
+ about:
+ manage_rules: Gesti is règulas de su serbidore
+ title: Informatziones
+ appearance:
+ title: Aspetu
+ default_noindex:
+ desc_html: Ìmplicat a totu is utentes chi no apant modificadu custa cunfiguratzione
+ title: Esclude in manera predefinida is utentes dae s'inditzamentu de is motores de chirca
+ discovery:
+ follow_recommendations: Cussìgios de sighidura
+ profile_directory: Diretòriu de profilos
+ public_timelines: Lìnias de tempos pùblicas
+ title: Iscoberta
+ trends: Tendèntzias
domain_blocks:
all: Pro totus
disabled: Pro nemos
users: Pro utentes locales in lìnia
+ registrations:
+ title: Registros
registrations_mode:
modes:
approved: Aprovatzione rechesta pro si registrare
@@ -439,7 +498,10 @@ sc:
site_uploads:
delete: Cantzella s'archìviu carrigadu
destroyed_msg: Càrriga de su situ cantzellada.
+ software_updates:
+ documentation_link: Àteras informatziones
statuses:
+ application: Aplicatzione
back_to_account: Torra a sa pàgina de su contu
deleted: Cantzelladu
media:
@@ -447,6 +509,10 @@ sc:
no_status_selected: Perunu istadu est istadu mudadu dae chi non nd'as seletzionadu
title: Istados de su contu
with_media: Cun elementos multimediales
+ strikes:
+ actions:
+ none: "%{name} at imbiadu un'avisu a %{target}"
+ suspend: "%{name} at suspèndidu su contu de %{target}"
system_checks:
database_schema_check:
message_html: Ddoe at tràmudas de base de datos in suspesu. Pone·ddas in esecutzione pro ti assegurare chi s'aplicatzione funtzionet comente si tocat
@@ -459,12 +525,24 @@ sc:
review: Revisiona s'istadu
updated_msg: Cunfiguratzione de etichetas atualizada
title: Amministratzione
+ trends:
+ pending_review: De revisionare
+ tags:
+ title: Etichetas de tendèntzia
+ title: Tendèntzias
warning_presets:
add_new: Agiunghe noa
delete: Cantzella
edit_preset: Modìfica s'avisu predefinidu
empty: No as cunfiguradu ancora perunu avisu predefinidu.
title: Gesti is cunfiguratziones predefinidas de is avisos
+ webhooks:
+ delete: Cantzella
+ disable: Disativa
+ disabled: Disativadu
+ enable: Ativa
+ enabled: Ativu
+ status: Istadu
admin_mailer:
new_pending_account:
body: Is detàllios de su contu nou sunt a suta. Podes aprovare o refudare custa rechesta.
@@ -473,6 +551,9 @@ sc:
body: "%{reporter} at sinnaladu %{target}"
body_remote: Una persone de su domìniu %{domain} at sinnaladu %{target}
subject: Informe nou pro %{instance} (#%{id})
+ new_trends:
+ new_trending_tags:
+ title: Etichetas de tendèntzia
aliases:
add_new: Crea unu nomìngiu
created_msg: Nomìngiu creadu. Immoe podes cumintzare a tramudare dae su contu betzu.
@@ -495,17 +576,21 @@ sc:
notification_preferences: Muda is preferèntzias de posta
salutation: "%{name},"
settings: 'Muda is preferèntzias de posta: %{link}'
+ unsubscribe: Annulla sa sutiscritzione
view: 'Visualizatzione:'
view_profile: Visualiza profilu
view_status: Ammustra s'istadu
applications:
created: Aplicatzione creada
destroyed: Aplicatzione cantzellada
+ logout: Essi
regenerate_token: Torra a generare s'identificadore de atzessu
token_regenerated: Identificadore de atzessu generadu
warning: Dae cara a custos datos. Non ddos cumpartzas mai cun nemos!
your_token: S'identificadore tuo de atzessu
auth:
+ confirmations:
+ login_link: intra
delete_account: Cantzella su contu
delete_account_html: Si boles cantzellare su contu, ddu podes fàghere inoghe. T'amus a dimandare una cunfirmatzione.
description:
@@ -528,11 +613,14 @@ sc:
register: Registru
registration_closed: "%{instance} no atzetat àteras persones"
reset_password: Reseta sa crae
+ rules:
+ back: A coa
security: Seguresa
set_new_password: Cunfigura una crae noa
status:
account_status: Istadu de su contu
confirming: Isetende chi sa posta eletrònica siat cumpletada.
+ functional: Su contu tuo est operativu.
pending: Sa dimanda tua est in protzessu de revisione dae su personale nostru. Podet serbire unu pagu de tempus. As a retzire unu messàgiu eletrònicu si sa dimanda est aprovada.
redirecting_to: Su contu tuo est inativu pro ite in die de oe est torrende a indiritzare a %{acct}.
too_fast: Formulàriu imbiadu tropu a lestru, torra a proare.
@@ -581,8 +669,14 @@ sc:
more_details_html: Pro àteros detàllios, bide sa normativa de riservadesa.
username_available: Su nòmine de utente tuo at a torrare a èssere a disponimentu
username_unavailable: Su nòmine de utente tuo no at a abarrare a disponimentu
+ disputes:
+ strikes:
+ title_actions:
+ none: Atentzione
domain_validator:
invalid_domain: no est unu nòmine de domìniu vàlidu
+ edit_profile:
+ other: Àteru
errors:
'400': Sa dimanda chi as imbiadu non fiat vàlida o non fiat curreta.
'403': Non tenes permissu pro bìdere custa pàgina.
@@ -638,11 +732,15 @@ sc:
title: Agiunghe unu filtru nou
generic:
all: Totus
+ cancel: Annulla
changes_saved_msg: Modìficas sarvadas.
+ confirm: Cunfirma
copy: Còpia
delete: Cantzella
+ none: Perunu
order_by: Òrdina pro
save_changes: Sarva is modìficas
+ today: oe
validation_errors:
one: Calicuna cosa ancora no est andende. Bide sa faddina in bàsciu
other: Calicuna cosa ancora no est andende. Bide is %{count} faddinas in bàsciu
@@ -655,12 +753,15 @@ sc:
overwrite: Subrascrie
overwrite_long: Sostitui is registros atuales cun cussos noos
preface: Podes importare datos chi as esportadu dae unu àteru serbidore, che a sa lista de sa gente chi ses sighende o blochende.
+ status: Istadu
success: Datos carrigados; ant a èssere protzessados luego
+ type: Casta de importatzione
types:
blocking: Lista de blocos
bookmarks: Sinnalibros
domain_blocking: Lista domìnios blocados
following: Lista de sighiduras
+ lists: Listas
muting: Lista gente a sa muda
upload: Càrriga
invites:
@@ -685,6 +786,13 @@ sc:
expires_at: Iscadit
uses: Impreos
title: Invita gente
+ login_activities:
+ authentication_methods:
+ password: crae
+ webauthn: craes de seguresa
+ mail_subscriptions:
+ unsubscribe:
+ title: Annulla sa sutiscritzione
media_attachments:
validations:
images_and_video: Non si podet allegare unu vìdeu in una publicatzione chi cuntenet giai immàgines
@@ -797,6 +905,8 @@ sc:
other: Àteru
posting_defaults: Valores predefinidos de publicatzione
public_timelines: Lìnias de tempos pùblicas
+ privacy:
+ search: Chirca
reactions:
errors:
limit_reached: Lìmite de reatziones diferentes cròmpidu
@@ -850,6 +960,7 @@ sc:
platforms:
adobe_air: Adobe Air
android: Android
+ chrome_os: ChromeOS
firefox_os: Firefox OS
ios: iOS
linux: Linux
@@ -934,6 +1045,7 @@ sc:
'2629746': 1 mese
'31556952': 1 annu
'5259492': 2 meses
+ '604800': 1 chida
'63113904': 2 annos
'7889238': 3 meses
stream_entries:
@@ -969,6 +1081,7 @@ sc:
subject: S'archìviu tuo est prontu pro èssere iscarrigadu
title: Collida dae s'archìviu
warning:
+ reason: 'Resone:'
subject:
disable: Su contu tuo %{acct} est istadu cungeladu
none: Avisu pro %{acct}
diff --git a/config/locales/simple_form.fil.yml b/config/locales/simple_form.fil.yml
new file mode 100644
index 0000000000..4084bf2f90
--- /dev/null
+++ b/config/locales/simple_form.fil.yml
@@ -0,0 +1 @@
+fil:
diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml
index 70c225e8ff..6e11f7fb93 100644
--- a/config/locales/simple_form.hu.yml
+++ b/config/locales/simple_form.hu.yml
@@ -81,8 +81,8 @@ hu:
bootstrap_timeline_accounts: Ezek a fiókok ki lesznek tűzve az új felhasználók követési javaslatainak élére.
closed_registrations_message: Akkor jelenik meg, amikor a regisztráció le van zárva
content_cache_retention_period: A más kiszolgálókról származó bejegyzések megadott számú nap után törölve lesznek, ha pozitív értékre van állítva. Ez lehet, hogy nem fordítható vissza.
- custom_css: A Mastodon webes verziójában használhatsz egyedi stílusokat.
- mascot: Felülvágja a haladó webes felületen található illusztrációt.
+ custom_css: A Mastodon webes verziójában használhatsz egyéni stílusokat.
+ mascot: Felülbírálja a speciális webes felületen található illusztrációt.
media_cache_retention_period: A letöltött médiafájlok megadott számú nap után törölve lesznek, ha pozitív értékre van állítva, és igény szerint újból le lesznek töltve.
peers_api_enabled: Azon domainek listája, melyekkel ez a kiszolgáló találkozott a fediverzumban. Nem csatolunk adatot arról, hogy föderált kapcsolatban vagy-e az adott kiszolgálóval, csak arról, hogy a kiszolgálód tud a másikról. Ezt olyan szolgáltatások használják, melyek általában a föderációról készítenek statisztikákat.
profile_directory: A profilok jegyzéke minden olyan felhasználót felsorol, akik engedélyezték a felfedezhetőségüket.
@@ -103,7 +103,7 @@ hu:
form_challenge:
current_password: Beléptél egy biztonsági térben
imports:
- data: Egy másik Mastodon kiszolgálóról exportált CSV-fájl
+ data: Egy másik Mastodon-kiszolgálóról exportált CSV-fájl
invite_request:
text: Ez segít nekünk átnézni a jelentkezésedet
ip_block:
@@ -199,7 +199,7 @@ hu:
otp_attempt: Kétlépcsős azonosító kód
password: Jelszó
phrase: Kulcsszó vagy kifejezés
- setting_advanced_layout: Haladó webes felület engedélyezése
+ setting_advanced_layout: Speciális webes felület engedélyezése
setting_aggregate_reblogs: Megtolások csoportosítása az idővonalakon
setting_always_send_emails: E-mail értesítések küldése mindig
setting_auto_play_gif: GIF-ek automatikus lejátszása
diff --git a/config/locales/simple_form.hy.yml b/config/locales/simple_form.hy.yml
index 56aa1d66b1..9dbcd1301e 100644
--- a/config/locales/simple_form.hy.yml
+++ b/config/locales/simple_form.hy.yml
@@ -43,7 +43,7 @@ hy:
setting_display_media_hide_all: Երբեք մեդիա ցոյց չտալ
setting_display_media_show_all: Մեդիա միշտ ցոյց տալ
setting_use_blurhash: Կտորները հիմնուում են թաքցուած վիզուալի վրայ՝ խամրեցնելով դետալները
- setting_use_pending_items: Թաքցնել հոսքի թարմացումները կտտոի ետեւում՝ աւտօմատ թարմացուող հոսքի փոխարէն
+ setting_use_pending_items: Թաքցնել հոսքի թարմացումները կոճակի ետեւում՝ աւտօմատ թարմացուող հոսքի փոխարէն
username: Միայն լատինատառեր, թուեր եւ տակի գծիկ
whole_word: Եթէ բանալի բառը կամ արտայայտութիւնը պարունակում է միայն այբբենական նիշեր եւ թուեր, ապա այն կիրառուելու է ամբողջ բառի հետ համընկնելու դէպքում միայն
domain_allow:
diff --git a/config/locales/simple_form.lt.yml b/config/locales/simple_form.lt.yml
index 39caaf6baf..6eb90340dc 100644
--- a/config/locales/simple_form.lt.yml
+++ b/config/locales/simple_form.lt.yml
@@ -27,14 +27,33 @@ lt:
none: Naudok šią parinktį norėdamas (-a) išsiųsti įspėjimą naudotojui, nesukeldamas (-a) jokio kito veiksmo.
sensitive: Priversk visus šio naudotojo medijos priedus pažymėti kaip jautrius.
silence: Neleisk naudotojui skelbti viešai matomų įrašų, paslėpk jų įrašus ir pranešimus nuo žmonių, kurie neseka jo. Uždaro visus su šia paskyra susijusius ataskaitas.
+ suspend: Neleisk jokios sąveikos iš šios paskyros arba į ją ir ištrink jos turinį. Sugrąžinama per 30 dienų. Uždaro visas su šia paskyra susijusias ataskaitas.
+ warning_preset_id: Pasirinktinai. Gali pridėti pasirinktinį tekstą iš anksto nustatyto rinkinio pabaigoje
+ announcement:
+ all_day: Jei pažymėta, bus rodomos tik laikotarpio datos
+ ends_at: Pasirinktinai. Skelbimas šiuo laiku bus automatiškai panaikintas
+ scheduled_at: Palik tuščią, kad skelbimas būtų paskelbtas iš karto
+ starts_at: Pasirinktinai. Jei skelbimas susietas su tam tikru laiko tarpu
+ text: Gali naudoti įrašo sintaksę. Būk dėmesingas (-a), kiek vietos naudotojo ekrane užims skelbimas
+ appeal:
+ text: Gali pateikti apeliaciją dėl streiko tik vieną kartą
defaults:
+ autofollow: Žmonės, kurie užsiregistruos per kvietimą, automatiškai seks tave
avatar: PNG, GIF arba JPG. Ne daugiau kaip %{size}. Bus sumažintas iki %{dimensions} tšk.
- header: PNG, GIF arba JPG. Ne daugiau kaip %{size}. Bus sumažintas iki %{dimensions}tšk.
+ bot: Signalizuoti kitiems, kad paskyroje daugiausia atliekami automatiniai veiksmai ir kad ji gali būti nestebima
+ context: Vienas arba keli kontekstai, kuriems turėtų būti taikomas filtras
+ current_password: Saugumo sumetimais įvesk dabartinės paskyros slaptažodį
+ current_username: Kad patvirtintum, įvesk dabartinės paskyros naudotojo vardą
+ digest: Siunčiama tik po ilgo neaktyvumo laikotarpio ir tik tuo atveju, jei negavai jokių asmeninių žinučių
+ email: Tau bus išsiųstas patvirtinimo el. laiškas
+ header: PNG, GIF arba JPG. Ne daugiau kaip %{size}. Bus sumažintas iki %{dimensions} tšk.
inbox_url: Nukopijuok URL adresą iš pradinio puslapio perdavėjo, kurį nori naudoti
irreversible: Filtruoti įrašai išnyks negrįžtamai, net jei vėliau filtras bus pašalintas
locale: Naudotojo sąsajos kalba, el. laiškai ir stumiamieji pranešimai
password: Naudok bent 8 simbolius
- phrase: Bus suderinta, neatsižvelgiant į teksto korpusą arba įrašo turinio įspėjimą
+ phrase: Bus suderinta, neatsižvelgiant į teksto lygį arba įrašo turinio įspėjimą
+ scopes: Prie kurių API programai bus leidžiama pasiekti. Pasirinkus aukščiausio lygio sritį, atskirų sričių pasirinkti nereikia.
+ setting_aggregate_reblogs: Nerodyti naujų pakėlimų įrašams, kurie neseniai buvo pakelti (taikoma tik naujai gautiems pakėlimams)
setting_always_send_emails: Paprastai pranešimai el. paštu nebus siunčiami, kai aktyviai naudoji Mastodon
setting_default_sensitive: Jautrioji medija pagal numatytuosius nustatymus yra paslėpta ir gali būti atskleista paspaudus
setting_display_media_default: Slėpti mediją, pažymėtą kaip jautrią
@@ -42,21 +61,116 @@ lt:
setting_display_media_show_all: Visada rodyti mediją
setting_use_blurhash: Gradientai pagrįsti paslėptų vaizdų spalvomis, tačiau užgožia bet kokias detales
setting_use_pending_items: Slėpti laiko skalės naujienas po paspaudimo, vietoj automatinio kanalo slinkimo
+ username: Gali naudoti raides, skaičius ir pabraukimus
+ whole_word: Kai raktažodis ar frazė yra tik raidinis ir skaitmeninis, jis bus taikomas tik tada, jei atitiks visą žodį
+ email_domain_block:
+ with_dns_records: Bus bandoma išspręsti nurodyto domeno DNS įrašus, o rezultatai taip pat bus blokuojami
featured_tag:
name: 'Štai keletas pastaruoju metu dažniausiai saitažodžių, kurių tu naudojai:'
+ filters:
+ action: Pasirink, kokį veiksmą atlikti, kai įrašas atitinka filtrą
+ actions:
+ hide: Visiškai paslėpti filtruotą turinį ir elgtis taip, tarsi jo neegzistuotų
+ warn: Slėpti filtruojamą turinį po įspėjimu, paminint filtro pavadinimą
form_admin_settings:
+ activity_api_enabled: Vietinių paskelbtų įrašų, aktyvių naudotojų ir naujų registracijų skaičiai kas savaitę
+ backups_retention_period: Laikyti sukurtus naudotojų archyvus nurodytą dienų skaičių.
peers_api_enabled: Domenų pavadinimų sąrašas, su kuriais šis serveris susidūrė fediverse. Čia nėra duomenų apie tai, ar tu bendrauji su tam tikru serveriu, tik apie tai, kad tavo serveris apie jį žino. Tai naudojama tarnybose, kurios renka federacijos statistiką bendrąja prasme.
site_contact_email: Kaip žmonės gali su tavimi susisiekti teisiniais ar pagalbos užklausimais.
site_contact_username: Kaip žmonės gali tave pasiekti Mastodon.
site_extended_description: Bet kokia papildoma informacija, kuri gali būti naudinga lankytojams ir naudotojams. Gali būti struktūrizuota naudojant Markdown sintaksę.
+ thumbnail: Maždaug 2:1 dydžio vaizdas, rodomas šalia tavo serverio informacijos.
+ timeline_preview: Atsijungę lankytojai galės naršyti naujausius viešus įrašus, esančius serveryje.
trends: Trendai rodo, kurios įrašai, saitažodžiai ir naujienų istorijos tavo serveryje sulaukia didžiausio susidomėjimo.
sessions:
- webauthn: Jei tai USB raktas, būtinai jį įkišk ir, jei reikia, paliesk.
+ otp: 'Įvesk telefono programėlėje sugeneruotą dviejų tapatybės kodą arba naudok vieną iš atkūrimo kodų:'
+ webauthn: Jei tai USB raktas, būtinai jį įkišk ir, jei reikia, paspausk.
settings:
indexable: Tavo profilio puslapis gali būti rodomas paieškos rezultatuose Google, Bing ir kituose.
+ user:
+ chosen_languages: Kai pažymėta, viešose laiko skalėse bus rodomi tik įrašai pasirinktomis kalbomis
+ role: Vaidmuo valdo, kokius leidimus naudotojas (-a) turi
labels:
+ account:
+ indexable: Įtraukti viešus įrašus į paieškos rezultatus
+ show_collections: Rodyti sekimus ir sekėjus profilyje
+ unlocked: Automatiškai priimti naujus sekėjus
+ account_warning_preset:
+ title: Pavadinimas
+ admin_account_action:
+ include_statuses: Įtraukti praneštus įrašus į el. laišką
+ defaults:
+ avatar: Profilio nuotrauka
+ bot: Tai automatinė paskyra
+ chosen_languages: Filtruoti kalbas
+ display_name: Rodomas vardas
+ email: El. pašto adresas
+ expires_in: Nustoja galioti po
+ fields: Papildomi laukai
+ irreversible: Mesti vietoj slėpti
+ locale: Sąsajos kalba
+ max_uses: Maksimalus naudojimo skaičius
+ new_password: Naujas slaptažodis
+ note: Biografija
+ password: Slaptažodis
+ phrase: Raktažodis arba frazė
+ setting_auto_play_gif: Automatiškai leisti animuotų GIF
+ setting_boost_modal: Rodyti patvirtinimo dialogą prieš pakėliant įrašą
+ setting_default_language: Skelbimo kalba
+ setting_default_privacy: Skelbimo privatumas
+ setting_default_sensitive: Visada žymėti mediją kaip jautrią
+ setting_delete_modal: Rodyti patvirtinimo dialogą prieš ištrinant įrašą
+ setting_display_media: Medijos rodymas
+ setting_display_media_hide_all: Slėpti viską
+ setting_display_media_show_all: Rodyti viską
+ setting_expand_spoilers: Visada išplėsti įrašus, pažymėtus turinio įspėjimais
+ setting_hide_network: Slėpti savo socialinę diagramą
+ setting_system_font_ui: Naudoti numatytąjį sistemos šriftą
+ setting_theme: Svetainės tema
+ setting_use_pending_items: Lėtas režimas
+ title: Pavadinimas
+ type: Importo tipas
+ username: Naudotojo vardas
+ username_or_email: Naudotojo vardas arba el. paštas
+ whole_word: Visas žodis
+ email_domain_block:
+ with_dns_records: Įtraukti MX įrašus ir domeno IP adresus
featured_tag:
name: Saitažodis
+ filters:
+ actions:
+ hide: Slėpti visiškai
+ warn: Slėpti su įspėjimu
+ form_admin_settings:
+ activity_api_enabled: Skelbti suvestinį statistiką apie naudotojų veiklą per API
+ bootstrap_timeline_accounts: Visada rekomenduoti šias paskyras naujiems naudotojams
+ content_cache_retention_period: Turinio talpyklos išlaikymo laikotarpis
+ custom_css: Pasirinktinis CSS
+ mascot: Pasirinktinis talismanas (pasenęs)
+ registrations_mode: Kas gali užsiregistruoti
+ show_domain_blocks_rationale: Rodyti, kodėl domenai buvo užblokuoti
+ site_extended_description: Išplėstas aprašymas
+ site_short_description: Serverio aprašymas
+ site_terms: Privatumo politika
+ site_title: Serverio pavadinimas
+ theme: Numatytoji tema
+ thumbnail: Serverio miniatūra
+ invite_request:
+ text: Kodėl nori prisijungti?
+ notification_emails:
+ favourite: Kažkas pamėgo tavo įrašą
+ follow: Kažkas seka tave
+ follow_request: Kažkas paprašė sekti tave
+ mention: Kažkas paminėjo tave
+ pending_account: Reikia peržiūros naujam paskyrui
+ reblog: Kažkas pakėlė tavo įrašą
+ software_updates:
+ label: Yra nauja Mastodon versija
+ patch: Pranešti apie klaidų ištaisymo atnaujinimus
+ rule:
+ text: Taisyklė
+ settings:
+ show_application: Rodyti, iš kurios programėles išsiuntei įrašą
tag:
listable: Leisti šį saitažodį rodyti paieškose ir pasiūlymuose
name: Saitažodis
@@ -64,11 +178,15 @@ lt:
usable: Leisti įrašams naudoti šį saitažodį
user:
role: Vaidmuo
+ time_zone: Laiko juosta
user_role:
+ color: Ženklelio spalva
+ highlighted: Rodyti vaidmenį kaip ženklelį naudotojo profiliuose
+ name: Pavadinimas
permissions_as_keys: Leidimai
position: Prioritetas
webhook:
- events: Įgalinti įvykiai
+ events: Įjungti įvykiai
template: Naudingosios apkrovos šablonas
url: Galutinio taško URL
'no': Ne
diff --git a/config/locales/simple_form.ne.yml b/config/locales/simple_form.ne.yml
new file mode 100644
index 0000000000..db03c5186b
--- /dev/null
+++ b/config/locales/simple_form.ne.yml
@@ -0,0 +1 @@
+ne:
diff --git a/config/locales/simple_form.ry.yml b/config/locales/simple_form.ry.yml
new file mode 100644
index 0000000000..6fe57b65cd
--- /dev/null
+++ b/config/locales/simple_form.ry.yml
@@ -0,0 +1 @@
+ry:
diff --git a/config/locales/simple_form.sc.yml b/config/locales/simple_form.sc.yml
index 2c47259961..5f5d633079 100644
--- a/config/locales/simple_form.sc.yml
+++ b/config/locales/simple_form.sc.yml
@@ -53,6 +53,8 @@ sc:
domain: Custu domìniu at a pòdere recuperare datos dae custu serbidore e is datos in intrada dae cue ant a èssere protzessados e archiviados
email_domain_block:
with_dns_records: S'at a fàghere unu tentativu de risòlvere is registros DNS de su domìniu e fintzas is risultados ant a èssere blocados
+ form_admin_settings:
+ activity_api_enabled: Nùmeru de tuts publicados in locale, utentes ativos e registros noos in perìodos chidajolos
form_challenge:
current_password: Ses intrende in un'àrea segura
imports:
@@ -155,6 +157,7 @@ sc:
setting_use_pending_items: Modalidade lenta
severity: Severidade
sign_in_token_attempt: Còdighe de seguresa
+ title: Tìtulu
type: Casta de importatzione
username: Nòmine utente
username_or_email: Nòmine utente o indiritzu de posta eletrònica
@@ -163,6 +166,16 @@ sc:
with_dns_records: Include registros MX e indiritzos IP de su domìniu
featured_tag:
name: Eticheta
+ form_admin_settings:
+ activity_api_enabled: Pùblica istatìsticas agregadas subra s'atividade de s'utente
+ custom_css: CSS personalizadu
+ peers_api_enabled: Pùblica sa lista de serbidores iscobertos in s'API
+ profile_directory: Ativa diretòriu de profilos
+ show_domain_blocks: Ammustra blocos de domìniu
+ site_contact_username: Nòmine de utente de su cuntatu
+ site_short_description: Descritzione de su serbidore
+ site_title: Nòmine de su serbidore
+ thumbnail: Miniadura de su serbidore
interactions:
must_be_follower: Bloca is notìficas dae chie non ti sighit
must_be_following: Bloca is notìficas dae gente chi non sighis
@@ -186,6 +199,7 @@ sc:
mention: Una persone t'at mentovadu
pending_account: Unu contu nou tenet bisòngiu de una revisione
reblog: Una persone at cumpartzidu s'istadu tuo
+ report: Imbiu de un'informe nou
rule:
text: Règula
tag:
@@ -193,6 +207,9 @@ sc:
name: Eticheta
trendable: Permite a custa eticheta de apàrrere in is tendèntzias
usable: Permite a is tuts de impreare custa eticheta
+ user_role:
+ name: Nòmine
+ permissions_as_keys: Permissos
'no': Nono
recommended: Cussigiadu
required:
diff --git a/config/locales/simple_form.tlh.yml b/config/locales/simple_form.tlh.yml
new file mode 100644
index 0000000000..884714fb71
--- /dev/null
+++ b/config/locales/simple_form.tlh.yml
@@ -0,0 +1 @@
+tlh:
diff --git a/config/locales/tlh.yml b/config/locales/tlh.yml
new file mode 100644
index 0000000000..884714fb71
--- /dev/null
+++ b/config/locales/tlh.yml
@@ -0,0 +1 @@
+tlh:
diff --git a/db/seeds/03_roles.rb b/db/seeds/03_roles.rb
index 8b359582b5..95a989a95c 100644
--- a/db/seeds/03_roles.rb
+++ b/db/seeds/03_roles.rb
@@ -6,6 +6,6 @@ UserRole.everyone
# Create default roles defined in config file
default_roles = YAML.load_file(Rails.root.join('config', 'roles.yml'))
-default_roles.each do |_, config|
+default_roles.each_value do |config|
UserRole.create_with(position: config['position'], permissions_as_keys: config['permissions'], highlighted: true).find_or_create_by(name: config['name'])
end
diff --git a/lib/mastodon/cli/accounts.rb b/lib/mastodon/cli/accounts.rb
index 33520df25d..4146753035 100644
--- a/lib/mastodon/cli/accounts.rb
+++ b/lib/mastodon/cli/accounts.rb
@@ -472,15 +472,13 @@ module Mastodon::CLI
end
total = 0
- total += Account.where(id: ::Follow.where(account: account).select(:target_account_id)).count if options[:follows]
- total += Account.where(id: ::Follow.where(target_account: account).select(:account_id)).count if options[:followers]
+ total += account.following.reorder(nil).count if options[:follows]
+ total += account.followers.reorder(nil).count if options[:followers]
progress = create_progress_bar(total)
processed = 0
if options[:follows]
- scope = Account.where(id: ::Follow.where(account: account).select(:target_account_id))
-
- scope.find_each do |target_account|
+ account.following.reorder(nil).find_each do |target_account|
UnfollowService.new.call(account, target_account)
rescue => e
progress.log pastel.red("Error processing #{target_account.id}: #{e}")
@@ -493,9 +491,7 @@ module Mastodon::CLI
end
if options[:followers]
- scope = Account.where(id: ::Follow.where(target_account: account).select(:account_id))
-
- scope.find_each do |target_account|
+ account.followers.reorder(nil).find_each do |target_account|
UnfollowService.new.call(target_account, account)
rescue => e
progress.log pastel.red("Error processing #{target_account.id}: #{e}")
diff --git a/lib/mastodon/cli/email_domain_blocks.rb b/lib/mastodon/cli/email_domain_blocks.rb
index 88a84ecb42..022b1dcbb1 100644
--- a/lib/mastodon/cli/email_domain_blocks.rb
+++ b/lib/mastodon/cli/email_domain_blocks.rb
@@ -7,10 +7,10 @@ module Mastodon::CLI
class EmailDomainBlocks < Base
desc 'list', 'List blocked e-mail domains'
def list
- EmailDomainBlock.where(parent_id: nil).order(id: 'DESC').find_each do |entry|
+ EmailDomainBlock.where(parent_id: nil).find_each do |entry|
say(entry.domain.to_s, :white)
- EmailDomainBlock.where(parent_id: entry.id).order(id: 'DESC').find_each do |child|
+ EmailDomainBlock.where(parent_id: entry.id).find_each do |child|
say(" #{child.domain}", :cyan)
end
end
diff --git a/lib/mastodon/cli/media.rb b/lib/mastodon/cli/media.rb
index c906161770..a796bb729a 100644
--- a/lib/mastodon/cli/media.rb
+++ b/lib/mastodon/cli/media.rb
@@ -48,8 +48,8 @@ module Mastodon::CLI
next if account.avatar.blank? && account.header.blank?
next if options[:remove_headers] && account.header.blank?
- size = (account.header_file_size || 0)
- size += (account.avatar_file_size || 0) if options[:prune_profiles]
+ size = account.header_file_size || 0
+ size += account.avatar_file_size || 0 if options[:prune_profiles]
unless dry_run?
account.header.destroy
@@ -265,6 +265,7 @@ module Mastodon::CLI
elsif options[:days].present?
scope = MediaAttachment.remote
else
+ say('Specify the source of media attachments', :red)
exit(1)
end
diff --git a/lib/mastodon/cli/statuses.rb b/lib/mastodon/cli/statuses.rb
index 0d6018a2b9..7acf3f9b77 100644
--- a/lib/mastodon/cli/statuses.rb
+++ b/lib/mastodon/cli/statuses.rb
@@ -120,7 +120,7 @@ module Mastodon::CLI
say('Beginning removal of now-orphaned media attachments to free up disk space...')
- scope = MediaAttachment.reorder(nil).unattached.where('created_at < ?', options[:days].pred.days.ago)
+ scope = MediaAttachment.unattached.where('created_at < ?', options[:days].pred.days.ago)
processed = 0
removed = 0
progress = create_progress_bar(scope.count)
diff --git a/lib/mastodon/snowflake.rb b/lib/mastodon/snowflake.rb
index 0a596b2940..ec4f6140ca 100644
--- a/lib/mastodon/snowflake.rb
+++ b/lib/mastodon/snowflake.rb
@@ -99,7 +99,7 @@ module Mastodon::Snowflake
def id_at(timestamp, with_random: true)
id = timestamp.to_i * 1000
id += rand(1000) if with_random
- id = id << 16
+ id <<= 16
id += rand(2**16) if with_random
id
end
diff --git a/package.json b/package.json
index 503df8d51d..692ebe8ee7 100644
--- a/package.json
+++ b/package.json
@@ -196,7 +196,7 @@
"eslint-plugin-jsx-a11y": "~6.8.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "~6.1.1",
- "eslint-plugin-react": "~7.33.0",
+ "eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.3",
"jest": "^29.5.0",
diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb
index 307e819501..1882ea8388 100644
--- a/spec/controllers/admin/accounts_controller_spec.rb
+++ b/spec/controllers/admin/accounts_controller_spec.rb
@@ -161,12 +161,13 @@ RSpec.describe Admin::AccountsController do
it 'logs action' do
expect(subject).to have_http_status 302
- log_item = Admin::ActionLog.last
-
- expect(log_item).to_not be_nil
- expect(log_item.action).to eq :approve
- expect(log_item.account_id).to eq current_user.account_id
- expect(log_item.target_id).to eq account.user.id
+ expect(latest_admin_action_log)
+ .to be_present
+ .and have_attributes(
+ action: eq(:approve),
+ account_id: eq(current_user.account_id),
+ target_id: eq(account.user.id)
+ )
end
end
@@ -201,12 +202,13 @@ RSpec.describe Admin::AccountsController do
it 'logs action' do
expect(subject).to have_http_status 302
- log_item = Admin::ActionLog.last
-
- expect(log_item).to_not be_nil
- expect(log_item.action).to eq :reject
- expect(log_item.account_id).to eq current_user.account_id
- expect(log_item.target_id).to eq account.user.id
+ expect(latest_admin_action_log)
+ .to be_present
+ .and have_attributes(
+ action: eq(:reject),
+ account_id: eq(current_user.account_id),
+ target_id: eq(account.user.id)
+ )
end
end
@@ -427,4 +429,10 @@ RSpec.describe Admin::AccountsController do
end
end
end
+
+ private
+
+ def latest_admin_action_log
+ Admin::ActionLog.last
+ end
end
diff --git a/spec/controllers/admin/action_logs_controller_spec.rb b/spec/controllers/admin/action_logs_controller_spec.rb
index b7854469dd..be4222df08 100644
--- a/spec/controllers/admin/action_logs_controller_spec.rb
+++ b/spec/controllers/admin/action_logs_controller_spec.rb
@@ -9,11 +9,9 @@ describe Admin::ActionLogsController do
let!(:account) { Fabricate(:account) }
before do
- _orphaned_logs = %w(
- Account User UserRole Report DomainBlock DomainAllow
- EmailDomainBlock UnavailableDomain Status AccountWarning
- Announcement IpBlock Instance CustomEmoji CanonicalEmailBlock Appeal
- ).map { |type| Admin::ActionLog.new(account: account, action: 'destroy', target_type: type, target_id: 1312).save! }
+ orphaned_log_types.map do |type|
+ Fabricate(:action_log, account: account, action: 'destroy', target_type: type, target_id: 1312)
+ end
end
describe 'GET #index' do
@@ -24,4 +22,27 @@ describe Admin::ActionLogsController do
expect(response).to have_http_status(200)
end
end
+
+ private
+
+ def orphaned_log_types
+ %w(
+ Account
+ AccountWarning
+ Announcement
+ Appeal
+ CanonicalEmailBlock
+ CustomEmoji
+ DomainAllow
+ DomainBlock
+ EmailDomainBlock
+ Instance
+ IpBlock
+ Report
+ Status
+ UnavailableDomain
+ User
+ UserRole
+ )
+ end
end
diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb
index 13826be366..22960f5312 100644
--- a/spec/controllers/admin/domain_blocks_controller_spec.rb
+++ b/spec/controllers/admin/domain_blocks_controller_spec.rb
@@ -192,16 +192,11 @@ RSpec.describe Admin::DomainBlocksController do
let(:original_severity) { 'suspend' }
let(:new_severity) { 'silence' }
- it 'changes the block severity' do
- expect { subject }.to change { domain_block.reload.severity }.from('suspend').to('silence')
- end
-
- it 'undoes individual suspensions' do
- expect { subject }.to change { remote_account.reload.suspended? }.from(true).to(false)
- end
-
- it 'performs individual silences' do
- expect { subject }.to change { remote_account.reload.silenced? }.from(false).to(true)
+ it 'changes the block severity, suspensions, and silences' do
+ expect { subject }
+ .to change_severity('suspend', 'silence')
+ .and change_suspended(true, false)
+ .and change_silenced(false, true)
end
end
@@ -209,17 +204,26 @@ RSpec.describe Admin::DomainBlocksController do
let(:original_severity) { 'silence' }
let(:new_severity) { 'suspend' }
- it 'changes the block severity' do
- expect { subject }.to change { domain_block.reload.severity }.from('silence').to('suspend')
+ it 'changes the block severity, silences, and suspensions' do
+ expect { subject }
+ .to change_severity('silence', 'suspend')
+ .and change_silenced(true, false)
+ .and change_suspended(false, true)
end
+ end
- it 'undoes individual silences' do
- expect { subject }.to change { remote_account.reload.silenced? }.from(true).to(false)
- end
+ private
- it 'performs individual suspends' do
- expect { subject }.to change { remote_account.reload.suspended? }.from(false).to(true)
- end
+ def change_severity(from, to)
+ change { domain_block.reload.severity }.from(from).to(to)
+ end
+
+ def change_silenced(from, to)
+ change { remote_account.reload.silenced? }.from(from).to(to)
+ end
+
+ def change_suspended(from, to)
+ change { remote_account.reload.suspended? }.from(from).to(to)
end
end
diff --git a/spec/controllers/admin/export_domain_allows_controller_spec.rb b/spec/controllers/admin/export_domain_allows_controller_spec.rb
index e1e5ecc1f0..0a2e342620 100644
--- a/spec/controllers/admin/export_domain_allows_controller_spec.rb
+++ b/spec/controllers/admin/export_domain_allows_controller_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Admin::ExportDomainAllowsController do
get :export, params: { format: :csv }
expect(response).to have_http_status(200)
- expect(response.body).to eq(File.read(File.join(file_fixture_path, 'domain_allows.csv')))
+ expect(response.body).to eq(domain_allows_csv_file)
end
end
@@ -40,7 +40,7 @@ RSpec.describe Admin::ExportDomainAllowsController do
# Domains should now be added
get :export, params: { format: :csv }
expect(response).to have_http_status(200)
- expect(response.body).to eq(File.read(File.join(file_fixture_path, 'domain_allows.csv')))
+ expect(response.body).to eq(domain_allows_csv_file)
end
it 'displays error on no file selected' do
@@ -49,4 +49,10 @@ RSpec.describe Admin::ExportDomainAllowsController do
expect(flash[:error]).to eq(I18n.t('admin.export_domain_allows.no_file'))
end
end
+
+ private
+
+ def domain_allows_csv_file
+ File.read(File.join(file_fixture_path, 'domain_allows.csv'))
+ end
end
diff --git a/spec/controllers/admin/export_domain_blocks_controller_spec.rb b/spec/controllers/admin/export_domain_blocks_controller_spec.rb
index 5a282c9572..bfcccfa06c 100644
--- a/spec/controllers/admin/export_domain_blocks_controller_spec.rb
+++ b/spec/controllers/admin/export_domain_blocks_controller_spec.rb
@@ -26,7 +26,13 @@ RSpec.describe Admin::ExportDomainBlocksController do
get :export, params: { format: :csv }
expect(response).to have_http_status(200)
- expect(response.body).to eq(File.read(File.join(file_fixture_path, 'domain_blocks.csv')))
+ expect(response.body).to eq(domain_blocks_csv_file)
+ end
+
+ private
+
+ def domain_blocks_csv_file
+ File.read(File.join(file_fixture_path, 'domain_blocks.csv'))
end
end
diff --git a/spec/fixtures/files/elite-assets.tar.gz b/spec/fixtures/files/elite-assets.tar.gz
new file mode 100644
index 0000000000..7b4f442570
Binary files /dev/null and b/spec/fixtures/files/elite-assets.tar.gz differ
diff --git a/spec/generators/post_deployment_migration_generator_spec.rb b/spec/generators/post_deployment_migration_generator_spec.rb
index d770a78e97..55e70a7917 100644
--- a/spec/generators/post_deployment_migration_generator_spec.rb
+++ b/spec/generators/post_deployment_migration_generator_spec.rb
@@ -12,7 +12,7 @@ describe PostDeploymentMigrationGenerator, type: :generator do
include FileUtils
tests described_class
- destination File.expand_path('../../tmp', __dir__)
+ destination Rails.root.join('tmp', 'generator-test')
before { prepare_destination }
after { rm_rf(destination_root) }
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 1ccf19a96b..82272b717f 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -29,15 +29,27 @@ describe ApplicationHelper do
describe 'body_classes' do
context 'with a body class string from a controller' do
- before do
- without_partial_double_verification do
- allow(helper).to receive_messages(body_class_string: 'modal-layout compose-standalone', current_flavour: 'glitch', current_skin: 'default', current_account: Fabricate(:account))
- end
- end
+ before { helper.extend controller_helpers }
it 'uses the controller body classes in the result' do
expect(helper.body_classes).to match(/modal-layout compose-standalone/)
end
+
+ private
+
+ def controller_helpers
+ Module.new do
+ def body_class_string = 'modal-layout compose-standalone'
+ def body_class_string = 'modal-layout compose-standalone'
+
+ def current_account
+ @current_account ||= Fabricate(:account)
+ end
+
+ def current_flavour = 'glitch'
+ def current_skin = 'default'
+ end
+ end
end
end
@@ -122,9 +134,7 @@ describe ApplicationHelper do
describe 'available_sign_up_path' do
context 'when registrations are closed' do
before do
- without_partial_double_verification do
- allow(Setting).to receive(:registrations_mode).and_return('none')
- end
+ allow(Setting).to receive(:[]).with('registrations_mode').and_return 'none'
end
it 'redirects to joinmastodon site' do
diff --git a/spec/helpers/home_helper_spec.rb b/spec/helpers/home_helper_spec.rb
index c6baec5a1f..befc8a5c80 100644
--- a/spec/helpers/home_helper_spec.rb
+++ b/spec/helpers/home_helper_spec.rb
@@ -23,12 +23,19 @@ RSpec.describe HomeHelper do
context 'with a valid account' do
let(:account) { Fabricate(:account) }
- it 'returns a link to the account' do
- without_partial_double_verification do
- allow(helper).to receive_messages(current_account: account, prefers_autoplay?: false)
- result = helper.account_link_to(account)
+ before { helper.extend controller_helpers }
- expect(result).to match "@#{account.acct}"
+ it 'returns a link to the account' do
+ result = helper.account_link_to(account)
+
+ expect(result).to match "@#{account.acct}"
+ end
+
+ private
+
+ def controller_helpers
+ Module.new do
+ def current_account = Account.last
end
end
end
diff --git a/spec/helpers/media_component_helper_spec.rb b/spec/helpers/media_component_helper_spec.rb
index 149f6a83ad..af5d92769c 100644
--- a/spec/helpers/media_component_helper_spec.rb
+++ b/spec/helpers/media_component_helper_spec.rb
@@ -3,16 +3,12 @@
require 'rails_helper'
describe MediaComponentHelper do
+ before { helper.extend controller_helpers }
+
describe 'render_video_component' do
let(:media) { Fabricate(:media_attachment, type: :video, status: Fabricate(:status)) }
let(:result) { helper.render_video_component(media.status) }
- before do
- without_partial_double_verification do
- allow(helper).to receive(:current_account).and_return(media.account)
- end
- end
-
it 'renders a react component for the video' do
expect(parsed_html.div['data-component']).to eq('Video')
end
@@ -22,12 +18,6 @@ describe MediaComponentHelper do
let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) }
let(:result) { helper.render_audio_component(media.status) }
- before do
- without_partial_double_verification do
- allow(helper).to receive(:current_account).and_return(media.account)
- end
- end
-
it 'renders a react component for the audio' do
expect(parsed_html.div['data-component']).to eq('Audio')
end
@@ -37,12 +27,6 @@ describe MediaComponentHelper do
let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) }
let(:result) { helper.render_media_gallery_component(media.status) }
- before do
- without_partial_double_verification do
- allow(helper).to receive(:current_account).and_return(media.account)
- end
- end
-
it 'renders a react component for the media gallery' do
expect(parsed_html.div['data-component']).to eq('MediaGallery')
end
@@ -54,10 +38,6 @@ describe MediaComponentHelper do
before do
PreviewCardsStatus.create(status: status, preview_card: Fabricate(:preview_card))
-
- without_partial_double_verification do
- allow(helper).to receive(:current_account).and_return(status.account)
- end
end
it 'returns the correct react component markup' do
@@ -69,12 +49,6 @@ describe MediaComponentHelper do
let(:status) { Fabricate(:status, poll: Fabricate(:poll)) }
let(:result) { helper.render_poll_component(status) }
- before do
- without_partial_double_verification do
- allow(helper).to receive(:current_account).and_return(status.account)
- end
- end
-
it 'returns the correct react component markup' do
expect(parsed_html.div['data-component']).to eq('Poll')
end
@@ -85,4 +59,10 @@ describe MediaComponentHelper do
def parsed_html
Nokogiri::Slop(result)
end
+
+ def controller_helpers
+ Module.new do
+ def current_account = Account.last
+ end
+ end
end
diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb
index 626cf4778c..3216d0d1bd 100644
--- a/spec/lib/mastodon/cli/accounts_spec.rb
+++ b/spec/lib/mastodon/cli/accounts_spec.rb
@@ -6,6 +6,8 @@ require 'mastodon/cli/accounts'
describe Mastodon::CLI::Accounts do
let(:cli) { described_class.new }
+ it_behaves_like 'CLI Command'
+
# `parallelize_with_progress` cannot run in transactions, so instead,
# stub it with an alternative implementation that runs sequentially
# and can run in transactions.
@@ -24,12 +26,6 @@ describe Mastodon::CLI::Accounts do
end
end
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
-
describe '#create' do
shared_examples 'a new user with given email address and username' do
it 'creates a new user with the specified email address' do
diff --git a/spec/lib/mastodon/cli/cache_spec.rb b/spec/lib/mastodon/cli/cache_spec.rb
index 3ab42dc8ce..c1ce04710c 100644
--- a/spec/lib/mastodon/cli/cache_spec.rb
+++ b/spec/lib/mastodon/cli/cache_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/cache'
describe Mastodon::CLI::Cache do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#clear' do
before { allow(Rails.cache).to receive(:clear) }
diff --git a/spec/lib/mastodon/cli/canonical_email_blocks_spec.rb b/spec/lib/mastodon/cli/canonical_email_blocks_spec.rb
index eb57a3cd15..6e4675748e 100644
--- a/spec/lib/mastodon/cli/canonical_email_blocks_spec.rb
+++ b/spec/lib/mastodon/cli/canonical_email_blocks_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/canonical_email_blocks'
describe Mastodon::CLI::CanonicalEmailBlocks do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#find' do
let(:arguments) { ['user@example.com'] }
diff --git a/spec/lib/mastodon/cli/domains_spec.rb b/spec/lib/mastodon/cli/domains_spec.rb
index ea58845c00..add754159c 100644
--- a/spec/lib/mastodon/cli/domains_spec.rb
+++ b/spec/lib/mastodon/cli/domains_spec.rb
@@ -4,9 +4,22 @@ require 'rails_helper'
require 'mastodon/cli/domains'
describe Mastodon::CLI::Domains do
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
+ let(:cli) { described_class.new }
+
+ it_behaves_like 'CLI Command'
+
+ describe '#purge' do
+ context 'with accounts from the domain' do
+ let(:options) { {} }
+ let(:domain) { 'host.example' }
+ let!(:account) { Fabricate(:account, domain: domain) }
+
+ it 'removes the account' do
+ expect { cli.invoke(:purge, [domain], options) }.to output(
+ a_string_including('Removed 1 accounts')
+ ).to_stdout
+ expect { account.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
end
end
end
diff --git a/spec/lib/mastodon/cli/email_domain_blocks_spec.rb b/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
index 333ae3f2b7..f5cb6c332b 100644
--- a/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
+++ b/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
@@ -4,9 +4,98 @@ require 'rails_helper'
require 'mastodon/cli/email_domain_blocks'
describe Mastodon::CLI::EmailDomainBlocks do
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
+ let(:cli) { described_class.new }
+
+ it_behaves_like 'CLI Command'
+
+ describe '#list' do
+ context 'with email domain block records' do
+ let!(:parent_block) { Fabricate(:email_domain_block) }
+ let!(:child_block) { Fabricate(:email_domain_block, parent: parent_block) }
+ let(:options) { {} }
+
+ it 'lists the blocks' do
+ expect { cli.invoke(:list, [], options) }.to output(
+ a_string_including(parent_block.domain)
+ .and(a_string_including(child_block.domain))
+ ).to_stdout
+ end
+ end
+ end
+
+ describe '#add' do
+ context 'without any options' do
+ let(:options) { {} }
+
+ it 'warns about usage and exits' do
+ expect { cli.invoke(:add, [], options) }.to output(
+ a_string_including('No domain(s) given')
+ ).to_stdout.and raise_error(SystemExit)
+ end
+ end
+
+ context 'when blocks exist' do
+ let(:options) { {} }
+ let(:domain) { 'host.example' }
+
+ before { Fabricate(:email_domain_block, domain: domain) }
+
+ it 'does not add a new block' do
+ expect { cli.invoke(:add, [domain], options) }.to output(
+ a_string_including('is already blocked')
+ ).to_stdout
+ .and(not_change(EmailDomainBlock, :count))
+ end
+ end
+
+ context 'when no blocks exist' do
+ let(:options) { {} }
+ let(:domain) { 'host.example' }
+
+ it 'adds a new block' do
+ expect { cli.invoke(:add, [domain], options) }.to output(
+ a_string_including('Added 1')
+ ).to_stdout
+ .and(change(EmailDomainBlock, :count).by(1))
+ end
+ end
+ end
+
+ describe '#remove' do
+ context 'without any options' do
+ let(:options) { {} }
+
+ it 'warns about usage and exits' do
+ expect { cli.invoke(:remove, [], options) }.to output(
+ a_string_including('No domain(s) given')
+ ).to_stdout.and raise_error(SystemExit)
+ end
+ end
+
+ context 'when blocks exist' do
+ let(:options) { {} }
+ let(:domain) { 'host.example' }
+
+ before { Fabricate(:email_domain_block, domain: domain) }
+
+ it 'removes the block' do
+ expect { cli.invoke(:remove, [domain], options) }.to output(
+ a_string_including('Removed 1')
+ ).to_stdout
+ .and(change(EmailDomainBlock, :count).by(-1))
+ end
+ end
+
+ context 'when no blocks exist' do
+ let(:options) { {} }
+ let(:domain) { 'host.example' }
+
+ it 'does not remove a block' do
+ expect { cli.invoke(:remove, [domain], options) }.to output(
+ a_string_including('is not yet blocked')
+ ).to_stdout
+ .and(not_change(EmailDomainBlock, :count))
+ end
end
end
end
diff --git a/spec/lib/mastodon/cli/emoji_spec.rb b/spec/lib/mastodon/cli/emoji_spec.rb
index 9b58653729..3441413b90 100644
--- a/spec/lib/mastodon/cli/emoji_spec.rb
+++ b/spec/lib/mastodon/cli/emoji_spec.rb
@@ -4,9 +4,65 @@ require 'rails_helper'
require 'mastodon/cli/emoji'
describe Mastodon::CLI::Emoji do
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
+ subject { cli.invoke(action, args, options) }
+
+ let(:cli) { described_class.new }
+ let(:args) { [] }
+ let(:options) { {} }
+
+ it_behaves_like 'CLI Command'
+
+ describe '#purge' do
+ let(:action) { :purge }
+
+ context 'with existing custom emoji' do
+ before { Fabricate(:custom_emoji) }
+
+ it 'reports a successful purge' do
+ expect { subject }
+ .to output_results('OK')
+ end
end
end
+
+ describe '#import' do
+ context 'with existing custom emoji' do
+ let(:import_path) { Rails.root.join('spec', 'fixtures', 'files', 'elite-assets.tar.gz') }
+ let(:action) { :import }
+ let(:args) { [import_path] }
+
+ it 'reports about imported emoji' do
+ expect { subject }
+ .to output_results('Imported 1')
+ .and change(CustomEmoji, :count).by(1)
+ end
+ end
+ end
+
+ describe '#export' do
+ context 'with existing custom emoji' do
+ before do
+ FileUtils.rm_rf(export_path.dirname)
+ FileUtils.mkdir_p(export_path.dirname)
+
+ Fabricate(:custom_emoji)
+ end
+
+ after { FileUtils.rm_rf(export_path.dirname) }
+
+ let(:export_path) { Rails.root.join('tmp', 'cli-tests', 'export.tar.gz') }
+ let(:args) { [export_path.dirname.to_s] }
+ let(:action) { :export }
+
+ it 'reports about exported emoji' do
+ expect { subject }
+ .to output_results('Exported 1')
+ .and change { File.exist?(export_path) }.from(false).to(true)
+ end
+ end
+ end
+
+ def output_results(string)
+ output(a_string_including(string)).to_stdout
+ end
end
diff --git a/spec/lib/mastodon/cli/feeds_spec.rb b/spec/lib/mastodon/cli/feeds_spec.rb
index 030f087212..e16113c854 100644
--- a/spec/lib/mastodon/cli/feeds_spec.rb
+++ b/spec/lib/mastodon/cli/feeds_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/feeds'
describe Mastodon::CLI::Feeds do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#build' do
before { Fabricate(:account) }
diff --git a/spec/lib/mastodon/cli/ip_blocks_spec.rb b/spec/lib/mastodon/cli/ip_blocks_spec.rb
index 030d9fcb19..684314dc7a 100644
--- a/spec/lib/mastodon/cli/ip_blocks_spec.rb
+++ b/spec/lib/mastodon/cli/ip_blocks_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/ip_blocks'
describe Mastodon::CLI::IpBlocks do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#add' do
let(:ip_list) do
diff --git a/spec/lib/mastodon/cli/main_spec.rb b/spec/lib/mastodon/cli/main_spec.rb
index e3709afe37..b5b5d69062 100644
--- a/spec/lib/mastodon/cli/main_spec.rb
+++ b/spec/lib/mastodon/cli/main_spec.rb
@@ -4,11 +4,7 @@ require 'rails_helper'
require 'mastodon/cli/main'
describe Mastodon::CLI::Main do
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe 'version' do
it 'returns the Mastodon version' do
diff --git a/spec/lib/mastodon/cli/maintenance_spec.rb b/spec/lib/mastodon/cli/maintenance_spec.rb
index a6789ea5a4..95e695ab55 100644
--- a/spec/lib/mastodon/cli/maintenance_spec.rb
+++ b/spec/lib/mastodon/cli/maintenance_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/maintenance'
describe Mastodon::CLI::Maintenance do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#fix_duplicates' do
context 'when the database version is too old' do
diff --git a/spec/lib/mastodon/cli/media_spec.rb b/spec/lib/mastodon/cli/media_spec.rb
index 9543640e96..6d510c1f5a 100644
--- a/spec/lib/mastodon/cli/media_spec.rb
+++ b/spec/lib/mastodon/cli/media_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/media'
describe Mastodon::CLI::Media do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#remove' do
context 'with --prune-profiles and --remove-headers' do
@@ -78,4 +74,89 @@ describe Mastodon::CLI::Media do
end
end
end
+
+ describe '#usage' do
+ context 'without options' do
+ let(:options) { {} }
+
+ it 'reports about storage size' do
+ expect { cli.invoke(:usage, [], options) }.to output(
+ a_string_including('0 Bytes')
+ ).to_stdout
+ end
+ end
+ end
+
+ describe '#refresh' do
+ context 'without any options' do
+ let(:options) { {} }
+
+ it 'warns about usage and exits' do
+ expect { cli.invoke(:refresh, [], options) }.to output(
+ a_string_including('Specify the source')
+ ).to_stdout.and raise_error(SystemExit)
+ end
+ end
+
+ context 'with --status option' do
+ before do
+ media_attachment.update(file_file_name: nil)
+ end
+
+ let(:media_attachment) { Fabricate(:media_attachment, status: status, remote_url: 'https://host.example/asset.jpg') }
+ let(:options) { { status: status.id } }
+ let(:status) { Fabricate(:status) }
+
+ it 'redownloads the attachment file' do
+ expect { cli.invoke(:refresh, [], options) }.to output(
+ a_string_including('Downloaded 1 media')
+ ).to_stdout
+ end
+ end
+
+ context 'with --account option' do
+ context 'when the account does not exist' do
+ let(:options) { { account: 'not-real-user@example.host' } }
+
+ it 'warns about usage and exits' do
+ expect { cli.invoke(:refresh, [], options) }.to output(
+ a_string_including('No such account')
+ ).to_stdout.and raise_error(SystemExit)
+ end
+ end
+
+ context 'when the account exists' do
+ before do
+ media_attachment.update(file_file_name: nil)
+ end
+
+ let(:media_attachment) { Fabricate(:media_attachment, account: account) }
+ let(:options) { { account: account.acct } }
+ let(:account) { Fabricate(:account) }
+
+ it 'redownloads the attachment file' do
+ expect { cli.invoke(:refresh, [], options) }.to output(
+ a_string_including('Downloaded 1 media')
+ ).to_stdout
+ end
+ end
+ end
+
+ context 'with --domain option' do
+ before do
+ media_attachment.update(file_file_name: nil)
+ end
+
+ let(:domain) { 'example.host' }
+ let(:media_attachment) { Fabricate(:media_attachment, account: account) }
+ let(:options) { { domain: domain } }
+ let(:account) { Fabricate(:account, domain: domain) }
+
+ it 'redownloads the attachment file' do
+ expect { cli.invoke(:refresh, [], options) }.to output(
+ a_string_including('Downloaded 1 media')
+ ).to_stdout
+ end
+ end
+ end
end
diff --git a/spec/lib/mastodon/cli/preview_cards_spec.rb b/spec/lib/mastodon/cli/preview_cards_spec.rb
index 1e064ed58e..a766d250eb 100644
--- a/spec/lib/mastodon/cli/preview_cards_spec.rb
+++ b/spec/lib/mastodon/cli/preview_cards_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/preview_cards'
describe Mastodon::CLI::PreviewCards do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#remove' do
context 'with relevant preview cards' do
diff --git a/spec/lib/mastodon/cli/search_spec.rb b/spec/lib/mastodon/cli/search_spec.rb
index d5cae5bf49..785dc2bd61 100644
--- a/spec/lib/mastodon/cli/search_spec.rb
+++ b/spec/lib/mastodon/cli/search_spec.rb
@@ -4,9 +4,5 @@ require 'rails_helper'
require 'mastodon/cli/search'
describe Mastodon::CLI::Search do
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
end
diff --git a/spec/lib/mastodon/cli/settings_spec.rb b/spec/lib/mastodon/cli/settings_spec.rb
index ae58e74e56..7dcd1110ba 100644
--- a/spec/lib/mastodon/cli/settings_spec.rb
+++ b/spec/lib/mastodon/cli/settings_spec.rb
@@ -4,11 +4,7 @@ require 'rails_helper'
require 'mastodon/cli/settings'
describe Mastodon::CLI::Settings do
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe 'subcommand "registrations"' do
let(:cli) { Mastodon::CLI::Registrations.new }
diff --git a/spec/lib/mastodon/cli/statuses_spec.rb b/spec/lib/mastodon/cli/statuses_spec.rb
index 38ebcd9934..70e4e2c086 100644
--- a/spec/lib/mastodon/cli/statuses_spec.rb
+++ b/spec/lib/mastodon/cli/statuses_spec.rb
@@ -6,11 +6,7 @@ require 'mastodon/cli/statuses'
describe Mastodon::CLI::Statuses do
let(:cli) { described_class.new }
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
- end
- end
+ it_behaves_like 'CLI Command'
describe '#remove', use_transactional_tests: false do
context 'with small batch size' do
diff --git a/spec/lib/mastodon/cli/upgrade_spec.rb b/spec/lib/mastodon/cli/upgrade_spec.rb
index 9e0ab9d06e..0d6494eeee 100644
--- a/spec/lib/mastodon/cli/upgrade_spec.rb
+++ b/spec/lib/mastodon/cli/upgrade_spec.rb
@@ -4,9 +4,24 @@ require 'rails_helper'
require 'mastodon/cli/upgrade'
describe Mastodon::CLI::Upgrade do
- describe '.exit_on_failure?' do
- it 'returns true' do
- expect(described_class.exit_on_failure?).to be true
+ let(:cli) { described_class.new }
+
+ it_behaves_like 'CLI Command'
+
+ describe '#storage_schema' do
+ context 'with records that dont need upgrading' do
+ let(:options) { {} }
+
+ before do
+ Fabricate(:account)
+ Fabricate(:media_attachment)
+ end
+
+ it 'does not upgrade storage for the attachments' do
+ expect { cli.invoke(:storage_schema, [], options) }.to output(
+ a_string_including('Upgraded storage schema of 0 records')
+ ).to_stdout
+ end
end
end
end
diff --git a/spec/models/concerns/remotable_spec.rb b/spec/models/concerns/remotable_spec.rb
index db690da3c2..9f6aeb7fb4 100644
--- a/spec/models/concerns/remotable_spec.rb
+++ b/spec/models/concerns/remotable_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Remotable do
end
end
- let(:attribute_name) { "#{hoge}_remote_url".to_sym }
+ let(:attribute_name) { :"#{hoge}_remote_url" }
let(:code) { 200 }
let(:file) { 'filename="foo.txt"' }
let(:foo) { foo_class.new }
diff --git a/spec/models/form/account_batch_spec.rb b/spec/models/form/account_batch_spec.rb
index fd8e909010..26fb1b953a 100644
--- a/spec/models/form/account_batch_spec.rb
+++ b/spec/models/form/account_batch_spec.rb
@@ -37,12 +37,10 @@ RSpec.describe Form::AccountBatch do
let(:select_all_matching) { '0' }
let(:account_ids) { [target_account.id, target_account2.id] }
- it 'suspends the expected users' do
- expect { subject }.to change { [target_account.reload.suspended?, target_account2.reload.suspended?] }.from([false, false]).to([true, true])
- end
-
- it 'closes open reports targeting the suspended users' do
- expect { subject }.to change { Report.unresolved.where(target_account: [target_account, target_account2]).count }.from(2).to(0)
+ it 'suspends the expected users and closes open reports' do
+ expect { subject }
+ .to change_account_suspensions
+ .and change_open_reports_for_accounts
end
end
@@ -50,13 +48,33 @@ RSpec.describe Form::AccountBatch do
let(:select_all_matching) { '1' }
let(:query) { Account.where(id: [target_account.id, target_account2.id]) }
- it 'suspends the expected users' do
- expect { subject }.to change { [target_account.reload.suspended?, target_account2.reload.suspended?] }.from([false, false]).to([true, true])
+ it 'suspends the expected users and closes open reports' do
+ expect { subject }
+ .to change_account_suspensions
+ .and change_open_reports_for_accounts
end
+ end
- it 'closes open reports targeting the suspended users' do
- expect { subject }.to change { Report.unresolved.where(target_account: [target_account, target_account2]).count }.from(2).to(0)
- end
+ private
+
+ def change_account_suspensions
+ change { relevant_account_suspension_statuses }
+ .from([false, false])
+ .to([true, true])
+ end
+
+ def change_open_reports_for_accounts
+ change(relevant_account_unresolved_reports, :count)
+ .from(2)
+ .to(0)
+ end
+
+ def relevant_account_unresolved_reports
+ Report.unresolved.where(target_account: [target_account, target_account2])
+ end
+
+ def relevant_account_suspension_statuses
+ [target_account.reload, target_account2.reload].map(&:suspended?)
end
end
end
diff --git a/spec/requests/api/v1/admin/account_actions_spec.rb b/spec/requests/api/v1/admin/account_actions_spec.rb
index c14e08c21c..4167911a13 100644
--- a/spec/requests/api/v1/admin/account_actions_spec.rb
+++ b/spec/requests/api/v1/admin/account_actions_spec.rb
@@ -21,12 +21,19 @@ RSpec.describe 'Account actions' do
it 'logs action' do
subject
- log_item = Admin::ActionLog.last
+ expect(latest_admin_action_log)
+ .to be_present
+ .and have_attributes(
+ action: eq(action_type),
+ account_id: eq(user.account_id),
+ target_id: eq(target_type == :user ? target_account.user.id : target_account.id)
+ )
+ end
- expect(log_item).to be_present
- expect(log_item.action).to eq(action_type)
- expect(log_item.account_id).to eq(user.account_id)
- expect(log_item.target_id).to eq(target_type == :user ? target_account.user.id : target_account.id)
+ private
+
+ def latest_admin_action_log
+ Admin::ActionLog.last
end
end
diff --git a/spec/requests/api/v1/admin/accounts_spec.rb b/spec/requests/api/v1/admin/accounts_spec.rb
index 8e158f623d..1615581f0e 100644
--- a/spec/requests/api/v1/admin/accounts_spec.rb
+++ b/spec/requests/api/v1/admin/accounts_spec.rb
@@ -151,12 +151,13 @@ RSpec.describe 'Accounts' do
it 'logs action', :aggregate_failures do
subject
- log_item = Admin::ActionLog.last
-
- expect(log_item).to be_present
- expect(log_item.action).to eq :approve
- expect(log_item.account_id).to eq user.account_id
- expect(log_item.target_id).to eq account.user.id
+ expect(latest_admin_action_log)
+ .to be_present
+ .and have_attributes(
+ action: eq(:approve),
+ account_id: eq(user.account_id),
+ target_id: eq(account.user.id)
+ )
end
end
@@ -202,12 +203,13 @@ RSpec.describe 'Accounts' do
it 'logs action', :aggregate_failures do
subject
- log_item = Admin::ActionLog.last
-
- expect(log_item).to be_present
- expect(log_item.action).to eq :reject
- expect(log_item.account_id).to eq user.account_id
- expect(log_item.target_id).to eq account.user.id
+ expect(latest_admin_action_log)
+ .to be_present
+ .and have_attributes(
+ action: eq(:reject),
+ account_id: eq(user.account_id),
+ target_id: eq(account.user.id)
+ )
end
end
@@ -398,4 +400,10 @@ RSpec.describe 'Accounts' do
end
end
end
+
+ private
+
+ def latest_admin_action_log
+ Admin::ActionLog.last
+ end
end
diff --git a/spec/requests/api/v1/lists_spec.rb b/spec/requests/api/v1/lists_spec.rb
index 22dde43a19..4635e936f5 100644
--- a/spec/requests/api/v1/lists_spec.rb
+++ b/spec/requests/api/v1/lists_spec.rb
@@ -135,8 +135,11 @@ RSpec.describe 'Lists' do
it_behaves_like 'forbidden for wrong scope', 'read read:lists'
- it 'returns the updated list', :aggregate_failures do
- subject
+ it 'returns the updated list and updates values', :aggregate_failures do
+ expect { subject }
+ .to change_list_title
+ .and change_list_replies_policy
+ .and change_list_exclusive
expect(response).to have_http_status(200)
list.reload
@@ -149,16 +152,16 @@ RSpec.describe 'Lists' do
})
end
- it 'updates the list title' do
- expect { subject }.to change { list.reload.title }.from('my list').to('list')
+ def change_list_title
+ change { list.reload.title }.from('my list').to('list')
end
- it 'updates the list replies_policy' do
- expect { subject }.to change { list.reload.replies_policy }.from('list').to('followed')
+ def change_list_replies_policy
+ change { list.reload.replies_policy }.from('list').to('followed')
end
- it 'updates the list exclusive' do
- expect { subject }.to change { list.reload.exclusive }.from(false).to(true)
+ def change_list_exclusive
+ change { list.reload.exclusive }.from(false).to(true)
end
context 'when the list does not exist' do
diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb
index c02a0800a3..09eb5ddee3 100644
--- a/spec/services/activitypub/process_account_service_spec.rb
+++ b/spec/services/activitypub/process_account_service_spec.rb
@@ -129,12 +129,10 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
stub_const 'ActivityPub::ProcessAccountService::SUBDOMAINS_RATELIMIT', 5
end
- it 'creates at least some accounts' do
- expect { subject }.to change { Account.remote.count }.by_at_least(2)
- end
-
- it 'creates no more account than the limit allows' do
- expect { subject }.to change { Account.remote.count }.by_at_most(5)
+ it 'creates accounts without exceeding rate limit' do
+ expect { subject }
+ .to create_some_remote_accounts
+ .and create_fewer_than_rate_limit_accounts
end
end
@@ -195,12 +193,20 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
end
end
- it 'creates at least some accounts' do
- expect { subject.call('user1', 'foo.test', payload) }.to change { Account.remote.count }.by_at_least(2)
- end
-
- it 'creates no more account than the limit allows' do
- expect { subject.call('user1', 'foo.test', payload) }.to change { Account.remote.count }.by_at_most(5)
+ it 'creates accounts without exceeding rate limit' do
+ expect { subject.call('user1', 'foo.test', payload) }
+ .to create_some_remote_accounts
+ .and create_fewer_than_rate_limit_accounts
end
end
+
+ private
+
+ def create_some_remote_accounts
+ change(Account.remote, :count).by_at_least(2)
+ end
+
+ def create_fewer_than_rate_limit_accounts
+ change(Account.remote, :count).by_at_most(5)
+ end
end
diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb
index 68ab491e4e..8a19d3cf74 100644
--- a/spec/services/delete_account_service_spec.rb
+++ b/spec/services/delete_account_service_spec.rb
@@ -27,8 +27,15 @@ RSpec.describe DeleteAccountService, type: :service do
let!(:account_note) { Fabricate(:account_note, account: account) }
- it 'deletes associated owned records' do
- expect { subject }.to change {
+ it 'deletes associated owned and target records and target notifications' do
+ expect { subject }
+ .to delete_associated_owned_records
+ .and delete_associated_target_records
+ .and delete_associated_target_notifications
+ end
+
+ def delete_associated_owned_records
+ change do
[
account.statuses,
account.media_attachments,
@@ -39,23 +46,23 @@ RSpec.describe DeleteAccountService, type: :service do
account.polls,
account.account_notes,
].map(&:count)
- }.from([2, 1, 1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0])
+ end.from([2, 1, 1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0])
end
- it 'deletes associated target records' do
- expect { subject }.to change {
+ def delete_associated_target_records
+ change do
[
AccountPin.where(target_account: account),
].map(&:count)
- }.from([1]).to([0])
+ end.from([1]).to([0])
end
- it 'deletes associated target notifications' do
- expect { subject }.to change {
+ def delete_associated_target_notifications
+ change do
%w(
poll favourite status mention follow
).map { |type| Notification.where(type: type).count }
- }.from([1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0])
+ end.from([1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0])
end
end
diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb
index edb7050083..c258995b7e 100644
--- a/spec/services/suspend_account_service_spec.rb
+++ b/spec/services/suspend_account_service_spec.rb
@@ -18,14 +18,15 @@ RSpec.describe SuspendAccountService, type: :service do
account.suspend!
end
- it "unmerges from local followers' feeds" do
- subject
+ it 'unmerges from feeds of local followers and preserves suspended flag' do
+ expect { subject }
+ .to_not change_suspended_flag
expect(FeedManager.instance).to have_received(:unmerge_from_home).with(account, local_follower)
expect(FeedManager.instance).to have_received(:unmerge_from_list).with(account, list)
end
- it 'does not change the “suspended” flag' do
- expect { subject }.to_not change(account, :suspended?)
+ def change_suspended_flag
+ change(account, :suspended?)
end
end
diff --git a/spec/services/unsuspend_account_service_spec.rb b/spec/services/unsuspend_account_service_spec.rb
index c555b661ec..2f737c6215 100644
--- a/spec/services/unsuspend_account_service_spec.rb
+++ b/spec/services/unsuspend_account_service_spec.rb
@@ -45,14 +45,19 @@ RSpec.describe UnsuspendAccountService, type: :service do
remote_follower.follow!(account)
end
- it "merges back into local followers' feeds" do
+ it 'merges back into feeds of local followers and sends update' do
subject
+
+ expect_feeds_merged
+ expect_updates_sent
+ end
+
+ def expect_feeds_merged
expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list)
end
- it 'sends an update actor to followers and reporters' do
- subject
+ def expect_updates_sent
expect(a_request(:post, remote_follower.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
expect(a_request(:post, remote_reporter.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
end
@@ -73,19 +78,20 @@ RSpec.describe UnsuspendAccountService, type: :service do
allow(resolve_account_service).to receive(:call).with(account).and_return(account)
end
- it 're-fetches the account' do
- subject
+ it 're-fetches the account, merges feeds, and preserves suspended' do
+ expect { subject }
+ .to_not change_suspended_flag
+ expect_feeds_merged
expect(resolve_account_service).to have_received(:call).with(account)
end
- it "merges back into local followers' feeds" do
- subject
+ def expect_feeds_merged
expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list)
end
- it 'does not change the “suspended” flag' do
- expect { subject }.to_not change(account, :suspended?)
+ def change_suspended_flag
+ change(account, :suspended?)
end
end
@@ -97,19 +103,20 @@ RSpec.describe UnsuspendAccountService, type: :service do
end
end
- it 're-fetches the account' do
- subject
+ it 're-fetches the account, does not merge feeds, marks suspended' do
+ expect { subject }
+ .to change_suspended_to_true
expect(resolve_account_service).to have_received(:call).with(account)
+ expect_feeds_not_merged
end
- it "does not merge back into local followers' feeds" do
- subject
+ def expect_feeds_not_merged
expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list)
end
- it 'marks account as suspended' do
- expect { subject }.to change(account, :suspended?).from(false).to(true)
+ def change_suspended_to_true
+ change(account, :suspended?).from(false).to(true)
end
end
@@ -118,13 +125,14 @@ RSpec.describe UnsuspendAccountService, type: :service do
allow(resolve_account_service).to receive(:call).with(account).and_return(nil)
end
- it 're-fetches the account' do
+ it 're-fetches the account and does not merge feeds' do
subject
+
expect(resolve_account_service).to have_received(:call).with(account)
+ expect_feeds_not_merged
end
- it "does not merge back into local followers' feeds" do
- subject
+ def expect_feeds_not_merged
expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list)
end
diff --git a/spec/support/examples/cli.rb b/spec/support/examples/cli.rb
new file mode 100644
index 0000000000..091c842bd1
--- /dev/null
+++ b/spec/support/examples/cli.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+shared_examples 'CLI Command' do
+ it 'configures Thor to exit on failure' do
+ expect(described_class.exit_on_failure?).to be true
+ end
+
+ it 'descends from the CLI base class' do
+ expect(described_class.new).to be_a(Mastodon::CLI::Base)
+ end
+end
diff --git a/spec/support/signed_request_helpers.rb b/spec/support/signed_request_helpers.rb
index 33d7dba6b8..eba4095e43 100644
--- a/spec/support/signed_request_helpers.rb
+++ b/spec/support/signed_request_helpers.rb
@@ -2,7 +2,7 @@
module SignedRequestHelpers
def get(path, headers: nil, sign_with: nil, **args)
- return super path, headers: headers, **args if sign_with.nil?
+ return super(path, headers: headers, **args) if sign_with.nil?
headers ||= {}
headers['Date'] = Time.now.utc.httpdate
@@ -16,6 +16,6 @@ module SignedRequestHelpers
headers['Signature'] = "keyId=\"#{key_id}\",algorithm=\"rsa-sha256\",headers=\"#{signed_headers.keys.join(' ').downcase}\",signature=\"#{signature}\""
- super path, headers: headers, **args
+ super(path, headers: headers, **args)
end
end
diff --git a/yarn.lock b/yarn.lock
index 183b5eb96c..24563cd7a8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2372,7 +2372,7 @@ __metadata:
eslint-plugin-jsx-a11y: "npm:~6.8.0"
eslint-plugin-prettier: "npm:^5.0.0"
eslint-plugin-promise: "npm:~6.1.1"
- eslint-plugin-react: "npm:~7.33.0"
+ eslint-plugin-react: "npm:^7.33.2"
eslint-plugin-react-hooks: "npm:^4.6.0"
exif-js: "npm:^2.3.0"
favico.js: "npm:^0.3.10"
@@ -2896,8 +2896,8 @@ __metadata:
linkType: hard
"@testing-library/jest-dom@npm:^6.0.0":
- version: 6.1.4
- resolution: "@testing-library/jest-dom@npm:6.1.4"
+ version: 6.1.5
+ resolution: "@testing-library/jest-dom@npm:6.1.5"
dependencies:
"@adobe/css-tools": "npm:^4.3.1"
"@babel/runtime": "npm:^7.9.2"
@@ -2921,7 +2921,7 @@ __metadata:
optional: true
vitest:
optional: true
- checksum: 2e23f120613fd8ae6d5169bbc94f1a2e4c82b07182057dc94db8ec54ebf32555833442e6c43a187e59715d83704ffb5df49ba88a71f6f32d2683f3d95ba721c7
+ checksum: f3643a56fcd970b5c7e8fd10faf3c4817d8ab0e74fb1198d726643bdc5ac675ceaac3b0068c5b4fbad254470e8f98ed50028741de875a29ceaa2f854570979c9
languageName: node
linkType: hard
@@ -3498,13 +3498,13 @@ __metadata:
linkType: hard
"@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:>=16.9.11, @types/react@npm:^18.2.7":
- version: 18.2.38
- resolution: "@types/react@npm:18.2.38"
+ version: 18.2.41
+ resolution: "@types/react@npm:18.2.41"
dependencies:
"@types/prop-types": "npm:*"
"@types/scheduler": "npm:*"
csstype: "npm:^3.0.2"
- checksum: 56edd4756081b677e38ee23ad6d340658c5e2468785cb20968318cec357e1ea7ccf3ecd9534981741192dd1b894200acfaf0f1551b4795c6077668f6afc19345
+ checksum: 5cc72491ce8be95e7bbedd8bf039ca971772ecd22d989feb045af7e73247c7e6cff25a2f1c2200be461fb2f6b5aacef739e1ba9fd83c744209dfd3ce8aa75afe
languageName: node
linkType: hard
@@ -3660,11 +3660,11 @@ __metadata:
linkType: hard
"@types/ws@npm:^8.5.9":
- version: 8.5.9
- resolution: "@types/ws@npm:8.5.9"
+ version: 8.5.10
+ resolution: "@types/ws@npm:8.5.10"
dependencies:
"@types/node": "npm:*"
- checksum: 678bdd6461c4653f2975c537fb673cb1918c331558e2d2422b69761c9ced67200bb07c664e2593f3864077a891cb7c13ef2a40d303b4aacb06173d095d8aa3ce
+ checksum: e9af279b984c4a04ab53295a40aa95c3e9685f04888df5c6920860d1dd073fcc57c7bd33578a04b285b2c655a0b52258d34bee0a20569dca8defb8393e1e5d29
languageName: node
linkType: hard
@@ -4171,12 +4171,12 @@ __metadata:
languageName: node
linkType: hard
-"ansi-escapes@npm:^5.0.0":
- version: 5.0.0
- resolution: "ansi-escapes@npm:5.0.0"
+"ansi-escapes@npm:^6.2.0":
+ version: 6.2.0
+ resolution: "ansi-escapes@npm:6.2.0"
dependencies:
- type-fest: "npm:^1.0.2"
- checksum: f705cc7fbabb981ddf51562cd950792807bccd7260cc3d9478a619dda62bff6634c87ca100f2545ac7aade9b72652c4edad8c7f0d31a0b949b5fa58f33eaf0d0
+ type-fest: "npm:^3.0.0"
+ checksum: 3eec75deedd8b10192c5f98e4cd9715cc3ff268d33fc463c24b7d22446668bfcd4ad1803993ea89c0f51f88b5a3399572bacb7c8cb1a067fc86e189c5f3b0c7e
languageName: node
linkType: hard
@@ -4242,7 +4242,7 @@ __metadata:
languageName: node
linkType: hard
-"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0":
+"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1":
version: 6.2.1
resolution: "ansi-styles@npm:6.2.1"
checksum: 5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c
@@ -5594,13 +5594,13 @@ __metadata:
languageName: node
linkType: hard
-"cli-truncate@npm:^3.1.0":
- version: 3.1.0
- resolution: "cli-truncate@npm:3.1.0"
+"cli-truncate@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "cli-truncate@npm:4.0.0"
dependencies:
slice-ansi: "npm:^5.0.0"
- string-width: "npm:^5.0.0"
- checksum: a19088878409ec0e5dc2659a5166929629d93cfba6d68afc9cde2282fd4c751af5b555bf197047e31c87c574396348d011b7aa806fec29c4139ea4f7f00b324c
+ string-width: "npm:^7.0.0"
+ checksum: d7f0b73e3d9b88cb496e6c086df7410b541b56a43d18ade6a573c9c18bd001b1c3fba1ad578f741a4218fdc794d042385f8ac02c25e1c295a2d8b9f3cb86eb4c
languageName: node
linkType: hard
@@ -5970,9 +5970,9 @@ __metadata:
linkType: hard
"core-js@npm:^3.30.2":
- version: 3.33.3
- resolution: "core-js@npm:3.33.3"
- checksum: 08abdc9470c8228b9d09f61e62ab312738681202c4c34e9638889125b304b235f34c4fe22e9d41c20906ac0fcc807dca57c5ff7d6b90021bf64e8fe23461d9ab
+ version: 3.34.0
+ resolution: "core-js@npm:3.34.0"
+ checksum: 408a77898abe03bf3e5dec2a451c36f4745081cca9022f8bdf9b817d57bb6d3a534d555f47a4b95e1daa5e21dbc79122eac2402e25720d425f5925127e55dcd8
languageName: node
linkType: hard
@@ -7007,7 +7007,7 @@ __metadata:
languageName: node
linkType: hard
-"emoji-regex@npm:10.3.0, emoji-regex@npm:^10.2.1":
+"emoji-regex@npm:10.3.0, emoji-regex@npm:^10.2.1, emoji-regex@npm:^10.3.0":
version: 10.3.0
resolution: "emoji-regex@npm:10.3.0"
checksum: b4838e8dcdceb44cf47f59abe352c25ff4fe7857acaf5fb51097c427f6f75b44d052eb907a7a3b86f86bc4eae3a93f5c2b7460abe79c407307e6212d65c91163
@@ -7511,7 +7511,7 @@ __metadata:
languageName: node
linkType: hard
-"eslint-plugin-react@npm:~7.33.0":
+"eslint-plugin-react@npm:^7.33.2":
version: 7.33.2
resolution: "eslint-plugin-react@npm:7.33.2"
dependencies:
@@ -8411,6 +8411,13 @@ __metadata:
languageName: node
linkType: hard
+"get-east-asian-width@npm:^1.0.0":
+ version: 1.2.0
+ resolution: "get-east-asian-width@npm:1.2.0"
+ checksum: 914b1e217cf38436c24b4c60b4c45289e39a45bf9e65ef9fd343c2815a1a02b8a0215aeec8bf9c07c516089004b6e3826332481f40a09529fcadbf6e579f286b
+ languageName: node
+ linkType: hard
+
"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2":
version: 1.2.2
resolution: "get-intrinsic@npm:1.2.2"
@@ -9634,6 +9641,15 @@ __metadata:
languageName: node
linkType: hard
+"is-fullwidth-code-point@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "is-fullwidth-code-point@npm:5.0.0"
+ dependencies:
+ get-east-asian-width: "npm:^1.0.0"
+ checksum: cd591b27d43d76b05fa65ed03eddce57a16e1eca0b7797ff7255de97019bcaf0219acfc0c4f7af13319e13541f2a53c0ace476f442b13267b9a6a7568f2b65c8
+ languageName: node
+ linkType: hard
+
"is-generator-fn@npm:^2.0.0":
version: 2.1.0
resolution: "is-generator-fn@npm:2.1.0"
@@ -10916,7 +10932,14 @@ __metadata:
languageName: node
linkType: hard
-"lilconfig@npm:2.1.0, lilconfig@npm:^2.1.0":
+"lilconfig@npm:3.0.0":
+ version: 3.0.0
+ resolution: "lilconfig@npm:3.0.0"
+ checksum: 7f5ee7a658dc016cacf146815e8d88b06f06f4402823b8b0934e305a57a197f55ccc9c5cd4fb5ea1b2b821c8ccaf2d54abd59602a4931af06eabda332388d3e6
+ languageName: node
+ linkType: hard
+
+"lilconfig@npm:^2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
checksum: 64645641aa8d274c99338e130554abd6a0190533c0d9eb2ce7ebfaf2e05c7d9961f3ffe2bfa39efd3b60c521ba3dd24fa236fe2775fc38501bf82bf49d4678b8
@@ -10931,36 +10954,36 @@ __metadata:
linkType: hard
"lint-staged@npm:^15.0.0":
- version: 15.1.0
- resolution: "lint-staged@npm:15.1.0"
+ version: 15.2.0
+ resolution: "lint-staged@npm:15.2.0"
dependencies:
chalk: "npm:5.3.0"
commander: "npm:11.1.0"
debug: "npm:4.3.4"
execa: "npm:8.0.1"
- lilconfig: "npm:2.1.0"
- listr2: "npm:7.0.2"
+ lilconfig: "npm:3.0.0"
+ listr2: "npm:8.0.0"
micromatch: "npm:4.0.5"
pidtree: "npm:0.6.0"
string-argv: "npm:0.3.2"
yaml: "npm:2.3.4"
bin:
lint-staged: bin/lint-staged.js
- checksum: d427408be98df7558e918593cb765d5caaa67a5cdca89671fb54280a6c959f4e448db36d4f85e8e0bd9c2c1e996aa133916925cf47c9df573b47308d5e298d84
+ checksum: 4a1ff25dd06dbd4346fd244c9a0ebb936532ba18c0caedeb895c2e232f3c6c5fd08f6667624716660bc29e3e0f9f0440a9175114394616e991ebd5fab4b1f092
languageName: node
linkType: hard
-"listr2@npm:7.0.2":
- version: 7.0.2
- resolution: "listr2@npm:7.0.2"
+"listr2@npm:8.0.0":
+ version: 8.0.0
+ resolution: "listr2@npm:8.0.0"
dependencies:
- cli-truncate: "npm:^3.1.0"
+ cli-truncate: "npm:^4.0.0"
colorette: "npm:^2.0.20"
eventemitter3: "npm:^5.0.1"
- log-update: "npm:^5.0.1"
+ log-update: "npm:^6.0.0"
rfdc: "npm:^1.3.0"
- wrap-ansi: "npm:^8.1.0"
- checksum: 37b6501be84ebea66dcce07c5f86c224aff0c01c9fb43f5055cc38a063030281d58198aad0aad481f174438309831ddf5f763b890e820cd7b7b4f4a5dfa229c9
+ wrap-ansi: "npm:^9.0.0"
+ checksum: 6e356df9127c68b69186c927c993645223557e941a76b0bb210e35786aedc53f577df437251db804606ff37ac509c5d945289a84b3daee7fadf2e3dcb889ecc9
languageName: node
linkType: hard
@@ -11128,16 +11151,16 @@ __metadata:
languageName: node
linkType: hard
-"log-update@npm:^5.0.1":
- version: 5.0.1
- resolution: "log-update@npm:5.0.1"
+"log-update@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "log-update@npm:6.0.0"
dependencies:
- ansi-escapes: "npm:^5.0.0"
+ ansi-escapes: "npm:^6.2.0"
cli-cursor: "npm:^4.0.0"
- slice-ansi: "npm:^5.0.0"
- strip-ansi: "npm:^7.0.1"
- wrap-ansi: "npm:^8.0.1"
- checksum: 1050ea2027e80f32e132aace909987cb00c2719368c78b82ffca681a5b3f4020eeb5f4b4e310c47c35c6c36aff258c1d1bc51485ac44d6fdac9eb0a4275c539f
+ slice-ansi: "npm:^7.0.0"
+ strip-ansi: "npm:^7.1.0"
+ wrap-ansi: "npm:^9.0.0"
+ checksum: e0b3c3401ef49ce3eb17e2f83d644765e4f7988498fc1344eaa4f31ab30e510dcc469a7fb64dc01bd1c8d9237d917598fa677a9818705fb3774c10f6e9d4b27c
languageName: node
linkType: hard
@@ -11785,12 +11808,12 @@ __metadata:
languageName: node
linkType: hard
-"nanoid@npm:^3.3.6":
- version: 3.3.6
- resolution: "nanoid@npm:3.3.6"
+"nanoid@npm:^3.3.7":
+ version: 3.3.7
+ resolution: "nanoid@npm:3.3.7"
bin:
nanoid: bin/nanoid.cjs
- checksum: 606b355960d0fcbe3d27924c4c52ef7d47d3b57208808ece73279420d91469b01ec1dce10fae512b6d4a8c5a5432b352b228336a8b2202a6ea68e67fa348e2ee
+ checksum: e3fb661aa083454f40500473bb69eedb85dc160e763150b9a2c567c7e9ff560ce028a9f833123b618a6ea742e311138b591910e795614a629029e86e180660f3
languageName: node
linkType: hard
@@ -13219,13 +13242,13 @@ __metadata:
linkType: hard
"postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.28":
- version: 8.4.31
- resolution: "postcss@npm:8.4.31"
+ version: 8.4.32
+ resolution: "postcss@npm:8.4.32"
dependencies:
- nanoid: "npm:^3.3.6"
+ nanoid: "npm:^3.3.7"
picocolors: "npm:^1.0.0"
source-map-js: "npm:^1.0.2"
- checksum: 748b82e6e5fc34034dcf2ae88ea3d11fd09f69b6c50ecdd3b4a875cfc7cdca435c958b211e2cb52355422ab6fccb7d8f2f2923161d7a1b281029e4a913d59acf
+ checksum: 39308a9195fa34d4dbdd7b58a896cff0c7809f84f7a4ac1b95b68ca86c9138a395addff33075668ed3983d41b90aac05754c445237a9365eb1c3a5602ebd03ad
languageName: node
linkType: hard
@@ -14664,8 +14687,8 @@ __metadata:
linkType: hard
"sass-loader@npm:^10.2.0":
- version: 10.4.1
- resolution: "sass-loader@npm:10.4.1"
+ version: 10.5.0
+ resolution: "sass-loader@npm:10.5.0"
dependencies:
klona: "npm:^2.0.4"
loader-utils: "npm:^2.0.0"
@@ -14674,7 +14697,7 @@ __metadata:
semver: "npm:^7.3.2"
peerDependencies:
fibers: ">= 3.1.0"
- node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+ node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
sass: ^1.3.0
webpack: ^4.36.0 || ^5.0.0
peerDependenciesMeta:
@@ -14684,7 +14707,7 @@ __metadata:
optional: true
sass:
optional: true
- checksum: bf04a440fe471928f3cf884bc12c6b70bc391795b35510b1b9021e8a2cca3b8f966aef9518f4171e87e9cb78193a774f695921e6b61881a1580ae0a3c7b1b5e4
+ checksum: be5da7784fd21c4f526cc3afaa1a765ba44cdc2f9798ecbac87b296ab44184ac5ba9bbda68a7a86f8cdcb6130acceefeb8912260fca14bdfc97f9dad02658400
languageName: node
linkType: hard
@@ -15074,6 +15097,16 @@ __metadata:
languageName: node
linkType: hard
+"slice-ansi@npm:^7.0.0":
+ version: 7.1.0
+ resolution: "slice-ansi@npm:7.1.0"
+ dependencies:
+ ansi-styles: "npm:^6.2.1"
+ is-fullwidth-code-point: "npm:^5.0.0"
+ checksum: 631c971d4abf56cf880f034d43fcc44ff883624867bf11ecbd538c47343911d734a4656d7bc02362b40b89d765652a7f935595441e519b59e2ad3f4d5d6fe7ca
+ languageName: node
+ linkType: hard
+
"smart-buffer@npm:^4.2.0":
version: 4.2.0
resolution: "smart-buffer@npm:4.2.0"
@@ -15517,7 +15550,7 @@ __metadata:
languageName: node
linkType: hard
-"string-width@npm:^5.0.0, string-width@npm:^5.0.1, string-width@npm:^5.1.2":
+"string-width@npm:^5.0.1, string-width@npm:^5.1.2":
version: 5.1.2
resolution: "string-width@npm:5.1.2"
dependencies:
@@ -15528,6 +15561,17 @@ __metadata:
languageName: node
linkType: hard
+"string-width@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "string-width@npm:7.0.0"
+ dependencies:
+ emoji-regex: "npm:^10.3.0"
+ get-east-asian-width: "npm:^1.0.0"
+ strip-ansi: "npm:^7.1.0"
+ checksum: 8ffaeeccf4a56ccce5b6235d0b99ee3a581e3e3e5d453708efe7aa8e264fa3a858b4fe2244310cb71c6a20d8c05921cedc8b2ccd88cbaad9f5c92051ff68edc6
+ languageName: node
+ linkType: hard
+
"string.prototype.matchall@npm:^4.0.6, string.prototype.matchall@npm:^4.0.8":
version: 4.0.8
resolution: "string.prototype.matchall@npm:4.0.8"
@@ -15642,7 +15686,7 @@ __metadata:
languageName: node
linkType: hard
-"strip-ansi@npm:^7.0.1":
+"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0":
version: 7.1.0
resolution: "strip-ansi@npm:7.1.0"
dependencies:
@@ -16403,13 +16447,20 @@ __metadata:
languageName: node
linkType: hard
-"type-fest@npm:^1.0.1, type-fest@npm:^1.0.2, type-fest@npm:^1.2.1, type-fest@npm:^1.2.2":
+"type-fest@npm:^1.0.1, type-fest@npm:^1.2.1, type-fest@npm:^1.2.2":
version: 1.4.0
resolution: "type-fest@npm:1.4.0"
checksum: a3c0f4ee28ff6ddf800d769eafafcdeab32efa38763c1a1b8daeae681920f6e345d7920bf277245235561d8117dab765cb5f829c76b713b4c9de0998a5397141
languageName: node
linkType: hard
+"type-fest@npm:^3.0.0":
+ version: 3.13.1
+ resolution: "type-fest@npm:3.13.1"
+ checksum: 547d22186f73a8c04590b70dcf63baff390078c75ea8acd366bbd510fd0646e348bd1970e47ecf795b7cff0b41d26e9c475c1fedd6ef5c45c82075fbf916b629
+ languageName: node
+ linkType: hard
+
"type-is@npm:~1.6.18":
version: 1.6.18
resolution: "type-is@npm:1.6.18"
@@ -17637,7 +17688,7 @@ __metadata:
languageName: node
linkType: hard
-"wrap-ansi@npm:^8.0.1, wrap-ansi@npm:^8.1.0":
+"wrap-ansi@npm:^8.1.0":
version: 8.1.0
resolution: "wrap-ansi@npm:8.1.0"
dependencies:
@@ -17648,6 +17699,17 @@ __metadata:
languageName: node
linkType: hard
+"wrap-ansi@npm:^9.0.0":
+ version: 9.0.0
+ resolution: "wrap-ansi@npm:9.0.0"
+ dependencies:
+ ansi-styles: "npm:^6.2.1"
+ string-width: "npm:^7.0.0"
+ strip-ansi: "npm:^7.1.0"
+ checksum: a139b818da9573677548dd463bd626a5a5286271211eb6e4e82f34a4f643191d74e6d4a9bb0a3c26ec90e6f904f679e0569674ac099ea12378a8b98e20706066
+ languageName: node
+ linkType: hard
+
"wrappy@npm:1":
version: 1.0.2
resolution: "wrappy@npm:1.0.2"