|
39 | 39 | { delay: 30.minutes, target: :sms, options: { urgent: true } } |
40 | 40 | ] |
41 | 41 |
|
| 42 | + # Capture the current time for consistent time calculations |
| 43 | + start_time = Time.current |
| 44 | + |
42 | 45 | # Start the cascade |
43 | 46 | expect(@notification.cascade_notify(cascade_config)).to be true |
44 | 47 |
|
45 | 48 | # Verify first job is scheduled |
46 | 49 | expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(1) |
47 | 50 | first_job = ActiveJob::Base.queue_adapter.enqueued_jobs.first |
48 | 51 | expect(first_job[:job]).to eq(ActivityNotification::CascadingNotificationJob) |
49 | | - expect(first_job[:at]).to be_within(1.second).of(5.minutes.from_now) |
| 52 | + expect(first_job[:at]).to be_within(1.second).of(start_time + 5.minutes) |
50 | 53 |
|
51 | 54 | # Simulate time passing and execute first job |
52 | | - travel_to(5.minutes.from_now) do |
| 55 | + travel_to(start_time + 5.minutes) do |
53 | 56 | expect(slack_target).to receive(:notify).with(@notification, { channel: '#general' }) |
54 | 57 |
|
55 | 58 | # Clear queue and perform the job |
|
60 | 63 | # Verify Slack was triggered successfully |
61 | 64 | expect(result).to eq({ slack: :success }) |
62 | 65 |
|
63 | | - # Verify next job was scheduled for email |
| 66 | + # Verify next job was scheduled for email (10 minutes from current travelled time) |
64 | 67 | expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(1) |
65 | 68 | next_job = ActiveJob::Base.queue_adapter.enqueued_jobs.first |
66 | | - expect(next_job[:at]).to be_within(1.second).of(10.minutes.from_now) |
| 69 | + expect(next_job[:at]).to be_within(1.second).of(start_time + 15.minutes) |
67 | 70 | end |
68 | 71 |
|
69 | 72 | # Simulate more time passing and execute second job |
70 | | - travel_to(15.minutes.from_now) do |
| 73 | + travel_to(start_time + 15.minutes) do |
71 | 74 | expect(email_target).to receive(:notify).with(@notification, {}) |
72 | 75 |
|
73 | 76 | # Clear queue and perform the job |
|
78 | 81 | # Verify email was triggered successfully |
79 | 82 | expect(result).to eq({ email: :success }) |
80 | 83 |
|
81 | | - # Verify next job was scheduled for SMS |
| 84 | + # Verify next job was scheduled for SMS (30 minutes from current travelled time) |
82 | 85 | expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(1) |
83 | 86 | next_job = ActiveJob::Base.queue_adapter.enqueued_jobs.first |
84 | | - expect(next_job[:at]).to be_within(1.second).of(30.minutes.from_now) |
| 87 | + expect(next_job[:at]).to be_within(1.second).of(start_time + 45.minutes) |
85 | 88 | end |
86 | 89 |
|
87 | 90 | # Simulate final time passing and execute third job |
88 | | - travel_to(45.minutes.from_now) do |
| 91 | + travel_to(start_time + 45.minutes) do |
89 | 92 | expect(sms_target).to receive(:notify).with(@notification, { urgent: true }) |
90 | 93 |
|
91 | 94 | # Clear queue and perform the job |
|
114 | 117 | { delay: 10.minutes, target: :email } |
115 | 118 | ] |
116 | 119 |
|
| 120 | + start_time = Time.current |
| 121 | + |
117 | 122 | # Start the cascade |
118 | 123 | @notification.cascade_notify(cascade_config) |
119 | 124 |
|
120 | 125 | # Simulate first job execution |
121 | | - travel_to(5.minutes.from_now) do |
| 126 | + travel_to(start_time + 5.minutes) do |
122 | 127 | expect(slack_target).to receive(:notify).with(@notification, {}) |
123 | 128 |
|
124 | 129 | ActiveJob::Base.queue_adapter.enqueued_jobs.clear |
|
130 | 135 | end |
131 | 136 |
|
132 | 137 | # User reads the notification before second job executes |
133 | | - travel_to(10.minutes.from_now) do |
| 138 | + travel_to(start_time + 15.minutes) do |
134 | 139 | @notification.open! |
135 | 140 | expect(@notification.opened?).to be true |
136 | 141 |
|
|
162 | 167 | { delay: 10.minutes, target: :email } |
163 | 168 | ] |
164 | 169 |
|
| 170 | + start_time = Time.current |
| 171 | + |
165 | 172 | @notification.cascade_notify(cascade_config) |
166 | 173 |
|
167 | 174 | # Simulate first job execution with failure |
168 | | - travel_to(5.minutes.from_now) do |
| 175 | + travel_to(start_time + 5.minutes) do |
169 | 176 | ActiveJob::Base.queue_adapter.enqueued_jobs.clear |
170 | 177 | job_instance = ActivityNotification::CascadingNotificationJob.new |
171 | 178 | result = job_instance.perform(@notification.id, cascade_config, 0) |
|
179 | 186 | end |
180 | 187 |
|
181 | 188 | # Simulate second job execution (should succeed) |
182 | | - travel_to(15.minutes.from_now) do |
| 189 | + travel_to(start_time + 15.minutes) do |
183 | 190 | expect(email_target).to receive(:notify).with(@notification, {}) |
184 | 191 |
|
185 | 192 | job_instance = ActivityNotification::CascadingNotificationJob.new |
|
203 | 210 | { delay: 5.minutes, target: :slack } |
204 | 211 | ] |
205 | 212 |
|
| 213 | + start_time = Time.current |
| 214 | + |
206 | 215 | @notification.cascade_notify(cascade_config) |
207 | 216 |
|
208 | 217 | # Simulate job execution |
209 | | - travel_to(5.minutes.from_now) do |
| 218 | + travel_to(start_time + 5.minutes) do |
210 | 219 | job_instance = ActivityNotification::CascadingNotificationJob.new |
211 | 220 | result = job_instance.perform(@notification.id, cascade_config, 0) |
212 | 221 |
|
|
223 | 232 | { delay: 5.minutes, target: :nonexistent_target } |
224 | 233 | ] |
225 | 234 |
|
| 235 | + start_time = Time.current |
| 236 | + |
226 | 237 | @notification.cascade_notify(cascade_config) |
227 | 238 |
|
228 | 239 | # Simulate job execution |
229 | | - travel_to(5.minutes.from_now) do |
| 240 | + travel_to(start_time + 5.minutes) do |
230 | 241 | job_instance = ActivityNotification::CascadingNotificationJob.new |
231 | 242 | result = job_instance.perform(@notification.id, cascade_config, 0) |
232 | 243 |
|
|
254 | 265 | { delay: 10.minutes, target: :email } |
255 | 266 | ] |
256 | 267 |
|
| 268 | + start_time = Time.current |
| 269 | + |
257 | 270 | # Expect immediate execution of first target |
258 | 271 | expect(slack_target).to receive(:notify).with(@notification, {}) |
259 | 272 |
|
|
263 | 276 | # Verify remaining cascade was scheduled |
264 | 277 | expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(1) |
265 | 278 | scheduled_job = ActiveJob::Base.queue_adapter.enqueued_jobs.first |
266 | | - expect(scheduled_job[:at]).to be_within(1.second).of(10.minutes.from_now) |
| 279 | + expect(scheduled_job[:at]).to be_within(1.second).of(start_time + 10.minutes) |
267 | 280 | end |
268 | 281 | end |
269 | 282 |
|
|
273 | 286 | { delay: 5.minutes, target: :slack } |
274 | 287 | ] |
275 | 288 |
|
| 289 | + start_time = Time.current |
| 290 | + |
276 | 291 | @notification.cascade_notify(cascade_config) |
277 | 292 |
|
278 | 293 | # Delete the notification |
279 | 294 | notification_id = @notification.id |
280 | 295 | @notification.destroy |
281 | 296 |
|
282 | 297 | # Simulate job execution with deleted notification |
283 | | - travel_to(5.minutes.from_now) do |
| 298 | + travel_to(start_time + 5.minutes) do |
284 | 299 | job_instance = ActivityNotification::CascadingNotificationJob.new |
285 | 300 | result = job_instance.perform(notification_id, cascade_config, 0) |
286 | 301 |
|
|
299 | 314 | { delay: 5.minutes, target: :slack } |
300 | 315 | ] |
301 | 316 |
|
| 317 | + start_time = Time.current |
| 318 | + |
302 | 319 | @notification.cascade_notify(cascade_config) |
303 | 320 |
|
304 | 321 | # Simulate job execution |
305 | | - travel_to(5.minutes.from_now) do |
| 322 | + travel_to(start_time + 5.minutes) do |
306 | 323 | expect(slack_target).to receive(:notify).with(@notification, {}) |
307 | 324 |
|
308 | 325 | ActiveJob::Base.queue_adapter.enqueued_jobs.clear |
|
0 commit comments