Merge remote-tracking branch 'upstream/main' into add_username_change_integration_test

This commit is contained in:
Angus McLeod 2025-02-24 08:48:08 +01:00
commit c8fbc194e9
17 changed files with 281 additions and 296 deletions

View File

@ -145,9 +145,6 @@ group :test do
# Used to mock environment variables # Used to mock environment variables
gem 'climate_control' gem 'climate_control'
# Add back helpers functions removed in Rails 5.1
gem 'rails-controller-testing', '~> 1.0'
# Validate schemas in specs # Validate schemas in specs
gem 'json-schema', '~> 5.0' gem 'json-schema', '~> 5.0'

View File

@ -194,7 +194,7 @@ GEM
devise_pam_authenticatable2 (9.2.0) devise_pam_authenticatable2 (9.2.0)
devise (>= 4.0.0) devise (>= 4.0.0)
rpam2 (~> 4.0) rpam2 (~> 4.0)
diff-lcs (1.5.1) diff-lcs (1.6.0)
discard (1.4.0) discard (1.4.0)
activerecord (>= 4.2, < 9.0) activerecord (>= 4.2, < 9.0)
docile (1.4.1) docile (1.4.1)
@ -409,11 +409,11 @@ GEM
mime-types (3.6.0) mime-types (3.6.0)
logger logger
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2025.0204) mime-types-data (3.2025.0220)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.8) mini_portile2 (2.8.8)
minitest (5.25.4) minitest (5.25.4)
msgpack (1.7.5) msgpack (1.8.0)
multi_json (1.15.0) multi_json (1.15.0)
mutex_m (0.3.0) mutex_m (0.3.0)
net-http (0.6.0) net-http (0.6.0)
@ -641,10 +641,6 @@ GEM
activesupport (= 8.0.1) activesupport (= 8.0.1)
bundler (>= 1.15.0) bundler (>= 1.15.0)
railties (= 8.0.1) railties (= 8.0.1)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
activesupport (>= 5.0.1.rc1)
rails-dom-testing (2.2.0) rails-dom-testing (2.2.0)
activesupport (>= 5.0.0) activesupport (>= 5.0.0)
minitest minitest
@ -687,7 +683,7 @@ GEM
responders (3.1.1) responders (3.1.1)
actionpack (>= 5.2) actionpack (>= 5.2)
railties (>= 5.2) railties (>= 5.2)
rexml (3.4.0) rexml (3.4.1)
rotp (6.3.0) rotp (6.3.0)
rouge (4.5.1) rouge (4.5.1)
rpam2 (4.0.2) rpam2 (4.0.2)
@ -774,7 +770,7 @@ GEM
activerecord (>= 4.0.0) activerecord (>= 4.0.0)
railties (>= 4.0.0) railties (>= 4.0.0)
securerandom (0.4.1) securerandom (0.4.1)
selenium-webdriver (4.28.0) selenium-webdriver (4.29.0)
base64 (~> 0.2) base64 (~> 0.2)
logger (~> 1.4) logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
@ -814,7 +810,7 @@ GEM
stackprof (0.2.27) stackprof (0.2.27)
stoplight (4.1.1) stoplight (4.1.1)
redlock (~> 1.0) redlock (~> 1.0)
stringio (3.1.2) stringio (3.1.4)
strong_migrations (2.2.0) strong_migrations (2.2.0)
activerecord (>= 7) activerecord (>= 7)
swd (1.3.0) swd (1.3.0)
@ -898,7 +894,7 @@ GEM
xorcist (1.1.3) xorcist (1.1.3)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
zeitwerk (2.7.1) zeitwerk (2.7.2)
PLATFORMS PLATFORMS
ruby ruby
@ -1009,7 +1005,6 @@ DEPENDENCIES
rack-cors (~> 2.0) rack-cors (~> 2.0)
rack-test (~> 2.1) rack-test (~> 2.1)
rails (~> 8.0) rails (~> 8.0)
rails-controller-testing (~> 1.0)
rails-i18n (~> 8.0) rails-i18n (~> 8.0)
rdf-normalize (~> 0.5) rdf-normalize (~> 0.5)
redcarpet (~> 3.6) redcarpet (~> 3.6)
@ -1059,4 +1054,4 @@ RUBY VERSION
ruby 3.4.1p0 ruby 3.4.1p0
BUNDLED WITH BUNDLED WITH
2.6.3 2.6.5

View File

