Destroy `NotificationRequest`s that are dismissed (#31008)

shrike
David Roetzel 2024-07-12 14:09:52 +02:00 committed by GitHub
parent c929b4cace
commit 35a437a03f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 57 additions and 40 deletions

View File

@ -28,14 +28,14 @@ class Api::V1::Notifications::RequestsController < Api::BaseController
end end
def dismiss def dismiss
@request.update!(dismissed: true) @request.destroy!
render_empty render_empty
end end
private private
def load_requests def load_requests
requests = NotificationRequest.where(account: current_account).where(dismissed: truthy_param?(:dismissed) || false).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id( requests = NotificationRequest.where(account: current_account).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id(
limit_param(DEFAULT_ACCOUNTS_LIMIT), limit_param(DEFAULT_ACCOUNTS_LIMIT),
params_slice(:max_id, :since_id, :min_id) params_slice(:max_id, :since_id, :min_id)
) )
@ -68,8 +68,4 @@ class Api::V1::Notifications::RequestsController < Api::BaseController
def pagination_since_id def pagination_since_id
@requests.first.id @requests.first.id
end end
def pagination_params(core_params)
params.slice(:dismissed).permit(:dismissed).merge(core_params)
end
end end

View File

@ -31,6 +31,6 @@ class NotificationPolicy < ApplicationRecord
private private
def pending_notification_requests def pending_notification_requests
@pending_notification_requests ||= notification_requests.where(dismissed: false).limit(MAX_MEANINGFUL_COUNT).pick(Arel.sql('count(*), coalesce(sum(notifications_count), 0)::bigint')) @pending_notification_requests ||= notification_requests.limit(MAX_MEANINGFUL_COUNT).pick(Arel.sql('count(*), coalesce(sum(notifications_count), 0)::bigint'))
end end
end end

View File

@ -9,12 +9,13 @@
# from_account_id :bigint(8) not null # from_account_id :bigint(8) not null
# last_status_id :bigint(8) # last_status_id :bigint(8)
# notifications_count :bigint(8) default(0), not null # notifications_count :bigint(8) default(0), not null
# dismissed :boolean default(FALSE), not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# #
class NotificationRequest < ApplicationRecord class NotificationRequest < ApplicationRecord
self.ignored_columns += %w(dismissed)
include Paginable include Paginable
MAX_MEANINGFUL_COUNT = 100 MAX_MEANINGFUL_COUNT = 100
@ -34,8 +35,6 @@ class NotificationRequest < ApplicationRecord
end end
def reconsider_existence! def reconsider_existence!
return if dismissed?
prepare_notifications_count prepare_notifications_count
if notifications_count.positive? if notifications_count.positive?

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class RemoveDismissedFromNotificationRequests < ActiveRecord::Migration[7.1]
def up
safety_assured do
execute 'DELETE FROM notification_requests WHERE dismissed'
remove_column :notification_requests, :dismissed
end
end
def down
add_column :notification_requests, :dismissed, :boolean, default: false, null: false
end
end

View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2024_06_07_094856) do ActiveRecord::Schema[7.1].define(version: 2024_07_12_064044) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -706,11 +706,9 @@ ActiveRecord::Schema[7.1].define(version: 2024_06_07_094856) do
t.bigint "from_account_id", null: false t.bigint "from_account_id", null: false
t.bigint "last_status_id" t.bigint "last_status_id"
t.bigint "notifications_count", default: 0, null: false t.bigint "notifications_count", default: 0, null: false
t.boolean "dismissed", default: false, null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["account_id", "from_account_id"], name: "index_notification_requests_on_account_id_and_from_account_id", unique: true t.index ["account_id", "from_account_id"], name: "index_notification_requests_on_account_id_and_from_account_id", unique: true
t.index ["account_id", "id"], name: "index_notification_requests_on_account_id_and_id", order: { id: :desc }, where: "(dismissed = false)"
t.index ["from_account_id"], name: "index_notification_requests_on_from_account_id" t.index ["from_account_id"], name: "index_notification_requests_on_from_account_id"
t.index ["last_status_id"], name: "index_notification_requests_on_last_status_id" t.index ["last_status_id"], name: "index_notification_requests_on_last_status_id"
end end

