From 62f3550830fcbbc2a8f361ca156b6c7a45d2a2f9 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 11 Mar 2026 17:47:56 +0100 Subject: [PATCH] Add `GET /api/v1/admin/warning_presets` and `GET /api/v1/admin/warning_presets/:id` --- .../v1/admin/warning_presets_controller.rb | 32 ++++++++ app/policies/account_warning_preset_policy.rb | 4 + .../account_warning_preset_serializer.rb | 9 ++ config/routes/api.rb | 1 + .../api/v1/admin/warning_presets_spec.rb | 82 +++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100644 app/controllers/api/v1/admin/warning_presets_controller.rb create mode 100644 app/serializers/rest/admin/account_warning_preset_serializer.rb create mode 100644 spec/requests/api/v1/admin/warning_presets_spec.rb diff --git a/app/controllers/api/v1/admin/warning_presets_controller.rb b/app/controllers/api/v1/admin/warning_presets_controller.rb new file mode 100644 index 00000000000..6dd29da1755 --- /dev/null +++ b/app/controllers/api/v1/admin/warning_presets_controller.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class Api::V1::Admin::WarningPresetsController < Api::BaseController + include Authorization + include AccountableConcern + + before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:reports' }, only: [:index, :show] + before_action :set_presets, only: :index + before_action :set_preset, except: :index + + after_action :verify_authorized + + def index + authorize :account_warning_preset, :show? + render json: @warning_presets, each_serializer: REST::Admin::AccountWarningPresetSerializer + end + + def show + authorize @warning_preset, :show? + render json: @warning_preset, serializer: REST::Admin::AccountWarningPresetSerializer + end + + private + + def set_presets + @warning_presets = AccountWarningPreset.all + end + + def set_preset + @warning_preset = AccountWarningPreset.find(params[:id]) + end +end diff --git a/app/policies/account_warning_preset_policy.rb b/app/policies/account_warning_preset_policy.rb index 59514e95163..d9684e41fb8 100644 --- a/app/policies/account_warning_preset_policy.rb +++ b/app/policies/account_warning_preset_policy.rb @@ -5,6 +5,10 @@ class AccountWarningPresetPolicy < ApplicationPolicy role.can?(:manage_settings) end + def show? + role.can?(:manage_settings, :manage_reports, :manage_users) + end + def create? role.can?(:manage_settings) end diff --git a/app/serializers/rest/admin/account_warning_preset_serializer.rb b/app/serializers/rest/admin/account_warning_preset_serializer.rb new file mode 100644 index 00000000000..63674c835d9 --- /dev/null +++ b/app/serializers/rest/admin/account_warning_preset_serializer.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class REST::Admin::AccountWarningPresetSerializer < ActiveModel::Serializer + attributes :id, :text, :title, :created_at, :updated_at + + def id + object.id.to_s + end +end diff --git a/config/routes/api.rb b/config/routes/api.rb index 285b032d01f..efede8baec5 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -298,6 +298,7 @@ namespace :api, format: false do resources :domain_blocks, only: [:index, :show, :update, :create, :destroy] resources :email_domain_blocks, only: [:index, :show, :create, :destroy] resources :ip_blocks, only: [:index, :show, :update, :create, :destroy] + resources :warning_presets, only: [:index, :show] namespace :trends do resources :tags, only: [:index] do diff --git a/spec/requests/api/v1/admin/warning_presets_spec.rb b/spec/requests/api/v1/admin/warning_presets_spec.rb new file mode 100644 index 00000000000..55ec3501386 --- /dev/null +++ b/spec/requests/api/v1/admin/warning_presets_spec.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Warning presets' do + include_context 'with API authentication', user_fabricator: :admin_user, oauth_scopes: 'admin:read:reports' + + describe 'GET /api/v1/admin/warning_presets' do + subject do + get '/api/v1/admin/warning_presets', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + context 'when there are no presets' do + it 'returns an empty list' do + subject + + expect(response) + .to have_http_status(200) + expect(response.content_type) + .to start_with('application/json') + expect(response.parsed_body) + .to be_empty + end + end + + context 'when there are presets' do + let!(:preset) { Fabricate(:account_warning_preset, title: 'Simple moderation warning', text: 'Boilerplate here') } + + it 'returns all available presets' do + subject + + expect(response) + .to have_http_status(200) + expect(response.content_type) + .to start_with('application/json') + expect(response.parsed_body) + .to match_array(a_hash_including({ + 'id' => preset.id.to_s, + 'text' => preset.text, + 'title' => preset.title, + })) + end + end + end + + describe 'GET /api/v1/admin/reports/:id' do + subject do + get "/api/v1/admin/reports/#{report.id}", headers: headers + end + + let(:report) { Fabricate(:report) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns the requested report content', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(response.content_type) + .to start_with('application/json') + expect(response.parsed_body).to include( + { + id: report.id.to_s, + action_taken: report.action_taken?, + category: report.category, + comment: report.comment, + account: a_hash_including(id: report.account.id.to_s), + target_account: a_hash_including(id: report.target_account.id.to_s), + statuses: report.statuses, + rules: report.rules, + forwarded: report.forwarded, + } + ) + end + end +end