@ -697,7 +697,7 @@
"poll_button.remove_poll": "Remove poll", "poll_button.remove_poll": "Remove poll",
"privacy.change": "Change post privacy", "privacy.change": "Change post privacy",
"privacy.direct.long": "Everyone mentioned in the post", "privacy.direct.long": "Everyone mentioned in the post",
"privacy.direct.short": "Specific people", "privacy.direct.short": "Private mention",
"privacy.private.long": "Only your followers", "privacy.private.long": "Only your followers",
"privacy.private.short": "Followers", "privacy.private.short": "Followers",
"privacy.public.long": "Anyone on and off Mastodon", "privacy.public.long": "Anyone on and off Mastodon",

View File

@ -264,6 +264,7 @@
"footer.privacy_policy": "Tasertit tabaḍnit", "footer.privacy_policy": "Tasertit tabaḍnit",
"footer.source_code": "Wali tangalt taɣbalut", "footer.source_code": "Wali tangalt taɣbalut",
"footer.status": "Addad", "footer.status": "Addad",
"footer.terms_of_service": "Tiwtilin n useqdec",
"generic.saved": "Yettwasekles", "generic.saved": "Yettwasekles",
"getting_started.heading": "Bdu", "getting_started.heading": "Bdu",
"hashtag.column_header.tag_mode.all": "d {additional}", "hashtag.column_header.tag_mode.all": "d {additional}",
@ -623,6 +624,7 @@
"subscribed_languages.save": "Sekles ibeddilen", "subscribed_languages.save": "Sekles ibeddilen",
"tabs_bar.home": "Agejdan", "tabs_bar.home": "Agejdan",
"tabs_bar.notifications": "Alɣuten", "tabs_bar.notifications": "Alɣuten",
"terms_of_service.title": "Tiwtilin n useqdec",
"time_remaining.days": "Mazal {number, plural, one {# wass} other {# wussan}}", "time_remaining.days": "Mazal {number, plural, one {# wass} other {# wussan}}",
"time_remaining.hours": "Mazal {number, plural, one {# usarag} other {# yisragen}}", "time_remaining.hours": "Mazal {number, plural, one {# usarag} other {# yisragen}}",
"time_remaining.minutes": "Mazal {number, plural, one {# n tesdat} other {# n tesdatin}}", "time_remaining.minutes": "Mazal {number, plural, one {# n tesdat} other {# n tesdatin}}",

View File

@ -379,6 +379,7 @@
"ignore_notifications_modal.filter_to_act_users": "Stále budeš môcť akceptovať, odmietnuť, alebo nahlásiť užívateľov", "ignore_notifications_modal.filter_to_act_users": "Stále budeš môcť akceptovať, odmietnuť, alebo nahlásiť užívateľov",
"ignore_notifications_modal.filter_to_avoid_confusion": "Triedenie pomáha vyvarovať sa možnému zmäteniu", "ignore_notifications_modal.filter_to_avoid_confusion": "Triedenie pomáha vyvarovať sa možnému zmäteniu",
"ignore_notifications_modal.ignore": "Ignoruj upozornenia", "ignore_notifications_modal.ignore": "Ignoruj upozornenia",
"ignore_notifications_modal.limited_accounts_title": "Ignorovať oboznámenia z obmedzených účtov?",
"ignore_notifications_modal.new_accounts_title": "Nevšímať si oznámenia z nových účtov?", "ignore_notifications_modal.new_accounts_title": "Nevšímať si oznámenia z nových účtov?",
"ignore_notifications_modal.not_followers_title": "Nevšímať si oznámenia od ľudí, ktorí ťa nenasledujú?", "ignore_notifications_modal.not_followers_title": "Nevšímať si oznámenia od ľudí, ktorí ťa nenasledujú?",
"ignore_notifications_modal.not_following_title": "Nevšímať si oznámenia od ľudí, ktorých nenasleduješ?", "ignore_notifications_modal.not_following_title": "Nevšímať si oznámenia od ľudí, ktorých nenasleduješ?",

View File

@ -1777,7 +1777,7 @@ eo:
migrate: Konta migrado migrate: Konta migrado
notifications: Retpoŝtaj sciigoj notifications: Retpoŝtaj sciigoj
preferences: Preferoj preferences: Preferoj
profile: Profilo profile: Publika profilo
relationships: Sekvatoj kaj sekvantoj relationships: Sekvatoj kaj sekvantoj
severed_relationships: Finitaj rilatoj severed_relationships: Finitaj rilatoj
statuses_cleanup: Automata mesaĝforigo statuses_cleanup: Automata mesaĝforigo

