active_delivery 0.2.1 → 0.3.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: 9cedb82b0e98de0ae19e5035da765b9ccdac620a1d06a278b078bd5154931f47
4
- data.tar.gz: 29f91381de756f4b4ae8d67a4cc86e060fab9401c2f47926b4e9a3ad396301c3
3
+ metadata.gz: b0f3637c02e517255d0d91c59b1dd3abf61f6ffd1aaf34f28723a3be0e3209cf
4
+ data.tar.gz: 48bd825dab16b2937d6275ff21ec04868a5a97bd3b98cfcc9a297bfc6c064d76
5
5
  SHA512:
6
- metadata.gz: 1b0c9deef2835eddf0513893908c3a97320e4b883b3a3b96dde6026a7c96b4eb3330ec58ff6d294c3b319a3af09192d6f317af511a7ba171343847146898bad4
7
- data.tar.gz: f13926f59dc414091d36b3a7b8fd238e1119fcc1a4da8b4c4070b0819b2c3015ff247d70bc663f653dcf85c4472bbd00069fb7a363fbf9488097eec9b9f22cc7
6
+ metadata.gz: 5284e71b7e9e84747f71bf78476536c50e16e912959fd0c2f97c9a533f86e4a589c47766f09890324459003b36113f677461c8a1e406c58e1b4263c2fcf71f21
7
+ data.tar.gz: 4d14d2914d4beec54d73cf9c08a4342b6775ee4941530394cd827d09ae4f7dfbd5f28c659e4c76be2dc193697e4d6ea3d86ca6956c2d7dfc241103b5558ff0fe
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.3.0 (2019-12-25)
6
+
7
+ - Add support of :only, :except params for callbacks. ([@curpeng][])
8
+
9
+ - Add negation rspec matcher: `have_not_delivered_to`. ([@StanisLove][])
10
+
11
+ - Improve RSpec matcher's failure message. ([@iBublik][])
12
+
5
13
  ## 0.2.1 (2018-01-15)
6
14
 
7
15
  - Backport `ActionMailer::Paremeterized` for Rails <5. ([@palkan][])
@@ -17,3 +25,4 @@
17
25
  Initial version.
18
26
 
19
27
  [@palkan]: https://github.com/palkan
28
+ [@curpeng]: https://github.com/curpeng
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Framework providing an entry point (single _interface_) for all types of notifications: mailers, push notifications, whatever you want.
7
7
 
