triggerable 0.1.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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +89 -0
  8. data/Rakefile +6 -0
  9. data/lib/triggerable.rb +78 -0
  10. data/lib/triggerable/actions.rb +27 -0
  11. data/lib/triggerable/conditions/condition.rb +42 -0
  12. data/lib/triggerable/conditions/field/exists.rb +12 -0
  13. data/lib/triggerable/conditions/field/field_condition.rb +29 -0
  14. data/lib/triggerable/conditions/field/in.rb +17 -0
  15. data/lib/triggerable/conditions/field/or_equal_to.rb +15 -0
  16. data/lib/triggerable/conditions/lambda_condition.rb +12 -0
  17. data/lib/triggerable/conditions/method_condition.rb +11 -0
  18. data/lib/triggerable/conditions/predicate/and.rb +7 -0
  19. data/lib/triggerable/conditions/predicate/or.rb +7 -0
  20. data/lib/triggerable/conditions/predicate/predicate_condition.rb +46 -0
  21. data/lib/triggerable/conditions/schedule/after.rb +28 -0
  22. data/lib/triggerable/conditions/schedule/before.rb +35 -0
  23. data/lib/triggerable/conditions/schedule/schedule_condition.rb +33 -0
  24. data/lib/triggerable/engine.rb +28 -0
  25. data/lib/triggerable/rules/automation.rb +13 -0
  26. data/lib/triggerable/rules/rule.rb +11 -0
  27. data/lib/triggerable/rules/trigger.rb +14 -0
  28. data/lib/triggerable/version.rb +3 -0
  29. data/spec/conditions_spec.rb +200 -0
  30. data/spec/integration/actions_spec.rb +37 -0
  31. data/spec/integration/automations_spec.rb +353 -0
  32. data/spec/integration/conditions_spec.rb +144 -0
  33. data/spec/integration/short_syntax_spec.rb +92 -0
  34. data/spec/models.rb +23 -0
  35. data/spec/schema.rb +27 -0
  36. data/spec/scopes_spec.rb +78 -0
  37. data/spec/spec_helper.rb +22 -0
  38. data/triggerable.gemspec +28 -0
  39. metadata +191 -0
