activity_notification 1.7.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.travis.yml +16 -2
- data/CHANGELOG.md +22 -2
- data/Gemfile +7 -0
- data/Procfile +2 -0
- data/README.md +366 -32
- data/Rakefile +19 -10
- data/activity_notification.gemspec +5 -3
- data/app/channels/activity_notification/notification_channel.rb +37 -0
- data/app/channels/activity_notification/notification_with_devise_channel.rb +51 -0
- data/app/controllers/activity_notification/notifications_controller.rb +1 -1
- data/app/controllers/activity_notification/subscriptions_controller.rb +1 -1
- data/app/jobs/activity_notification/notify_all_job.rb +16 -0
- data/app/jobs/activity_notification/notify_job.rb +17 -0
- data/app/jobs/activity_notification/notify_to_job.rb +16 -0
- data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +1 -1
- data/app/views/activity_notification/notifications/default/index.html.erb +55 -2
- data/bin/_dynamodblocal +4 -0
- data/{scripts → bin}/bundle_update.sh +1 -0
- data/bin/deploy_on_heroku.sh +14 -0
- data/bin/install_dynamodblocal.sh +5 -0
- data/bin/start_dynamodblocal.sh +47 -0
- data/bin/stop_dynamodblocal.sh +34 -0
- data/gemfiles/Gemfile.rails-4.2 +1 -0
- data/gemfiles/Gemfile.rails-5.0 +2 -0
- data/gemfiles/Gemfile.rails-5.1 +1 -0
- data/gemfiles/Gemfile.rails-5.2 +1 -0
- data/gemfiles/Gemfile.rails-6.0.rc +21 -0
- data/lib/activity_notification.rb +1 -0
- data/lib/activity_notification/apis/notification_api.rb +289 -136
- data/lib/activity_notification/apis/subscription_api.rb +80 -53
- data/lib/activity_notification/common.rb +3 -3
- data/lib/activity_notification/config.rb +89 -33
- data/lib/activity_notification/controllers/common_controller.rb +19 -7
- data/lib/activity_notification/helpers/errors.rb +4 -0
- data/lib/activity_notification/helpers/view_helpers.rb +1 -1
- data/lib/activity_notification/models/concerns/notifiable.rb +61 -53
- data/lib/activity_notification/models/concerns/subscriber.rb +7 -6
- data/lib/activity_notification/models/concerns/target.rb +73 -28
- data/lib/activity_notification/optional_targets/base.rb +2 -2
- data/lib/activity_notification/orm/active_record/notification.rb +4 -23
- data/lib/activity_notification/orm/dynamoid.rb +495 -0
- data/lib/activity_notification/orm/dynamoid/extension.rb +184 -0
- data/lib/activity_notification/orm/dynamoid/notification.rb +189 -0
- data/lib/activity_notification/orm/dynamoid/subscription.rb +82 -0
- data/lib/activity_notification/orm/mongoid.rb +4 -1
- data/lib/activity_notification/orm/mongoid/notification.rb +8 -25
- data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
- data/lib/activity_notification/roles/acts_as_notifiable.rb +33 -5
- data/lib/activity_notification/roles/acts_as_target.rb +62 -9
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/templates/activity_notification.rb +30 -7
- data/lib/tasks/activity_notification_tasks.rake +14 -4
- data/spec/channels/notification_channel_shared_examples.rb +59 -0
- data/spec/channels/notification_channel_spec.rb +50 -0
- data/spec/channels/notification_with_devise_channel_spec.rb +99 -0
- data/spec/concerns/apis/notification_api_spec.rb +2 -2
- data/spec/concerns/apis/subscription_api_spec.rb +2 -2
- data/spec/concerns/models/notifiable_spec.rb +72 -7
- data/spec/concerns/models/subscriber_spec.rb +53 -49
- data/spec/concerns/models/target_spec.rb +135 -13
- data/spec/config_spec.rb +41 -1
- data/spec/controllers/notifications_controller_shared_examples.rb +7 -3
- data/spec/controllers/subscriptions_controller_shared_examples.rb +7 -3
- data/spec/helpers/view_helpers_spec.rb +12 -10
- data/spec/models/dummy/dummy_group_spec.rb +4 -0
- data/spec/models/dummy/dummy_notifiable_spec.rb +4 -0
- data/spec/models/dummy/dummy_notifier_spec.rb +4 -0
- data/spec/models/dummy/dummy_subscriber_spec.rb +3 -0
- data/spec/models/dummy/dummy_target_spec.rb +4 -0
- data/spec/models/notification_spec.rb +164 -45
- data/spec/models/subscription_spec.rb +69 -14
- data/spec/orm/dynamoid_spec.rb +115 -0
- data/spec/rails_app/app/assets/javascripts/application.js +2 -1
- data/spec/rails_app/app/assets/javascripts/cable.js +12 -0
- data/spec/rails_app/app/controllers/comments_controller.rb +3 -4
- data/spec/rails_app/app/models/admin.rb +6 -4
- data/spec/rails_app/app/models/article.rb +2 -2
- data/spec/rails_app/app/models/comment.rb +17 -5
- data/spec/rails_app/app/models/user.rb +5 -3
- data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +1 -0
- data/spec/rails_app/config/application.rb +6 -1
- data/spec/rails_app/config/cable.yml +8 -0
- data/spec/rails_app/config/dynamoid.rb +5 -0
- data/spec/rails_app/config/environment.rb +4 -1
- data/spec/rails_app/config/environments/production.rb +1 -1
- data/spec/rails_app/config/initializers/activity_notification.rb +30 -7
- data/spec/rails_app/config/locales/activity_notification.en.yml +2 -0
- data/spec/rails_app/db/seeds.rb +21 -5
- data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +12 -4
- data/spec/roles/acts_as_notifiable_spec.rb +2 -2
- data/spec/roles/acts_as_target_spec.rb +1 -1
- data/spec/spec_helper.rb +15 -8
- metadata +67 -20
- data/spec/rails_app/app/models/.keep +0 -0
- data/spec/rails_app/app/views/activity_notification/notifications/users/overriden/custom/_test.html.erb +0 -1
@@ -8,7 +8,7 @@ module ActivityNotification
|
|
8
8
|
# @param [String] name Association name
|
9
9
|
# @param [Object] instance Associated instance
|
10
10
|
# @return [Mongoid::Criteria<Notificaion>] Database query of filtered notifications
|
11
|
-
scope :filtered_by_association, ->(name, instance) {
|
11
|
+
scope :filtered_by_association, ->(name, instance) { where("#{name}_id" => instance.present? ? instance.id : nil, "#{name}_type" => instance.present? ? instance.class.name : nil) }
|
12
12
|
end
|
13
13
|
|
14
14
|
class_methods do
|
@@ -24,6 +24,8 @@ module ActivityNotification
|
|
24
24
|
id_field, type_field = "#{association_name}_id", "#{association_name}_type"
|
25
25
|
field id_field, type: String
|
26
26
|
field type_field, type: String
|
27
|
+
associated_record_field = "#{association_name}_record"
|
28
|
+
field associated_record_field, type: String if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
27
29
|
|
28
30
|
self.instance_eval do
|
29
31
|
define_method(name) do |reload = false|
|
@@ -41,6 +43,7 @@ module ActivityNotification
|
|
41
43
|
if new_instance.nil? then instance_id, instance_type = nil, nil else instance_id, instance_type = new_instance.id, new_instance.class.name end
|
42
44
|
self.send("#{id_field}=", instance_id)
|
43
45
|
self.send("#{type_field}=", instance_type)
|
46
|
+
self.send("#{associated_record_field}=", new_instance.to_json) if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
44
47
|
self.instance_variable_set("@#{name}", nil)
|
45
48
|
end
|
46
49
|
end
|
@@ -19,12 +19,12 @@ module ActivityNotification
|
|
19
19
|
# Belongs to target instance of this notification as polymorphic association.
|
20
20
|
# @scope instance
|
21
21
|
# @return [Object] Target instance of this notification
|
22
|
-
belongs_to_polymorphic_xdb_record :target
|
22
|
+
belongs_to_polymorphic_xdb_record :target, store_with_associated_records: true
|
23
23
|
|
24
24
|
# Belongs to notifiable instance of this notification as polymorphic association.
|
25
25
|
# @scope instance
|
26
26
|
# @return [Object] Notifiable instance of this notification
|
27
|
-
belongs_to_polymorphic_xdb_record :notifiable
|
27
|
+
belongs_to_polymorphic_xdb_record :notifiable, store_with_associated_records: true
|
28
28
|
|
29
29
|
# Belongs to group instance of this notification as polymorphic association.
|
30
30
|
# @scope instance
|
@@ -53,7 +53,7 @@ module ActivityNotification
|
|
53
53
|
# Belongs to :otifier instance of this notification.
|
54
54
|
# @scope instance
|
55
55
|
# @return [Object] Notifier instance of this notification
|
56
|
-
belongs_to_polymorphic_xdb_record :notifier
|
56
|
+
belongs_to_polymorphic_xdb_record :notifier, store_with_associated_records: true
|
57
57
|
|
58
58
|
validates :target, presence: true
|
59
59
|
validates :notifiable, presence: true
|
@@ -170,26 +170,6 @@ module ActivityNotification
|
|
170
170
|
# Dummy reload method for test of notifications.
|
171
171
|
scope :reload, -> { }
|
172
172
|
|
173
|
-
# Returns latest notification instance.
|
174
|
-
# @return [Notification] Latest notification instance
|
175
|
-
def self.latest
|
176
|
-
latest_order.first
|
177
|
-
end
|
178
|
-
|
179
|
-
# Returns earliest notification instance.
|
180
|
-
# @return [Notification] Earliest notification instance
|
181
|
-
def self.earliest
|
182
|
-
earliest_order.first
|
183
|
-
end
|
184
|
-
|
185
|
-
# Selects unique keys from query for notifications.
|
186
|
-
# @return [Array<String>] Array of notification unique keys
|
187
|
-
def self.uniq_keys
|
188
|
-
# distinct method cannot keep original sort
|
189
|
-
# distinct(:key)
|
190
|
-
pluck(:key).uniq
|
191
|
-
end
|
192
|
-
|
193
173
|
# Returns if the notification is group owner.
|
194
174
|
# Calls NotificationApi#group_owner? as super method.
|
195
175
|
# @return [Boolean] If the notification is group owner
|
@@ -197,9 +177,12 @@ module ActivityNotification
|
|
197
177
|
super
|
198
178
|
end
|
199
179
|
|
200
|
-
# Raise DeleteRestrictionError for notifications.
|
180
|
+
# Raise ActivityNotification::DeleteRestrictionError for notifications.
|
181
|
+
# @param [String] error_text Error text for raised exception
|
182
|
+
# @raise ActivityNotification::DeleteRestrictionError
|
183
|
+
# @return [void]
|
201
184
|
def self.raise_delete_restriction_error(error_text)
|
202
|
-
raise error_text
|
185
|
+
raise ActivityNotification::DeleteRestrictionError, error_text
|
203
186
|
end
|
204
187
|
|
205
188
|
protected
|
@@ -26,7 +26,7 @@ module ActivityNotification
|
|
26
26
|
field :subscribed_to_email_at, type: DateTime
|
27
27
|
field :unsubscribed_to_email_at, type: DateTime
|
28
28
|
field :optional_targets, type: Hash, default: {}
|
29
|
-
|
29
|
+
|
30
30
|
validates :target, presence: true
|
31
31
|
validates :key, presence: true
|
32
32
|
validates_inclusion_of :subscribing, in: [true, false]
|
@@ -95,6 +95,18 @@ module ActivityNotification
|
|
95
95
|
# acts_as_notifiable :users, targets: User.all, email_allowed: true
|
96
96
|
# end
|
97
97
|
#
|
98
|
+
# * :action_cable_allowed
|
99
|
+
# * Whether activity_notification publishes notifications to ActionCable channel.
|
100
|
+
# Specified method or symbol is expected to return true (not nil) or false (nil).
|
101
|
+
# This parameter is a optional since default value is false.
|
102
|
+
# To use ActionCable for notifications, action_cable_allowed option must return true (not nil) in both of notifiable and target model.
|
103
|
+
# This can be also configured default option in initializer.
|
104
|
+
# @example Enable notification ActionCable for this notifiable model
|
105
|
+
# # app/models/comment.rb
|
106
|
+
# class Comment < ActiveRecord::Base
|
107
|
+
# acts_as_notifiable :users, targets: User.all, action_cable_allowed: true
|
108
|
+
# end
|
109
|
+
#
|
98
110
|
# * :notifiable_path
|
99
111
|
# * Path to redirect from open or move action of notification controller.
|
100
112
|
# You can also use this notifiable_path as notifiable link in notification view.
|
@@ -196,6 +208,7 @@ module ActivityNotification
|
|
196
208
|
# @option options [Symbol, Proc, Object] :notifier (nil) Notifier of the notifications
|
197
209
|
# @option options [Symbol, Proc, Hash] :parameters ({}) Additional parameters of the notifications
|
198
210
|
# @option options [Symbol, Proc, Boolean] :email_allowed (ActivityNotification.config.email_enabled) Whether activity_notification sends notification email
|
211
|
+
# @option options [Symbol, Proc, Boolean] :action_cable_allowed (ActivityNotification.config.action_cable_enabled) Whether activity_notification publishes WebSocket using ActionCable
|
199
212
|
# @option options [Symbol, Proc, String] :notifiable_path (polymorphic_path(self)) Path to redirect from open or move action of notification controller
|
200
213
|
# @option options [Boolean, Hash] :tracked (nil) Flag or parameters for automatic tracked notifications
|
201
214
|
# @option options [Symbol, Proc, String] :printable_name (ActivityNotification::Common.printable_name) Printable notifiable name
|
@@ -220,7 +233,7 @@ module ActivityNotification
|
|
220
233
|
|
221
234
|
options[:printable_notifiable_name] ||= options.delete(:printable_name)
|
222
235
|
configured_params
|
223
|
-
.merge set_acts_as_parameters_for_target(target_type, [:targets, :group, :group_expiry_delay, :parameters, :email_allowed], options, "notification_")
|
236
|
+
.merge set_acts_as_parameters_for_target(target_type, [:targets, :group, :group_expiry_delay, :parameters, :email_allowed, :action_cable_allowed], options, "notification_")
|
224
237
|
.merge set_acts_as_parameters_for_target(target_type, [:notifier, :notifiable_path, :printable_notifiable_name, :optional_targets], options)
|
225
238
|
end
|
226
239
|
|
@@ -233,6 +246,7 @@ module ActivityNotification
|
|
233
246
|
:notifier,
|
234
247
|
:parameters,
|
235
248
|
:email_allowed,
|
249
|
+
:action_cable_allowed,
|
236
250
|
:notifiable_path,
|
237
251
|
:printable_notifiable_name, :printable_name,
|
238
252
|
:dependent_notifications,
|
@@ -284,11 +298,22 @@ module ActivityNotification
|
|
284
298
|
# See the followings:
|
285
299
|
# https://github.com/rails/rails/issues/30779
|
286
300
|
# https://github.com/rails/rails/pull/32167
|
287
|
-
|
301
|
+
|
302
|
+
# :only-rails5-plus#only-rails-without-callback-issue:
|
303
|
+
# :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
|
304
|
+
# :except-rails5-plus#only-rails-without-callback-issue:
|
305
|
+
# :except-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
|
288
306
|
if !(Gem::Version.new("5.1.6") <= Rails.gem_version && Rails.gem_version < Gem::Version.new("5.2.2")) && respond_to?(:after_commit)
|
289
307
|
after_commit tracked_proc, on: tracked_action
|
290
|
-
# :only-rails-without-callback-issue:
|
291
|
-
# :only-rails-
|
308
|
+
# :only-rails5-plus#only-rails-without-callback-issue:
|
309
|
+
# :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
|
310
|
+
# :except-rails5-plus#only-rails-without-callback-issue:
|
311
|
+
# :except-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
|
312
|
+
|
313
|
+
# :only-rails5-plus#only-rails-with-callback-issue:
|
314
|
+
# :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
|
315
|
+
# :except-rails5-plus#only-rails-with-callback-issue:
|
316
|
+
# :except-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
|
292
317
|
else
|
293
318
|
case tracked_action
|
294
319
|
when :create
|
@@ -297,7 +322,10 @@ module ActivityNotification
|
|
297
322
|
after_update tracked_proc
|
298
323
|
end
|
299
324
|
end
|
300
|
-
# :only-rails-with-callback-issue:
|
325
|
+
# :only-rails5-plus#only-rails-with-callback-issue:
|
326
|
+
# :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
|
327
|
+
# :except-rails5-plus#only-rails-with-callback-issue:
|
328
|
+
# :except-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
|
301
329
|
end
|
302
330
|
|
303
331
|
# Adds destroy dependency.
|
@@ -34,6 +34,57 @@ module ActivityNotification
|
|
34
34
|
# acts_as_target email: :email, email_allowed: :confirmed_at
|
35
35
|
# end
|
36
36
|
#
|
37
|
+
# * :batch_email_allowed
|
38
|
+
# * Whether activity_notification sends batch notification email to this target.
|
39
|
+
# Specified method or symbol is expected to return true (not nil) or false (nil).
|
40
|
+
# This parameter is a optional since default value is false.
|
41
|
+
# To use batch notification email, both of batch_email_allowed and subscription_allowed options must return true (not nil) in target model.
|
42
|
+
# This can be also configured default option in initializer.
|
43
|
+
# @example Always enable batch email notification for this target
|
44
|
+
# # app/models/user.rb
|
45
|
+
# class User < ActiveRecord::Base
|
46
|
+
# acts_as_target email: :email, batch_email_allowed: true
|
47
|
+
# end
|
48
|
+
# @example Use confirmed_at of devise field to decide whether activity_notification sends batch notification email to this user
|
49
|
+
# # app/models/user.rb
|
50
|
+
# class User < ActiveRecord::Base
|
51
|
+
# acts_as_target email: :email, batch_email_allowed: :confirmed_at
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# * :subscription_allowed
|
55
|
+
# * Whether activity_notification manages subscriptions of this target.
|
56
|
+
# Specified method or symbol is expected to return true (not nil) or false (nil).
|
57
|
+
# This parameter is a optional since default value is false.
|
58
|
+
# This can be also configured default option in initializer.
|
59
|
+
# @example Subscribe notifications for this target
|
60
|
+
# # app/models/user.rb
|
61
|
+
# class User < ActiveRecord::Base
|
62
|
+
# acts_as_target subscription_allowed: true
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# * :action_cable_allowed
|
66
|
+
# * Whether activity_notification publishes WebSocket notifications using ActionCable to this target.
|
67
|
+
# Specified method or symbol is expected to return true (not nil) or false (nil).
|
68
|
+
# This parameter is a optional since default value is false.
|
69
|
+
# To use ActionCable for notifications, action_cable_enabled option must return true (not nil) in both of notifiable and target model.
|
70
|
+
# This can be also configured default option in initializer.
|
71
|
+
# @example Enable notification ActionCable for this target
|
72
|
+
# # app/models/user.rb
|
73
|
+
# class User < ActiveRecord::Base
|
74
|
+
# acts_as_target action_cable_allowed: true
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# * :action_cable_with_devise
|
78
|
+
# * Whether activity_notification publishes WebSocket notifications using ActionCable only to authenticated target with Devise.
|
79
|
+
# Specified method or symbol is expected to return true (not nil) or false (nil).
|
80
|
+
# This parameter is a optional since default value is false.
|
81
|
+
# To use ActionCable for notifications, also action_cable_enabled option must return true (not nil) in the target model.
|
82
|
+
# @example Enable notification ActionCable for this target
|
83
|
+
# # app/models/user.rb
|
84
|
+
# class User < ActiveRecord::Base
|
85
|
+
# acts_as_target action_cable_allowed: true, action_cable_with_devise* true
|
86
|
+
# end
|
87
|
+
#
|
37
88
|
# * :devise_resource
|
38
89
|
# * Integrated resource with devise authentication.
|
39
90
|
# This parameter is a optional since `self` is used as default value.
|
@@ -121,20 +172,22 @@ module ActivityNotification
|
|
121
172
|
# end
|
122
173
|
#
|
123
174
|
# @param [Hash] options Options for notifiable model configuration
|
124
|
-
# @option options [Symbol, Proc, String] :email
|
125
|
-
# @option options [Symbol, Proc, Boolean] :email_allowed
|
126
|
-
# @option options [Symbol, Proc, Boolean] :batch_email_allowed
|
127
|
-
# @option options [Symbol, Proc, Boolean] :subscription_allowed
|
128
|
-
# @option options [Symbol, Proc,
|
129
|
-
# @option options [Symbol, Proc,
|
130
|
-
# @option options [Symbol, Proc,
|
175
|
+
# @option options [Symbol, Proc, String] :email (nil) Email address to send notification email
|
176
|
+
# @option options [Symbol, Proc, Boolean] :email_allowed (ActivityNotification.config.email_enabled) Whether activity_notification sends notification email to this target
|
177
|
+
# @option options [Symbol, Proc, Boolean] :batch_email_allowed (ActivityNotification.config.email_enabled) Whether activity_notification sends batch notification email to this target
|
178
|
+
# @option options [Symbol, Proc, Boolean] :subscription_allowed (ActivityNotification.config.subscription_enabled) Whether activity_notification manages subscriptions of this target
|
179
|
+
# @option options [Symbol, Proc, Boolean] :action_cable_allowed (ActivityNotification.config.action_cable_enabled) Whether activity_notification publishes WebSocket notifications using ActionCable to this target
|
180
|
+
# @option options [Symbol, Proc, Boolean] :action_cable_with_devise (false) Whether activity_notification publishes WebSocket notifications using ActionCable only to authenticated target with Devise
|
181
|
+
# @option options [Symbol, Proc, Object] :devise_resource (->(model) { model }) Integrated resource with devise authentication
|
182
|
+
# @option options [Symbol, Proc, Object] :current_devise_target (->(current_resource) { current_resource }) Current authenticated target by devise authentication
|
183
|
+
# @option options [Symbol, Proc, String] :printable_name (ActivityNotification::Common.printable_name) Printable notification target name
|
131
184
|
# @return [Hash] Configured parameters as target model
|
132
185
|
def acts_as_target(options = {})
|
133
186
|
include Target
|
134
187
|
|
135
188
|
options[:printable_notification_target_name] ||= options.delete(:printable_name)
|
136
189
|
options[:batch_notification_email_allowed] ||= options.delete(:batch_email_allowed)
|
137
|
-
acts_as_params = set_acts_as_parameters([:email, :email_allowed, :subscription_allowed, :devise_resource, :current_devise_target], options, "notification_")
|
190
|
+
acts_as_params = set_acts_as_parameters([:email, :email_allowed, :subscription_allowed, :action_cable_allowed, :action_cable_with_devise, :devise_resource, :current_devise_target], options, "notification_")
|
138
191
|
.merge set_acts_as_parameters([:batch_notification_email_allowed, :printable_notification_target_name], options)
|
139
192
|
include Subscriber if subscription_enabled?
|
140
193
|
acts_as_params
|
@@ -144,7 +197,7 @@ module ActivityNotification
|
|
144
197
|
# Returns array of available target options in acts_as_target.
|
145
198
|
# @return [Array<Symbol>] Array of available target options
|
146
199
|
def available_target_options
|
147
|
-
[:email, :email_allowed, :batch_email_allowed, :subscription_allowed, :devise_resource, :printable_notification_target_name, :printable_name].freeze
|
200
|
+
[:email, :email_allowed, :batch_email_allowed, :subscription_allowed, :action_cable_enabled, :action_cable_with_devise, :devise_resource, :printable_notification_target_name, :printable_name].freeze
|
148
201
|
end
|
149
202
|
end
|
150
203
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
ActivityNotification.configure do |config|
|
2
2
|
|
3
|
-
# Configure
|
4
|
-
# Set
|
5
|
-
ENV['AN_ORM'] = 'active_record' unless ENV['AN_ORM'] == 'mongoid'
|
6
|
-
config.orm = ENV['AN_ORM']
|
7
|
-
|
8
|
-
# Configure if all activity notifications are enabled.
|
9
|
-
# Set false when you want to turn off activity notifications.
|
3
|
+
# Configure if all activity notifications are enabled
|
4
|
+
# Set false when you want to turn off activity notifications
|
10
5
|
config.enabled = true
|
11
6
|
|
7
|
+
# Configure ORM name for ActivityNotification.
|
8
|
+
# Set :active_record, :mongoid or :dynamoid.
|
9
|
+
ENV['AN_ORM'] = 'active_record' if ['mongoid', 'dynamoid'].exclude?(ENV['AN_ORM'])
|
10
|
+
config.orm = ENV['AN_ORM'].to_sym
|
11
|
+
|
12
12
|
# Configure table name to store notification data.
|
13
13
|
config.notification_table_name = "notifications"
|
14
14
|
|
@@ -47,6 +47,9 @@ ActivityNotification.configure do |config|
|
|
47
47
|
# Configure the parent class for activity_notification controllers.
|
48
48
|
# config.parent_controller = 'ApplicationController'
|
49
49
|
|
50
|
+
# Configure the parent class for activity_notification channels.
|
51
|
+
# config.parent_channel = 'ActionCable::Channel::Base'
|
52
|
+
|
50
53
|
# Configure the custom mailer templates directory
|
51
54
|
# config.mailer_templates_dir = 'activity_notification/mailer'
|
52
55
|
|
@@ -56,4 +59,24 @@ ActivityNotification.configure do |config|
|
|
56
59
|
# Configure ActiveJob queue name for delayed notifications.
|
57
60
|
config.active_job_queue = :activity_notification
|
58
61
|
|
62
|
+
# Configure delimiter of composite key for DynamoDB.
|
63
|
+
# config.composite_key_delimiter = '#'
|
64
|
+
|
65
|
+
# Configure if activity_notification stores notificaion records including associated records like target and notifiable..
|
66
|
+
# This store_with_associated_records option can be set true only when you use mongoid or dynamoid ORM.
|
67
|
+
config.store_with_associated_records = false
|
68
|
+
|
69
|
+
# Configure if WebSocket subscription using ActionCable is enabled.
|
70
|
+
# Note that you can configure them for each model by acts_as roles.
|
71
|
+
# Set true when you want to turn on WebSocket subscription using ActionCable as default.
|
72
|
+
config.action_cable_enabled = false
|
73
|
+
|
74
|
+
# Configure if ctivity_notification publishes WebSocket notifications using ActionCable only to authenticated target with Devise.
|
75
|
+
# Note that you can configure them for each model by acts_as roles.
|
76
|
+
# Set true when you want to use Device integration with WebSocket subscription using ActionCable as default.
|
77
|
+
config.action_cable_with_devise = false
|
78
|
+
|
79
|
+
# Configure notification channel prefix for ActionCable.
|
80
|
+
config.notification_channel_prefix = 'activity_notification_channel'
|
81
|
+
|
59
82
|
end
|
@@ -1,4 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
namespace :activity_notification do
|
2
|
+
desc "Create Amazon DynamoDB tables used by activity_notification with Dynamoid"
|
3
|
+
task create_dynamodb_tables: :environment do
|
4
|
+
if ActivityNotification.config.orm == :dynamoid
|
5
|
+
ActivityNotification::Notification.create_table(sync: true)
|
6
|
+
puts "Created table: #{ActivityNotification::Notification.table_name}"
|
7
|
+
ActivityNotification::Subscription.create_table(sync: true)
|
8
|
+
puts "Created table: #{ActivityNotification::Subscription.table_name}"
|
9
|
+
else
|
10
|
+
puts "Error: ActivityNotification.config.orm is not set to :dynamoid."
|
11
|
+
puts "Error: Confirm to set AN_ORM environment variable to dynamoid or set ActivityNotification.config.orm to :dynamoid."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# @See https://github.com/palkan/action-cable-testing
|
2
|
+
shared_examples_for :notification_channel do
|
3
|
+
let(:target_params) { { target_type: target_type }.merge(extra_params || {}) }
|
4
|
+
|
5
|
+
before { stub_connection }
|
6
|
+
|
7
|
+
context "with target_type and target_id parameters" do
|
8
|
+
it "successfully subscribes" do
|
9
|
+
subscribe(target_params.merge({ target_id: test_target.id, typed_target_param => 'dummy' }))
|
10
|
+
expect(subscription).to be_confirmed
|
11
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "with target_type and (typed_target)_id parameters" do
|
16
|
+
it "successfully subscribes" do
|
17
|
+
subscribe(target_params.merge({ typed_target_param => test_target.id }))
|
18
|
+
expect(subscription).to be_confirmed
|
19
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "without any parameters" do
|
24
|
+
it "rejects subscription" do
|
25
|
+
subscribe
|
26
|
+
expect(subscription).to be_rejected
|
27
|
+
expect {
|
28
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
29
|
+
}.to raise_error(/Must be subscribed!/)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "without target_type parameter" do
|
34
|
+
it "rejects subscription" do
|
35
|
+
subscribe({ typed_target_param => test_target.id })
|
36
|
+
expect(subscription).to be_rejected
|
37
|
+
expect {
|
38
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
39
|
+
}.to raise_error(/Must be subscribed!/)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "without target_id and (typed_target)_id parameters" do
|
44
|
+
it "rejects subscription" do
|
45
|
+
subscribe(target_params)
|
46
|
+
expect(subscription).to be_rejected
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with not found (typed_target)_id parameter" do
|
51
|
+
it "rejects subscription" do
|
52
|
+
subscribe(target_params.merge({ typed_target_param => 0 }))
|
53
|
+
expect(subscription).to be_rejected
|
54
|
+
expect {
|
55
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
56
|
+
}.to raise_error(/Must be subscribed!/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
if Rails::VERSION::MAJOR >= 5
|
2
|
+
require 'channels/notification_channel_shared_examples'
|
3
|
+
|
4
|
+
# @See https://github.com/palkan/action-cable-testing
|
5
|
+
describe ActivityNotification::NotificationChannel, type: :channel do
|
6
|
+
let(:test_target) { create(:user) }
|
7
|
+
let(:target_type) { "User" }
|
8
|
+
let(:typed_target_param) { "user_id" }
|
9
|
+
let(:extra_params) { {} }
|
10
|
+
|
11
|
+
context "when target.notification_action_cable_with_devise? returns true" do
|
12
|
+
before do
|
13
|
+
@user_notification_action_cable_with_devise = User._notification_action_cable_with_devise
|
14
|
+
User._notification_action_cable_with_devise = true
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
User._notification_action_cable_with_devise = @user_notification_action_cable_with_devise
|
19
|
+
end
|
20
|
+
|
21
|
+
it "rejects subscription even if target_type and target_id parameters are passed" do
|
22
|
+
subscribe({ target_type: target_type, target_id: test_target.id })
|
23
|
+
expect(subscription).to be_rejected
|
24
|
+
expect {
|
25
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
26
|
+
}.to raise_error(/Must be subscribed!/)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when target.notification_action_cable_with_devise? returns false" do
|
31
|
+
before do
|
32
|
+
@user_notification_action_cable_with_devise = User._notification_action_cable_with_devise
|
33
|
+
User._notification_action_cable_with_devise = false
|
34
|
+
end
|
35
|
+
|
36
|
+
after do
|
37
|
+
User._notification_action_cable_with_devise = @user_notification_action_cable_with_devise
|
38
|
+
end
|
39
|
+
|
40
|
+
it "successfully subscribes with target_type and target_id parameters" do
|
41
|
+
subscribe({ target_type: target_type, target_id: test_target.id })
|
42
|
+
expect(subscription).to be_confirmed
|
43
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
44
|
+
expect(subscription).to have_stream_from("activity_notification_channel_User##{test_target.id}")
|
45
|
+
end
|
46
|
+
|
47
|
+
it_behaves_like :notification_channel
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|