View File

@ -4,5 +4,4 @@ Fabricator(:notification_request) do
account account
from_account { Fabricate.build(:account) } from_account { Fabricate.build(:account) }
last_status { Fabricate.build(:status) } last_status { Fabricate.build(:status) }
dismissed false
end end

View File

@ -4,9 +4,7 @@ require 'rails_helper'
RSpec.describe NotificationRequest do RSpec.describe NotificationRequest do
describe '#reconsider_existence!' do describe '#reconsider_existence!' do
subject { Fabricate(:notification_request, dismissed: dismissed) } subject { Fabricate(:notification_request) }
let(:dismissed) { false }
context 'when there are remaining notifications' do context 'when there are remaining notifications' do
before do before do
@ -28,14 +26,6 @@ RSpec.describe NotificationRequest do
subject.reconsider_existence! subject.reconsider_existence!
end end
context 'when dismissed' do
let(:dismissed) { true }
it 'leaves request intact' do
expect(subject.destroyed?).to be false
end
end
it 'removes the request' do it 'removes the request' do
expect(subject.destroyed?).to be true expect(subject.destroyed?).to be true
end end

View File

@ -17,7 +17,6 @@ RSpec.describe 'Requests' do
before do before do
Fabricate(:notification_request, account: user.account) Fabricate(:notification_request, account: user.account)
Fabricate(:notification_request, account: user.account, dismissed: true)
end end
it_behaves_like 'forbidden for wrong scope', 'write write:notifications' it_behaves_like 'forbidden for wrong scope', 'write write:notifications'
@ -29,16 +28,6 @@ RSpec.describe 'Requests' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
end end
context 'with dismissed' do
let(:params) { { dismissed: '1' } }
it 'returns http success', :aggregate_failures do
subject
expect(response).to have_http_status(200)
end
end
end end
describe 'POST /api/v1/notifications/requests/:id/accept' do describe 'POST /api/v1/notifications/requests/:id/accept' do
@ -78,15 +67,14 @@ RSpec.describe 'Requests' do
post "/api/v1/notifications/requests/#{notification_request.id}/dismiss", headers: headers post "/api/v1/notifications/requests/#{notification_request.id}/dismiss", headers: headers
end end
let(:notification_request) { Fabricate(:notification_request, account: user.account) } let!(:notification_request) { Fabricate(:notification_request, account: user.account) }
it_behaves_like 'forbidden for wrong scope', 'read read:notifications' it_behaves_like 'forbidden for wrong scope', 'read read:notifications'
it 'returns http success and dismisses the notification request', :aggregate_failures do it 'returns http success and destroys the notification request', :aggregate_failures do
subject expect { subject }.to change(NotificationRequest, :count).by(-1)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(notification_request.reload.dismissed?).to be true
end end
context 'when notification request belongs to someone else' do context 'when notification request belongs to someone else' do

View File

@ -129,6 +129,39 @@ RSpec.describe NotifyService do
end end
end end
context 'with filtered notifications' do
let(:unknown) { Fabricate(:account, username: 'unknown') }
let(:status) { Fabricate(:status, account: unknown) }
let(:activity) { Fabricate(:mention, account: recipient, status: status) }
let(:type) { :mention }
before do
Fabricate(:notification_policy, account: recipient, filter_not_following: true)
end
it 'creates a filtered notification' do
expect { subject }.to change(Notification, :count)
expect(Notification.last).to be_filtered
end
context 'when no notification request exists' do
it 'creates a notification request' do
expect { subject }.to change(NotificationRequest, :count)
end
end
context 'when a notification request exists' do
let!(:notification_request) do
Fabricate(:notification_request, account: recipient, from_account: unknown, last_status: Fabricate(:status, account: unknown))
end
it 'updates the existing notification request' do
expect { subject }.to_not change(NotificationRequest, :count)
expect(notification_request.reload.last_status).to eq status
end
end
end
describe NotifyService::DismissCondition do describe NotifyService::DismissCondition do
subject { described_class.new(notification) } subject { described_class.new(notification) }