abstract_notifier 0.1.1 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f53c7d7582adccf56af7c488e41063cf5b344cbe198a548885d52b60f030772
4
- data.tar.gz: d13d22f8e543f15c4bbf48bb29838746cdf0843430a1eb55e1c89cafa3c417da
3
+ metadata.gz: a36463d0a1ed93c6f48229bed9135f6c1ec3e301c76dc5b9edcc28f19d75cc3e
4
+ data.tar.gz: 7c56ec837be932967f22c592018b2210912fb2e53a40e5b8526b619dff70c4b1
5
5
  SHA512:
6
- metadata.gz: 462d22226d63a1c862f089f5a4b78cac6c457ca78160510b82588129c3d914a649daf4349945a989429202fde18ac87eff4ec3c42d670240eaa90959a5d7a010
7
- data.tar.gz: 86f83533acc72205f77d7c83486e4cee9f9b59b5d6efe6ab6692dac18c3fbd58959c5d96b2537eaf5f7c9b95a9810297908ea0f6366cd8dec6cc2db2eed7f1cd
6
+ metadata.gz: 4a191cf257f1691d8df1b395ed14610246e2ae8614bde594abd359fea8104fe3c903a9332060545563e289652b45716d76c89d2f763a8bd0c911d305641c594d
7
+ data.tar.gz: 888f89197efafc92cbbfffc220959c449fcd405c8fea6932ab3f1dde4ed4f1d726e2c19ce4c43e68ca2021a8cc040a53831506c05a5272ce7f43330e4b054364
@@ -0,0 +1,15 @@
1
+ # Change log
2
+
3
+ ## master
4
+
5
+ ## 0.2.0 (2018-01-11)
6
+
7
+ - Add class-level defaults. ([@palkan][])
8
+
9
+ - Add `#notification_name`. ([@palkan][])
10
+
11
+ ## 0.1.0 (2018-12-21)
12
+
13
+ Initial version.
14
+
15
+ [@palkan]: https://github.com/palkan
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Abstract Notifier is a tool which allows you to describe/model any text-based notifications (such as Push Notifications) the same way Action Mailer does for email notifications.
7
7
 
8
- Abstract Notifier (as the name states) doesn't provide any specific implementaion for sending notifications. Instead if provide tools to organize your notification-specific code and make it easily testable.
8
+ Abstract Notifier (as the name states) doesn't provide any specific implementation for sending notifications. Instead, it offers tools to organize your notification-specific code and make it easily testable.
9
9
 
10
10
  <a href="https://evilmartians.com/?utm_source=action_policy">
11
11
  <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
@@ -31,7 +31,7 @@ $ bundle
31
31
 
32
32
  ## Usage
33
33
 
34
- Notifer class is very similar to Action Mailer mailer class with `notification` method instead of a `mail` method:
34
+ Notifier class is very similar to Action Mailer mailer class with `notification` method instead of a `mail` method:
35
35
 
36
36
  ```ruby
37
37
  class EventsNotifier < ApplicationNotifier
@@ -60,7 +60,7 @@ class ApplicationNotifier < AbstractNotifier::Base
60
60
  end
61
61
  ```
62
62
 
63
- Driver could be any callbable Ruby object (i.e. anything that responds to `#call`).
63
+ A driver could be any callable Ruby object (i.e., anything that responds to `#call`).
64
64
 
65
65
  That's a developer responsibility to implement the driver (we do not provide any drivers out-of-the-box; at least yet).
66
66
 
@@ -83,13 +83,47 @@ end
83
83
  EventsNotifier.with(profile: profile).canceled(event).notify_later
84
84
  ```
85
85
 
86
+ ### Defaults
87
+
88
+ You can specify default notification fields at a class level:
89
+
90
+ ```ruby
91
+ class EventsNotifier < ApplicationNotifier
92
+ # `category` field will be added to the notification
93
+ # if missing
94
+ default category: "EVENTS"
95
+
96
+ # ...
97
+ end
98
+ ```
99
+
100
+ **NOTE**: when subclassing notifiers, default parameters are merged.
101
+
102
+ You can also specify a block or a method name as the default params _generator_.
103
+ This could be useful in combination with the `#notification_name` method to generate dynamic payloads:
104
+
105
+ ```ruby
106
+ class ApplicationNotifier < AbstractNofitier::Base
107
+ default :build_defaults_from_locale
108
+
109
+
110
+ private
111
+
112
+ def build_defaults_from_locale
113
+ {
114
+ subject: I18n.t(notification_name, scope: [:notifiers, self.class.name.underscore])
115
+ }
116
+ end
117
+ end
118
+ ```
119
+
86
120
  ### Background jobs / async notifications
87
121
 
88
122
  To use `notify_later` you **must** configure `async_adapter`.
89
123
 
90
124
  We provide Active Job adapter out-of-the-box and use it if Active Job is present.
91
125
 
92
- Custom async adapter must implement `enqueue` method:
126
+ The custom async adapter must implement `enqueue` method:
93
127
 
