abstract_notifier 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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