# frozen_string_literal: true require "rails_helper" describe Ajax::WebPushController, :ajax_controller, type: :controller do before do Rpush::Webpush::App.create( name: "webpush", certificate: { public_key: "AAAA", private_key: "BBBB", subject: "" }.to_json, connections: 1 ) end describe "#key" do subject { get :key, format: :json } let(:expected_response) do { "message" => "", "status" => "okay", "success" => true, "key" => "AAAA" } end context "user signed in" do let(:user) { FactoryBot.create(:user) } before { sign_in user } include_examples "returns the expected response" end end describe "#subscribe" do subject { post :subscribe, params: } context "user signed in" do let(:user) { FactoryBot.create(:user) } before { sign_in user } context "given a valid subscription" do let(:params) do { subscription: { endpoint: "https://some.webpush/endpoint", keys: {} } } end let(:expected_response) do { "message" => I18n.t("settings.push_notifications.subscription_count.one"), "status" => "okay", "success" => true } end it "stores the subscription" do expect { subject } .to( change { WebPushSubscription.count } .by(1) ) end include_examples "returns the expected response" end end context "given no subscription param" do let(:params) do {} end end end describe "#unsubscribe" do subject { delete :unsubscribe, params: } shared_examples_for "does not remove any subscriptions" do it "does not remove any subscriptions" do expect { subject }.not_to(change { WebPushSubscription.count }) end end context "user signed in" do let(:user) { FactoryBot.create(:user) } before { sign_in user } context "valid subscription" do let(:endpoint) { "some endpoint" } let!(:subscription) do WebPushSubscription.create( user:, subscription: { endpoint:, keys: {} } ) end let!(:other_subscription) do WebPushSubscription.create( user:, subscription: { endpoint: "other endpoint", keys: {} } ) end let(:params) do { endpoint: } end let(:expected_response) do { "status" => "okay", "success" => true, "message" => I18n.t("ajax.web_push.subscription_count.one"), "count" => 1 } end it "removes the subscription" do subject expect(WebPushSubscription.exists?(subscription.id)).to eq(false) expect(WebPushSubscription.exists?(other_subscription.id)).to eq(true) end include_examples "returns the expected response" end context "invalid subscription" do let!(:subscription) do WebPushSubscription.create( user:, subscription: { endpoint: "other endpoint", keys: {} } ) end let(:params) do { endpoint: "some endpoint" } end let(:expected_response) do { "status" => "err", "success" => false, "message" => I18n.t("ajax.web_push.subscription_count.one"), "count" => 1 } end include_examples "does not remove any subscriptions" include_examples "returns the expected response" end context "someone else's subscription" do let(:endpoint) { "some endpoint" } let(:other_user) { FactoryBot.create(:user) } let!(:subscription) do WebPushSubscription.create( user: other_user, subscription: { endpoint:, keys: {} } ) end let(:params) do { endpoint: } end let(:expected_response) do { "status" => "err", "success" => false, "message" => I18n.t("ajax.web_push.subscription_count.zero"), "count" => 0 } end include_examples "does not remove any subscriptions" include_examples "returns the expected response" end context "no subscription provided" do let(:other_user) { FactoryBot.create(:user) } let(:params) { {} } before do 4.times do |i| WebPushSubscription.create( user: i.zero? ? other_user : user, subscription: { endpoint: i, keys: {} } ) end end it "removes all own subscriptions" do expect { subject } .to( change { WebPushSubscription.count } .from(4) .to(1) ) end end end end describe "#check" do subject { post :check, params: } context "user signed in" do let(:user) { FactoryBot.create(:user) } let(:endpoint) { "https://some.domain/some/webpush/endpoint" } let!(:subscription) do WebPushSubscription.create( user:, subscription: { endpoint:, keys: {} }, failures: ) end let(:expected_response) do { "message" => "", "status" => expected_status, "success" => true } end before { sign_in user } context "subscription exists" do let(:params) do { endpoint: } end context "without failures" do let(:failures) { 0 } let(:expected_status) { "subscribed" } it_behaves_like "returns the expected response" end context "with 2 failures" do let(:failures) { 2 } let(:expected_status) { "subscribed" } it_behaves_like "returns the expected response" end context "with 3 failures" do let(:failures) { 3 } let(:expected_status) { "failed" } it_behaves_like "returns the expected response" end end context "subscription doesn't exist" do let(:params) do { endpoint: "https;//some.domain/some/other/endpoint" } end let(:failures) { 0 } let(:expected_status) { "unsubscribed" } it_behaves_like "returns the expected response" end end end end