View File

@ -434,9 +434,12 @@ kab:
search: Anadi search: Anadi
title: Ihacṭagen title: Ihacṭagen
terms_of_service: terms_of_service:
changelog: Amaynut
draft: Arewway draft: Arewway
history: Amazray
publish: Asuffeɣ publish: Asuffeɣ
save_draft: Sekles arewway save_draft: Sekles arewway
title: Tiwtilin n useqdec
title: Tadbelt title: Tadbelt
trends: trends:
allow: Sireg allow: Sireg
@ -832,6 +835,8 @@ kab:
'7889238': 3 n wayyuren '7889238': 3 n wayyuren
stream_entries: stream_entries:
sensitive_content: Agbur amḥulfu sensitive_content: Agbur amḥulfu
terms_of_service:
title: Tiwtilin n useqdec
themes: themes:
contrast: Maṣṭudun (agnil awriran) contrast: Maṣṭudun (agnil awriran)
default: Maṣṭudun (Aberkan) default: Maṣṭudun (Aberkan)
@ -854,6 +859,8 @@ kab:
user_mailer: user_mailer:
appeal_approved: appeal_approved:
action: Iɣewwaṛen n umiḍan action: Iɣewwaṛen n umiḍan
terms_of_service_changed:
sign_off: Agraw n %{domain}
warning: warning:
categories: categories:
spam: Aspam spam: Aspam

View File

@ -193,7 +193,7 @@ eo:
text: Klarigu kial ĉi tiu decido devas inversigitis text: Klarigu kial ĉi tiu decido devas inversigitis
defaults: defaults:
autofollow: Inviti al sekvi vian konton autofollow: Inviti al sekvi vian konton
avatar: Rolfiguro avatar: Profilbildo
bot: Ĉi tio estas aŭtomata konto bot: Ĉi tio estas aŭtomata konto
chosen_languages: Filtri lingvojn chosen_languages: Filtri lingvojn
confirm_new_password: Konfirmi novan pasvorton confirm_new_password: Konfirmi novan pasvorton

View File

@ -141,6 +141,8 @@ kab:
text: Alugen text: Alugen
tag: tag:
name: Ahacṭag name: Ahacṭag
terms_of_service:
text: Tiwtilin n useqdec
user: user:
role: Tamlilt role: Tamlilt
time_zone: Tamnaḍt tasragant time_zone: Tamnaḍt tasragant

View File

