active_delivery 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: ba024e906a6a7bdf0dafd6a4e83ecefc7121b475ec9f9e7dfdadaacf4a2e04c0
4
- data.tar.gz: 1045c894dc23a4d90282fac45a158af962839d9cd026ff8d5331371141c5c120
3
+ metadata.gz: fab4f00d6e9540f490e987b355133449d9213d2a1f9cb683aced62e16ae36a84
4
+ data.tar.gz: e9728da5a0a19ba23e7412a2ed678cabb28e7c1c6ac16ae89246302a80b8f2dc
5
5
  SHA512:
6
- metadata.gz: 0f54fd937683e8e70871ece3900d2f75026e0674e316cc8969ad5066e5757b4982697f3e2c5e59d9969497c54874b6c9ea107ee08eae502d1ef87f7013234943
7
- data.tar.gz: 4af2720f68788f2cc35d4acbdfc2ed6870a809d075b08a16663ddbd459ebc734939eab1208a4acfc6fd46dc1ac2a19603d1de5ccfbfbeb1d5ff1a11ae749ff45
6
+ metadata.gz: c3be343f6a4151bcd434105b22c0e4a028dcc0bc4a22ea1e70e13de1213a3469d4cc6ef942959df8005784eab0d41b2bcf42858aa3d7915743a4b8b337e13f0e
7
+ data.tar.gz: ef751694baca35139d81ef11a277adde948e63b59528d040ef08390c36952a6ff35da49174b80070cf5df6d836c054d1d6d30ee23cbd7103ab0c73c32b723b83
data/.rubocop.yml CHANGED
@@ -16,6 +16,9 @@ AllCops:
16
16
  Standard/SemanticBlocks:
17
17
  Enabled: false
18
18
 
19
+ Style/FrozenStringLiteralComment:
20
+ Enabled: true
21
+
19
22
  Style/TrailingCommaInArrayLiteral:
20
23
  EnforcedStyleForMultiline: no_comma
21
24
 
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Change log
2
+
3
+ ## master
4
+
5
+ ## 0.2.0 (2018-01-11)
6
+
7
+ - Add `#notification_name`. ([@palkan][])
8
+
9
+ - Support anonymous callbacks. ([@palkan][])
10
+
11
+ ## 0.1.0 (2018-12-20)
12
+
13
+ Initial version.
14
+
15
+ [@palkan]: https://github.com/palkan
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # Active Delivery
5
5
 
6
- Framework providing an entrypoint (single _interface_) for all types of notifications: mailers, push notifications, whatever you want.
6
+ Framework providing an entry point (single _interface_) for all types of notifications: mailers, push notifications, whatever you want.
7
7
 
8
8
  <a href="https://evilmartians.com/?utm_source=action_policy">
9
9
  <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
@@ -17,13 +17,13 @@ Requirements:
17
17
 
18
18
  We need a way to handle different notifications _channel_ (mail, push) in one place.
19
19
 
20
- From the business-logic point of view we want to _notify_ a user, hence we need a _separate abstraction layer_ as an entrypoint to different types of notifications.
20
+ From the business-logic point of view we want to _notify_ a user, hence we need a _separate abstraction layer_ as an entry point to different types of notifications.
21
21
 
22
22
  ## The solution
23
23
 
24
- Here comes the _Active Delivery_.
24
+ Here comes _Active Delivery_.
25
25
 
26
- In the simplest case when we have only mailers Active Delivery is just a wrapper for Mailer with (possibly) some additional logic provided (e.g. preventing emails to unsubscribed users).
26
+ In the simplest case when we have only mailers Active Delivery is just a wrapper for Mailer with (possibly) some additional logic provided (e.g., preventing emails to unsubscribed users).
27
27
 
28
28
  Motivations behind Active Delivery:
29
29
  - organize notifications related logic:
@@ -59,7 +59,7 @@ $ bundle
59
59
 
60
60
  ## Usage
61
61
 
