From 575ab085bec5730835330970e771db69a4758a7c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:08:17 -0500 Subject: [PATCH 01/16] Disable `Rails/ApplicationController` for `HealthController` (#28705) --- .rubocop_todo.yml | 5 ----- app/controllers/health_controller.rb | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6ab8957055..bf4a9a09fe 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -56,11 +56,6 @@ RSpec/MultipleMemoizedHelpers: RSpec/NestedGroups: Max: 6 -# This cop supports unsafe autocorrection (--autocorrect-all). -Rails/ApplicationController: - Exclude: - - 'app/controllers/health_controller.rb' - # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/HasAndBelongsToMany: diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index 2a22a05570..7bc424d0a4 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class HealthController < ActionController::Base +class HealthController < ActionController::Base # rubocop:disable Rails/ApplicationController def show render plain: 'OK' end From 923fc831903c11ae5cc885c9454403007c77d734 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 12 Jan 2024 10:09:57 +0100 Subject: [PATCH 02/16] Improve `lint-staged` config (#28704) --- .prettierignore | 2 ++ lint-staged.config.js | 11 +++++++++++ package.json | 6 ------ streaming/package.json | 2 +- streaming/tsconfig.json | 1 + tsconfig.json | 2 ++ 6 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 lint-staged.config.js diff --git a/.prettierignore b/.prettierignore index 305f0fd753..51850b2b28 100644 --- a/.prettierignore +++ b/.prettierignore @@ -73,3 +73,5 @@ app/javascript/styles/mastodon/reset.scss # Ignore the generated AUTHORS.md AUTHORS.md + +!lint-staged.config.js diff --git a/lint-staged.config.js b/lint-staged.config.js new file mode 100644 index 0000000000..06fe66d11e --- /dev/null +++ b/lint-staged.config.js @@ -0,0 +1,11 @@ +const config = { + '*': 'prettier --ignore-unknown --write', + 'Capfile|Gemfile|*.{rb,ruby,ru,rake}': + 'bundle exec rubocop --force-exclusion -a', + '*.{js,jsx,ts,tsx}': 'eslint --fix', + '*.{css,scss}': 'stylelint --fix', + '*.haml': 'bundle exec haml-lint -a', + '**/*.ts?(x)': () => 'tsc -p tsconfig.json --noEmit', +}; + +module.exports = config; diff --git a/package.json b/package.json index 16ed4decaa..e3ba91f45c 100644 --- a/package.json +++ b/package.json @@ -218,11 +218,5 @@ "react-router-dom": { "optional": true } - }, - "lint-staged": { - "*": "prettier --ignore-unknown --write", - "Capfile|Gemfile|*.{rb,ruby,ru,rake}": "bundle exec rubocop --force-exclusion -a", - "*.{js,jsx,ts,tsx}": "eslint --fix", - "*.{css,scss}": "stylelint --fix" } } diff --git a/streaming/package.json b/streaming/package.json index 2d70acb829..149055ca1b 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -13,7 +13,7 @@ }, "scripts": { "start": "node ./index.js", - "check:types": "tsc --noEmit" + "typecheck": "tsc --noEmit" }, "dependencies": { "cors": "^2.8.5", diff --git a/streaming/tsconfig.json b/streaming/tsconfig.json index 032274d856..f7bb711b9b 100644 --- a/streaming/tsconfig.json +++ b/streaming/tsconfig.json @@ -5,6 +5,7 @@ "module": "CommonJS", "moduleResolution": "node", "noUnusedParameters": false, + "tsBuildInfoFile": "../tmp/cache/streaming/tsconfig.tsbuildinfo", "paths": {} }, "include": ["./*.js", "./.eslintrc.js"] diff --git a/tsconfig.json b/tsconfig.json index ff9da29497..d1a77e5493 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,8 @@ "esModuleInterop": true, "skipLibCheck": true, "baseUrl": "./", + "incremental": true, + "tsBuildInfoFile": "tmp/cache/tsconfig.tsbuildinfo", "paths": { "mastodon": ["app/javascript/mastodon"], "mastodon/*": ["app/javascript/mastodon/*"] From 32eeca9c7b59c156425c6b16c0014dcdcd7fb739 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:10:37 -0500 Subject: [PATCH 03/16] Refresh instance counts in spec (fixes intermittent failure) (#28698) --- spec/controllers/admin/instances_controller_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/controllers/admin/instances_controller_spec.rb b/spec/controllers/admin/instances_controller_spec.rb index 74d69d1aaa..e6fa0b9def 100644 --- a/spec/controllers/admin/instances_controller_spec.rb +++ b/spec/controllers/admin/instances_controller_spec.rb @@ -12,6 +12,8 @@ RSpec.describe Admin::InstancesController do before do _account_less_popular = Fabricate(:account, domain: 'less.popular') _account_popular_other = Fabricate(:account, domain: 'popular') + Instance.refresh + sign_in current_user, scope: :user end From cd37048439f9b324f48e6af1f426a7894c54b4da Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:11:34 -0500 Subject: [PATCH 04/16] Move followable_by coverage to suggestions (#28697) --- .../follow_recommendation_mute_fabricator.rb | 6 ++ spec/models/account_spec.rb | 23 -------- .../models/account_suggestions/source_spec.rb | 57 +++++++++++++++++++ 3 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 spec/fabricators/follow_recommendation_mute_fabricator.rb create mode 100644 spec/models/account_suggestions/source_spec.rb diff --git a/spec/fabricators/follow_recommendation_mute_fabricator.rb b/spec/fabricators/follow_recommendation_mute_fabricator.rb new file mode 100644 index 0000000000..0f924386e9 --- /dev/null +++ b/spec/fabricators/follow_recommendation_mute_fabricator.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +Fabricator(:follow_recommendation_mute) do + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } +end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 1a4c14c45c..ab74579624 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1011,27 +1011,4 @@ RSpec.describe Account do expect(subject.reload.followers_count).to eq 15 end end - - describe '.followable_by' do - context 'with follows and follow requests' do - let!(:account) { Fabricate(:account) } - let!(:eligible_account) { Fabricate(:account) } - let!(:following_account) { Fabricate(:account) } - let!(:follow_requested_account) { Fabricate(:account) } - - before do - Fabricate :follow, account: account, target_account: following_account - Fabricate :follow_request, account: account, target_account: follow_requested_account - end - - it 'returns accounts not already following or requested to follow' do - results = described_class.followable_by(account) - - expect(results) - .to include(eligible_account) - .and not_include(following_account) - .and not_include(follow_requested_account) - end - end - end end diff --git a/spec/models/account_suggestions/source_spec.rb b/spec/models/account_suggestions/source_spec.rb new file mode 100644 index 0000000000..d8227e01bc --- /dev/null +++ b/spec/models/account_suggestions/source_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe AccountSuggestions::Source do + describe '#base_account_scope' do + subject { FakeSource.new } + + before do + stub_const 'FakeSource', fake_source_class + end + + context 'with follows and follow requests' do + let!(:account_domain_blocked_account) { Fabricate(:account, domain: 'blocked.host') } + let!(:account) { Fabricate(:account) } + let!(:blocked_account) { Fabricate(:account) } + let!(:eligible_account) { Fabricate(:account) } + let!(:follow_recommendation_muted_account) { Fabricate(:account) } + let!(:follow_requested_account) { Fabricate(:account) } + let!(:following_account) { Fabricate(:account) } + let!(:moved_account) { Fabricate(:account, moved_to_account: Fabricate(:account)) } + + before do + Fabricate :account_domain_block, account: account, domain: account_domain_blocked_account.domain + Fabricate :block, account: account, target_account: blocked_account + Fabricate :follow_recommendation_mute, account: account, target_account: follow_recommendation_muted_account + Fabricate :follow_request, account: account, target_account: follow_requested_account + Fabricate :follow, account: account, target_account: following_account + end + + it 'returns eligible accounts' do + results = subject.get(account) + + expect(results) + .to include(eligible_account) + .and not_include(account_domain_blocked_account) + .and not_include(account) + .and not_include(blocked_account) + .and not_include(follow_recommendation_muted_account) + .and not_include(follow_requested_account) + .and not_include(following_account) + .and not_include(moved_account) + end + end + end + + private + + def fake_source_class + Class.new described_class do + def get(account, limit: 10) + base_account_scope(account) + .limit(limit) + end + end + end +end From df9e220364484acccdb3f51b71a7081dfa0bec2f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:12:31 -0500 Subject: [PATCH 05/16] Add JS console errors check (#28682) --- lib/tasks/spec.rake | 2 ++ spec/support/javascript_errors.rb | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 spec/support/javascript_errors.rb diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake index 8f2cbeea35..d505a47195 100644 --- a/lib/tasks/spec.rake +++ b/lib/tasks/spec.rake @@ -3,6 +3,8 @@ if Rake::Task.task_defined?('spec:system') namespace :spec do task :enable_system_specs do # rubocop:disable Rails/RakeEnvironment + ENV['LOCAL_DOMAIN'] = 'localhost:3000' + ENV['LOCAL_HTTPS'] = 'false' ENV['RUN_SYSTEM_SPECS'] = 'true' end end diff --git a/spec/support/javascript_errors.rb b/spec/support/javascript_errors.rb new file mode 100644 index 0000000000..bdce1cc76d --- /dev/null +++ b/spec/support/javascript_errors.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +RSpec.configure do |config| + config.after(:each, type: :system) do + errors = page.driver.browser.logs.get(:browser) + if errors.present? + aggregate_failures 'javascript errrors' do + errors.each do |error| + expect(error.level).to_not eq('SEVERE'), error.message + next unless error.level == 'WARNING' + + $stderr.warn 'WARN: javascript warning' + $stderr.warn error.message + end + end + end + end +end From b86083f0dc22e68451aaee5b2a01a8c69de60334 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 10:17:10 +0100 Subject: [PATCH 06/16] New Crowdin Translations (automated) (#28708) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/de.json | 2 +- config/locales/eu.yml | 2 +- config/locales/ro.yml | 1 + config/locales/sk.yml | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 2608b91563..462352750c 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -489,7 +489,7 @@ "onboarding.profile.lead": "Du kannst das später in den Einstellungen vervollständigen, wo noch mehr Anpassungsmöglichkeiten zur Verfügung stehen.", "onboarding.profile.note": "Über mich", "onboarding.profile.note_hint": "Du kannst andere @Profile erwähnen oder #Hashtags verwenden …", - "onboarding.profile.save_and_continue": "Speichern und fortsetzen", + "onboarding.profile.save_and_continue": "Speichern und fortfahren", "onboarding.profile.title": "Profil einrichten", "onboarding.profile.upload_avatar": "Profilbild hochladen", "onboarding.profile.upload_header": "Titelbild hochladen", diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 0d253e9b3b..9174b83b43 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1445,7 +1445,7 @@ eu: cooldown: Migratu eta gero egonaldi tarte bat egongo da eta bitartean ezin izango duzu berriro migratu disabled_account: Zure uneko kontua ezin izango da gero erabili. Hala ere, datua exporatu ahal izango dituzu, eta berriro aktibatu. followers: Ekintza honek jarraitzaile guztiak eramango ditu uneko kontutik kontu berrira - only_redirect_html: Bestela, zure profilean birbideratze soil bat jarri dezakezu. + only_redirect_html: Bestela, zure profilean birbideratze bat jar dezakezu. other_data: Ez da beste daturik migratuko automatikoki redirect: Zure uneko kontuaren profila eguneratuko da birbideratze ohar batekin eta bilaketetatik kenduko da moderation: diff --git a/config/locales/ro.yml b/config/locales/ro.yml index a0f20d57dc..12c06505b8 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -93,6 +93,7 @@ ro: moderation: active: Activ all: Toate + disabled: Dezactivat pending: În așteptare silenced: Limitat suspended: Suspendate diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 89d41b4616..a91f1d620e 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -184,6 +184,7 @@ sk: create_domain_block: Vytvor zákaz domény create_email_domain_block: Vytvor zákaz emailovej domény create_ip_block: Vytvor IP pravidlo + create_unavailable_domain: Vytvor nedostupnú doménu create_user_role: Vytvoriť rolu demote_user: Zniž užívateľskú rolu destroy_announcement: Vymaž oboznámenie @@ -245,6 +246,7 @@ sk: destroy_email_domain_block_html: "%{name} odblokoval/a e-mailovú doménu %{target}" destroy_ip_block_html: "%{name} vymazal/a pravidlo pre IP %{target}" destroy_status_html: "%{name} zmazal/a príspevok od %{target}" + destroy_unavailable_domain_html: "%{name} znova spustil/a doručovanie pre doménu %{target}" destroy_user_role_html: "%{name} vymazal/a rolu pre %{target}" enable_user_html: "%{name} povolil/a prihlásenie pre používateľa %{target}" memorialize_account_html: "%{name} zmenil/a účet %{target} na pamätnú stránku" From 7801db7ba463a71b8a11a2867486b012a2ec3972 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:19:25 -0500 Subject: [PATCH 07/16] Spec coverage for custom css endpoint (#28706) --- app/controllers/custom_css_controller.rb | 13 +++++ app/views/custom_css/show.css.erb | 6 +-- spec/requests/custom_css_spec.rb | 60 ++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 spec/requests/custom_css_spec.rb diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb index e7a02ea89c..62f8e0d772 100644 --- a/app/controllers/custom_css_controller.rb +++ b/app/controllers/custom_css_controller.rb @@ -1,8 +1,21 @@ # frozen_string_literal: true class CustomCssController < ActionController::Base # rubocop:disable Rails/ApplicationController + before_action :set_user_roles + def show expires_in 3.minutes, public: true render content_type: 'text/css' end + + private + + def custom_css_styles + Setting.custom_css + end + helper_method :custom_css_styles + + def set_user_roles + @user_roles = UserRole.where(highlighted: true).where.not(color: [nil, '']) + end end diff --git a/app/views/custom_css/show.css.erb b/app/views/custom_css/show.css.erb index 9cd38fb371..78da809ed6 100644 --- a/app/views/custom_css/show.css.erb +++ b/app/views/custom_css/show.css.erb @@ -1,8 +1,8 @@ -<%- if Setting.custom_css.present? %> -<%= raw Setting.custom_css %> +<%- if custom_css_styles.present? %> +<%= raw custom_css_styles %> <%- end %> -<%- UserRole.where(highlighted: true).select { |role| role.color.present? }.each do |role| %> +<%- @user_roles.each do |role| %> .user-role-<%= role.id %> { --user-role-accent: <%= role.color %>; } diff --git a/spec/requests/custom_css_spec.rb b/spec/requests/custom_css_spec.rb new file mode 100644 index 0000000000..5271ed4a5a --- /dev/null +++ b/spec/requests/custom_css_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Custom CSS' do + include RoutingHelper + + describe 'GET /custom.css' do + context 'without any CSS or User Roles' do + it 'returns empty stylesheet' do + get '/custom.css' + + expect(response.content_type).to include('text/css') + expect(response.body.presence).to be_nil + end + end + + context 'with CSS settings' do + before do + Setting.custom_css = expected_css + end + + it 'returns stylesheet from settings' do + get '/custom.css' + + expect(response.content_type).to include('text/css') + expect(response.body.strip).to eq(expected_css) + end + + def expected_css + <<~CSS.strip + body { background-color: red; } + CSS + end + end + + context 'with highlighted colored UserRole records' do + before do + _highlighted_colored = Fabricate :user_role, highlighted: true, color: '#336699', id: '123_123_123' + _highlighted_no_color = Fabricate :user_role, highlighted: true, color: '' + _no_highlight_with_color = Fabricate :user_role, highlighted: false, color: '' + end + + it 'returns stylesheet from settings' do + get '/custom.css' + + expect(response.content_type).to include('text/css') + expect(response.body.strip).to eq(expected_css) + end + + def expected_css + <<~CSS.strip + .user-role-123123123 { + --user-role-accent: #336699; + } + CSS + end + end + end +end From a90696011e563e62100cba56e2d52f6babbaff00 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:21:00 -0500 Subject: [PATCH 08/16] Add coverage/bugfix for invalid appeal submission (#28703) --- app/views/disputes/strikes/show.html.haml | 2 +- .../disputes/appeals_controller_spec.rb | 37 ++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/app/views/disputes/strikes/show.html.haml b/app/views/disputes/strikes/show.html.haml index 62695b155e..5f72138821 100644 --- a/app/views/disputes/strikes/show.html.haml +++ b/app/views/disputes/strikes/show.html.haml @@ -21,7 +21,7 @@ .report-header .report-header__card - = render 'card', strike: @strike + = render 'disputes/strikes/card', strike: @strike .report-header__details .report-header__details__item diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb index 452bd60dc5..da2f86ade5 100644 --- a/spec/controllers/disputes/appeals_controller_spec.rb +++ b/spec/controllers/disputes/appeals_controller_spec.rb @@ -10,19 +10,38 @@ RSpec.describe Disputes::AppealsController do let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } describe '#create' do - let(:current_user) { Fabricate(:user) } - let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } + context 'with valid params' do + let(:current_user) { Fabricate(:user) } + let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } - before do - post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } } + before do + post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } } + end + + it 'notifies staff about new appeal', :sidekiq_inline do + expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) + end + + it 'redirects back to the strike page' do + expect(response).to redirect_to(disputes_strike_path(strike.id)) + end end - it 'notifies staff about new appeal', :sidekiq_inline do - expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) - end + context 'with invalid params' do + let(:current_user) { Fabricate(:user) } + let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } - it 'redirects back to the strike page' do - expect(response).to redirect_to(disputes_strike_path(strike.id)) + before do + post :create, params: { strike_id: strike.id, appeal: { text: '' } } + end + + it 'does not send email', :sidekiq_inline do + expect(ActionMailer::Base.deliveries.size).to eq(0) + end + + it 'renders the strike show page' do + expect(response).to render_template('disputes/strikes/show') + end end end end From c6684aa1e392f2dd86af4362b4259809549abaad Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 12 Jan 2024 10:32:45 +0100 Subject: [PATCH 09/16] Use the assets pipeline to load `inert.css` (#28701) --- app/javascript/packs/inert.js | 4 ++++ public/inert.css => app/javascript/styles/inert.scss | 2 ++ app/views/layouts/application.html.haml | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 app/javascript/packs/inert.js rename public/inert.css => app/javascript/styles/inert.scss (78%) diff --git a/app/javascript/packs/inert.js b/app/javascript/packs/inert.js new file mode 100644 index 0000000000..7c04a97faf --- /dev/null +++ b/app/javascript/packs/inert.js @@ -0,0 +1,4 @@ +/* Placeholder file to have `inert.scss` compiled by Webpack + This is used by the `wicg-inert` polyfill */ + +import '../styles/inert.scss'; diff --git a/public/inert.css b/app/javascript/styles/inert.scss similarity index 78% rename from public/inert.css rename to app/javascript/styles/inert.scss index 54e10616d2..a60045d7be 100644 --- a/public/inert.css +++ b/app/javascript/styles/inert.scss @@ -1,3 +1,5 @@ +/* This is needed for the wicg-inert polyfill */ + [inert] { pointer-events: none; cursor: default; diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 1244fd5eb3..6f6b1825f6 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -28,12 +28,14 @@ = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous' = stylesheet_pack_tag current_theme, media: 'all', crossorigin: 'anonymous' + -# Needed for the wicg-inert polyfill. It needs to be on it's own