Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Notification::EmailNotificationService do
|
||||
let(:account) { create(:account) }
|
||||
let(:agent) { create(:user, account: account, confirmed_at: Time.current) }
|
||||
let(:conversation) { create(:conversation, account: account) }
|
||||
let(:notification) { create(:notification, notification_type: :conversation_creation, user: agent, account: account, primary_actor: conversation) }
|
||||
let(:mailer) { double }
|
||||
let(:mailer_action) { double }
|
||||
|
||||
before do
|
||||
# Setup notification settings for the agent
|
||||
notification_setting = agent.notification_settings.find_by(account_id: account.id)
|
||||
notification_setting.selected_email_flags = [:email_conversation_creation]
|
||||
notification_setting.save!
|
||||
end
|
||||
|
||||
describe '#perform' do
|
||||
context 'when notification is read' do
|
||||
before do
|
||||
notification.update!(read_at: Time.current)
|
||||
end
|
||||
|
||||
it 'does not send email' do
|
||||
expect(AgentNotifications::ConversationNotificationsMailer).not_to receive(:with)
|
||||
described_class.new(notification: notification).perform
|
||||
end
|
||||
end
|
||||
|
||||
context 'when agent is not confirmed' do
|
||||
before do
|
||||
agent.update!(confirmed_at: nil)
|
||||
end
|
||||
|
||||
it 'does not send email' do
|
||||
expect(AgentNotifications::ConversationNotificationsMailer).not_to receive(:with)
|
||||
described_class.new(notification: notification).perform
|
||||
end
|
||||
end
|
||||
|
||||
context 'when agent is confirmed' do
|
||||
before do
|
||||
allow(AgentNotifications::ConversationNotificationsMailer).to receive(:with).and_return(mailer)
|
||||
allow(mailer).to receive(:public_send).and_return(mailer_action)
|
||||
allow(mailer_action).to receive(:deliver_later)
|
||||
end
|
||||
|
||||
it 'sends email' do
|
||||
described_class.new(notification: notification).perform
|
||||
expect(mailer).to have_received(:public_send).with(
|
||||
'conversation_creation',
|
||||
conversation,
|
||||
agent,
|
||||
nil
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is not subscribed to notification type' do
|
||||
before do
|
||||
notification_setting = agent.notification_settings.find_by(account_id: account.id)
|
||||
notification_setting.selected_email_flags = []
|
||||
notification_setting.save!
|
||||
end
|
||||
|
||||
it 'does not send email' do
|
||||
expect(AgentNotifications::ConversationNotificationsMailer).not_to receive(:with)
|
||||
described_class.new(notification: notification).perform
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,70 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Notification::FcmService do
|
||||
let(:project_id) { 'test_project_id' }
|
||||
let(:credentials) { '{ "type": "service_account", "project_id": "test_project_id" }' }
|
||||
let(:fcm_service) { described_class.new(project_id, credentials) }
|
||||
let(:fcm_double) { instance_double(FCM) }
|
||||
let(:token_info) { { token: 'test_token', expires_at: 1.hour.from_now } }
|
||||
let(:creds_double) do
|
||||
instance_double(Google::Auth::ServiceAccountCredentials, fetch_access_token!: { 'access_token' => 'test_token', 'expires_in' => 3600 })
|
||||
end
|
||||
|
||||
before do
|
||||
allow(FCM).to receive(:new).and_return(fcm_double)
|
||||
allow(fcm_service).to receive(:generate_token).and_return(token_info)
|
||||
allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds).and_return(creds_double)
|
||||
end
|
||||
|
||||
describe '#fcm_client' do
|
||||
it 'returns an FCM client' do
|
||||
expect(fcm_service.fcm_client).to eq(fcm_double)
|
||||
expect(FCM).to have_received(:new).with('test_token', anything, project_id)
|
||||
end
|
||||
|
||||
it 'generates a new token if expired' do
|
||||
allow(fcm_service).to receive(:generate_token).and_return(token_info)
|
||||
allow(fcm_service).to receive(:token_expired?).and_return(true)
|
||||
|
||||
expect(fcm_service.fcm_client).to eq(fcm_double)
|
||||
expect(FCM).to have_received(:new).with('test_token', anything, project_id)
|
||||
expect(fcm_service).to have_received(:generate_token)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'private methods' do
|
||||
describe '#current_token' do
|
||||
it 'returns the current token if not expired' do
|
||||
fcm_service.instance_variable_set(:@token_info, token_info)
|
||||
expect(fcm_service.send(:current_token)).to eq('test_token')
|
||||
end
|
||||
|
||||
it 'generates a new token if expired' do
|
||||
expired_token_info = { token: 'expired_token', expires_at: 1.hour.ago }
|
||||
fcm_service.instance_variable_set(:@token_info, expired_token_info)
|
||||
allow(fcm_service).to receive(:generate_token).and_return(token_info)
|
||||
|
||||
expect(fcm_service.send(:current_token)).to eq('test_token')
|
||||
expect(fcm_service).to have_received(:generate_token)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#generate_token' do
|
||||
it 'generates a new token' do
|
||||
allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds).and_return(creds_double)
|
||||
|
||||
token = fcm_service.send(:generate_token)
|
||||
expect(token[:token]).to eq('test_token')
|
||||
expect(token[:expires_at]).to be_within(1.second).of(Time.zone.now + 3600)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#credentials_path' do
|
||||
it 'creates a StringIO with credentials' do
|
||||
string_io = fcm_service.send(:credentials_path)
|
||||
expect(string_io).to be_a(StringIO)
|
||||
expect(string_io.read).to eq(credentials)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
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
|
||||
Reference in New Issue
Block a user