mirror of
https://github.com/lingble/chatwoot.git
synced 2025-12-03 03:23:39 +00:00
Webpush gem throws errors such as `WebPush::ExpiredSubscription`, `WebPush::InvalidSubscription`, `WebPush::Unauthorized`. We handled only ExpiredSubscription. If the SDK threw any other errors, it would pause sending the notification to all other devices for that user. This change would update the logic to remove the expired subscription and handle the rest of the errors gracefully. Fixes https://linear.app/chatwoot/issue/CW-3399/webpushinvalidsubscription-host-fcmgoogleapiscom-nethttpnotfound-404
66 lines
2.9 KiB
Ruby
66 lines
2.9 KiB
Ruby
require 'rails_helper'
|
|
|
|
describe Notification::PushNotificationService do
|
|
let!(:account) { create(:account) }
|
|
let!(:user) { create(:user, account: account) }
|
|
let!(:notification) { create(:notification, user: user, account: user.accounts.first) }
|
|
let(:fcm_double) { instance_double(FCM) }
|
|
let(:fcm_service_double) { instance_double(Notification::FcmService, fcm_client: fcm_double) }
|
|
|
|
describe '#perform' do
|
|
context 'when the push server returns success' do
|
|
before do
|
|
allow(WebPush).to receive(:payload_send).and_return(true)
|
|
allow(Rails.logger).to receive(:info)
|
|
allow(Notification::FcmService).to receive(:new).and_return(fcm_service_double)
|
|
allow(fcm_double).to receive(:send_v1).and_return({ body: { 'results': [] }.to_json })
|
|
allow(GlobalConfigService).to receive(:load).with('FIREBASE_PROJECT_ID', nil).and_return('test_project_id')
|
|
allow(GlobalConfigService).to receive(:load).with('FIREBASE_CREDENTIALS', nil).and_return('test_credentials')
|
|
end
|
|
|
|
it 'sends webpush notifications for webpush subscription' do
|
|
with_modified_env VAPID_PUBLIC_KEY: 'test' do
|
|
create(:notification_subscription, user: notification.user)
|
|
|
|
described_class.new(notification: notification).perform
|
|
expect(WebPush).to have_received(:payload_send)
|
|
expect(Notification::FcmService).not_to have_received(:new)
|
|
expect(Rails.logger).to have_received(:info).with("Browser push sent to #{user.email} with title #{notification.push_message_title}")
|
|
end
|
|
end
|
|
|
|
it 'sends a fcm notification for firebase subscription' do
|
|
with_modified_env ENABLE_PUSH_RELAY_SERVER: 'false' do
|
|
create(:notification_subscription, user: notification.user, subscription_type: 'fcm')
|
|
|
|
described_class.new(notification: notification).perform
|
|
expect(Notification::FcmService).to have_received(:new)
|
|
expect(fcm_double).to have_received(:send_v1)
|
|
expect(WebPush).not_to have_received(:payload_send)
|
|
expect(Rails.logger).to have_received(:info).with("FCM push sent to #{user.email} with title #{notification.push_message_title}")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when the push server returns error' do
|
|
it 'sends webpush notifications for webpush subscription' do
|
|
with_modified_env VAPID_PUBLIC_KEY: 'test' do
|
|
mock_response = instance_double(Net::HTTPResponse, body: 'Subscription is invalid')
|
|
mock_host = 'fcm.googleapis.com'
|
|
|
|
allow(WebPush).to receive(:payload_send).and_raise(WebPush::InvalidSubscription.new(mock_response, mock_host))
|
|
allow(Rails.logger).to receive(:info)
|
|
|
|
create(:notification_subscription, :browser_push, user: notification.user)
|
|
|
|
expect(Rails.logger).to receive(:info) do |message|
|
|
expect(message).to include('WebPush subscription expired:')
|
|
end
|
|
|
|
described_class.new(notification: notification).perform
|
|
end
|
|
end
|
|
end
|
|
end
|