triggerable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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