8
- 📖 Read the introduction post: ["Crafting user notifications in Rails with Active Delivery"](https://dev.to/evilmartians/crafting-user-notifications-in-rails-with-active-delivery-5cn6")
8
+ 📖 Read the introduction post: ["Crafting user notifications in Rails with Active Delivery"](https://evilmartians.com/chronicles/crafting-user-notifications-in-rails-with-active-delivery)
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>
@@ -109,9 +109,15 @@ See [Rails docs](https://api.rubyonrails.org/classes/ActionMailer/Parameterized.
109
109
  # NOTE: when `false` is returned the execution is halted
110
110
  before_notify :do_something
111
111
 
112
- # You can specify a notification method (to run callback only for that method)
112
+ # You can specify a notification line (to run callback only for that line)
113
113
  before_notify :do_mail_something, on: :mailer
114
114
 
115
+ # You can specify a notification name (to run callback only for specific notification)
116
+ after_notify :mark_user_as_notified, only: %i[user_reminder]
117
+
118
+ # if and unless options are also at your disposal
119
+ after_notify :mark_user_as_notified, if: -> { params[:user].present? }
120
+
115
121
  # after_ and around_ callbacks are also supported
116
122
  after_notify :cleanup
117
123
 
@@ -158,7 +164,7 @@ it "delivers to RSVPed members via .notify" do
158
164
  end
159
165
  ```
160
166
 
161
- If you want to test that no notification is delivered you can use negation:
167
+ If you want to test that no notification is delivered you can use negation
162
168
 
163
169
  ```ruby
164
170
  specify "when event is not found" do
@@ -168,6 +174,16 @@ specify "when event is not found" do
168
174
  end
169
175
  ```
170
176
 
177
+ or use matcher
178
+
179
+ ```ruby
180
+ specify "when event is not found" do
181
+ expect do
182
+ described_class.perform_now(profile.id, "123", "one_hour_before")
183
+ end.to have_not_delivered_to(Community::EventsDelivery)
184
+ end
185
+ ```
186
+
171
187
  *NOTE:** test mode activated automatically if `RAILS_ENV` or `RACK_ENV` env variable is equal to "test". Otherwise add `require "active_delivery/testing"` to your `spec_helper.rb` / `rails_helper.rb` manually.
172
188
 
173
189
  ## Custom "lines"
@@ -190,7 +206,7 @@ class EventPigeon
190
206
 
191
207
  # delegate delivery action to the instance
192
208
  def message_arrived(*args)
193
- new.message_arrived(*arsg)
209
+ new.message_arrived(*args)
194
210
  end
195
211
  end
196
212
 
@@ -204,7 +220,7 @@ class EventPigeon
204
220
  end
205
221
  ```
206
222
 
207
- Now we want to add a _pigeon_ line to our `EventDelivery,` that is we want to send pigeons when
223
+ Now we want to add a _pigeon_ line to our `EventDelivery,` that is we want to send pigeons when
208
224
  we call `EventDelivery.notify(:message_arrived, "ping-pong!")`.
209
225
 
210
226
  Line class has the following API:
@@ -220,7 +236,7 @@ class PigeonLine < ActiveDelivery::Lines::Base
220
236
 
221
237
  # This method should return true if the sender recognizes the delivery action
222
238
  def notify?(delivery_action)
223
- # `handler_class` is available within the line instance
239
+ # `handler_class` is available within the line instance
224
240
  sender_class.respond_to?(delivery_action)
225
241
  end
226
242
 
@@ -261,7 +277,7 @@ class EventDelivery < ActiveDelivery::Base
261
277
  # under the hood a new instance of PigeonLine is created
262
278
  # and used to send pigeons!
263
279
  register_line :pigeon, PigeonLine
264
-
280
+
265
281
  # you can pass additional options to customize your line
266
282
  # (and use multiple pigeons lines with different configuration)
267
283
  #
@@ -271,7 +287,7 @@ class EventDelivery < ActiveDelivery::Base
271
287
  # pigeon MyCustomPigeon
272
288
  #
273
289
  # or define pigeon specific callbacks
274
- #
290
+ #
275
291
  # before_notify :ensure_pigeon_is_not_dead, on: :pigeon
276
292
  end
277
293
  ```
@@ -17,6 +17,14 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.required_ruby_version = ">= 2.4"
19
19
 
20
+ spec.metadata = {
21
+ "bug_tracker_uri" => "http://github.com/palkan/active_delivery/issues",
22
+ "changelog_uri" => "https://github.com/palkan/active_delivery/blob/master/CHANGELOG.md",
23
+ "documentation_uri" => "http://github.com/palkan/active_delivery",
24
+ "homepage_uri" => "http://github.com/palkan/active_delivery",
25
+ "source_code_uri" => "http://github.com/palkan/active_delivery"
26
+ }
27
+
20
28
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
29
  spec.require_paths = ["lib"]
22
30
 
@@ -58,25 +58,41 @@ module ActiveDelivery
58
58
  end
59
59
 
60
60
  class_methods do
61
+ def _normalize_callback_options(options)
62
+ _normalize_callback_option(options, :only, :if)
63
+ _normalize_callback_option(options, :except, :unless)
64
+ end
65
+
66
+ def _normalize_callback_option(options, from, to)
67
+ if (from = options[from])
68
+ from_set = Array(from).map(&:to_s).to_set
69
+ from = proc { |c| from_set.include? c.notification_name.to_s }
70
+ options[to] = Array(options[to]).unshift(from)
71
+ end
72
+ end
73
+
61
74
  def define_line_callbacks(name)
62
75
  define_callbacks name,
63
76
  terminator: CALLBACK_TERMINATOR,
64
77
  skip_after_callbacks_if_terminated: true
65
78
  end
66
79
 
67
- def before_notify(method_or_block = nil, on: :notify)
80
+ def before_notify(method_or_block = nil, on: :notify, **options)
68
81
  method_or_block ||= Proc.new
69
- set_callback on, :before, method_or_block
82
+ _normalize_callback_options(options)
83
+ set_callback on, :before, method_or_block, options
70
84
  end
71
85
 
72
- def after_notify(method_or_block = nil, on: :notify)
86
+ def after_notify(method_or_block = nil, on: :notify, **options)
73
87
  method_or_block ||= Proc.new
74
- set_callback on, :after, method_or_block
88
+ _normalize_callback_options(options)
89
+ set_callback on, :after, method_or_block, options
75
90
  end
76
91
 
77
- def around_notify(method_or_block = nil, on: :notify)
92
+ def around_notify(method_or_block = nil, on: :notify, **options)
78
93
  method_or_block ||= Proc.new
79
- set_callback on, :around, method_or_block
94
+ _normalize_callback_options(options)
95
+ set_callback on, :around, method_or_block, options
80
96
  end
81
97
  end
82
98
  end
@@ -41,7 +41,7 @@ module ActiveDelivery
41
41
  return @handler_class = nil if owner.abstract_class?
42
42
 
43
43
  @handler_class = resolve_class(owner.name) ||
44
- superclass_handler
44
+ superclass_handler
45
45
  end
46
46
 
47
47
  private
@@ -97,14 +97,12 @@ module ActiveDelivery
97
97
  msg << "\n#{message_expectation_modifier}, but"
98
98
 
99
99
  if @unmatching_deliveries.any?
100
- msg << " delivered the following notifications:"
101
- @unmatching_deliveries.each do |(delivery, event, args, options)|
102
- msg << "\n :#{event} via #{delivery.class}" \
103
- "#{options[:sync] ? " (sync)" : ""}" \
104
- " with:" \
105
- "\n - params: #{delivery.params.empty? ? "<none>" : delivery.params.to_s}" \
106
- "\n - args: #{args}"
107
- end
100
+ msg << " delivered the following unexpected notifications:"
101
+ msg << deliveries_description(@unmatching_deliveries)
102
+ elsif @matching_count.positive?
103
+ msg << " delivered #{@matching_count} matching notifications" \
104
+ " (#{count_failure_message}):"
105
+ msg << deliveries_description(@matching_deliveries)
108
106
  else
109
107
  msg << " haven't delivered anything"
110
108
  end
@@ -137,6 +135,25 @@ module ActiveDelivery
137
135
  end
138
136
  end
139
137
 
138
+ def count_failure_message
139
+ diff = @matching_count - @expected_number
140
+ if diff.positive?
141
+ "#{diff} extra item(s)"
142
+ else
143
+ "#{diff} missing item(s)"
144
+ end
145
+ end
146
+
147
+ def deliveries_description(deliveries)
148
+ deliveries.each.with_object(+"") do |(delivery, event, args, options), msg|
149
+ msg << "\n :#{event} via #{delivery.class}" \
150
+ "#{options[:sync] ? " (sync)" : ""}" \
151
+ " with:" \
152
+ "\n - params: #{delivery.params.empty? ? "<none>" : delivery.params.to_s}" \
153
+ "\n - args: #{args}"
154
+ end
155
+ end
156
+
140
157
  def params_description(data)
141
158
  if data.is_a?(RSpec::Matchers::Composable)
142
159
  data.description
@@ -154,3 +171,5 @@ RSpec.configure do |config|
154
171
  end
155
172
  end)
156
173
  end
174
+
175
+ RSpec::Matchers.define_negated_matcher :have_not_delivered_to, :have_delivered_to
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveDelivery
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
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.2.1
4
+ version: 0.3.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: 2019-01-15 00:00:00.000000000 Z
11
+ date: 2019-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -99,7 +99,12 @@ files:
99
99
  homepage: https://github.com/palkan/active_delivery
100
100
  licenses:
101
101
  - MIT
102
- metadata: {}
102
+ metadata:
103
+ bug_tracker_uri: http://github.com/palkan/active_delivery/issues
104
+ changelog_uri: https://github.com/palkan/active_delivery/blob/master/CHANGELOG.md
105
+ documentation_uri: http://github.com/palkan/active_delivery
106
+ homepage_uri: http://github.com/palkan/active_delivery
107
+ source_code_uri: http://github.com/palkan/active_delivery
103
108
  post_install_message:
104
109
  rdoc_options: []
105
110
  require_paths:
@@ -115,8 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
120
  - !ruby/object:Gem::Version
116
121
  version: '0'
117
122
  requirements: []
118
- rubyforge_project:
119
- rubygems_version: 2.7.6
123
+ rubygems_version: 3.0.3
120
124
  signing_key:
121
125
  specification_version: 4
122
126
  summary: Rails framework for managing all types of notifications in one place