Add policy param to POST /api/v1/push/subscriptions (#16040)

With possible values `all`, `followed`, `follower`, and `none`,
control from whom notifications will generate a Web Push alert
This commit is contained in:
Eugen Rochko
2021-04-15 05:00:25 +02:00
committed by GitHub
parent c968d22ee9
commit ce2148c571
6 changed files with 170 additions and 51 deletions

View File

@ -27,20 +27,27 @@ describe Api::V1::Push::SubscriptionsController do
let(:alerts_payload) do
{
data: {
policy: 'all',
alerts: {
follow: true,
follow_request: true,
favourite: false,
reblog: true,
mention: false,
poll: true,
status: false,
}
}
}.with_indifferent_access
end
describe 'POST #create' do
it 'saves push subscriptions' do
before do
post :create, params: create_payload
end
it 'saves push subscriptions' do
push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])
expect(push_subscription.endpoint).to eq(create_payload[:subscription][:endpoint])
@ -52,31 +59,34 @@ describe Api::V1::Push::SubscriptionsController do
it 'replaces old subscription on repeat calls' do
post :create, params: create_payload
post :create, params: create_payload
expect(Web::PushSubscription.where(endpoint: create_payload[:subscription][:endpoint]).count).to eq 1
end
end
describe 'PUT #update' do
it 'changes alert settings' do
before do
post :create, params: create_payload
put :update, params: alerts_payload
end
it 'changes alert settings' do
push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])
expect(push_subscription.data.dig('alerts', 'follow')).to eq(alerts_payload[:data][:alerts][:follow].to_s)
expect(push_subscription.data.dig('alerts', 'favourite')).to eq(alerts_payload[:data][:alerts][:favourite].to_s)
expect(push_subscription.data.dig('alerts', 'reblog')).to eq(alerts_payload[:data][:alerts][:reblog].to_s)
expect(push_subscription.data.dig('alerts', 'mention')).to eq(alerts_payload[:data][:alerts][:mention].to_s)
expect(push_subscription.data['policy']).to eq(alerts_payload[:data][:policy])
%w(follow follow_request favourite reblog mention poll status).each do |type|
expect(push_subscription.data['alerts'][type]).to eq(alerts_payload[:data][:alerts][type.to_sym].to_s)
end
end
end
describe 'DELETE #destroy' do
it 'removes the subscription' do
before do
post :create, params: create_payload
delete :destroy
end
it 'removes the subscription' do
expect(Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])).to be_nil
end
end

View File

@ -22,11 +22,16 @@ describe Api::Web::PushSubscriptionsController do
let(:alerts_payload) do
{
data: {
policy: 'all',
alerts: {
follow: true,
follow_request: false,
favourite: false,
reblog: true,
mention: false,
poll: true,
status: false,
}
}
}
@ -59,10 +64,11 @@ describe Api::Web::PushSubscriptionsController do
push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])
expect(push_subscription.data['alerts']['follow']).to eq(alerts_payload[:data][:alerts][:follow].to_s)
expect(push_subscription.data['alerts']['favourite']).to eq(alerts_payload[:data][:alerts][:favourite].to_s)
expect(push_subscription.data['alerts']['reblog']).to eq(alerts_payload[:data][:alerts][:reblog].to_s)
expect(push_subscription.data['alerts']['mention']).to eq(alerts_payload[:data][:alerts][:mention].to_s)
expect(push_subscription.data['policy']).to eq 'all'
%w(follow follow_request favourite reblog mention poll status).each do |type|
expect(push_subscription.data['alerts'][type]).to eq(alerts_payload[:data][:alerts][type.to_sym].to_s)
end
end
end
end
@ -81,10 +87,11 @@ describe Api::Web::PushSubscriptionsController do
push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])
expect(push_subscription.data['alerts']['follow']).to eq(alerts_payload[:data][:alerts][:follow].to_s)
expect(push_subscription.data['alerts']['favourite']).to eq(alerts_payload[:data][:alerts][:favourite].to_s)
expect(push_subscription.data['alerts']['reblog']).to eq(alerts_payload[:data][:alerts][:reblog].to_s)
expect(push_subscription.data['alerts']['mention']).to eq(alerts_payload[:data][:alerts][:mention].to_s)
expect(push_subscription.data['policy']).to eq 'all'
%w(follow follow_request favourite reblog mention poll status).each do |type|
expect(push_subscription.data['alerts'][type]).to eq(alerts_payload[:data][:alerts][type.to_sym].to_s)
end
end
end
end

View File

@ -1,16 +1,94 @@
require 'rails_helper'
RSpec.describe Web::PushSubscription, type: :model do
let(:alerts) { { mention: true, reblog: false, follow: true, follow_request: false, favourite: true } }
let(:push_subscription) { Web::PushSubscription.new(data: { alerts: alerts }) }
let(:account) { Fabricate(:account) }
let(:policy) { 'all' }
let(:data) do
{
policy: policy,
alerts: {
mention: true,
reblog: false,
follow: true,
follow_request: false,
favourite: true,
},
}
end
subject { described_class.new(data: data) }
describe '#pushable?' do
it 'obeys alert settings' do
expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Mention'))).to eq true
expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Status'))).to eq false
expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Follow'))).to eq true
expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'FollowRequest'))).to eq false
expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Favourite'))).to eq true
let(:notification_type) { :mention }
let(:notification) { Fabricate(:notification, account: account, type: notification_type) }
%i(mention reblog follow follow_request favourite).each do |type|
context "when notification is a #{type}" do
let(:notification_type) { type }
it "returns boolean corresonding to alert setting" do
expect(subject.pushable?(notification)).to eq data[:alerts][type]
end
end
end
context 'when policy is all' do
let(:policy) { 'all' }
it 'returns true' do
expect(subject.pushable?(notification)).to eq true
end
end
context 'when policy is none' do
let(:policy) { 'none' }
it 'returns false' do
expect(subject.pushable?(notification)).to eq false
end
end
context 'when policy is followed' do
let(:policy) { 'followed' }
context 'and notification is from someone you follow' do
before do
account.follow!(notification.from_account)
end
it 'returns true' do
expect(subject.pushable?(notification)).to eq true
end
end
context 'and notification is not from someone you follow' do
it 'returns false' do
expect(subject.pushable?(notification)).to eq false
end
end
end
context 'when policy is follower' do
let(:policy) { 'follower' }
context 'and notification is from someone who follows you' do
before do
notification.from_account.follow!(account)
end
it 'returns true' do
expect(subject.pushable?(notification)).to eq true
end
end
context 'and notification is not from someone who follows you' do
it 'returns false' do
expect(subject.pushable?(notification)).to eq false
end
end
end
end
end