mirror of
https://github.com/discourse/discourse.git
synced 2024-11-30 11:43:56 +08:00
7b4e338c0e
Due to some changes we started notifying via push notifications on other families of notifications. There are a total of about 30 or so possible notification you could get, some can be pushed. This fallback means that if for any reason we are unable to find an icon for a push notification we just fallback to the Discourse logo. Also go with a simple reply icon for watching first post. Note, that in production `image_url` can return an exception if an image is missing. This is not the case in test / development.
128 lines
3.9 KiB
Ruby
128 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe PushNotificationPusher do
|
|
|
|
it "returns badges url by default" do
|
|
expect(PushNotificationPusher.get_badge).to eq("/assets/push-notifications/discourse.png")
|
|
end
|
|
|
|
it "returns custom badges url" do
|
|
upload = Fabricate(:upload)
|
|
SiteSetting.push_notifications_icon = upload
|
|
|
|
expect(PushNotificationPusher.get_badge)
|
|
.to eq(UrlHelper.absolute(upload.url))
|
|
end
|
|
|
|
context "with user" do
|
|
fab!(:user) { Fabricate(:user) }
|
|
|
|
def create_subscription
|
|
data = <<~JSON
|
|
{
|
|
"endpoint": "endpoint",
|
|
"keys": {
|
|
"p256dh": "p256dh",
|
|
"auth": "auth"
|
|
}
|
|
}
|
|
JSON
|
|
PushSubscription.create!(user_id: user.id, data: data)
|
|
end
|
|
|
|
def execute_push(notification_type: 1)
|
|
PushNotificationPusher.push(user, {
|
|
topic_title: 'Topic',
|
|
username: 'system',
|
|
excerpt: 'description',
|
|
topic_id: 1,
|
|
post_url: "https://example.com/t/1/2",
|
|
notification_type: notification_type
|
|
})
|
|
end
|
|
|
|
it "correctly guesses an image if missing" do
|
|
message = execute_push(notification_type: -1)
|
|
expect(message[:icon]).to eq("/assets/push-notifications/discourse.png")
|
|
end
|
|
|
|
it "correctly finds image if exists" do
|
|
message = execute_push(notification_type: 1)
|
|
expect(message[:icon]).to eq("/assets/push-notifications/mentioned.png")
|
|
end
|
|
|
|
it "sends notification in user's locale" do
|
|
SiteSetting.allow_user_locale = true
|
|
user.update!(locale: 'pt_BR')
|
|
|
|
TranslationOverride.upsert!("pt_BR", "discourse_push_notifications.popup.mentioned", "pt_BR notification")
|
|
|
|
Webpush.expects(:payload_send).with do |*args|
|
|
JSON.parse(args.first[:message])["title"] == "pt_BR notification"
|
|
end.once
|
|
|
|
create_subscription
|
|
execute_push
|
|
end
|
|
|
|
it "deletes subscriptions which are erroring regularly" do
|
|
start = freeze_time
|
|
|
|
sub = create_subscription
|
|
|
|
response = Struct.new(:body, :inspect, :message).new("test", "test", "failed")
|
|
error = Webpush::ResponseError.new(response, "localhost")
|
|
|
|
Webpush.expects(:payload_send).raises(error).times(4)
|
|
|
|
# 3 failures in more than 24 hours
|
|
3.times do
|
|
execute_push
|
|
|
|
freeze_time 1.minute.from_now
|
|
end
|
|
|
|
sub.reload
|
|
expect(sub.error_count).to eq(3)
|
|
expect(sub.first_error_at).to eq_time(start)
|
|
|
|
freeze_time(2.days.from_now)
|
|
|
|
execute_push
|
|
|
|
expect(PushSubscription.where(id: sub.id).exists?).to eq(false)
|
|
end
|
|
|
|
it "deletes invalid subscriptions during send" do
|
|
missing_endpoint = PushSubscription.create!(user_id: user.id, data:
|
|
{ p256dh: "public ECDH key", keys: { auth: "private ECDH key" } }.to_json)
|
|
|
|
missing_p256dh = PushSubscription.create!(user_id: user.id, data:
|
|
{ endpoint: "endpoint 1", keys: { auth: "private ECDH key" } }.to_json)
|
|
|
|
missing_auth = PushSubscription.create!(user_id: user.id, data:
|
|
{ endpoint: "endpoint 2", keys: { p256dh: "public ECDH key" } }.to_json)
|
|
|
|
valid_subscription = PushSubscription.create!(user_id: user.id, data:
|
|
{ endpoint: "endpoint 3", keys: { p256dh: "public ECDH key", auth: "private ECDH key" } }.to_json)
|
|
|
|
expect(PushSubscription.where(user_id: user.id)).to contain_exactly(missing_endpoint, missing_p256dh, missing_auth, valid_subscription)
|
|
Webpush.expects(:payload_send).with(has_entries(endpoint: "endpoint 3", p256dh: "public ECDH key", auth: "private ECDH key")).once
|
|
|
|
execute_push
|
|
|
|
expect(PushSubscription.where(user_id: user.id)).to contain_exactly(valid_subscription)
|
|
end
|
|
|
|
it "handles timeouts" do
|
|
Webpush.expects(:payload_send).raises(Net::ReadTimeout.new)
|
|
subscription = create_subscription
|
|
|
|
expect { execute_push }.to_not raise_exception
|
|
|
|
subscription.reload
|
|
expect(subscription.error_count).to eq(1)
|
|
end
|
|
end
|
|
end
|