Skip to content

Commit 3ddebc6

Browse files
Paul Woolcockhiyuki2578
authored andcommitted
Add account_id param to GET /api/v1/notifications (mastodon#10796)
* Add `from_account` to notifications API this adds the ability to filter notifications by the account they originated from * passing a non-existent user should cause none to be returned * Fix codeclimate warnings * fix more codeclimate warnings * make requested changes: * use account id instead of user@domain * name the param `account_id` instead of `from_account` * Don't use `return` in a lambda
1 parent df62781 commit 3ddebc6

3 files changed

Lines changed: 77 additions & 3 deletions

File tree

app/controllers/api/v1/notifications_controller.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def paginated_notifications
4444
end
4545

4646
def browserable_account_notifications
47-
current_account.notifications.browserable(exclude_types)
47+
current_account.notifications.browserable(exclude_types, from_account)
4848
end
4949

5050
def target_statuses_from_notifications
@@ -81,6 +81,10 @@ def exclude_types
8181
val
8282
end
8383

84+
def from_account
85+
params[:account_id]
86+
end
87+
8488
def pagination_params(core_params)
8589
params.slice(:limit, :exclude_types).permit(:limit, exclude_types: []).merge(core_params)
8690
end

app/models/notification.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ class Notification < ApplicationRecord
4141
validates :account_id, uniqueness: { scope: [:activity_type, :activity_id] }
4242
validates :activity_type, inclusion: { in: TYPE_CLASS_MAP.values }
4343

44-
scope :browserable, ->(exclude_types = []) {
44+
scope :browserable, ->(exclude_types = [], account_id = nil) {
4545
types = TYPE_CLASS_MAP.values - activity_types_from_types(exclude_types + [:follow_request])
46-
where(activity_type: types)
46+
if account_id.nil?
47+
where(activity_type: types)
48+
else
49+
where(activity_type: types, from_account_id: account_id)
50+
end
4751
}
4852

4953
cache_associated :from_account, status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account, poll: [status: STATUS_INCLUDES]

spec/controllers/api/v1/notifications_controller_spec.rb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
77
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
88
let(:other) { Fabricate(:user, account: Fabricate(:account, username: 'bob')) }
9+
let(:third) { Fabricate(:user, account: Fabricate(:account, username: 'carol')) }
910

1011
before do
1112
allow(controller).to receive(:doorkeeper_token) { token }
@@ -55,6 +56,7 @@
5556
mentioning_status = PostStatusService.new.call(other.account, text: 'Hello @alice')
5657
@mention_from_status = mentioning_status.mentions.first
5758
@favourite = FavouriteService.new.call(other.account, first_status)
59+
@second_favourite = FavouriteService.new.call(third.account, first_status)
5860
@follow = FollowService.new.call(other.account, 'alice')
5961
end
6062

@@ -84,6 +86,66 @@
8486
end
8587
end
8688

89+
describe 'from specified user' do
90+
before do
91+
get :index, params: { account_id: third.account.id }
92+
end
93+
94+
it 'returns http success' do
95+
expect(response).to have_http_status(200)
96+
end
97+
98+
it 'includes favourite' do
99+
expect(assigns(:notifications).map(&:activity)).to include(@second_favourite)
100+
end
101+
102+
it 'excludes favourite' do
103+
expect(assigns(:notifications).map(&:activity)).to_not include(@favourite)
104+
end
105+
106+
it 'excludes mention' do
107+
expect(assigns(:notifications).map(&:activity)).to_not include(@mention_from_status)
108+
end
109+
110+
it 'excludes reblog' do
111+
expect(assigns(:notifications).map(&:activity)).to_not include(@reblog_of_first_status)
112+
end
113+
114+
it 'excludes follow' do
115+
expect(assigns(:notifications).map(&:activity)).to_not include(@follow)
116+
end
117+
end
118+
119+
describe 'from nonexistent user' do
120+
before do
121+
get :index, params: { account_id: 'foo' }
122+
end
123+
124+
it 'returns http success' do
125+
expect(response).to have_http_status(200)
126+
end
127+
128+
it 'excludes favourite' do
129+
expect(assigns(:notifications).map(&:activity)).to_not include(@favourite)
130+
end
131+
132+
it 'excludes second favourite' do
133+
expect(assigns(:notifications).map(&:activity)).to_not include(@second_favourite)
134+
end
135+
136+
it 'excludes mention' do
137+
expect(assigns(:notifications).map(&:activity)).to_not include(@mention_from_status)
138+
end
139+
140+
it 'excludes reblog' do
141+
expect(assigns(:notifications).map(&:activity)).to_not include(@reblog_of_first_status)
142+
end
143+
144+
it 'excludes follow' do
145+
expect(assigns(:notifications).map(&:activity)).to_not include(@follow)
146+
end
147+
end
148+
87149
describe 'with excluded mentions' do
88150
before do
89151
get :index, params: { exclude_types: ['mention'] }
@@ -105,6 +167,10 @@
105167
expect(assigns(:notifications).map(&:activity)).to include(@favourite)
106168
end
107169

170+
it 'includes third favourite' do
171+
expect(assigns(:notifications).map(&:activity)).to include(@second_favourite)
172+
end
173+
108174
it 'includes follow' do
109175
expect(assigns(:notifications).map(&:activity)).to include(@follow)
110176
end

0 commit comments

Comments
 (0)