62
- _Delivery_ class is used to trigger notifications. It describes how to notify a user (e.g. via email or via push notification or both):
62
+ The _Delivery_ class is used to trigger notifications. It describes how to notify a user (e.g., via email or push notification or both):
63
63
 
64
64
  ```ruby
65
65
  class PostsDelivery < ActiveDelivery::Base
@@ -68,7 +68,7 @@ class PostsDelivery < ActiveDelivery::Base
68
68
  end
69
69
  ```
70
70
 
71
- It acts like a proxy in front of the different delivery channels (i.e. mailers, notifiers). That means that calling a method on delivery class invokes the same method on the corresponding _sender_ class, e.g.:
71
+ It acts as a proxy in front of the different delivery channels (i.e., mailers, notifiers). That means that calling a method on delivery class invokes the same method on the corresponding _sender_ class, e.g.:
72
72
 
73
73
  ```ruby
74
74
  PostsDelivery.notify(:published, user, post)
@@ -88,7 +88,7 @@ Delivery also supports _parameterized_ calling:
88
88
  PostsDelivery.with(user: user).notify(:published, post)
89
89
  ```
90
90
 
91
- The parameters could be accessed through `params` instance method (e.g. to implement guard-like logic).
91
+ The parameters could be accessed through the `params` instance method (e.g., to implement guard-like logic).
92
92
 
93
93
  **NOTE**: When params are presents the parametrized mailer is used, i.e.:
94
94
 
