Destroy NotificationRequests that are dismissed (#31008)
				
					
				
			This commit is contained in:
		
							parent
							
								
									c929b4cace
								
							
						
					
					
						commit
						35a437a03f
					
				| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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? | ||||||
|  | |||||||
| @ -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 | ||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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) } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user