require "rails_helper" RSpec.describe PushNotifications::Send, type: :service do let(:user) { create(:user) } let(:user2) { create(:user) } let(:params) do { user_ids: [user.id], title: "Alert", body: "some alert here", payload: "" } end let(:many_targets_params) do { user_ids: [user.id, user2.id], title: "Alert 2", body: "some other alert", payload: "" } end before do allow(ApplicationConfig).to receive(:[]).with("RPUSH_IOS_PEM").and_return("dGVzdGluZw==") allow(ApplicationConfig).to receive(:[]).with("RPUSH_FCM_KEY").and_return("dGVzdGluZw==") allow(ApplicationConfig).to receive(:[]).and_return("stub") end context "with no devices for user" do it "does nothing", :aggregate_failures do described_class.call(**params) sidekiq_assert_no_enqueued_jobs(only: PushNotifications::DeliverWorker) end end context "with devices for one user" do it "creates a notification and enqueues it" do device = create(:device, user: user) mocked_objects = mock_rpush(device.consumer_app) described_class.call(**params) expect(mocked_objects[:rpush_notification]).to have_received(:save!).once sidekiq_assert_enqueued_jobs(1, only: PushNotifications::DeliverWorker) end it "creates a single notification for each of the user's devices when they have multiple" do consumer_app = create(:consumer_app) devices = create_list(:device, 2, user: user, consumer_app: consumer_app) mocked_objects = mock_rpush(consumer_app) described_class.call(**params) expect(mocked_objects[:rpush_notification]).to have_received(:save!).exactly(devices.size).times sidekiq_assert_enqueued_jobs(1, only: PushNotifications::DeliverWorker) end end context "with devices for multiple users" do let(:consumer_app_ios) { create(:consumer_app, platform: Device::IOS) } let(:consumer_app_android) { create(:consumer_app, platform: Device::ANDROID) } before do create(:device, user: user, consumer_app: consumer_app_ios) create(:device, user: user2, consumer_app: consumer_app_ios) create(:device, user: user2, consumer_app: consumer_app_android, platform: Device::ANDROID) end it "creates a notification and enqueues it" do mocked_objects = mock_rpush(consumer_app_ios) described_class.call(**params) expect(mocked_objects[:rpush_notification]).to have_received(:save!).once sidekiq_assert_enqueued_jobs(1, only: PushNotifications::DeliverWorker) end it "creates a single notification for each of the user's devices when they have multiple" do ios_mocked_objects = mock_rpush(consumer_app_ios) android_mocked_objects = mock_rpush(consumer_app_android) described_class.call(**many_targets_params) expect(ios_mocked_objects[:rpush_notification]).to have_received(:save!).twice expect(android_mocked_objects[:rpush_notification]).to have_received(:save!).once sidekiq_assert_enqueued_jobs(1, only: PushNotifications::DeliverWorker) end end context "when associated to operational vs non-operational ConsumerApp" do it "doesn't create any new (RPush) Push Notifications if non-operational" do bad_consumer_app = create(:consumer_app, auth_key: nil) create(:device, user: user, consumer_app: bad_consumer_app) bad_params = { user_ids: [user.id], title: "Alert 3", body: "some other alert!", payload: "" } mocked_objects = mock_rpush(bad_consumer_app) described_class.call(**bad_params) # rpush_notification was saved 0 times -> No new notifications were created expect(mocked_objects[:rpush_notification]).to have_received(:save!).exactly(0).times end end it "does create new (RPush) Push Notifications if operational" do device = create(:device, user: user) mocked_objects = mock_rpush(device.consumer_app) described_class.call(**params) # rpush_notification was saved 1 times -> One new notifications was created expect(mocked_objects[:rpush_notification]).to have_received(:save!).exactly(1).times end end