@@ -0,0 +1,353 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Automations' do
4
+ before(:each) do
5
+ Engine.clear
6
+ TestTask.destroy_all
7
+ end
8
+
9
+ it 'after' do
10
+ constantize_time_now Time.utc 2012, 9, 1, 12, 00
11
+
12
+ TestTask.automation if: {and: [{updated_at: {after: 24.hours}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
13
+ TestTask.create kind: 'follow up'
14
+ end
15
+
16
+ task = TestTask.create
17
+ expect(TestTask.count).to eq(1)
18
+ task.update_attributes status: 'solved', kind: 'service'
19
+ expect(TestTask.count).to eq(1)
20
+
21
+ constantize_time_now Time.utc 2012, 9, 1, 20, 00
22
+ Engine.run_automations(1.hour)
23
+ expect(TestTask.count).to eq(1)
24
+
25
+ constantize_time_now Time.utc 2012, 9, 2, 13, 00
26
+ Engine.run_automations(1.hour)
27
+
28
+ expect(TestTask.count).to eq(2)
29
+ expect(TestTask.all.last.kind).to eq('follow up')
30
+ end
31
+
32
+ it 'before' do
33
+ constantize_time_now Time.utc 2012, 9, 1, 12, 00
34
+
35
+ TestTask.automation if: {and: [{scheduled_at: {before: 2.hours}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
36
+ TestTask.create kind: 'follow up'
37
+ end
38
+
39
+ task = TestTask.create scheduled_at: Time.utc(2012, 9, 1, 20, 00)
40
+ expect(TestTask.count).to eq(1)
41
+ task.update_attributes status: 'solved', kind: 'service'
42
+ expect(TestTask.count).to eq(1)
43
+
44
+ constantize_time_now Time.utc 2012, 9, 1, 15, 00
45
+ Engine.run_automations(1.hour)
46
+ expect(TestTask.count).to eq(1)
47
+
48
+ constantize_time_now Time.utc 2012, 9, 1, 18, 00
49
+ Engine.run_automations(1.hour)
50
+ expect(TestTask.count).to eq(2)
51
+ expect(TestTask.all.last.kind).to eq('follow up')
52
+ end
53
+
54
+ it 'after 30 mins with 30 mins interval' do
55
+ constantize_time_now Time.utc 2012, 9, 1, 11, 55
56
+
57
+ TestTask.automation if: {and: [{updated_at: {after: 30.minutes}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
58
+ TestTask.create kind: 'follow up'
59
+ end
60
+
61
+ task = TestTask.create
62
+ expect(TestTask.count).to eq(1)
63
+ task.update_attributes status: 'solved', kind: 'service'
64
+ expect(TestTask.count).to eq(1)
65
+
66
+ constantize_time_now Time.utc 2012, 9, 1, 12, 12
67
+ Engine.run_automations(30.minutes)
68
+ expect(TestTask.count).to eq(1)
69
+
70
+ constantize_time_now Time.utc 2012, 9, 1, 12, 50
71
+ Engine.run_automations(30.minutes)
72
+
73
+ expect(TestTask.count).to eq(2)
74
+ expect(TestTask.all.last.kind).to eq('follow up')
75
+ end
76
+
77
+ it 'before 30 mins with 30 mins interval' do
78
+ constantize_time_now Time.utc 2012, 9, 1, 12, 00
79
+
80
+ TestTask.automation if: {and: [{scheduled_at: {before: 30.minutes}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
81
+ TestTask.create kind: 'follow up'
82
+ end
83
+
84
+ task = TestTask.create scheduled_at: Time.utc(2012, 9, 1, 15, 35)
85
+ task.update_attributes status: 'solved', kind: 'service'
86
+ expect(TestTask.count).to eq(1)
87
+
88
+ constantize_time_now Time.utc 2012, 9, 1, 14, 31
89
+ Engine.run_automations(30.minutes)
90
+ expect(TestTask.count).to eq(1)
91
+
92
+ constantize_time_now Time.utc 2012, 9, 1, 15, 03
93
+ Engine.run_automations(30.minutes)
94
+ expect(TestTask.count).to eq(2)
95
+ expect(TestTask.all.last.kind).to eq('follow up')
96
+ end
97
+
98
+ it 'after 2 hour with 4 hours interval' do
99
+ constantize_time_now Time.utc 2012, 9, 1, 11, 55
100
+
101
+ TestTask.automation if: {and: [{updated_at: {after: 2.hours}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
102
+ TestTask.create kind: 'follow up'
103
+ end
104
+
105
+ task = TestTask.create
106
+ expect(TestTask.count).to eq(1)
107
+ task.update_attributes status: 'solved', kind: 'service'
108
+ expect(TestTask.count).to eq(1)
109
+
110
+ constantize_time_now Time.utc 2012, 9, 1, 12, 00
111
+ Engine.run_automations(4.hours)
112
+ expect(TestTask.count).to eq(1)
113
+
114
+ constantize_time_now Time.utc 2012, 9, 1, 16, 00
115
+ Engine.run_automations(4.hours)
116
+
117
+ expect(TestTask.count).to eq(2)
118
+ expect(TestTask.all.last.kind).to eq('follow up')
119
+ end
120
+
121
+ it 'before 4 hour with 2 hour interval' do
122
+ constantize_time_now Time.utc 2012, 9, 1, 12, 00
123
+
124
+ TestTask.automation if: {and: [{scheduled_at: {before: 4.hour}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
125
+ TestTask.create kind: 'follow up'
126
+ end
127
+
128
+ task = TestTask.create scheduled_at: Time.utc(2012, 9, 1, 15, 35)
129
+ task.update_attributes status: 'solved', kind: 'service'
130
+ expect(TestTask.count).to eq(1)
131
+
132
+ constantize_time_now Time.utc 2012, 9, 1, 04, 05
133
+ Engine.run_automations(2.hour)
134
+ expect(TestTask.count).to eq(1)
135
+
136
+ constantize_time_now Time.utc 2012, 9, 1, 10, 01
137
+ Engine.run_automations(2.hour)
138
+ expect(TestTask.count).to eq(2)
139
+ expect(TestTask.all.last.kind).to eq('follow up')
140
+ end
141
+
142
+ it 'after 2 hour with 15 minutes interval' do
143
+ constantize_time_now Time.utc 2012, 9, 1, 11, 55
144
+
145
+ TestTask.automation if: {and: [{updated_at: {after: 2.hours}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
146
+ TestTask.create kind: 'follow up'
147
+ end
148
+
149
+ task = TestTask.create
150
+ expect(TestTask.count).to eq(1)
151
+ task.update_attributes status: 'solved', kind: 'service'
152
+ expect(TestTask.count).to eq(1)
153
+
154
+ constantize_time_now Time.utc 2012, 9, 1, 11, 46
155
+ Engine.run_automations(15.minutes)
156
+ expect(TestTask.count).to eq(1)
157
+
158
+ constantize_time_now Time.utc 2012, 9, 1, 13, 46
159
+ Engine.run_automations(15.minutes)
160
+ expect(TestTask.count).to eq(1)
161
+
162
+ constantize_time_now Time.utc 2012, 9, 1, 14, 02
163
+ Engine.run_automations(15.minutes)
164
+
165
+ expect(TestTask.count).to eq(2)
166
+ expect(TestTask.all.last.kind).to eq('follow up')
167
+
168
+ constantize_time_now Time.utc 2012, 9, 1, 14, 17
169
+ Engine.run_automations(15.minutes)
170
+ expect(TestTask.count).to eq(2)
171
+ end
172
+
173
+ it 'before 2 hour with 15 minutes interval' do
174
+ constantize_time_now Time.utc 2012, 9, 1, 12, 00
175
+
176
+ TestTask.automation if: {and: [{scheduled_at: {before: 2.hour}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
177
+ TestTask.create kind: 'follow up'
178
+ end
179
+
180
+ task = TestTask.create scheduled_at: Time.utc(2012, 9, 1, 15, 35)
181
+ task.update_attributes status: 'solved', kind: 'service'
182
+ expect(TestTask.count).to eq(1)
183
+
184
+ constantize_time_now Time.utc 2012, 9, 1, 10, 05
185
+ Engine.run_automations(15.minutes)
186
+ expect(TestTask.count).to eq(1)
187
+
188
+ constantize_time_now Time.utc 2012, 9, 1, 13, 30
189
+ Engine.run_automations(15.minutes)
190
+ expect(TestTask.count).to eq(2)
191
+ expect(TestTask.all.last.kind).to eq('follow up')
192
+
193
+ constantize_time_now Time.utc 2012, 9, 1, 15, 32
194
+ Engine.run_automations(15.minutes)
195
+ expect(TestTask.count).to eq(2)
196
+ end
197
+
198
+ it 'after greater than 2 hours' do
199
+ constantize_time_now Time.utc 2012, 9, 1, 11, 55
200
+
201
+ TestTask.automation if: {and: [{updated_at: {after: {greater_than: 2.hours}}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
202
+ TestTask.create kind: 'follow up'
203
+ end
204
+
205
+ task = TestTask.create
206
+ expect(TestTask.count).to eq(1)
207
+ task.update_attributes status: 'solved', kind: 'service'
208
+ expect(TestTask.count).to eq(1)
209
+
210
+ constantize_time_now Time.utc 2012, 9, 1, 12, 10
211
+ Engine.run_automations(15.minutes)
212
+ expect(TestTask.count).to eq(1)
213
+
214
+ constantize_time_now Time.utc 2012, 9, 1, 12, 25
215
+ Engine.run_automations(15.minutes)
216
+ expect(TestTask.count).to eq(1)
217
+
218
+ constantize_time_now Time.utc 2012, 9, 1, 13, 55
219
+ Engine.run_automations(15.minutes)
220
+ expect(TestTask.count).to eq(2)
221
+ expect(TestTask.all.last.kind).to eq('follow up')
222
+
223
+ constantize_time_now Time.utc 2012, 9, 1, 14, 10
224
+ Engine.run_automations(15.minutes)
225
+ expect(TestTask.count).to eq(3)
226
+
227
+ constantize_time_now Time.utc 2012, 9, 1, 14, 25
228
+ Engine.run_automations(15.minutes)
229
+ expect(TestTask.count).to eq(4)
230
+ end
231
+
232
+ it 'after less than 2 hours' do
233
+ constantize_time_now Time.utc 2012, 9, 1, 11, 55
234
+
235
+ TestTask.automation if: {and: [{updated_at: {after: {less_than: 2.hours}}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
236
+ TestTask.create kind: 'follow up'
237
+ end
238
+
239
+ task = TestTask.create
240
+ expect(TestTask.count).to eq(1)
241
+ task.update_attributes status: 'solved', kind: 'service'
242
+ expect(TestTask.count).to eq(1)
243
+
244
+ constantize_time_now Time.utc 2012, 9, 1, 12, 10
245
+ Engine.run_automations(15.minutes)
246
+ expect(TestTask.count).to eq(2)
247
+
248
+ constantize_time_now Time.utc 2012, 9, 1, 12, 25
249
+ Engine.run_automations(15.minutes)
250
+ expect(TestTask.count).to eq(3)
251
+
252
+ constantize_time_now Time.utc 2012, 9, 1, 13, 55
253
+ Engine.run_automations(15.minutes)
254
+ expect(TestTask.count).to eq(4)
255
+ expect(TestTask.all.last.kind).to eq('follow up')
256
+
257
+ constantize_time_now Time.utc 2012, 9, 1, 14, 10
258
+ Engine.run_automations(15.minutes)
259
+ expect(TestTask.count).to eq(4)
260
+
261
+ constantize_time_now Time.utc 2012, 9, 1, 14, 25
262
+ Engine.run_automations(15.minutes)
263
+ expect(TestTask.count).to eq(4)
264
+ end
265
+
266
+ it 'before greater than 2 hours' do
267
+ constantize_time_now Time.utc 2012, 9, 1, 11, 55
268
+
269
+ TestTask.automation if: {and: [{scheduled_at: {before: {greater_than: 2.hours}}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
270
+ TestTask.create kind: 'follow up'
271
+ end
272
+
273
+ task = TestTask.create scheduled_at: Time.utc(2012, 9, 1, 20, 00)
274
+ expect(TestTask.count).to eq(1)
275
+ task.update_attributes status: 'solved', kind: 'service'
276
+ expect(TestTask.count).to eq(1)
277
+
278
+ constantize_time_now Time.utc 2012, 9, 1, 12, 10
279
+ Engine.run_automations(15.minutes)
280
+ expect(TestTask.count).to eq(1)
281
+
282
+ constantize_time_now Time.utc 2012, 9, 1, 12, 25
283
+ Engine.run_automations(15.minutes)
284
+ expect(TestTask.count).to eq(1)
285
+
286
+ constantize_time_now Time.utc 2012, 9, 1, 17, 55
287
+ Engine.run_automations(15.minutes)
288
+ expect(TestTask.count).to eq(1)
289
+
290
+ constantize_time_now Time.utc 2012, 9, 1, 18, 00
291
+ Engine.run_automations(15.minutes)
292
+ expect(TestTask.count).to eq(1)
293
+
294
+ constantize_time_now Time.utc 2012, 9, 1, 18, 30
295
+ Engine.run_automations(15.minutes)
296
+ expect(TestTask.count).to eq(2)
297
+ expect(TestTask.all.last.kind).to eq('follow up')
298
+
299
+ constantize_time_now Time.utc 2012, 9, 1, 19, 55
300
+ Engine.run_automations(15.minutes)
301
+ expect(TestTask.count).to eq(3)
302
+
303
+ constantize_time_now Time.utc 2012, 9, 1, 20, 00
304
+ Engine.run_automations(15.minutes)
305
+ expect(TestTask.count).to eq(4)
306
+
307
+ constantize_time_now Time.utc 2012, 9, 1, 20, 05
308
+ Engine.run_automations(15.minutes)
309
+ expect(TestTask.count).to eq(4)
310
+
311
+ constantize_time_now Time.utc 2012, 9, 1, 20, 10
312
+ Engine.run_automations(15.minutes)
313
+ expect(TestTask.count).to eq(4)
314
+ end
315
+
316
+ it 'before less than 2 hours' do
317
+ constantize_time_now Time.utc 2012, 9, 1, 11, 55
318
+
319
+ TestTask.automation if: {and: [{scheduled_at: {before: {less_than: 2.hours}}}, {status: {is: :solved}}, {kind: {is: :service}}]} do
320
+ TestTask.create kind: 'follow up'
321
+ end
322
+
323
+ task = TestTask.create scheduled_at: Time.utc(2012, 9, 1, 20, 00)
324
+ expect(TestTask.count).to eq(1)
325
+ task.update_attributes status: 'solved', kind: 'service'
326
+ expect(TestTask.count).to eq(1)
327
+
328
+ constantize_time_now Time.utc 2012, 9, 1, 12, 10
329
+ Engine.run_automations(15.minutes)
330
+ expect(TestTask.count).to eq(2)
331
+
332
+ constantize_time_now Time.utc 2012, 9, 1, 12, 25
333
+ Engine.run_automations(15.minutes)
334
+ expect(TestTask.count).to eq(3)
335
+
336
+ constantize_time_now Time.utc 2012, 9, 1, 17, 55
337
+ Engine.run_automations(15.minutes)
338
+ expect(TestTask.count).to eq(4)
339
+
340
+ constantize_time_now Time.utc 2012, 9, 1, 18, 00
341
+ Engine.run_automations(15.minutes)
342
+ expect(TestTask.count).to eq(5)
343
+ expect(TestTask.all.last.kind).to eq('follow up')
344
+
345
+ constantize_time_now Time.utc 2012, 9, 1, 18, 30
346
+ Engine.run_automations(15.minutes)
347
+ expect(TestTask.count).to eq(5)
348
+
349
+ constantize_time_now Time.utc 2012, 9, 1, 18, 40
350
+ Engine.run_automations(15.minutes)
351
+ expect(TestTask.count).to eq(5)
352
+ end
353
+ end
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+
3
+ describe Conditions do
4
+ before(:each) do
5
+ Engine.clear
6
+ TestTask.destroy_all
7
+ end
8
+
9
+ it 'is' do
10
+ TestTask.trigger on: :after_update, if: {status: {is: 'solved'}} do
11
+ TestTask.create kind: 'follow up'
12
+ end
13
+
14
+ task = TestTask.create
15
+ expect(TestTask.count).to eq(1)
16
+
17
+ task.update_attributes status: 'solved'
18
+ expect(TestTask.count).to eq(2)
19
+ expect(TestTask.all.last.kind).to eq('follow up')
20
+ end
21
+
22
+ it 'is_not' do
23
+ TestTask.trigger on: :after_update, if: {status: {is_not: 'solved'}} do
24
+ TestTask.create kind: 'follow up'
25
+ end
26
+
27
+ task = TestTask.create status: 'solved'
28
+ expect(TestTask.count).to eq(1)
29
+
30
+ task.update_attributes status: 'completed'
31
+ expect(TestTask.count).to eq(2)
32
+ expect(TestTask.all.last.kind).to eq('follow up')
33
+ end
34
+
35
+ it 'greater_than' do
36
+ TestTask.trigger on: :after_update, if: {failure_count: {greater_than: 1}} do
37
+ TestTask.create kind: 'follow up'
38
+ end
39
+
40
+ task = TestTask.create failure_count: 0
41
+ expect(TestTask.count).to eq(1)
42
+
43
+ task.update_attributes failure_count: 1
44
+ expect(TestTask.count).to eq(1)
45
+
46
+ task.update_attributes failure_count: 2
47
+ expect(TestTask.count).to eq(2)
48
+ expect(TestTask.all.last.kind).to eq('follow up')
49
+ end
50
+
51
+ it 'less_than' do
52
+ TestTask.trigger on: :after_update, if: {failure_count: {less_than: 2}} do
53
+ TestTask.create kind: 'follow up'
54
+ end
55
+
56
+ task = TestTask.create failure_count: 2
57
+ expect(TestTask.count).to eq(1)
58
+
59
+ task.update_attributes failure_count: 1
60
+ expect(TestTask.count).to eq(2)
61
+ expect(TestTask.all.last.kind).to eq('follow up')
62
+ end
63
+
64
+ it 'exists' do
65
+ TestTask.trigger on: :after_update, if: {failure_count: {exists: true}} do
66
+ TestTask.create kind: 'follow up'
67
+ end
68
+
69
+ task = TestTask.create
70
+ expect(TestTask.count).to eq(1)
71
+
72
+ task.update_attributes failure_count: 1
73
+ expect(TestTask.count).to eq(2)
74
+ expect(TestTask.all.last.kind).to eq('follow up')
75
+ end
76
+
77
+ it 'and' do
78
+ TestTask.trigger on: :after_update, if: {and: [{status: {is: 'solved'}}, {kind: {is: 'service'}}]} do
79
+ TestTask.create kind: 'follow up'
80
+ end
81
+
82
+ task = TestTask.create
83
+ expect(TestTask.count).to eq(1)
84
+
85
+ task.update_attributes status: 'solved', kind: 'service'
86
+ expect(TestTask.count).to eq(2)
87
+ expect(TestTask.all.last.kind).to eq('follow up')
88
+ end
89
+
90
+ it 'or' do
91
+ TestTask.trigger on: :after_update, if: {or: [{status: {is: 'solved'}}, {kind: {is: 'service'}}]} do
92
+ TestTask.create kind: 'follow up'
93
+ end
94
+
95
+ task = TestTask.create
96
+ expect(TestTask.count).to eq(1)
97
+
98
+ task.update_attributes status: 'solved'
99
+ expect(TestTask.count).to eq(2)
100
+ expect(TestTask.all.last.kind).to eq('follow up')
101
+
102
+ task2 = TestTask.create
103
+ expect(TestTask.count).to eq(3)
104
+
105
+ task2.update_attributes kind: 'service'
106
+ expect(TestTask.count).to eq(4)
107
+ expect(TestTask.all.last.kind).to eq('follow up')
108
+ end
109
+
110
+ it 'in' do
111
+ TestTask.trigger on: :after_update, if: {status: {in: ['solved', 'confirmed']}} do
112
+ TestTask.create kind: 'follow up'
113
+ end
114
+
115
+ task = TestTask.create
116
+ expect(TestTask.count).to eq(1)
117
+
118
+ task.update_attributes status: 'solved'
119
+ expect(TestTask.count).to eq(2)
120
+ expect(TestTask.all.last.kind).to eq('follow up')
121
+
122
+ task2 = TestTask.create
123
+ expect(TestTask.count).to eq(3)
124
+
125
+ task2.update_attributes status: 'confirmed'
126
+ expect(TestTask.count).to eq(4)
127
+ expect(TestTask.all.last.kind).to eq('follow up')
128
+ end
129
+
130
+ it 'lambda' do
131
+ TestTask.trigger on: :after_update, if: -> {
132
+ status == 'solved' && kind == 'service'
133
+ } do
134
+ TestTask.create kind: 'follow up'
135
+ end
136
+
137
+ task = TestTask.create
138
+ expect(TestTask.count).to eq(1)
139
+
140
+ task.update_attributes status: 'solved', kind: 'service'
141
+ expect(TestTask.count).to eq(2)
142
+ expect(TestTask.all.last.kind).to eq('follow up')
143
+ end
144
+ end