Merge remote-tracking branch 'parent/main' into upstream-20240225

This commit is contained in:
KMY 2025-02-25 08:15:45 +09:00
commit a72160b66f
115 changed files with 1002 additions and 731 deletions

View file

@ -3,14 +3,142 @@
require 'rails_helper'
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) }
it 'gracefully handles invalid nested params' do
post admin_roles_path(user_role: 'invalid')
describe 'POST /admin/roles' do
it 'gracefully handles invalid nested params' do
post admin_roles_path(user_role: 'invalid')
expect(response)
.to have_http_status(400)
expect(response)
.to have_http_status(400)
end
end
end
end

View file

@ -3,6 +3,34 @@
require 'rails_helper'
RSpec.describe 'Admin Users Roles' do
context 'when target user is higher ranked than current user' do
let(:current_role) { UserRole.create(name: 'Foo', permissions: UserRole::FLAGS[:manage_roles], position: 10) }
let(:current_user) { Fabricate(:user, role: current_role) }
let(:previous_role) { UserRole.create(name: 'Baz', permissions: UserRole::FLAGS[:administrator], position: 100) }
let(:user) { Fabricate(:user, role: previous_role) }
before { sign_in(current_user) }
describe 'GET /admin/users/:user_id/role' do
it 'returns http forbidden' do
get admin_user_role_path(user.id)
expect(response)
.to have_http_status(403)
end
end
describe 'PUT /admin/users/:user_id/role' do
it 'returns http forbidden' do
put admin_user_role_path(user.id)
expect(response)
.to have_http_status(403)
end
end
end
describe 'PUT /admin/users/:user_id/role' do
before { sign_in Fabricate(:admin_user) }

View file

@ -16,4 +16,20 @@ RSpec.describe 'Settings 2FA Confirmations' do
.to have_http_status(400)
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

View file

@ -59,7 +59,6 @@ RSpec.describe 'Statuses' do
expect(response)
.to have_http_status(200)
.and render_template(:show)
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('public'),
@ -114,9 +113,11 @@ RSpec.describe 'Statuses' do
end
context 'when signed in' do
subject { get short_account_status_path(account_username: account.username, id: status.id, format: format) }
let(:user) { Fabricate(:user) }
before { sign_in(user) }
before { sign_in_with_session(user) }
context 'when account blocks user' do
before { account.block!(user.account) }
@ -128,6 +129,167 @@ RSpec.describe 'Statuses' do
.to have_http_status(404)
end
end
context 'when status is public' do
context 'with HTML' do
let(:format) { 'html' }
it 'renders status successfully', :aggregate_failures do
subject
expect(response)
.to have_http_status(200)
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Link' => include('activity+json')
)
expect(response.body)
.to include(status.text)
end
end
context 'with JSON' do
let(:format) { 'json' }
it 'renders ActivityPub Note object successfully', :aggregate_failures do
subject
expect(response)
.to have_http_status(200)
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
end
end
end
context 'when status is private' do
let(:status) { Fabricate(:status, account: account, visibility: :private) }
context 'when user is authorized to see it' do
before { user.account.follow!(account) }
context 'with HTML' do
let(:format) { 'html' }
it 'renders status successfully', :aggregate_failures do
subject
expect(response)
.to have_http_status(200)
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Link' => include('activity+json')
)
expect(response.body)
.to include(status.text)
end
end
context 'with JSON' do
let(:format) { 'json' }
it 'renders ActivityPub Note object successfully', :aggregate_failures do
subject
expect(response)
.to have_http_status(200)
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
end
end
end
context 'when user is not authorized to see it' do
let(:format) { 'html' }
it 'returns http not found' do
subject
expect(response)
.to have_http_status(404)
end
end
end
context 'when status is direct' do
let(:status) { Fabricate(:status, account: account, visibility: :direct) }
context 'when user is authorized to see it' do
before { Fabricate(:mention, account: user.account, status: status) }
context 'with HTML' do
let(:format) { 'html' }
it 'renders status successfully', :aggregate_failures do
subject
expect(response)
.to have_http_status(200)
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Link' => include('activity+json')
)
expect(response.body)
.to include(status.text)
end
end
context 'with JSON' do
let(:format) { 'json' }
it 'renders ActivityPub Note object successfully' do
subject
expect(response)
.to have_http_status(200)
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
end
end
end
context 'when user is not authorized to see it' do
let(:format) { 'html' }
it 'returns http not found' do
subject
expect(response)
.to have_http_status(404)
end
end
end
private
def sign_in_with_session(user)
# The regular `sign_in` helper does not actually set session cookies
# The endpoint responses here rely on cookie/session checks to set cache privacy headers
# To enable that, perform a full sign in which will establish those cookies for subsequent spec requests
post user_session_path, params: { user: { email: user.email, password: user.password } }
end
end
context 'with "HTTP Signature" access signed by a remote account' do