@@ -100,11 +100,11 @@ See [Rails docs](https://api.rubyonrails.org/classes/ActionMailer/Parameterized.
100
100
 
101
101
  ## Callbacks support
102
102
 
103
- **NOTE:** callbacks are only available if ActiveSupport is present in the app's env.
103
+ **NOTE:** callbacks are only available if ActiveSupport is present in the app's runtime.
104
104
 
105
105
  ```ruby
106
106
  # Run method before delivering notification
107
- # NOTE: when `false` is returned the executation is halted
107
+ # NOTE: when `false` is returned the execution is halted
108
108
  before_notify :do_something
109
109
 
110
110
  # You can specify a notification method (to run callback only for that method)
@@ -116,11 +116,26 @@ after_notify :cleanup
116
116
  around_notify :set_context
117
117
  ```
118
118
 
119
+ Example:
120
+
121
+ ```ruby
122
+ # Let's log notifications
123
+ class MyDelivery < ActiveDelivery::Base
124
+ after_notify do
125
+ # You can access the notificaion name within the instance
126
+ MyLogger.info "Delivery triggered: #{notification_name}"
127
+ end
128
+ end
129
+
130
+ MyDeliver.notify(:something_wicked_this_way_comes)
131
+ #=> Delivery triggered: something_wicked_this_way_comes
132
+ ```
133
+
119
134
  ## Testing
120
135
 
121
136
  **NOTE:** RSpec only for the time being.
122
137
 
123
- Active Delivery provides an elegant way to test deliveries in your code (i.e. when you want to test whether a notification has been sent) through a `have_delivered_to` matcher:
138
+ Active Delivery provides an elegant way to test deliveries in your code (i.e., when you want to check whether a notification has been sent) through a `have_delivered_to` matcher:
124
139
 
125
140
  ```ruby
126
141
  it "delivers notification" do
@@ -131,7 +146,7 @@ it "delivers notification" do
131
146
  You can also use such RSpec features as [compound expectations](https://relishapp.com/rspec/rspec-expectations/docs/compound-expectations) and [composed matchers](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/composing-matchers):
132
147
 
133
148
  ```ruby
134
- it "delivers to rsvped members via .notify" do
149
+ it "delivers to RSVPed members via .notify" do
135
150
  expect { subject }.
136
151
  to have_delivered_to(Community::EventsDelivery, :canceled, an_instance_of(event)).with(
137
152
  a_hash_including(profile: another_profile)
@@ -141,7 +156,7 @@ it "delivers to rsvped members via .notify" do
141
156
  end
142
157
  ```
143
158
 
144
- If you want to test that no notification is deliver you can use negation:
159
+ If you want to test that no notification is delivered you can use negation:
145
160
 
146
161
  ```ruby
147
162
  specify "when event is not found" do
@@ -155,11 +170,11 @@ end
155
170
 
156
171
  ## Custom "lines"
157
172
 
158
- _Line_ class describes the way you want to _transfer_ your deliveries.
173
+ The _Line_ class describes the way you want to _transfer_ your deliveries.
159
174
 
160
- Out-of-the box we provide only Action Mailer _line_.
175
+ We only provide only Action Mailer _line_ out-of-the-box.
161
176
 
162
- Line connects _delivery_ to the _sender_ class responsible for sending notifications.
177
+ A line connects _delivery_ to the _sender_ class responsible for sending notifications.
163
178
 
164
179
  If you want to use parameterized deliveries, your _sender_ class must respond to `.with(params)` method.
165
180
 
@@ -168,10 +183,10 @@ Assume that we want to send messages via _pigeons_ and we have the following sen
168
183
  ```ruby
169
184
  class EventPigeon
170
185
  class << self
171
- # Add `.with` method as an alias
186
+ # Add `.with` method as an alias
172
187
  alias with new
173
188
 
174
- # delegate delivery action to instance
189
+ # delegate delivery action to the instance
175
190
  def message_arrived(*args)
176
191
  new.message_arrived(*arsg)
177
192
  end
@@ -182,13 +197,13 @@ class EventPigeon
182
197
  end
183
198
 
184
199
  def message_arrived(msg)
185
- # send pigeon with the message
200
+ # send a pigeon with the message
186
201
  end
187
202
  end
188
203
  ```
189
204
 
190
- Now we want to add a _pigeon_ line to our `EventDelivery`, that is we want to send pigeons when
191
- we call `EventDelivery.notify(:message_arrived, "ping-ping!")`.
205
+ Now we want to add a _pigeon_ line to our `EventDelivery,` that is we want to send pigeons when
206
+ we call `EventDelivery.notify(:message_arrived, "ping-pong!")`.
192
207
 
193
208
  Line class has the following API:
194
209
 
@@ -201,7 +216,7 @@ class PigeonLine < ActiveDelivery::Lines::Base
201
216
  name.gsub(/Delivery$/, "Pigeon").safe_constantize
202
217
  end
203
218
 
204
- # This method should return true if sender recognizes the delivery action
219
+ # This method should return true if the sender recognizes the delivery action
205
220
  def notify?(delivery_action)
206
221
  # `handler_class` is available within the line instance
207
222
  sender_class.respond_to?(delivery_action)
@@ -217,8 +232,8 @@ class PigeonLine < ActiveDelivery::Lines::Base
217
232
  PigeonService.launch pigeon
218
233
  end
219
234
 
220
- # Called when we want to send message asynchronously.
221
- # For example, you can use background job here.
235
+ # Called when we want to send a message asynchronously.
236
+ # For example, you can use a background job here.
222
237
  def notify_later(sender, delivery_action, *args)
223
238
  pigeon = sender.public_send(delivery_action, *args)
224
239
  # PigeonLaunchService do all the sending job
@@ -231,13 +246,13 @@ end
231
246
  You can disable automatic inference of sender classes by marking delivery as _abstract_:
232
247
 
233
248
  ```ruby
234
- # we don't not want to use ApplicationMailer by default, don't we?
249
+ # we don't want to use ApplicationMailer by default, don't we?
235
250
  class ApplicationDelivery < ActiveDelivery::Base
236
251
  self.abstract_class = true
237
252
  end
238
253
  ```
239
254
 
240
- Final step is to register the line within your delivery class:
255
+ The final step is to register the line within your delivery class:
241
256
 
242
257
  ```ruby
243
258
  class EventDelivery < ActiveDelivery::Base
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
  require "rubocop/rake_task"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  gem "activesupport", "~> 4.2"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  gem "rails", github: "rails/rails"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_delivery/version"
2
4
  require "active_delivery/base"
3
5
  require "active_delivery/callbacks" if defined?(ActiveSupport)
@@ -78,7 +78,7 @@ module ActiveDelivery
78
78
  end
79
79
  end
80
80
 
81
- attr_reader :params
81
+ attr_reader :params, :notification_name
82
82
 
83
83
  def initialize(**params)
84
84
  @params = params
@@ -86,13 +86,9 @@ module ActiveDelivery
86
86
  end
87
87
 
88
88
  # Enqueues delivery (i.e. uses #deliver_later for mailers)
89
- def notify(mid, *args, sync: false)
90
- delivery_lines.each do |type, line|
91
- next if line.handler_class.nil?
92
- next unless line.notify?(mid)
93
-
94
- notify_line(type, mid, *args, params: params, sync: sync)
95
- end
89
+ def notify(mid, *args)
90
+ @notification_name = mid
91
+ do_notify(*args)
96
92
  end
97
93
 
98
94
  # The same as .notify but delivers synchronously
@@ -103,8 +99,17 @@ module ActiveDelivery
103
99
 
104
100
  private
105
101
 
106
- def notify_line(type, mid, *args)
107
- delivery_lines[type].notify(mid, *args)
102
+ def do_notify(*args, sync: false)
103
+ delivery_lines.each do |type, line|
104
+ next if line.handler_class.nil?
105
+ next unless line.notify?(notification_name)
106
+
107
+ notify_line(type, *args, params: params, sync: sync)
108
+ end
109
+ end
110
+
111
+ def notify_line(type, *args)
112
+ delivery_lines[type].notify(notification_name, *args)
108
113
  end
109
114
 
110
115
  def delivery_lines
@@ -41,7 +41,7 @@ module ActiveDelivery
41
41
  end
42
42
 
43
43
  module InstanceExt
44
- def notify(*)
44
+ def do_notify(*)
45
45
  run_callbacks(:notify) { super }
46
46
  end
47
47
 
@@ -64,16 +64,19 @@ module ActiveDelivery
64
64
  skip_after_callbacks_if_terminated: true
65
65
  end
66
66
 
67
- def before_notify(method_name, on: :notify)
68
- set_callback on, :before, method_name
67
+ def before_notify(method_or_block = nil, on: :notify)
68
+ method_or_block ||= Proc.new
69
+ set_callback on, :before, method_or_block
69
70
  end
70
71
 
71
- def after_notify(method_name, on: :notify)
72
- set_callback on, :after, method_name
72
+ def after_notify(method_or_block = nil, on: :notify)
73
+ method_or_block ||= Proc.new
74
+ set_callback on, :after, method_or_block
73
75
  end
74
76
 
75
- def around_notify(method_name, on: :notify)
76
- set_callback on, :around, method_name
77
+ def around_notify(method_or_block = nil, on: :notify)
78
+ method_or_block ||= Proc.new
79
+ set_callback on, :around, method_or_block
77
80
  end
78
81
  end
79
82
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveDelivery
2
4
  module Lines
3
5
  class Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveDelivery
2
4
  module Lines
3
5
  class Mailer < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveDelivery
2
4
  module TestDelivery
3
5
  class << self
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveDelivery
2
4
  class HaveDeliveredTo < RSpec::Matchers::BuiltIn::BaseMatcher
3
5
  attr_reader :delivery_class, :event, :args, :params, :sync_value
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveDelivery
2
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_delivery
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-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -77,6 +77,7 @@ files:
77
77
  - ".rspec"
78
78
  - ".rubocop.yml"
79
79
  - ".travis.yml"
80
+ - CHANGELOG.md
80
81
  - Gemfile
81
82
  - LICENSE.txt
82
83
  - README.md
@@ -114,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
115
  version: '0'
115
116
  requirements: []
116
117
  rubyforge_project:
117
- rubygems_version: 2.7.7
118
+ rubygems_version: 2.7.6
118
119
  signing_key:
119
120
  specification_version: 4
120
121
  summary: Rails framework for managing all types of notifications in one place