94
128
  ```ruby
95
129
  class MyAsyncAdapter
@@ -99,7 +133,7 @@ class MyAsyncAdapter
99
133
 
100
134
  # `enqueue` method accepts notifier class and notification
101
135
  # payload.
102
- # We need to know notifier class to use it's driver.
136
+ # We need to know notifier class to use its driver.
103
137
  def enqueue(notifier_class, payload)
104
138
  # your implementation here
105
139
  end
@@ -159,7 +193,7 @@ expect { EventsNotifier.with(profile: profile).canceled(event).notify_later}.
159
193
 
160
194
  ### [`active_delivery`](https://github.com/palkan/active_delivery)
161
195
 
162
- Active Delivery is the next-level abstraction which allows to combine multiple notification channels in one place.
196
+ Active Delivery is the next-level abstraction which allows combining multiple notification channels in one place.
163
197
 
164
198
  Abstract Notifier provides a _notifier_ line for Active Delivery:
165
199
 
@@ -169,11 +203,11 @@ class ApplicationDelivery < ActiveDelivery::Base
169
203
  register_line :notifier, ActiveDelivery::Lines::Notifier,
170
204
  # you may provide a resolver, which infers notifier class
171
205
  # from delivery name (resolver is a callable).
172
- rsolver: ->(name) { resolve_somehow(name) }
206
+ resolver: ->(name) { resolve_somehow(name) }
173
207
  end
174
208
  ```
175
209
 
176
- **NOTE:** we automatically add `:notifier` line with `"*Delivery" -> *Notifier` resolution mechanism if `#safe_constantize` method is defined for String, i.e. you don't have to configure the default notifier line when running Rails.
210
+ **NOTE:** we automatically add `:notifier` line with `"*Delivery" -> *Notifier` resolution mechanism if `#safe_constantize` method is defined for String, i.e., you don't have to configure the default notifier line when running Rails.
177
211
 
178
212
  ## Contributing
179
213
 
@@ -25,9 +25,26 @@ module AbstractNotifier
25
25
 
26
26
  # Base class for notifiers
27
27
  class Base
28
- class << self
29
- alias with new
28
+ class ParamsProxy
29
+ attr_reader :notifier_class, :params
30
+
31
+ def initialize(notifier_class, params)
32
+ @notifier_class = notifier_class
33
+ @params = params
34
+ end
35
+
36
+ # rubocop:disable Style/MethodMissingSuper
37
+ def method_missing(method_name, *args)
38
+ notifier_class.new(method_name, params).public_send(method_name, *args)
39
+ end
40
+ # rubocop:enable Style/MethodMissingSuper
41
+
42
+ def respond_to_missing?(*args)
43
+ notifier_class.respond_to_missing?(*args)
44
+ end
45
+ end
30
46
 
47
+ class << self
31
48
  attr_writer :driver
32
49
 
33
50
  def driver
@@ -58,14 +75,51 @@ module AbstractNotifier
58
75
  end
59
76
  end
60
77
 
78
+ def default(method_name = nil, **hargs)
79
+ return @defaults_generator = Proc.new if block_given?
80
+
81
+ return @defaults_generator = proc { send(method_name) } unless method_name.nil?
82
+
83
+ @default_params =
84
+ if superclass.respond_to?(:default_params)
85
+ superclass.default_params.merge(hargs).freeze
86
+ else
87
+ hargs.freeze
88
+ end
89
+ end
90
+
91
+ def defaults_generator
92
+ return @defaults_generator if instance_variable_defined?(:@defaults_generator)
93
+
94
+ @defaults_generator =
95
+ if superclass.respond_to?(:defaults_generator)
96
+ superclass.defaults_generator
97
+ end
98
+ end
99
+
100
+ def default_params
101
+ return @default_params if instance_variable_defined?(:@default_params)
102
+
103
+ @default_params =
104
+ if superclass.respond_to?(:default_params)
105
+ superclass.default_params.dup
106
+ else
107
+ {}
108
+ end
109
+ end
110
+
61
111
  def method_missing(method_name, *args)
62
112
  if action_methods.include?(method_name.to_s)
63
- new.public_send(method_name, *args)
113
+ new(method_name).public_send(method_name, *args)
64
114
  else
65
115
  super
66
116
  end
67
117
  end
68
118
 
119
+ def with(params)
120
+ ParamsProxy.new(self, params)
121
+ end
122
+
69
123
  def respond_to_missing?(method_name, _include_private = false)
70
124
  action_methods.include?(method_name.to_s) || super
71
125
  end
@@ -87,16 +141,34 @@ module AbstractNotifier
87
141
  end
88
142
  end
89
143
 
90
- attr_reader :params
144
+ attr_reader :params, :notification_name
91
145
 
92
- def initialize(**params)
146
+ def initialize(notification_name, **params)
147
+ @notification_name = notification_name
93
148
  @params = params.freeze
94
149
  end
95
150
 
96
151
  def notification(**payload)
152
+ merge_defaults!(payload)
153
+
97
154
  raise ArgumentError, "Notification body must be present" if
98
155
  payload[:body].nil? || payload[:body].empty?
99
156
  Notification.new(self.class, payload)
100
157
  end
158
+
159
+ private
160
+
161
+ def merge_defaults!(payload)
162
+ defaults =
163
+ if self.class.defaults_generator
164
+ instance_exec(&self.class.defaults_generator)
165
+ else
166
+ self.class.default_params
167
+ end
168
+
169
+ defaults.each do |k, v|
170
+ payload[k] = v unless payload.key?(k)
171
+ end
172
+ end
101
173
  end
102
174
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbstractNotifier
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abstract_notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-21 00:00:00.000000000 Z
11
+ date: 2019-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_delivery
@@ -91,6 +91,7 @@ files:
91
91
  - ".rspec"
92
92
  - ".rubocop.yml"
93
93
  - ".travis.yml"
94
+ - CHANGELOG.md
94
95
  - Gemfile
95
96
  - LICENSE.txt
96
97
  - README.md
@@ -128,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  version: '0'
129
130
  requirements: []
130
131
  rubyforge_project:
131
- rubygems_version: 2.7.7
132
+ rubygems_version: 2.7.6
132
133
  signing_key:
133
134
  specification_version: 4
134
135
  summary: ActionMailer-like interface for any type of notifications