active_delivery 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: 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