active_delivery 1.1.0 → 1.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +53 -21
- data/lib/.rbnext/3.0/abstract_notifier/async_adapters/active_job.rb +2 -2
- data/lib/.rbnext/3.0/abstract_notifier/base.rb +4 -4
- data/lib/.rbnext/3.0/active_delivery/base.rb +8 -8
- data/lib/.rbnext/3.0/active_delivery/lines/base.rb +4 -4
- data/lib/.rbnext/3.0/active_delivery/testing/minitest.rb +58 -0
- data/lib/.rbnext/3.0/active_delivery/testing.rb +1 -0
- data/lib/.rbnext/3.1/abstract_notifier/async_adapters/active_job.rb +2 -2
- data/lib/.rbnext/3.1/abstract_notifier/base.rb +4 -4
- data/lib/.rbnext/3.1/active_delivery/base.rb +8 -8
- data/lib/.rbnext/3.1/active_delivery/lines/base.rb +4 -4
- data/lib/.rbnext/3.1/active_delivery/testing/minitest.rb +58 -0
- data/lib/.rbnext/3.2/abstract_notifier/async_adapters/active_job.rb +36 -0
- data/lib/.rbnext/3.2/abstract_notifier/base.rb +223 -0
- data/lib/.rbnext/3.2/abstract_notifier/testing/rspec.rb +164 -0
- data/lib/.rbnext/3.2/abstract_notifier/testing.rb +53 -0
- data/lib/.rbnext/3.2/active_delivery/base.rb +249 -0
- data/lib/.rbnext/3.2/active_delivery/lines/base.rb +101 -0
- data/lib/.rbnext/3.2/active_delivery/lines/notifier.rb +57 -0
- data/lib/.rbnext/3.2/active_delivery/testing/rspec.rb +222 -0
- data/lib/abstract_notifier/async_adapters/active_job.rb +2 -2
- data/lib/abstract_notifier/base.rb +4 -4
- data/lib/abstract_notifier/testing/minitest.rb +1 -1
- data/lib/abstract_notifier/testing/rspec.rb +4 -4
- data/lib/abstract_notifier/testing.rb +2 -2
- data/lib/active_delivery/base.rb +8 -8
- data/lib/active_delivery/lines/base.rb +4 -4
- data/lib/active_delivery/lines/notifier.rb +6 -6
- data/lib/active_delivery/testing/minitest.rb +58 -0
- data/lib/active_delivery/testing/rspec.rb +4 -4
- data/lib/active_delivery/testing.rb +1 -0
- data/lib/active_delivery/version.rb +1 -1
- metadata +17 -6
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless "".respond_to?(:safe_constantize)
|
4
|
+
require "active_delivery/ext/string_constantize"
|
5
|
+
using ActiveDelivery::Ext::StringConstantize
|
6
|
+
end
|
7
|
+
|
8
|
+
module ActiveDelivery
|
9
|
+
module Lines
|
10
|
+
class Base
|
11
|
+
attr_reader :id, :options
|
12
|
+
attr_accessor :owner
|
13
|
+
attr_accessor :handler_class_name
|
14
|
+
|
15
|
+
def initialize(id:, owner:, **options)
|
16
|
+
@id = id
|
17
|
+
@owner = owner
|
18
|
+
@options = options.tap(&:freeze)
|
19
|
+
@resolver = options[:resolver] || build_pattern_resolver(options[:resolver_pattern])
|
20
|
+
end
|
21
|
+
|
22
|
+
def dup_for(new_owner)
|
23
|
+
self.class.new(id:, **options, owner: new_owner)
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolve_class(name)
|
27
|
+
resolver&.call(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def notify?(method_name)
|
31
|
+
handler_class&.respond_to?(method_name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def notify_now(handler, mid, ...)
|
35
|
+
end
|
36
|
+
|
37
|
+
def notify_later(handler, mid, ...)
|
38
|
+
end
|
39
|
+
|
40
|
+
def notify_later_with_options(handler, enqueue_options, mid, ...)
|
41
|
+
notify_later(handler, mid, ...)
|
42
|
+
end
|
43
|
+
|
44
|
+
def notify(mid, *__rest__, params:, sync:, enqueue_options:, **__kwrest__)
|
45
|
+
clazz = params.empty? ? handler_class : handler_class.with(**params)
|
46
|
+
if sync
|
47
|
+
return notify_now(clazz, mid, *__rest__, **__kwrest__)
|
48
|
+
end
|
49
|
+
|
50
|
+
if enqueue_options.empty?
|
51
|
+
notify_later(clazz, mid, *__rest__, **__kwrest__)
|
52
|
+
else
|
53
|
+
notify_later_with_options(clazz, enqueue_options, mid, *__rest__, **__kwrest__)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def handler_class
|
58
|
+
if ::ActiveDelivery.cache_classes
|
59
|
+
return @handler_class if instance_variable_defined?(:@handler_class)
|
60
|
+
end
|
61
|
+
|
62
|
+
return @handler_class = nil if owner.abstract_class?
|
63
|
+
|
64
|
+
superline = owner.superclass.delivery_lines[id] if owner.superclass.respond_to?(:delivery_lines) && owner.superclass.delivery_lines[id]
|
65
|
+
|
66
|
+
# If an explicit class name has been specified somewhere in the ancestor chain, use it.
|
67
|
+
class_name = @handler_class_name || superline&.handler_class_name
|
68
|
+
|
69
|
+
@handler_class =
|
70
|
+
if class_name
|
71
|
+
class_name.is_a?(Class) ? class_name : class_name.safe_constantize
|
72
|
+
else
|
73
|
+
resolve_class(owner) || superline&.handler_class
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
attr_reader :resolver
|
80
|
+
|
81
|
+
def build_pattern_resolver(pattern)
|
82
|
+
return unless pattern
|
83
|
+
|
84
|
+
proc do |delivery|
|
85
|
+
delivery_class = delivery.name
|
86
|
+
|
87
|
+
next unless delivery_class
|
88
|
+
|
89
|
+
*namespace, delivery_name = delivery_class.split("::")
|
90
|
+
|
91
|
+
delivery_namespace = ""
|
92
|
+
delivery_namespace = "#{namespace.join("::")}::" unless namespace.empty?
|
93
|
+
|
94
|
+
delivery_name = delivery_name.sub(/Delivery$/, "")
|
95
|
+
|
96
|
+
(pattern % {delivery_class:, delivery_name:, delivery_namespace:}).safe_constantize
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless "".respond_to?(:safe_constantize)
|
4
|
+
require "active_delivery/ext/string_constantize"
|
5
|
+
using ActiveDelivery::Ext::StringConstantize
|
6
|
+
end
|
7
|
+
|
8
|
+
module ActiveDelivery
|
9
|
+
module Lines
|
10
|
+
# AbstractNotifier line for Active Delivery.
|
11
|
+
#
|
12
|
+
# You must provide custom `resolver` to infer notifier class
|
13
|
+
# (if String#safe_constantize is defined, we convert "*Delivery" -> "*Notifier").
|
14
|
+
#
|
15
|
+
# Resolver is a callable object.
|
16
|
+
class Notifier < ActiveDelivery::Lines::Base
|
17
|
+
DEFAULT_SUFFIX = "Notifier"
|
18
|
+
|
19
|
+
def initialize(**opts)
|
20
|
+
super
|
21
|
+
@resolver ||= build_resolver(options.fetch(:suffix, DEFAULT_SUFFIX))
|
22
|
+
end
|
23
|
+
|
24
|
+
def resolve_class(klass)
|
25
|
+
resolver&.call(klass)
|
26
|
+
end
|
27
|
+
|
28
|
+
def notify?(method_name)
|
29
|
+
return unless handler_class
|
30
|
+
handler_class.action_methods.include?(method_name.to_s)
|
31
|
+
end
|
32
|
+
|
33
|
+
def notify_now(handler, mid, *__rest__)
|
34
|
+
handler.public_send(mid, *__rest__).notify_now
|
35
|
+
end
|
36
|
+
|
37
|
+
def notify_later(handler, mid, *__rest__)
|
38
|
+
handler.public_send(mid, *__rest__).notify_later
|
39
|
+
end
|
40
|
+
|
41
|
+
def notify_later_with_options(handler, enqueue_options, mid, *__rest__)
|
42
|
+
handler.public_send(mid, *__rest__).notify_later(**enqueue_options)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :resolver
|
48
|
+
|
49
|
+
def build_resolver(suffix)
|
50
|
+
lambda do |klass|
|
51
|
+
klass_name = klass.name
|
52
|
+
klass_name&.sub(/Delivery\z/, suffix)&.safe_constantize
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveDelivery
|
4
|
+
class HaveDeliveredTo < RSpec::Matchers::BuiltIn::BaseMatcher
|
5
|
+
attr_reader :delivery_class, :event, :args, :kwargs, :params, :sync_value
|
6
|
+
|
7
|
+
def initialize(delivery_class, event = nil, *args, **kwargs)
|
8
|
+
@delivery_class = delivery_class
|
9
|
+
@event = event
|
10
|
+
@args = args
|
11
|
+
@kwargs = kwargs
|
12
|
+
set_expected_number(:exactly, 1)
|
13
|
+
end
|
14
|
+
|
15
|
+
def with(params)
|
16
|
+
@params = params
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def synchronously
|
21
|
+
@sync_value = true
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def exactly(count)
|
26
|
+
set_expected_number(:exactly, count)
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def at_least(count)
|
31
|
+
set_expected_number(:at_least, count)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def at_most(count)
|
36
|
+
set_expected_number(:at_most, count)
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def times
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def once
|
45
|
+
exactly(:once)
|
46
|
+
end
|
47
|
+
|
48
|
+
def twice
|
49
|
+
exactly(:twice)
|
50
|
+
end
|
51
|
+
|
52
|
+
def thrice
|
53
|
+
exactly(:thrice)
|
54
|
+
end
|
55
|
+
|
56
|
+
def supports_block_expectations?
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
def matches?(proc)
|
61
|
+
raise ArgumentError, "have_delivered_to only supports block expectations" unless Proc === proc
|
62
|
+
|
63
|
+
TestDelivery.enable { proc.call }
|
64
|
+
|
65
|
+
actual_deliveries = TestDelivery.store
|
66
|
+
|
67
|
+
@matching_deliveries, @unmatching_deliveries =
|
68
|
+
actual_deliveries.partition do |(delivery, options)|
|
69
|
+
next false unless delivery_class == delivery.owner.class
|
70
|
+
|
71
|
+
next false if !sync_value.nil? && (options.fetch(:sync, false) != sync_value)
|
72
|
+
|
73
|
+
next false unless params.nil? || params === delivery.owner.params
|
74
|
+
|
75
|
+
next false unless event.nil? || event == delivery.notification
|
76
|
+
|
77
|
+
actual_args = delivery.params
|
78
|
+
actual_kwargs = delivery.options
|
79
|
+
|
80
|
+
next false unless args.each.with_index.all? do |arg, i|
|
81
|
+
arg === actual_args[i]
|
82
|
+
end
|
83
|
+
|
84
|
+
next false unless kwargs.all? do |k, v|
|
85
|
+
v === actual_kwargs[k]
|
86
|
+
end
|
87
|
+
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
@matching_count = @matching_deliveries.size
|
92
|
+
|
93
|
+
case @expectation_type
|
94
|
+
when :exactly then @expected_number == @matching_count
|
95
|
+
when :at_most then @expected_number >= @matching_count
|
96
|
+
when :at_least then @expected_number <= @matching_count
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def failure_message
|
101
|
+
(+"expected to deliver").tap do |msg|
|
102
|
+
msg << " :#{event} notification" if event
|
103
|
+
msg << " via #{delivery_class}#{sync_value ? " (sync)" : ""} with:"
|
104
|
+
msg << "\n - params: #{params_description(params)}" if params
|
105
|
+
msg << "\n - args: #{args.empty? ? "<none>" : args}"
|
106
|
+
msg << "\n#{message_expectation_modifier}, but"
|
107
|
+
|
108
|
+
if @unmatching_deliveries.any?
|
109
|
+
msg << " delivered the following unexpected notifications:"
|
110
|
+
msg << deliveries_description(@unmatching_deliveries)
|
111
|
+
elsif @matching_count.positive?
|
112
|
+
msg << " delivered #{@matching_count} matching notifications" \
|
113
|
+
" (#{count_failure_message}):"
|
114
|
+
msg << deliveries_description(@matching_deliveries)
|
115
|
+
else
|
116
|
+
msg << " haven't delivered anything"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def set_expected_number(relativity, count)
|
124
|
+
@expectation_type = relativity
|
125
|
+
@expected_number =
|
126
|
+
case count
|
127
|
+
when :once then 1
|
128
|
+
when :twice then 2
|
129
|
+
when :thrice then 3
|
130
|
+
else Integer(count)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def failure_message_when_negated
|
135
|
+
"expected not to deliver #{event ? " :#{event} notification" : ""} via #{delivery_class}"
|
136
|
+
end
|
137
|
+
|
138
|
+
def message_expectation_modifier
|
139
|
+
number_modifier = (@expected_number == 1) ? "once" : "#{@expected_number} times"
|
140
|
+
case @expectation_type
|
141
|
+
when :exactly then "exactly #{number_modifier}"
|
142
|
+
when :at_most then "at most #{number_modifier}"
|
143
|
+
when :at_least then "at least #{number_modifier}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def count_failure_message
|
148
|
+
diff = @matching_count - @expected_number
|
149
|
+
if diff.positive?
|
150
|
+
"#{diff} extra item(s)"
|
151
|
+
else
|
152
|
+
"#{diff} missing item(s)"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def deliveries_description(deliveries)
|
157
|
+
deliveries.each.with_object(+"") do |(delivery, options), msg|
|
158
|
+
msg << "\n :#{delivery.notification} via #{delivery.owner.class}" \
|
159
|
+
"#{options[:sync] ? " (sync)" : ""}" \
|
160
|
+
" with:" \
|
161
|
+
"\n - params: #{delivery.owner.params.empty? ? "<none>" : delivery.owner.params.inspect}" \
|
162
|
+
"\n - args: #{delivery.params}" \
|
163
|
+
"\n - kwargs: #{delivery.options}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def params_description(data)
|
168
|
+
if data.is_a?(RSpec::Matchers::Composable)
|
169
|
+
data.description
|
170
|
+
else
|
171
|
+
data
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
class DeliverVia < RSpec::Matchers::BuiltIn::BaseMatcher
|
177
|
+
attr_reader :lines
|
178
|
+
|
179
|
+
def initialize(*lines)
|
180
|
+
@actual_lines = []
|
181
|
+
@lines = lines.sort
|
182
|
+
end
|
183
|
+
|
184
|
+
def supports_block_expectations?
|
185
|
+
true
|
186
|
+
end
|
187
|
+
|
188
|
+
def matches?(proc)
|
189
|
+
raise ArgumentError, "deliver_via only supports block expectations" unless Proc === proc
|
190
|
+
|
191
|
+
TestDelivery.lines.clear
|
192
|
+
|
193
|
+
proc.call
|
194
|
+
|
195
|
+
@actual_lines = TestDelivery.lines.sort
|
196
|
+
|
197
|
+
lines == @actual_lines
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def failure_message
|
203
|
+
"expected to deliver via #{lines.join(", ")} lines, but delivered to #{@actual_lines.any? ? @actual_lines.join(", ") : "none"}"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
RSpec.configure do |config|
|
209
|
+
config.include(Module.new do
|
210
|
+
def have_delivered_to(*__rest__)
|
211
|
+
ActiveDelivery::HaveDeliveredTo.new(*__rest__)
|
212
|
+
end
|
213
|
+
end)
|
214
|
+
|
215
|
+
config.include(Module.new do
|
216
|
+
def deliver_via(*__rest__)
|
217
|
+
ActiveDelivery::DeliverVia.new(*__rest__)
|
218
|
+
end
|
219
|
+
end, type: :delivery)
|
220
|
+
end
|
221
|
+
|
222
|
+
RSpec::Matchers.define_negated_matcher :have_not_delivered_to, :have_delivered_to
|
@@ -22,8 +22,8 @@ module AbstractNotifier
|
|
22
22
|
job.set(queue:).perform_later(...)
|
23
23
|
end
|
24
24
|
|
25
|
-
def enqueue_delivery(delivery, **
|
26
|
-
job.set(queue:, **
|
25
|
+
def enqueue_delivery(delivery, **)
|
26
|
+
job.set(queue:, **).perform_later(
|
27
27
|
delivery.notifier_class.name,
|
28
28
|
delivery.action_name,
|
29
29
|
**delivery.delivery_params
|
@@ -23,9 +23,9 @@ module AbstractNotifier
|
|
23
23
|
|
24
24
|
alias_method :notification, :processed
|
25
25
|
|
26
|
-
def notify_later(**
|
26
|
+
def notify_later(**)
|
27
27
|
if notifier_class.async_adapter.respond_to?(:enqueue_delivery)
|
28
|
-
notifier_class.async_adapter.enqueue_delivery(self, **
|
28
|
+
notifier_class.async_adapter.enqueue_delivery(self, **)
|
29
29
|
else
|
30
30
|
notifier_class.async_adapter.enqueue(notifier_class.name, action_name, params:, args:, kwargs:)
|
31
31
|
end
|
@@ -73,8 +73,8 @@ module AbstractNotifier
|
|
73
73
|
end
|
74
74
|
# rubocop:enable Style/MethodMissingSuper
|
75
75
|
|
76
|
-
def respond_to_missing?(*
|
77
|
-
notifier_class.respond_to_missing?(*
|
76
|
+
def respond_to_missing?(*)
|
77
|
+
notifier_class.respond_to_missing?(*)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -19,7 +19,7 @@ module AbstractNotifier
|
|
19
19
|
|
20
20
|
def assert_notifications_enqueued(count, params)
|
21
21
|
yield
|
22
|
-
assert_equal
|
22
|
+
assert_equal count, enqueued_deliveries.count
|
23
23
|
count.times do |i|
|
24
24
|
delivery = enqueued_deliveries[0 - i]
|
25
25
|
if !params[:via]
|
@@ -153,12 +153,12 @@ end
|
|
153
153
|
|
154
154
|
RSpec.configure do |config|
|
155
155
|
config.include(Module.new do
|
156
|
-
def have_sent_notification(*
|
157
|
-
AbstractNotifier::HaveSentNotification.new(*
|
156
|
+
def have_sent_notification(*)
|
157
|
+
AbstractNotifier::HaveSentNotification.new(*)
|
158
158
|
end
|
159
159
|
|
160
|
-
def have_enqueued_notification(*
|
161
|
-
AbstractNotifier::HaveEnqueuedNotification.new(*
|
160
|
+
def have_enqueued_notification(*)
|
161
|
+
AbstractNotifier::HaveEnqueuedNotification.new(*)
|
162
162
|
end
|
163
163
|
end)
|
164
164
|
end
|
@@ -36,12 +36,12 @@ module AbstractNotifier
|
|
36
36
|
Driver.send_notification payload.merge(via: notifier.class)
|
37
37
|
end
|
38
38
|
|
39
|
-
def notify_later(**
|
39
|
+
def notify_later(**)
|
40
40
|
return super unless AbstractNotifier.test?
|
41
41
|
|
42
42
|
payload = notification.payload
|
43
43
|
|
44
|
-
Driver.enqueue_notification payload.merge(via: notifier.class, **
|
44
|
+
Driver.enqueue_notification payload.merge(via: notifier.class, **)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
data/lib/active_delivery/base.rb
CHANGED
@@ -77,8 +77,8 @@ module ActiveDelivery
|
|
77
77
|
|
78
78
|
# The same as .notify but delivers synchronously
|
79
79
|
# (i.e. #deliver_now for mailers)
|
80
|
-
def notify!(mid,
|
81
|
-
notify(mid,
|
80
|
+
def notify!(mid, *, **hargs)
|
81
|
+
notify(mid, *, **hargs, sync: true)
|
82
82
|
end
|
83
83
|
|
84
84
|
alias_method :notify_now, :notify!
|
@@ -93,7 +93,7 @@ module ActiveDelivery
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
def register_line(line_id, line_class = nil, notifier: nil, **
|
96
|
+
def register_line(line_id, line_class = nil, notifier: nil, **)
|
97
97
|
raise ArgumentError, "A line class or notifier configuration must be provided" if line_class.nil? && notifier.nil?
|
98
98
|
|
99
99
|
# Configure Notifier
|
@@ -101,7 +101,7 @@ module ActiveDelivery
|
|
101
101
|
line_class = ActiveDelivery::Lines::Notifier
|
102
102
|
end
|
103
103
|
|
104
|
-
delivery_lines[line_id] = line_class.new(id: line_id, owner: self, **
|
104
|
+
delivery_lines[line_id] = line_class.new(id: line_id, owner: self, **)
|
105
105
|
|
106
106
|
instance_eval <<~CODE, __FILE__, __LINE__ + 1
|
107
107
|
def #{line_id}(val)
|
@@ -152,13 +152,13 @@ module ActiveDelivery
|
|
152
152
|
super
|
153
153
|
end
|
154
154
|
|
155
|
-
def method_missing(mid,
|
155
|
+
def method_missing(mid, *, **)
|
156
156
|
return super unless respond_to_missing?(mid)
|
157
157
|
|
158
158
|
# Lazily define a class method to avoid lookups
|
159
159
|
delivers(mid)
|
160
160
|
|
161
|
-
public_send(mid,
|
161
|
+
public_send(mid, *, **)
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
@@ -197,7 +197,7 @@ module ActiveDelivery
|
|
197
197
|
super
|
198
198
|
end
|
199
199
|
|
200
|
-
def method_missing(mid,
|
200
|
+
def method_missing(mid, *, **)
|
201
201
|
return super unless respond_to_missing?(mid)
|
202
202
|
|
203
203
|
# Lazily define a method to avoid future lookups
|
@@ -211,7 +211,7 @@ module ActiveDelivery
|
|
211
211
|
end
|
212
212
|
CODE
|
213
213
|
|
214
|
-
public_send(mid,
|
214
|
+
public_send(mid, *, **)
|
215
215
|
end
|
216
216
|
|
217
217
|
protected
|
@@ -41,16 +41,16 @@ module ActiveDelivery
|
|
41
41
|
notify_later(handler, mid, ...)
|
42
42
|
end
|
43
43
|
|
44
|
-
def notify(mid,
|
44
|
+
def notify(mid, *, params:, sync:, enqueue_options:, **)
|
45
45
|
clazz = params.empty? ? handler_class : handler_class.with(**params)
|
46
46
|
if sync
|
47
|
-
return notify_now(clazz, mid,
|
47
|
+
return notify_now(clazz, mid, *, **)
|
48
48
|
end
|
49
49
|
|
50
50
|
if enqueue_options.empty?
|
51
|
-
notify_later(clazz, mid,
|
51
|
+
notify_later(clazz, mid, *, **)
|
52
52
|
else
|
53
|
-
notify_later_with_options(clazz, enqueue_options, mid,
|
53
|
+
notify_later_with_options(clazz, enqueue_options, mid, *, **)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -30,16 +30,16 @@ module ActiveDelivery
|
|
30
30
|
handler_class.action_methods.include?(method_name.to_s)
|
31
31
|
end
|
32
32
|
|
33
|
-
def notify_now(handler, mid, *
|
34
|
-
handler.public_send(mid, *
|
33
|
+
def notify_now(handler, mid, *)
|
34
|
+
handler.public_send(mid, *).notify_now
|
35
35
|
end
|
36
36
|
|
37
|
-
def notify_later(handler, mid, *
|
38
|
-
handler.public_send(mid, *
|
37
|
+
def notify_later(handler, mid, *)
|
38
|
+
handler.public_send(mid, *).notify_later
|
39
39
|
end
|
40
40
|
|
41
|
-
def notify_later_with_options(handler, enqueue_options, mid, *
|
42
|
-
handler.public_send(mid, *
|
41
|
+
def notify_later_with_options(handler, enqueue_options, mid, *)
|
42
|
+
handler.public_send(mid, *).notify_later(**enqueue_options)
|
43
43
|
end
|
44
44
|
|
45
45
|
private
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveDelivery
|
4
|
+
module TestHelper
|
5
|
+
def assert_deliveries(count)
|
6
|
+
TestDelivery.enable { yield }
|
7
|
+
|
8
|
+
assert_equal TestDelivery.store.count, count, "Expected #{count} deliveries, got #{TestDelivery.store.count}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def assert_no_deliveries(&) = assert_deliveries(0, &)
|
12
|
+
|
13
|
+
def assert_delivery_enqueued(delivery_class, event, count: 1, params: nil, with: nil)
|
14
|
+
TestDelivery.enable { yield }
|
15
|
+
|
16
|
+
deliveries = TestDelivery.store
|
17
|
+
|
18
|
+
if with
|
19
|
+
args = with
|
20
|
+
kwargs = args.pop if args.last.is_a?(Hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
matching_deliveries, _unmatching_deliveries =
|
24
|
+
deliveries.partition do |(delivery, options)|
|
25
|
+
next false if delivery_class != delivery.owner.class
|
26
|
+
|
27
|
+
next false if event != delivery.notification
|
28
|
+
|
29
|
+
next false if params && !hash_include?(delivery.owner.params, params)
|
30
|
+
|
31
|
+
next true unless with
|
32
|
+
|
33
|
+
actual_args = delivery.params
|
34
|
+
actual_kwargs = delivery.options
|
35
|
+
|
36
|
+
next false unless args.each.with_index.all? do |arg, i|
|
37
|
+
arg === actual_args[i]
|
38
|
+
end
|
39
|
+
|
40
|
+
next false unless kwargs.all? do |k, v|
|
41
|
+
v === actual_kwargs[k]
|
42
|
+
end
|
43
|
+
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
assert_equal count, matching_deliveries.count, "Expected #{count} deliveries, got #{deliveries.count}"
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def hash_include?(haystack, needle)
|
53
|
+
needle.all? do |k, v|
|
54
|
+
haystack.key?(k) && haystack[k] == v
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -207,14 +207,14 @@ end
|
|
207
207
|
|
208
208
|
RSpec.configure do |config|
|
209
209
|
config.include(Module.new do
|
210
|
-
def have_delivered_to(*
|
211
|
-
ActiveDelivery::HaveDeliveredTo.new(*
|
210
|
+
def have_delivered_to(*)
|
211
|
+
ActiveDelivery::HaveDeliveredTo.new(*)
|
212
212
|
end
|
213
213
|
end)
|
214
214
|
|
215
215
|
config.include(Module.new do
|
216
|
-
def deliver_via(*
|
217
|
-
ActiveDelivery::DeliverVia.new(*
|
216
|
+
def deliver_via(*)
|
217
|
+
ActiveDelivery::DeliverVia.new(*)
|
218
218
|
end
|
219
219
|
end, type: :delivery)
|
220
220
|
end
|