mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 03:00:33 +02:00
Allow reporting (local) Collections (#37848)
This commit is contained in:
@@ -23,6 +23,10 @@ class Api::V1::ReportsController < Api::BaseController
|
||||
end
|
||||
|
||||
def report_params
|
||||
params.permit(:account_id, :comment, :category, :forward, forward_to_domains: [], status_ids: [], rule_ids: [])
|
||||
if Mastodon::Feature.collections_enabled?
|
||||
params.permit(:account_id, :comment, :category, :forward, forward_to_domains: [], status_ids: [], collection_ids: [], rule_ids: [])
|
||||
else
|
||||
params.permit(:account_id, :comment, :category, :forward, forward_to_domains: [], status_ids: [], rule_ids: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,6 +26,7 @@ class Collection < ApplicationRecord
|
||||
belongs_to :tag, optional: true
|
||||
|
||||
has_many :collection_items, dependent: :delete_all
|
||||
has_many :collection_reports, dependent: :delete_all
|
||||
|
||||
validates :name, presence: true
|
||||
validates :description, presence: true
|
||||
|
||||
16
app/models/collection_report.rb
Normal file
16
app/models/collection_report.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: collection_reports
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# collection_id :bigint(8) not null
|
||||
# report_id :bigint(8) not null
|
||||
#
|
||||
class CollectionReport < ApplicationRecord
|
||||
belongs_to :collection
|
||||
belongs_to :report
|
||||
end
|
||||
@@ -40,6 +40,8 @@ class Report < ApplicationRecord
|
||||
belongs_to :assigned_account, optional: true
|
||||
end
|
||||
|
||||
has_many :collection_reports, dependent: :delete_all
|
||||
has_many :collections, through: :collection_reports
|
||||
has_many :notes, class_name: 'ReportNote', inverse_of: :report, dependent: :destroy
|
||||
has_many :notifications, as: :activity, dependent: :destroy
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
class REST::ReportSerializer < ActiveModel::Serializer
|
||||
attributes :id, :action_taken, :action_taken_at, :category, :comment,
|
||||
:forwarded, :created_at, :status_ids, :rule_ids
|
||||
:forwarded, :created_at, :status_ids, :rule_ids,
|
||||
:collection_ids
|
||||
|
||||
has_one :target_account, serializer: REST::AccountSerializer
|
||||
|
||||
@@ -17,4 +18,8 @@ class REST::ReportSerializer < ActiveModel::Serializer
|
||||
def rule_ids
|
||||
object&.rule_ids&.map(&:to_s)
|
||||
end
|
||||
|
||||
def collection_ids
|
||||
object.collection_ids.map(&:to_s)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ class ReportService < BaseService
|
||||
@source_account = source_account
|
||||
@target_account = target_account
|
||||
@status_ids = options.delete(:status_ids).presence || []
|
||||
@collection_ids = options.delete(:collection_ids).presence || []
|
||||
@comment = options.delete(:comment).presence || ''
|
||||
@category = options[:rule_ids].present? ? 'violation' : (options.delete(:category).presence || 'other')
|
||||
@rule_ids = options.delete(:rule_ids).presence
|
||||
@@ -32,6 +33,7 @@ class ReportService < BaseService
|
||||
@report = @source_account.reports.create!(
|
||||
target_account: @target_account,
|
||||
status_ids: reported_status_ids,
|
||||
collection_ids: reported_collection_ids,
|
||||
comment: @comment,
|
||||
uri: @options[:uri],
|
||||
forwarded: forward_to_origin?,
|
||||
@@ -91,6 +93,10 @@ class ReportService < BaseService
|
||||
scope.where(id: Array(@status_ids)).pluck(:id)
|
||||
end
|
||||
|
||||
def reported_collection_ids
|
||||
@target_account.collections.find(Array(@collection_ids)).pluck(:id)
|
||||
end
|
||||
|
||||
def payload
|
||||
Oj.dump(serialize_payload(@report, ActivityPub::FlagSerializer, account: some_local_account))
|
||||
end
|
||||
|
||||
12
db/migrate/20260212131934_create_collection_reports.rb
Normal file
12
db/migrate/20260212131934_create_collection_reports.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CreateCollectionReports < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :collection_reports do |t|
|
||||
t.references :collection, null: false, foreign_key: { on_delete: :cascade }
|
||||
t.references :report, null: false, foreign_key: { on_delete: :cascade }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
13
db/schema.rb
13
db/schema.rb
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2026_02_12_113020) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2026_02_12_131934) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
|
||||
@@ -372,6 +372,15 @@ ActiveRecord::Schema[8.0].define(version: 2026_02_12_113020) do
|
||||
t.index ["object_uri"], name: "index_collection_items_on_object_uri", unique: true, where: "(activity_uri IS NOT NULL)"
|
||||
end
|
||||
|
||||
create_table "collection_reports", force: :cascade do |t|
|
||||
t.bigint "collection_id", null: false
|
||||
t.bigint "report_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["collection_id"], name: "index_collection_reports_on_collection_id"
|
||||
t.index ["report_id"], name: "index_collection_reports_on_report_id"
|
||||
end
|
||||
|
||||
create_table "collections", id: :bigint, default: -> { "timestamp_id('collections'::text)" }, force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.string "name", null: false
|
||||
@@ -1431,6 +1440,8 @@ ActiveRecord::Schema[8.0].define(version: 2026_02_12_113020) do
|
||||
add_foreign_key "canonical_email_blocks", "accounts", column: "reference_account_id", on_delete: :cascade
|
||||
add_foreign_key "collection_items", "accounts"
|
||||
add_foreign_key "collection_items", "collections", on_delete: :cascade
|
||||
add_foreign_key "collection_reports", "collections", on_delete: :cascade
|
||||
add_foreign_key "collection_reports", "reports", on_delete: :cascade
|
||||
add_foreign_key "collections", "accounts"
|
||||
add_foreign_key "collections", "tags"
|
||||
add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade
|
||||
|
||||
@@ -11,20 +11,22 @@ RSpec.describe 'Reports' do
|
||||
end
|
||||
|
||||
let!(:admin) { Fabricate(:admin_user) }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:target_account) { status.account }
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
let(:category) { 'other' }
|
||||
let(:forward) { nil }
|
||||
let(:rule_ids) { nil }
|
||||
let(:status_ids) { nil }
|
||||
let(:collection_ids) { nil }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
status_ids: [status.id],
|
||||
status_ids:,
|
||||
collection_ids:,
|
||||
account_id: target_account.id,
|
||||
comment: 'reasons',
|
||||
category: category,
|
||||
rule_ids: rule_ids,
|
||||
forward: forward,
|
||||
category:,
|
||||
rule_ids:,
|
||||
forward:,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -38,7 +40,6 @@ RSpec.describe 'Reports' do
|
||||
.to start_with('application/json')
|
||||
expect(response.parsed_body).to match(
|
||||
a_hash_including(
|
||||
status_ids: [status.id.to_s],
|
||||
category: category,
|
||||
comment: 'reasons'
|
||||
)
|
||||
@@ -57,18 +58,6 @@ RSpec.describe 'Reports' do
|
||||
)
|
||||
end
|
||||
|
||||
context 'when a status does not belong to the reported account' do
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a category is chosen' do
|
||||
let(:category) { 'spam' }
|
||||
|
||||
@@ -91,5 +80,69 @@ RSpec.describe 'Reports' do
|
||||
expect(target_account.targeted_reports.first.rule_ids).to contain_exactly(rule.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with attached status' do
|
||||
let(:status) { Fabricate(:status, account: target_account) }
|
||||
let(:status_ids) { [status.id] }
|
||||
|
||||
it 'creates a report including the status ids', :aggregate_failures, :inline_jobs do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
expect(response.parsed_body).to match(
|
||||
a_hash_including(
|
||||
status_ids: [status.id.to_s],
|
||||
category: category,
|
||||
comment: 'reasons'
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'when a status does not belong to the reported account' do
|
||||
let(:status) { Fabricate(:status) }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with attached collection', feature: :collections do
|
||||
let(:collection) { Fabricate(:collection, account: target_account) }
|
||||
let(:collection_ids) { [collection.id] }
|
||||
|
||||
it 'creates a report including the collection ids', :aggregate_failures, :inline_jobs do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
expect(response.parsed_body).to match(
|
||||
a_hash_including(
|
||||
collection_ids: [collection.id.to_s],
|
||||
category: category,
|
||||
comment: 'reasons'
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'when a collection does not belong to the reported account' do
|
||||
let(:collection) { Fabricate(:collection) }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user