@ -69,7 +69,8 @@ RSpec.describe Admin::DomainBlocksController do
expect(DomainBlockWorker).to_not have_received(:perform_async) expect(DomainBlockWorker).to_not have_received(:perform_async)
expect(response).to render_template :new expect(response.parsed_body.title)
.to match(I18n.t('admin.domain_blocks.new.title'))
end end
end end
@ -84,7 +85,8 @@ RSpec.describe Admin::DomainBlocksController do
expect(DomainBlockWorker).to_not have_received(:perform_async) expect(DomainBlockWorker).to_not have_received(:perform_async)
expect(response).to render_template :confirm_suspension expect(response.parsed_body.title)
.to match(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com'))
end end
end end
@ -119,7 +121,8 @@ RSpec.describe Admin::DomainBlocksController do
expect(DomainBlockWorker).to_not have_received(:perform_async) expect(DomainBlockWorker).to_not have_received(:perform_async)
expect(response).to render_template :confirm_suspension expect(response.parsed_body.title)
.to match(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com'))
end end
end end

View File

@ -1,235 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Admin::RolesController do
render_views
let(:permissions) { UserRole::Flags::NONE }
let(:current_role) { UserRole.create(name: 'Foo', permissions: permissions, position: 10) }
let(:current_user) { Fabricate(:user, role: current_role) }
before do
sign_in current_user, scope: :user
end
describe 'GET #index' do
before do
get :index
end
context 'when user does not have permission to manage roles' do
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
context 'when user has permission to manage roles' do
let(:permissions) { UserRole::FLAGS[:manage_roles] }
it 'returns http success' do
expect(response).to have_http_status(:success)
end
end
end
describe 'GET #new' do
before do
get :new
end
context 'when user does not have permission to manage roles' do
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
context 'when user has permission to manage roles' do
let(:permissions) { UserRole::FLAGS[:manage_roles] }
it 'returns http success' do
expect(response).to have_http_status(:success)
end
end
end
describe 'POST #create' do
let(:selected_position) { 1 }
let(:selected_permissions_as_keys) { %w(manage_roles) }
before do
post :create, params: { user_role: { name: 'Bar', position: selected_position, permissions_as_keys: selected_permissions_as_keys } }
end
context 'when user has permission to manage roles' do
let(:permissions) { UserRole::FLAGS[:manage_roles] }
context 'when new role\'s does not elevate above the user\'s role' do
let(:selected_position) { 1 }
let(:selected_permissions_as_keys) { %w(manage_roles) }
it 'redirects to roles page and creates role' do
expect(response).to redirect_to(admin_roles_path)
expect(UserRole.find_by(name: 'Bar')).to_not be_nil
end
end
context 'when new role\'s position is higher than user\'s role' do
let(:selected_position) { 100 }
let(:selected_permissions_as_keys) { %w(manage_roles) }
it 'renders new template and does not create role' do
expect(response).to render_template(:new)
expect(UserRole.find_by(name: 'Bar')).to be_nil
end
end
context 'when new role has permissions the user does not have' do
let(:selected_position) { 1 }
let(:selected_permissions_as_keys) { %w(manage_roles manage_users manage_reports) }
it 'renders new template and does not create role' do
expect(response).to render_template(:new)
expect(UserRole.find_by(name: 'Bar')).to be_nil
end
end
context 'when user has administrator permission' do
let(:permissions) { UserRole::FLAGS[:administrator] }
let(:selected_position) { 1 }
let(:selected_permissions_as_keys) { %w(manage_roles manage_users manage_reports) }
it 'redirects to roles page and creates new role' do
expect(response).to redirect_to(admin_roles_path)
expect(UserRole.find_by(name: 'Bar')).to_not be_nil
end
end
end
end
describe 'GET #edit' do
let(:role_position) { 8 }
let(:role) { UserRole.create(name: 'Bar', permissions: UserRole::FLAGS[:manage_users], position: role_position) }
before do
get :edit, params: { id: role.id }
end
context 'when user does not have permission to manage roles' do
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
context 'when user has permission to manage roles' do
let(:permissions) { UserRole::FLAGS[:manage_roles] }
context 'when user outranks the role' do
it 'returns http success' do
expect(response).to have_http_status(:success)
end
end
context 'when role outranks user' do
let(:role_position) { current_role.position + 1 }
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
end
end
describe 'PUT #update' do
let(:role_position) { 8 }
let(:role_permissions) { UserRole::FLAGS[:manage_users] }
let(:role) { UserRole.create(name: 'Bar', permissions: role_permissions, position: role_position) }
let(:selected_position) { 8 }
let(:selected_permissions_as_keys) { %w(manage_users) }
before do
put :update, params: { id: role.id, user_role: { name: 'Baz', position: selected_position, permissions_as_keys: selected_permissions_as_keys } }
end
context 'when user does not have permission to manage roles' do
it 'returns http forbidden and does not update role' do
expect(response).to have_http_status(403)
expect(role.reload.name).to eq 'Bar'
end
end
context 'when user has permission to manage roles' do
let(:permissions) { UserRole::FLAGS[:manage_roles] }
context 'when role has permissions the user doesn\'t' do
it 'renders edit template and does not update role' do
expect(response).to render_template(:edit)
expect(role.reload.name).to eq 'Bar'
end
end
context 'when user has all permissions of the role' do
let(:permissions) { UserRole::FLAGS[:manage_roles] | UserRole::FLAGS[:manage_users] }
context 'when user outranks the role' do
it 'redirects to roles page and updates role' do
expect(response).to redirect_to(admin_roles_path)
expect(role.reload.name).to eq 'Baz'
end
end
context 'when role outranks user' do
let(:role_position) { current_role.position + 1 }
it 'returns http forbidden and does not update role' do
expect(response).to have_http_status(403)
expect(role.reload.name).to eq 'Bar'
end
end
end
end
end
describe 'DELETE #destroy' do
let(:role_position) { 8 }
let(:role) { UserRole.create(name: 'Bar', permissions: UserRole::FLAGS[:manage_users], position: role_position) }
before do
delete :destroy, params: { id: role.id }
end
context 'when user does not have permission to manage roles' do
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
context 'when user has permission to manage roles' do
let(:permissions) { UserRole::FLAGS[:manage_roles] }
context 'when user outranks the role' do
it 'redirects to roles page' do
expect(response).to redirect_to(admin_roles_path)
end
end
context 'when role outranks user' do
let(:role_position) { current_role.position + 1 }
it 'returns http forbidden' do
expect(response).to have_http_status(403)
end
end
end
end
end

View File

@ -5,14 +5,14 @@ require 'rails_helper'
RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do
render_views render_views
shared_examples 'renders :new' do shared_examples 'renders expected page' do
it 'renders the new view' do it 'renders the new view with QR code' do
subject subject
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response).to render_template(:new)
expect(response.body) expect(response.body)
.to include(qr_code_markup) .to include(qr_code_markup)
.and include(I18n.t('settings.two_factor_authentication'))
end end
def qr_code_markup def qr_code_markup
@ -34,7 +34,7 @@ RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do
get :new, session: { challenge_passed_at: Time.now.utc, new_otp_secret: 'thisisasecretforthespecofnewview' } get :new, session: { challenge_passed_at: Time.now.utc, new_otp_secret: 'thisisasecretforthespecofnewview' }
end end
include_examples 'renders :new' include_examples 'renders expected page'
end end
it 'redirects if a new otp_secret has not been set in the session' do it 'redirects if a new otp_secret has not been set in the session' do
@ -66,10 +66,13 @@ RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do
expect { post_create_with_options } expect { post_create_with_options }
.to change { user.reload.otp_secret }.to 'thisisasecretforthespecofnewview' .to change { user.reload.otp_secret }.to 'thisisasecretforthespecofnewview'
expect(flash[:notice]).to eq 'Two-factor authentication successfully enabled' expect(flash[:notice])
expect(response).to have_http_status(200) .to eq(I18n.t('two_factor_authentication.enabled_success'))
expect(response).to render_template('settings/two_factor_authentication/recovery_codes/index') expect(response)
expect(response.body).to include(*otp_backup_codes) .to have_http_status(200)
expect(response.body)
.to include(*otp_backup_codes)
.and include(I18n.t('settings.two_factor_authentication'))
end end
end end
@ -86,10 +89,12 @@ RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do
it 'renders page with error message' do it 'renders page with error message' do
subject subject
expect(response.body).to include 'The entered code was invalid! Are server time and device time correct?'
expect(response.body)
.to include(I18n.t('otp_authentication.wrong_code'))
end end
include_examples 'renders :new' include_examples 'renders expected page'
end end
private private
@ -116,18 +121,4 @@ RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do
end end
end end
end end
context 'when not signed in' do
it 'redirects on POST to create' do
post :create, params: { form_two_factor_confirmation: { otp_attempt: '123456' } }
expect(response).to redirect_to('/auth/sign_in')
end
it 'redirects on GET to new' do
get :new
expect(response).to redirect_to('/auth/sign_in')
end
end
end end

View File

@ -3,14 +3,142 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe 'Admin Roles' do RSpec.describe 'Admin Roles' do
describe 'POST /admin/roles' do context 'when signed in as lower permissions user' do
let(:user_role) { Fabricate(:user_role, permissions: UserRole::Flags::NONE) }
before { sign_in Fabricate(:user, role: user_role) }
describe 'GET /admin/roles' do
it 'returns http forbidden' do
get admin_roles_path
expect(response)
.to have_http_status(403)
end
end
describe 'GET /admin/roles/new' do
it 'returns http forbidden' do
get new_admin_role_path
expect(response)
.to have_http_status(403)
end
end
describe 'GET /admin/roles/:id/edit' do
let(:role) { Fabricate(:user_role) }
it 'returns http forbidden' do
get edit_admin_role_path(role)
expect(response)
.to have_http_status(403)
end
end
describe 'PUT /admin/roles/:id' do
let(:role) { Fabricate(:user_role) }
it 'returns http forbidden' do
put admin_role_path(role)
expect(response)
.to have_http_status(403)
end
end
describe 'DELETE /admin/roles/:id' do
let(:role) { Fabricate(:user_role) }
it 'returns http forbidden' do
delete admin_role_path(role)
expect(response)
.to have_http_status(403)
end
end
end
context 'when user has permissions to manage roles' do
let(:user_role) { Fabricate(:user_role, permissions: UserRole::FLAGS[:manage_users]) }
before { sign_in Fabricate(:user, role: user_role) }
context 'when target role permission outranks user' do
let(:role) { Fabricate(:user_role, position: user_role.position + 1) }
describe 'GET /admin/roles/:id/edit' do
it 'returns http forbidden' do
get edit_admin_role_path(role)
expect(response)
.to have_http_status(403)
end
end
describe 'PUT /admin/roles/:id' do
it 'returns http forbidden' do
put admin_role_path(role)
expect(response)
.to have_http_status(403)
end
end
describe 'DELETE /admin/roles/:id' do
it 'returns http forbidden' do
delete admin_role_path(role)
expect(response)
.to have_http_status(403)
end
end
end
end
context 'when attempting to add permissions the user does not have' do
let(:user_role) { Fabricate(:user_role, permissions: UserRole::FLAGS[:manage_roles], position: 5) }
before { sign_in Fabricate(:user, role: user_role) }
describe 'POST /admin/roles' do
subject { post admin_roles_path, params: { user_role: { name: 'Bar', position: 2, permissions_as_keys: %w(manage_roles manage_users manage_reports) } } }
it 'does not create role' do
expect { subject }
.to_not change(UserRole, :count)
expect(response.body)
.to include(I18n.t('admin.roles.add_new'))
end
end
describe 'PUT /admin/roles/:id' do
subject { put admin_role_path(role), params: { user_role: { position: 2, permissions_as_keys: %w(manage_roles manage_users manage_reports) } } }
let(:role) { Fabricate(:user_role, name: 'Bar') }
it 'does not create role' do
expect { subject }
.to_not(change { role.reload.permissions })
expect(response.parsed_body.title)
.to match(I18n.t('admin.roles.edit', name: 'Bar'))
end
end
end
context 'when signed in as admin' do
before { sign_in Fabricate(:admin_user) } before { sign_in Fabricate(:admin_user) }
it 'gracefully handles invalid nested params' do describe 'POST /admin/roles' do
post admin_roles_path(user_role: 'invalid') it 'gracefully handles invalid nested params' do
post admin_roles_path(user_role: 'invalid')
expect(response) expect(response)
.to have_http_status(400) .to have_http_status(400)
end
end end
end end
end end

View File

@ -16,4 +16,20 @@ RSpec.describe 'Settings 2FA Confirmations' do
.to have_http_status(400) .to have_http_status(400)
end end
end end
context 'when not signed in' do
it 'redirects on POST to create' do
post settings_two_factor_authentication_confirmation_path(form_two_factor_confirmation: { otp_attempt: '123456' })
expect(response)
.to redirect_to(new_user_session_path)
end
it 'redirects on GET to new' do
get new_settings_two_factor_authentication_confirmation_path
expect(response)
.to redirect_to(new_user_session_path)
end
end
end end

View File

@ -0,0 +1,78 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Admin::Roles' do
context 'when user has administrator permissions' do
let(:user_role) { Fabricate(:user_role, permissions: UserRole::FLAGS[:administrator], position: 10) }
before { sign_in Fabricate(:user, role: user_role) }
it 'creates new user role' do
visit new_admin_role_path
fill_in 'user_role_name', with: 'Baz'
fill_in 'user_role_position', with: '1'
check 'user_role_permissions_as_keys_manage_reports'
check 'user_role_permissions_as_keys_manage_roles'
expect { click_on I18n.t('admin.roles.add_new') }
.to change(UserRole, :count)
expect(page)
.to have_title(I18n.t('admin.roles.title'))
end
end
context 'when user has permissions to manage roles' do
let(:user_role) { Fabricate(:user_role, permissions: UserRole::FLAGS[:manage_roles], position: 10) }
before { sign_in Fabricate(:user, role: user_role) }
it 'Creates user roles' do
visit admin_roles_path
expect(page)
.to have_title(I18n.t('admin.roles.title'))
click_on I18n.t('admin.roles.add_new')
expect(page)
.to have_title(I18n.t('admin.roles.add_new'))
# Position too high
fill_in 'user_role_name', with: 'Baz'
fill_in 'user_role_position', with: '100'
expect { click_on I18n.t('admin.roles.add_new') }
.to_not change(UserRole, :count)
expect(page)
.to have_content(I18n.t('activerecord.errors.models.user_role.attributes.position.elevated'))
# Valid submission
fill_in 'user_role_name', with: 'Baz'
fill_in 'user_role_position', with: '5' # Lower than user
check 'user_role_permissions_as_keys_manage_roles' # User has permission
expect { click_on I18n.t('admin.roles.add_new') }
.to change(UserRole, :count)
expect(page)
.to have_title(I18n.t('admin.roles.title'))
end
it 'Manages existing user roles' do
role = Fabricate :user_role, name: 'Baz'
visit edit_admin_role_path(role)
expect(page)
.to have_title(I18n.t('admin.roles.edit', name: 'Baz'))
# Update role attribute
fill_in 'user_role_position', with: '5' # Lower than user
expect { click_on submit_button }
.to(change { role.reload.position })
# Destroy the role
visit edit_admin_role_path(role)
expect { click_on I18n.t('admin.roles.delete') }
.to change(UserRole, :count).by(-1)
expect(page)
.to have_title(I18n.t('admin.roles.title'))
end
end
end

View File

@ -652,7 +652,7 @@ const startServer = async () => {
// filtering of statuses: // filtering of statuses:
// Filter based on language: // Filter based on language:
if (Array.isArray(req.chosenLanguages) && payload.language !== null && req.chosenLanguages.indexOf(payload.language) === -1) { if (Array.isArray(req.chosenLanguages) && req.chosenLanguages.indexOf(payload.language) === -1) {
log.debug(`Message ${payload.id} filtered by language (${payload.language})`); log.debug(`Message ${payload.id} filtered by language (${payload.language})`);
return; return;
} }

View File

@ -14125,13 +14125,13 @@ __metadata:
linkType: hard linkType: hard
"postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.49": "postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.49":
version: 8.5.2 version: 8.5.3
resolution: "postcss@npm:8.5.2" resolution: "postcss@npm:8.5.3"
dependencies: dependencies:
nanoid: "npm:^3.3.8" nanoid: "npm:^3.3.8"
picocolors: "npm:^1.1.1" picocolors: "npm:^1.1.1"
source-map-js: "npm:^1.2.1" source-map-js: "npm:^1.2.1"
checksum: 10c0/3044d49bc725029ab62292e8bf9849741251b95f3b754e191bf8b4025414d40ec3b4ac05c5a563d4b50060b5c8e96683eb4d783d8d8fa3867eb7b763cbe66127 checksum: 10c0/b75510d7b28c3ab728c8733dd01538314a18c52af426f199a3c9177e63eb08602a3938bfb66b62dc01350b9aed62087eabbf229af97a1659eb8d3513cec823b3
languageName: node languageName: node
linkType: hard linkType: hard
@ -17749,11 +17749,11 @@ __metadata:
linkType: hard linkType: hard
"uuid@npm:^11.0.0": "uuid@npm:^11.0.0":
version: 11.0.5 version: 11.1.0
resolution: "uuid@npm:11.0.5" resolution: "uuid@npm:11.1.0"
bin: bin:
uuid: dist/esm/bin/uuid uuid: dist/esm/bin/uuid
checksum: 10c0/6f59f0c605e02c14515401084ca124b9cb462b4dcac866916a49862bcf831874508a308588c23a7718269226ad11a92da29b39d761ad2b86e736623e3a33b6e7 checksum: 10c0/34aa51b9874ae398c2b799c88a127701408cd581ee89ec3baa53509dd8728cbb25826f2a038f9465f8b7be446f0fbf11558862965b18d21c993684297628d4d3
languageName: node languageName: node
linkType: hard linkType: hard
@ -18622,8 +18622,8 @@ __metadata:
linkType: hard linkType: hard
"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.18.0": "ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.18.0":
version: 8.18.0 version: 8.18.1
resolution: "ws@npm:8.18.0" resolution: "ws@npm:8.18.1"
peerDependencies: peerDependencies:
bufferutil: ^4.0.1 bufferutil: ^4.0.1
utf-8-validate: ">=5.0.2" utf-8-validate: ">=5.0.2"
@ -18632,7 +18632,7 @@ __metadata:
optional: true optional: true
utf-8-validate: utf-8-validate:
optional: true optional: true
checksum: 10c0/25eb33aff17edcb90721ed6b0eb250976328533ad3cd1a28a274bd263682e7296a6591ff1436d6cbc50fa67463158b062f9d1122013b361cec99a05f84680e06 checksum: 10c0/e498965d6938c63058c4310ffb6967f07d4fa06789d3364829028af380d299fe05762961742971c764973dce3d1f6a2633fe8b2d9410c9b52e534b4b882a99fa
languageName: node languageName: node
linkType: hard linkType: hard