activity_notification 2.1.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +10 -16
- data/CHANGELOG.md +53 -0
- data/Gemfile +2 -3
- data/README.md +1 -1
- data/activity_notification.gemspec +1 -1
- data/app/channels/activity_notification/notification_api_with_devise_channel.rb +1 -1
- data/app/channels/activity_notification/notification_channel.rb +1 -1
- data/app/channels/activity_notification/notification_with_devise_channel.rb +1 -1
- data/app/controllers/activity_notification/notifications_api_with_devise_controller.rb +1 -1
- data/app/controllers/activity_notification/notifications_controller.rb +0 -20
- data/app/controllers/activity_notification/subscriptions_api_controller.rb +1 -1
- data/app/controllers/activity_notification/subscriptions_api_with_devise_controller.rb +1 -1
- data/bin/bundle_update.sh +0 -1
- data/docs/Functions.md +2 -2
- data/docs/Setup.md +190 -63
- data/gemfiles/Gemfile.rails-5.0 +3 -1
- data/gemfiles/Gemfile.rails-5.1 +3 -1
- data/gemfiles/Gemfile.rails-5.2 +3 -1
- data/gemfiles/Gemfile.rails-6.0 +2 -3
- data/gemfiles/Gemfile.rails-6.1 +24 -0
- data/lib/activity_notification/apis/notification_api.rb +7 -0
- data/lib/activity_notification/common.rb +15 -4
- data/lib/activity_notification/controllers/common_controller.rb +2 -18
- data/lib/activity_notification/models/concerns/notifiable.rb +12 -12
- data/lib/activity_notification/models/concerns/swagger/notification_schema.rb +34 -34
- data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +17 -17
- data/lib/activity_notification/models/concerns/target.rb +5 -9
- data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +1 -1
- data/lib/activity_notification/optional_targets/action_cable_channel.rb +1 -1
- data/lib/activity_notification/orm/active_record.rb +1 -1
- data/lib/activity_notification/orm/active_record/notification.rb +3 -3
- data/lib/activity_notification/orm/dynamoid.rb +10 -3
- data/lib/activity_notification/orm/dynamoid/notification.rb +49 -14
- data/lib/activity_notification/orm/dynamoid/subscription.rb +1 -1
- data/lib/activity_notification/orm/mongoid.rb +10 -3
- data/lib/activity_notification/orm/mongoid/notification.rb +8 -6
- data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
- data/lib/activity_notification/renderable.rb +2 -2
- data/lib/activity_notification/roles/acts_as_notifiable.rb +13 -16
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/templates/migrations/migration.rb +1 -1
- data/spec/channels/notification_api_channel_spec.rb +42 -44
- data/spec/channels/notification_api_with_devise_channel_spec.rb +57 -59
- data/spec/channels/notification_channel_spec.rb +41 -43
- data/spec/channels/notification_with_devise_channel_spec.rb +75 -77
- data/spec/concerns/common_spec.rb +25 -3
- data/spec/concerns/models/notifiable_spec.rb +35 -35
- data/spec/concerns/models/target_spec.rb +10 -12
- data/spec/concerns/renderable_spec.rb +5 -5
- data/spec/config_spec.rb +26 -15
- data/spec/controllers/controller_spec_utility.rb +15 -51
- data/spec/generators/migration/migration_generator_spec.rb +2 -10
- data/spec/helpers/view_helpers_spec.rb +1 -1
- data/spec/models/subscription_spec.rb +8 -0
- data/spec/optional_targets/action_cable_api_channel_spec.rb +21 -24
- data/spec/optional_targets/action_cable_channel_spec.rb +26 -29
- data/spec/rails_app/app/controllers/users_controller.rb +5 -0
- data/spec/rails_app/app/javascript/App.vue +8 -72
- data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +3 -4
- data/spec/rails_app/app/javascript/components/Top.vue +2 -3
- data/spec/rails_app/app/javascript/packs/spa.js +6 -3
- data/spec/rails_app/app/javascript/router/index.js +73 -0
- data/spec/rails_app/app/javascript/store/{auth.js → index.js} +0 -0
- data/spec/rails_app/app/models/dummy/dummy_group.rb +8 -0
- data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +8 -0
- data/spec/rails_app/app/models/user.rb +2 -1
- data/spec/rails_app/config/application.rb +6 -7
- data/spec/rails_app/config/dynamoid.rb +11 -3
- data/spec/rails_app/config/environments/production.rb +3 -0
- data/spec/rails_app/config/environments/test.rb +2 -11
- data/spec/rails_app/config/initializers/activity_notification.rb +3 -3
- data/spec/rails_app/config/initializers/copy_it.aws.rb.template +6 -0
- data/spec/rails_app/config/routes.rb +5 -1
- data/spec/rails_app/db/seeds.rb +9 -2
- data/spec/roles/acts_as_notifiable_spec.rb +5 -5
- data/spec/spec_helper.rb +1 -5
- metadata +14 -12
- data/gemfiles/Gemfile.rails-4.2 +0 -23
- data/spec/support/patch_rails_42_action_controller_test_response.rb +0 -11
@@ -26,7 +26,7 @@ module ActivityNotification
|
|
26
26
|
# @return [Boolean] Whether Action Cable notification API is allowed
|
27
27
|
def notification_action_cable_api_allowed?(notification)
|
28
28
|
notification.target.notification_action_cable_allowed?(notification.notifiable, notification.key) &&
|
29
|
-
notification.notifiable.
|
29
|
+
notification.notifiable.notifiable_action_cable_api_allowed?(notification.target, notification.key)
|
30
30
|
end
|
31
31
|
|
32
32
|
# Format message to broadcast
|
@@ -44,7 +44,7 @@ module ActivityNotification
|
|
44
44
|
# @return [Boolean] Whether Action Cable notification is allowed
|
45
45
|
def notification_action_cable_allowed?(notification)
|
46
46
|
notification.target.notification_action_cable_allowed?(notification.notifiable, notification.key) &&
|
47
|
-
notification.notifiable.
|
47
|
+
notification.notifiable.notifiable_action_cable_allowed?(notification.target, notification.key)
|
48
48
|
end
|
49
49
|
|
50
50
|
# Format message to broadcast
|
@@ -6,7 +6,7 @@ module ActivityNotification
|
|
6
6
|
# Defines has_many association with ActivityNotification models.
|
7
7
|
# @return [ActiveRecord_AssociationRelation<Object>] Database query of associated model instances
|
8
8
|
def has_many_records(name, options = {})
|
9
|
-
has_many name, options
|
9
|
+
has_many name, **options
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -23,14 +23,14 @@ module ActivityNotification
|
|
23
23
|
# Belongs to group instance of this notification as polymorphic association.
|
24
24
|
# @scope instance
|
25
25
|
# @return [Object] Group instance of this notification
|
26
|
-
belongs_to :group, { polymorphic: true
|
26
|
+
belongs_to :group, **{ polymorphic: true, optional: true }
|
27
27
|
|
28
28
|
# Belongs to group owner notification instance of this notification.
|
29
29
|
# Only group member instance has :group_owner value.
|
30
30
|
# Group owner instance has nil as :group_owner association.
|
31
31
|
# @scope instance
|
32
32
|
# @return [Notification] Group owner notification instance of this notification
|
33
|
-
belongs_to :group_owner, { class_name: "ActivityNotification::Notification"
|
33
|
+
belongs_to :group_owner, **{ class_name: "ActivityNotification::Notification", optional: true }
|
34
34
|
|
35
35
|
# Has many group member notification instances of this notification.
|
36
36
|
# Only group owner instance has :group_members value.
|
@@ -42,7 +42,7 @@ module ActivityNotification
|
|
42
42
|
# Belongs to :notifier instance of this notification.
|
43
43
|
# @scope instance
|
44
44
|
# @return [Object] Notifier instance of this notification
|
45
|
-
belongs_to :notifier, { polymorphic: true
|
45
|
+
belongs_to :notifier, **{ polymorphic: true, optional: true }
|
46
46
|
|
47
47
|
# Serialize parameters Hash
|
48
48
|
serialize :parameters, Hash
|
@@ -22,8 +22,8 @@ module ActivityNotification
|
|
22
22
|
association_name = name.to_s.singularize.underscore
|
23
23
|
composite_field = "#{association_name}_key".to_sym
|
24
24
|
field composite_field, :string
|
25
|
-
associated_record_field = "#{association_name}
|
26
|
-
field associated_record_field, :
|
25
|
+
associated_record_field = "stored_#{association_name}".to_sym
|
26
|
+
field associated_record_field, :raw if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
27
27
|
|
28
28
|
self.instance_eval do
|
29
29
|
define_method(name) do |reload = false|
|
@@ -43,7 +43,14 @@ module ActivityNotification
|
|
43
43
|
self.send("#{composite_field}=", nil)
|
44
44
|
else
|
45
45
|
self.send("#{composite_field}=", "#{new_instance.class.name}#{ActivityNotification.config.composite_key_delimiter}#{new_instance.id}")
|
46
|
-
|
46
|
+
associated_record_json = new_instance.as_json(_options[:as_json_options] || {})
|
47
|
+
# Cast Time and DateTime field to String to handle Dynamoid unsupported type error
|
48
|
+
if associated_record_json.present?
|
49
|
+
associated_record_json.each do |k, v|
|
50
|
+
associated_record_json[k] = v.to_s if v.is_a?(Time) || v.is_a?(DateTime)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
self.send("#{associated_record_field}=", associated_record_json) if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
47
54
|
end
|
48
55
|
self.instance_variable_set("@#{name}", nil)
|
49
56
|
end
|
@@ -20,17 +20,17 @@ module ActivityNotification
|
|
20
20
|
# Belongs to target instance of this notification as polymorphic association using composite key.
|
21
21
|
# @scope instance
|
22
22
|
# @return [Object] Target instance of this notification
|
23
|
-
belongs_to_composite_xdb_record :target, store_with_associated_records: true
|
23
|
+
belongs_to_composite_xdb_record :target, store_with_associated_records: true, as_json_options: { methods: [:printable_type, :printable_target_name] }
|
24
24
|
|
25
25
|
# Belongs to notifiable instance of this notification as polymorphic association using composite key.
|
26
26
|
# @scope instance
|
27
27
|
# @return [Object] Notifiable instance of this notification
|
28
|
-
belongs_to_composite_xdb_record :notifiable, store_with_associated_records: true
|
28
|
+
belongs_to_composite_xdb_record :notifiable, store_with_associated_records: true, as_json_options: { methods: [:printable_type] }
|
29
29
|
|
30
30
|
# Belongs to group instance of this notification as polymorphic association using composite key.
|
31
31
|
# @scope instance
|
32
32
|
# @return [Object] Group instance of this notification
|
33
|
-
belongs_to_composite_xdb_record :group
|
33
|
+
belongs_to_composite_xdb_record :group, store_with_associated_records: true, as_json_options: { methods: [:printable_type, :printable_group_name] }
|
34
34
|
|
35
35
|
field :key, :string
|
36
36
|
field :parameters, :raw, default: {}
|
@@ -42,7 +42,7 @@ module ActivityNotification
|
|
42
42
|
# Group owner instance has nil as :group_owner association.
|
43
43
|
# @scope instance
|
44
44
|
# @return [Notification] Group owner notification instance of this notification
|
45
|
-
belongs_to :group_owner, { class_name: "ActivityNotification::Notification", foreign_key: :group_owner_id
|
45
|
+
belongs_to :group_owner, { class_name: "ActivityNotification::Notification", foreign_key: :group_owner_id, optional: true }
|
46
46
|
|
47
47
|
# Customized method that belongs to group owner notification instance of this notification.
|
48
48
|
# @raise [Errors::RecordNotFound] Record not found error
|
@@ -64,14 +64,54 @@ module ActivityNotification
|
|
64
64
|
# Belongs to :otifier instance of this notification.
|
65
65
|
# @scope instance
|
66
66
|
# @return [Object] Notifier instance of this notification
|
67
|
-
belongs_to_composite_xdb_record :notifier, store_with_associated_records: true
|
67
|
+
belongs_to_composite_xdb_record :notifier, store_with_associated_records: true, as_json_options: { methods: [:printable_type, :printable_notifier_name] }
|
68
|
+
|
69
|
+
# Additional fields to store from instance method when config.store_with_associated_records is enabled
|
70
|
+
if ActivityNotification.config.store_with_associated_records
|
71
|
+
field :stored_notifiable_path, :string
|
72
|
+
field :stored_printable_notifiable_name, :string
|
73
|
+
field :stored_group_member_notifier_count, :integer
|
74
|
+
field :stored_group_notification_count, :integer
|
75
|
+
field :stored_group_members, :array
|
76
|
+
|
77
|
+
# Returns prepared notification object to store
|
78
|
+
# @return [Object] prepared notification object to store
|
79
|
+
def prepare_to_store
|
80
|
+
self.stored_notifiable_path = notifiable_path
|
81
|
+
self.stored_printable_notifiable_name = printable_notifiable_name
|
82
|
+
if group_owner?
|
83
|
+
self.stored_group_notification_count = 0
|
84
|
+
self.stored_group_member_notifier_count = 0
|
85
|
+
self.stored_group_members = []
|
86
|
+
end
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
# Call after store action with stored notification
|
91
|
+
def after_store
|
92
|
+
if group_owner?
|
93
|
+
self.stored_group_notification_count = group_notification_count
|
94
|
+
self.stored_group_member_notifier_count = group_member_notifier_count
|
95
|
+
self.stored_group_members = group_members.as_json
|
96
|
+
self.stored_group_members.each do |group_member|
|
97
|
+
# Cast Time and DateTime field to String to handle Dynamoid unsupported type error
|
98
|
+
group_member.each do |k, v|
|
99
|
+
group_member[k] = v.to_s if v.is_a?(Time) || v.is_a?(DateTime)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
save
|
103
|
+
else
|
104
|
+
group_owner.after_store
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
68
108
|
|
69
109
|
# Mandatory global secondary index to query effectively
|
70
|
-
global_secondary_index hash_key: :target_key, range_key: :created_at, projected_attributes: :all
|
71
|
-
global_secondary_index hash_key: :group_owner_id, range_key: :created_at, projected_attributes: :all
|
110
|
+
global_secondary_index name: :index_target_key_created_at, hash_key: :target_key, range_key: :created_at, projected_attributes: :all
|
111
|
+
global_secondary_index name: :index_group_owner_id_created_at, hash_key: :group_owner_id, range_key: :created_at, projected_attributes: :all
|
72
112
|
# Optional global secondary index to sort by created_at
|
73
|
-
global_secondary_index hash_key: :notifier_key, range_key: :created_at, projected_attributes: :all
|
74
|
-
global_secondary_index hash_key: :notifiable_key, range_key: :created_at, projected_attributes: :all
|
113
|
+
global_secondary_index name: :index_notifier_key_created_at, hash_key: :notifier_key, range_key: :created_at, projected_attributes: :all
|
114
|
+
global_secondary_index name: :index_notifiable_key_created_at, hash_key: :notifiable_key, range_key: :created_at, projected_attributes: :all
|
75
115
|
|
76
116
|
validates :target, presence: true
|
77
117
|
validates :notifiable, presence: true
|
@@ -122,11 +162,6 @@ module ActivityNotification
|
|
122
162
|
raise ActivityNotification::DeleteRestrictionError, error_text
|
123
163
|
end
|
124
164
|
|
125
|
-
# Returns prepared notification object to store
|
126
|
-
# @return [Object] prepared notification object to store
|
127
|
-
# def prepare_to_store
|
128
|
-
# end
|
129
|
-
|
130
165
|
protected
|
131
166
|
|
132
167
|
# Returns count of group members of the unopened notification.
|
@@ -28,7 +28,7 @@ module ActivityNotification
|
|
28
28
|
field :unsubscribed_to_email_at, :datetime
|
29
29
|
field :optional_targets, :raw, default: {}
|
30
30
|
|
31
|
-
global_secondary_index hash_key: :target_key, range_key: :created_at, projected_attributes: :all
|
31
|
+
global_secondary_index name: :index_target_key_created_at, hash_key: :target_key, range_key: :created_at, projected_attributes: :all
|
32
32
|
|
33
33
|
validates :target, presence: true
|
34
34
|
validates :key, presence: true, uniqueness: { scope: :target_key }
|
@@ -24,8 +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}
|
28
|
-
field associated_record_field, type:
|
27
|
+
associated_record_field = "stored_#{association_name}"
|
28
|
+
field associated_record_field, type: Hash if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
29
29
|
|
30
30
|
self.instance_eval do
|
31
31
|
define_method(name) do |reload = false|
|
@@ -43,7 +43,14 @@ module ActivityNotification
|
|
43
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
|
44
44
|
self.send("#{id_field}=", instance_id)
|
45
45
|
self.send("#{type_field}=", instance_type)
|
46
|
-
|
46
|
+
associated_record_json = new_instance.as_json(_options[:as_json_options] || {})
|
47
|
+
# Cast Hash $oid field to String id to handle BSON::String::IllegalKey
|
48
|
+
if associated_record_json.present?
|
49
|
+
associated_record_json.each do |k, v|
|
50
|
+
associated_record_json[k] = v['$oid'] if v.is_a?(Hash) && v.has_key?('$oid')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
self.send("#{associated_record_field}=", associated_record_json) if ActivityNotification.config.store_with_associated_records && _options[:store_with_associated_records]
|
47
54
|
self.instance_variable_set("@#{name}", nil)
|
48
55
|
end
|
49
56
|
end
|
@@ -19,17 +19,17 @@ 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, store_with_associated_records: true
|
22
|
+
belongs_to_polymorphic_xdb_record :target, store_with_associated_records: true, as_json_options: { methods: [:printable_type, :printable_target_name] }
|
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, store_with_associated_records: true
|
27
|
+
belongs_to_polymorphic_xdb_record :notifiable, store_with_associated_records: true, as_json_options: { methods: [:printable_type] }
|
28
28
|
|
29
29
|
# Belongs to group instance of this notification as polymorphic association.
|
30
30
|
# @scope instance
|
31
31
|
# @return [Object] Group instance of this notification
|
32
|
-
belongs_to_polymorphic_xdb_record :group
|
32
|
+
belongs_to_polymorphic_xdb_record :group, as_json_options: { methods: [:printable_type, :printable_group_name] }
|
33
33
|
|
34
34
|
field :key, type: String
|
35
35
|
field :parameters, type: Hash, default: {}
|
@@ -41,7 +41,7 @@ module ActivityNotification
|
|
41
41
|
# Group owner instance has nil as :group_owner association.
|
42
42
|
# @scope instance
|
43
43
|
# @return [Notification] Group owner notification instance of this notification
|
44
|
-
belongs_to :group_owner, { class_name: "ActivityNotification::Notification"
|
44
|
+
belongs_to :group_owner, { class_name: "ActivityNotification::Notification", optional: true }
|
45
45
|
|
46
46
|
# Has many group member notification instances of this notification.
|
47
47
|
# Only group owner instance has :group_members value.
|
@@ -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, store_with_associated_records: true
|
56
|
+
belongs_to_polymorphic_xdb_record :notifier, store_with_associated_records: true, as_json_options: { methods: [:printable_type, :printable_notifier_name] }
|
57
57
|
|
58
58
|
validates :target, presence: true
|
59
59
|
validates :notifiable, presence: true
|
@@ -140,7 +140,9 @@ module ActivityNotification
|
|
140
140
|
scope :filtered_by_group, ->(group) {
|
141
141
|
group.present? ?
|
142
142
|
where(group_id: group.id, group_type: group.class.name) :
|
143
|
-
|
143
|
+
Gem::Version.new(::Mongoid::VERSION) >= Gem::Version.new('7.1.0') ?
|
144
|
+
where(:group_id.exists => false, :group_type.exists => false).or(group_id: nil, group_type: nil) :
|
145
|
+
any_of({ :group_id.exists => false, :group_type.exists => false }, { group_id: nil, group_type: nil })
|
144
146
|
}
|
145
147
|
|
146
148
|
# Selects filtered notifications later than specified time.
|
@@ -28,7 +28,7 @@ module ActivityNotification
|
|
28
28
|
field :optional_targets, type: Hash, default: {}
|
29
29
|
|
30
30
|
validates :target, presence: true
|
31
|
-
validates :key, presence: true, uniqueness: { scope: :
|
31
|
+
validates :key, presence: true, uniqueness: { scope: [:target_type, :target_id] }
|
32
32
|
validates_inclusion_of :subscribing, in: [true, false]
|
33
33
|
validates_inclusion_of :subscribing_to_email, in: [true, false]
|
34
34
|
validate :subscribing_to_email_cannot_be_true_when_subscribing_is_false
|
@@ -29,8 +29,8 @@ module ActivityNotification
|
|
29
29
|
)
|
30
30
|
|
31
31
|
# Generate the :default fallback key without using pluralization key :count
|
32
|
-
default = I18n.t(k, attrs)
|
33
|
-
I18n.t(k, attrs.merge(count: group_notification_count, default: default))
|
32
|
+
default = I18n.t(k, **attrs)
|
33
|
+
I18n.t(k, **attrs.merge(count: group_notification_count, default: default))
|
34
34
|
end
|
35
35
|
|
36
36
|
# Renders notification from views.
|
@@ -239,25 +239,21 @@ module ActivityNotification
|
|
239
239
|
configured_params.update(add_destroy_dependency(target_type, options[:dependent_notifications]))
|
240
240
|
end
|
241
241
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
unless options[:optional_targets].has_key?(ActivityNotification::OptionalTarget::ActionCableChannel)
|
248
|
-
options[:optional_targets][ActivityNotification::OptionalTarget::ActionCableChannel] = {}
|
249
|
-
end
|
242
|
+
if options[:action_cable_allowed] || (ActivityNotification.config.action_cable_enabled && options[:action_cable_allowed] != false)
|
243
|
+
options[:optional_targets] ||= {}
|
244
|
+
require 'activity_notification/optional_targets/action_cable_channel'
|
245
|
+
unless options[:optional_targets].has_key?(ActivityNotification::OptionalTarget::ActionCableChannel)
|
246
|
+
options[:optional_targets][ActivityNotification::OptionalTarget::ActionCableChannel] = {}
|
250
247
|
end
|
248
|
+
end
|
251
249
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
end
|
250
|
+
if options[:action_cable_api_allowed] || (ActivityNotification.config.action_cable_api_enabled && options[:action_cable_api_allowed] != false)
|
251
|
+
options[:optional_targets] ||= {}
|
252
|
+
require 'activity_notification/optional_targets/action_cable_api_channel'
|
253
|
+
unless options[:optional_targets].has_key?(ActivityNotification::OptionalTarget::ActionCableApiChannel)
|
254
|
+
options[:optional_targets][ActivityNotification::OptionalTarget::ActionCableApiChannel] = {}
|
258
255
|
end
|
259
256
|
end
|
260
|
-
# :nocov:
|
261
257
|
|
262
258
|
if options[:optional_targets].is_a?(Hash)
|
263
259
|
options[:optional_targets] = arrange_optional_targets_option(options[:optional_targets])
|
@@ -265,7 +261,8 @@ module ActivityNotification
|
|
265
261
|
|
266
262
|
options[:printable_notifiable_name] ||= options.delete(:printable_name)
|
267
263
|
configured_params
|
268
|
-
.merge set_acts_as_parameters_for_target(target_type, [:targets, :group, :group_expiry_delay, :parameters, :email_allowed
|
264
|
+
.merge set_acts_as_parameters_for_target(target_type, [:targets, :group, :group_expiry_delay, :parameters, :email_allowed], options, "notification_")
|
265
|
+
.merge set_acts_as_parameters_for_target(target_type, [:action_cable_allowed, :action_cable_api_allowed], options, "notifiable_")
|
269
266
|
.merge set_acts_as_parameters_for_target(target_type, [:notifier, :notifiable_path, :printable_notifiable_name, :optional_targets], options)
|
270
267
|
end
|
271
268
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Migration responsible for creating a table with notifications
|
2
|
-
class <%= @migration_name %> < ActiveRecord::Migration<%=
|
2
|
+
class <%= @migration_name %> < ActiveRecord::Migration<%= "[#{Rails.version.to_f}]" %>
|
3
3
|
# Create tables
|
4
4
|
def change
|
5
5
|
<% if @migration_tables.include?('notifications') %>create_table :notifications do |t|
|
@@ -1,51 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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_api_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
26
|
-
}.to raise_error(/Must be subscribed!/)
|
27
|
-
end
|
1
|
+
require 'channels/notification_api_channel_shared_examples'
|
2
|
+
|
3
|
+
# @See https://github.com/palkan/action-cable-testing
|
4
|
+
describe ActivityNotification::NotificationApiChannel, type: :channel do
|
5
|
+
let(:test_target) { create(:user) }
|
6
|
+
let(:target_type) { "User" }
|
7
|
+
let(:typed_target_param) { "user_id" }
|
8
|
+
let(:extra_params) { {} }
|
9
|
+
|
10
|
+
context "when target.notification_action_cable_with_devise? returns true" do
|
11
|
+
before do
|
12
|
+
@user_notification_action_cable_with_devise = User._notification_action_cable_with_devise
|
13
|
+
User._notification_action_cable_with_devise = true
|
28
14
|
end
|
29
15
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
User._notification_action_cable_with_devise = false
|
34
|
-
@auth_headers = {}
|
35
|
-
end
|
36
|
-
|
37
|
-
after do
|
38
|
-
User._notification_action_cable_with_devise = @user_notification_action_cable_with_devise
|
39
|
-
end
|
16
|
+
after do
|
17
|
+
User._notification_action_cable_with_devise = @user_notification_action_cable_with_devise
|
18
|
+
end
|
40
19
|
|
41
|
-
|
42
|
-
|
43
|
-
|
20
|
+
it "rejects subscription even if target_type and target_id parameters are passed" do
|
21
|
+
subscribe({ target_type: target_type, target_id: test_target.id })
|
22
|
+
expect(subscription).to be_rejected
|
23
|
+
expect {
|
44
24
|
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_api_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
45
|
-
|
46
|
-
|
25
|
+
}.to raise_error(/Must be subscribed!/)
|
26
|
+
end
|
27
|
+
end
|
47
28
|
|
48
|
-
|
29
|
+
context "when target.notification_action_cable_with_devise? returns false" do
|
30
|
+
before do
|
31
|
+
@user_notification_action_cable_with_devise = User._notification_action_cable_with_devise
|
32
|
+
User._notification_action_cable_with_devise = false
|
33
|
+
@auth_headers = {}
|
49
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_api_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
44
|
+
expect(subscription).to have_stream_from("activity_notification_api_channel_User##{test_target.id}")
|
45
|
+
end
|
46
|
+
|
47
|
+
it_behaves_like :notification_api_channel
|
50
48
|
end
|
51
|
-
end
|
49
|
+
end
|
@@ -1,78 +1,76 @@
|
|
1
|
-
|
2
|
-
require 'channels/notification_api_channel_shared_examples'
|
1
|
+
require 'channels/notification_api_channel_shared_examples'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
# @See https://github.com/palkan/action-cable-testing
|
4
|
+
describe ActivityNotification::NotificationApiWithDeviseChannel, type: :channel do
|
5
|
+
let(:test_user) { create(:confirmed_user) }
|
6
|
+
let(:unauthenticated_user) { create(:confirmed_user) }
|
7
|
+
let(:test_target) { create(:admin, user: test_user) }
|
8
|
+
let(:target_type) { "Admin" }
|
9
|
+
let(:typed_target_param) { "admin_id" }
|
10
|
+
let(:extra_params) { { devise_type: :users } }
|
11
|
+
let(:valid_session) {}
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
# @See https://github.com/lynndylanhurley/devise_token_auth
|
14
|
+
def sign_in(current_target)
|
15
|
+
@auth_headers = current_target.create_new_auth_token
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
before do
|
19
|
+
@user_notification_action_cable_with_devise = User._notification_action_cable_with_devise
|
20
|
+
User._notification_action_cable_with_devise = true
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
after do
|
24
|
+
User._notification_action_cable_with_devise = @user_notification_action_cable_with_devise
|
25
|
+
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
it_behaves_like :notification_api_channel
|
27
|
+
context "signed in with devise as authenticated user" do
|
28
|
+
before do
|
29
|
+
sign_in test_user
|
34
30
|
end
|
31
|
+
|
32
|
+
it_behaves_like :notification_api_channel
|
33
|
+
end
|
35
34
|
|
36
|
-
|
37
|
-
|
35
|
+
context "signed in with devise as unauthenticated user" do
|
36
|
+
let(:target_params) { { target_type: target_type, devise_type: :users } }
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
before do
|
39
|
+
sign_in unauthenticated_user
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
42
|
+
it "rejects subscription" do
|
43
|
+
subscribe(target_params.merge({ typed_target_param => test_target }).merge(@auth_headers))
|
44
|
+
expect(subscription).to be_rejected
|
45
|
+
expect {
|
46
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_api_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
47
|
+
}.to raise_error(/Must be subscribed!/)
|
50
48
|
end
|
49
|
+
end
|
51
50
|
|
52
|
-
|
53
|
-
|
51
|
+
context "unsigned in with devise" do
|
52
|
+
let(:target_params) { { target_type: target_type, devise_type: :users } }
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
54
|
+
it "rejects subscription" do
|
55
|
+
subscribe(target_params.merge({ typed_target_param => test_target }))
|
56
|
+
expect(subscription).to be_rejected
|
57
|
+
expect {
|
58
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_api_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
59
|
+
}.to raise_error(/Must be subscribed!/)
|
62
60
|
end
|
61
|
+
end
|
63
62
|
|
64
|
-
|
65
|
-
|
63
|
+
context "without target_id and (typed_target)_id parameters for devise integrated channel with devise_type option" do
|
64
|
+
let(:target_params) { { target_type: target_type, devise_type: :users } }
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
before do
|
67
|
+
sign_in test_target.user
|
68
|
+
end
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
70
|
+
it "successfully subscribes" do
|
71
|
+
subscribe(target_params.merge(@auth_headers))
|
72
|
+
expect(subscription).to have_stream_from("#{ActivityNotification.config.notification_api_channel_prefix}_#{test_target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{test_target.id}")
|
73
|
+
expect(subscription).to have_stream_from("activity_notification_api_channel_Admin##{test_target.id}")
|
76
74
|
end
|
77
75
|
end
|
78
76
|
end
|