about summary refs log tree commit diff
path: root/spec
diff options
context:
space:
mode:
authorSorin Davidoi <sorin.davidoi@gmail.com>2017-07-13 22:15:32 +0200
committerEugen Rochko <eugen@zeonfederated.com>2017-07-13 22:15:32 +0200
commit0c7c188c459117770ac1f74f70a9e65ed2be606f (patch)
tree58d79950391d56b9742b448c2d0c83e46bbb9046 /spec
parentc2753fdfb471209fe7f2cdb8844e049207af8ba3 (diff)
Web Push Notifications (#3243)
* feat: Register push subscription

* feat: Notify when mentioned

* feat: Boost, favourite, reply, follow, follow request

* feat: Notification interaction

* feat: Handle change of public key

* feat: Unsubscribe if things go wrong

* feat: Do not send normal notifications if push is enabled

* feat: Focus client if open

* refactor: Move push logic to WebPushSubscription

* feat: Better title and body

* feat: Localize messages

* chore: Fix lint errors

* feat: Settings

* refactor: Lazy load

* fix: Check if push settings exist

* feat: Device-based preferences

* refactor: Simplify logic

* refactor: Pull request feedback

* refactor: Pull request feedback

* refactor: Create /api/web/push_subscriptions endpoint

* feat: Spec PushSubscriptionController

* refactor: WebPushSubscription => Web::PushSubscription

* feat: Spec Web::PushSubscription

* feat: Display first media attachment

* feat: Support direction

* fix: Stuff broken while rebasing

* refactor: Integration with session activations

* refactor: Cleanup

* refactor: Simplify implementation

* feat: Set VAPID keys via environment

* chore: Comments

* fix: Crash when no alerts

* fix: Set VAPID keys in testing environment

* fix: Follow link

* feat: Notification actions

* fix: Delete previous subscription

* chore: Temporary logs

* refactor: Move migration to a later date

* fix: Fetch the correct session activation and misc bugs

* refactor: Move migration to a later date

* fix: Remove follow request (no notifications)

* feat: Send administrator contact to push service

* feat: Set time-to-live

* fix: Do not show sensitive images

* fix: Reducer crash in error handling

* feat: Add badge

* chore: Fix lint error

* fix: Checkbox label overlap

* fix: Check for payload support

* fix: Rename action "type" (crash in latest Chrome)

* feat: Action to expand notification

* fix: Lint errors

* fix: Unescape notification body

* fix: Do not allow boosting if the status is hidden

* feat: Add VAPID keys to the production sample environment

* fix: Strip HTML tags from status

* refactor: Better error messages

* refactor: Handle browser not implementing the VAPID protocol (Samsung Internet)

* fix: Error when target_status is nil

* fix: Handle lack of image

* fix: Delete reference to invalid subscriptions

* feat: Better error handling

* fix: Unescape HTML characters after tags are striped

* refactor: Simpify code

* fix: Modify to work with #4091

* Sort strings alphabetically

* i18n: Updated Polish translation

it annoys me that it's not fully localized :P

* refactor: Use current_session in PushSubscriptionController

* fix: Rebase mistake

* fix: Set cacheName to mastodon

* refactor: Pull request feedback

* refactor: Remove logging statements

* chore(yarn): Fix conflicts with master

* chore(yarn): Copy latest from master

* chore(yarn): Readd offline-plugin

* refactor: Use save! and update!

* refactor: Send notifications async

* fix: Allow retry when push fails

* fix: Save track for failed pushes

* fix: Minify sw.js

* fix: Remove account_id from fabricator
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/api/web/push_subscriptions_controller_spec.rb81
-rw-r--r--spec/fabricators/web_push_subscription_fabricator.rb5
-rw-r--r--spec/models/web/push_subscription_spec.rb28
3 files changed, 114 insertions, 0 deletions
diff --git a/spec/controllers/api/web/push_subscriptions_controller_spec.rb b/spec/controllers/api/web/push_subscriptions_controller_spec.rb
new file mode 100644
index 000000000..871176a07
--- /dev/null
+++ b/spec/controllers/api/web/push_subscriptions_controller_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Api::Web::PushSubscriptionsController do
+  render_views
+
+  let(:user) { Fabricate(:user) }
+
+  let(:create_payload) do
+    {
+      data: {
+        endpoint: 'https://fcm.googleapis.com/fcm/send/fiuH06a27qE:APA91bHnSiGcLwdaxdyqVXNDR9w1NlztsHb6lyt5WDKOC_Z_Q8BlFxQoR8tWFSXUIDdkyw0EdvxTu63iqamSaqVSevW5LfoFwojws8XYDXv_NRRLH6vo2CdgiN4jgHv5VLt2A8ah6lUX',
+        keys: {
+          p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=',
+          auth: 'eH_C8rq2raXqlcBVDa1gLg==',
+        },
+      }
+    }
+  end
+
+  let(:alerts_payload) do
+    {
+      data: {
+        alerts: {
+          follow: true,
+          favourite: false,
+          reblog: true,
+          mention: false,
+        }
+      }
+    }
+  end
+
+  describe 'POST #create' do
+    it 'saves push subscriptions' do
+      sign_in(user)
+
+      stub_request(:post, create_payload[:data][:endpoint]).to_return(status: 200)
+
+      post :create, format: :json, params: create_payload
+
+      user.reload
+
+      push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:data][:endpoint])
+
+      expect(push_subscription['endpoint']).to eq(create_payload[:data][:endpoint])
+      expect(push_subscription['key_p256dh']).to eq(create_payload[:data][:keys][:p256dh])
+      expect(push_subscription['key_auth']).to eq(create_payload[:data][:keys][:auth])
+    end
+
+    it 'sends welcome notification' do
+      sign_in(user)
+
+      stub_request(:post, create_payload[:data][:endpoint]).to_return(status: 200)
+
+      post :create, format: :json, params: create_payload
+    end
+  end
+
+  describe 'PUT #update' do
+    it 'changes alert settings' do
+      sign_in(user)
+
+      stub_request(:post, create_payload[:data][:endpoint]).to_return(status: 200)
+
+      post :create, format: :json, params: create_payload
+
+      alerts_payload[:id] = Web::PushSubscription.find_by(endpoint: create_payload[:data][:endpoint]).id
+
+      put :update, format: :json, params: alerts_payload
+
+      push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:data][:endpoint])
+
+      expect(push_subscription.data['follow']).to eq(alerts_payload[:data][:follow])
+      expect(push_subscription.data['favourite']).to eq(alerts_payload[:data][:favourite])
+      expect(push_subscription.data['reblog']).to eq(alerts_payload[:data][:reblog])
+      expect(push_subscription.data['mention']).to eq(alerts_payload[:data][:mention])
+    end
+  end
+end
diff --git a/spec/fabricators/web_push_subscription_fabricator.rb b/spec/fabricators/web_push_subscription_fabricator.rb
new file mode 100644
index 000000000..72d11b77c
--- /dev/null
+++ b/spec/fabricators/web_push_subscription_fabricator.rb
@@ -0,0 +1,5 @@
+Fabricator(:web_push_subscription) do
+  endpoint   Faker::Internet.url
+  key_p256dh Faker::Internet.password
+  key_auth   Faker::Internet.password
+end
diff --git a/spec/models/web/push_subscription_spec.rb b/spec/models/web/push_subscription_spec.rb
new file mode 100644
index 000000000..574da55ac
--- /dev/null
+++ b/spec/models/web/push_subscription_spec.rb
@@ -0,0 +1,28 @@
+require 'rails_helper'
+
+RSpec.describe Web::PushSubscription, type: :model do
+  let(:alerts) { { mention: true, reblog: false, follow: true, follow_request: false, favourite: true } }
+  let(:payload_no_alerts) { Web::PushSubscription.new(id: 1, endpoint: 'a', key_p256dh: 'c', key_auth: 'd').as_payload }
+  let(:payload_alerts) { Web::PushSubscription.new(id: 1, endpoint: 'a', key_p256dh: 'c', key_auth: 'd', data: { alerts: alerts }).as_payload }
+  let(:push_subscription) { Web::PushSubscription.new(data: { alerts: alerts }) }
+
+  describe '#as_payload' do
+    it 'only returns id and endpoint' do
+      expect(payload_no_alerts.keys).to eq [:id, :endpoint]
+    end
+
+    it 'returns alerts if set' do
+      expect(payload_alerts.keys).to eq [:id, :endpoint, :alerts]
+    end
+  end
+
+  describe '#pushable?' do
+    it 'obeys alert settings' do
+      expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Mention'))).to eq true
+      expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Status'))).to eq false
+      expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Follow'))).to eq true
+      expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'FollowRequest'))).to eq false
+      expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Favourite'))).to eq true
+    end
+  end
+end