ruote-kit 2.2.0.3 → 2.3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG.txt +28 -1
  2. data/CREDITS.txt +8 -2
  3. data/LICENSE.txt +1 -1
  4. data/Rakefile +21 -9
  5. data/lib/ruote-kit.rb +13 -4
  6. data/lib/ruote-kit/core_ext.rb +15 -0
  7. data/lib/ruote-kit/helpers/json_helpers.rb +22 -7
  8. data/lib/ruote-kit/helpers/link_helpers.rb +9 -7
  9. data/lib/ruote-kit/helpers/pagination_helpers.rb +1 -2
  10. data/lib/ruote-kit/helpers/render_helpers.rb +1 -1
  11. data/lib/ruote-kit/public/_ruote/images/favicon.png +0 -0
  12. data/lib/ruote-kit/public/_ruote/images/{ruote_buttons.png → ruote-buttons.png} +0 -0
  13. data/lib/ruote-kit/public/_ruote/images/ruote.png +0 -0
  14. data/lib/ruote-kit/public/_ruote/javascripts/foolbox-all.min.js +3 -0
  15. data/lib/ruote-kit/public/_ruote/javascripts/jquery-1.9.1.min.js +5 -0
  16. data/lib/ruote-kit/public/_ruote/javascripts/rk.js +68 -17
  17. data/lib/ruote-kit/public/_ruote/javascripts/ruote-fluo-all.min.js +3 -0
  18. data/lib/ruote-kit/public/_ruote/stylesheets/rk.css +82 -12
  19. data/lib/ruote-kit/public/_ruote/stylesheets/ruote-buttons.png +0 -0
  20. data/lib/ruote-kit/public/_ruote/stylesheets/ruote-fluo-editor.css +9 -6
  21. data/lib/ruote-kit/public/_ruote/stylesheets/ruote-fluo.css +62 -0
  22. data/lib/ruote-kit/resources/errors.rb +8 -3
  23. data/lib/ruote-kit/resources/expressions.rb +38 -35
  24. data/lib/ruote-kit/resources/participants.rb +1 -1
  25. data/lib/ruote-kit/resources/processes.rb +61 -4
  26. data/lib/ruote-kit/resources/workitems.rb +4 -4
  27. data/lib/ruote-kit/version.rb +1 -1
  28. data/lib/ruote-kit/views/_pagination.html.haml +2 -2
  29. data/lib/ruote-kit/views/_tree_editor.html.haml +63 -30
  30. data/lib/ruote-kit/views/error.html.haml +50 -9
  31. data/lib/ruote-kit/views/errors.html.haml +1 -1
  32. data/lib/ruote-kit/views/expression.html.haml +83 -33
  33. data/lib/ruote-kit/views/expressions.html.haml +23 -8
  34. data/lib/ruote-kit/views/http_error.html.haml +9 -2
  35. data/lib/ruote-kit/views/layout.html.haml +14 -13
  36. data/lib/ruote-kit/views/process.html.haml +75 -20
  37. data/lib/ruote-kit/views/processes.html.haml +9 -3
  38. data/lib/ruote-kit/views/processes_new.html.haml +19 -2
  39. data/lib/ruote-kit/views/schedules.html.haml +2 -2
  40. data/lib/ruote-kit/views/workitem.html.haml +17 -6
  41. data/ruote-kit.gemspec +9 -7
  42. data/spec/cases/orphan_workitem_spec.rb +141 -0
  43. data/spec/core_ext_spec.rb +19 -0
  44. data/spec/resources/errors_spec.rb +182 -156
  45. data/spec/resources/expressions_spec.rb +497 -379
  46. data/spec/resources/index_spec.rb +5 -5
  47. data/spec/resources/participants_spec.rb +64 -75
  48. data/spec/resources/processes_spec.rb +396 -277
  49. data/spec/resources/schedules_spec.rb +92 -76
  50. data/spec/resources/workitems_spec.rb +352 -343
  51. data/spec/ruote-kit_configure_spec.rb +41 -13
  52. data/spec/spec_helper.rb +6 -8
  53. data/spec/support/link_helper.rb +11 -0
  54. data/spec/webapp_helpers_spec.rb +29 -23
  55. metadata +161 -180
  56. data/README.rdoc +0 -313
  57. data/lib/ruote-kit/public/_ruote/images/favicon.ico +0 -0
  58. data/lib/ruote-kit/public/_ruote/javascripts/jquery-1.4.2.min.js +0 -154
  59. data/lib/ruote-kit/public/_ruote/javascripts/ruote-fluo-editor.js +0 -548
  60. data/lib/ruote-kit/public/_ruote/javascripts/ruote-fluo.js +0 -1118
@@ -1,605 +1,723 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+ require 'spec_helper'
3
3
 
4
4
 
5
- describe 'GET /_ruote/expressions' do
5
+ describe '/_ruote/expressions' do
6
6
 
7
7
  before(:each) do
8
-
9
- prepare_engine
8
+ prepare_engine_with_participants
10
9
  end
11
-
12
10
  after(:each) do
13
-
14
11
  shutdown_and_purge_engine
15
12
  end
16
13
 
17
- it 'should 404 (HTML)' do
14
+ describe 'GET /_ruote/expressions' do
15
+
16
+ it 'goes 404 (HTML)' do
18
17
 
19
- get '/_ruote/expressions'
18
+ get '/_ruote/expressions'
20
19
 
21
- last_response.status.should be(404)
20
+ last_response.status.should be(404)
21
+ end
22
22
  end
23
- end
24
23
 
25
- describe 'GET /_ruote/expressions/wfid' do
24
+ describe 'GET /_ruote/expressions/:wfid' do
26
25
 
27
- before(:each) do
26
+ context 'with running processes' do
28
27
 
29
- prepare_engine_with_participants
30
- end
28
+ before(:each) do
29
+ @wfid = launch_nada_process
30
+ end
31
31
 
32
- after(:each) do
32
+ it 'renders the expressions (HTML)' do
33
33
 
34
- shutdown_and_purge_engine
35
- end
34
+ get "/_ruote/expressions/#{@wfid}"
36
35
 
37
- describe 'with running processes' do
36
+ last_response.should be_ok
37
+ end
38
38
 
39
- before(:each) do
40
- @wfid = launch_nada_process
41
- end
39
+ it 'renders the expressions (JSON)' do
42
40
 
43
- it 'should render the expressions (HTML)' do
41
+ get "/_ruote/expressions/#{@wfid}.json"
44
42
 
45
- get "/_ruote/expressions/#{@wfid}"
43
+ last_response.should be_ok
46
44
 
47
- last_response.should be_ok
45
+ last_response.json_body['expressions'].first.keys.sort.should == %w[
46
+ class fei links name parent state
47
+ ]
48
+ end
48
49
  end
49
50
 
50
- it 'should render the expressions (JSON)' do
51
+ context 'without running processes' do
52
+
53
+ it 'goes 404 correctly (HTML)' do
54
+
55
+ get "/_ruote/expressions/foo"
56
+
57
+ last_response.should_not be_ok
58
+ last_response.status.should be(404)
59
+ end
51
60
 
52
- get "/_ruote/expressions/#{@wfid}.json"
61
+ it 'goes 404 correctly (JSON)' do
53
62
 
54
- last_response.should be_ok
63
+ get '/_ruote/expressions/foo.json'
55
64
 
56
- last_response.json_body['expressions'].first.keys.sort.should == %w[
57
- class fei links name parent
58
- ]
65
+ last_response.should_not be_ok
66
+ last_response.status.should be(404)
67
+ end
59
68
  end
60
69
  end
61
70
 
62
- describe 'without running processes' do
71
+ describe 'GET /_ruote/expressions/:fei' do
63
72
 
64
- it 'should 404 correctly (HTML)' do
73
+ context 'with running processes' do
65
74
 
66
- get "/_ruote/expressions/foo"
75
+ before(:each) do
67
76
 
68
- last_response.should_not be_ok
69
- last_response.status.should be(404)
70
- end
77
+ @wfid = launch_nada_process
78
+ @nada_fexp = RuoteKit.engine.process(@wfid).expressions.last
79
+ @nada_fei = @nada_fexp.fei
80
+ end
71
81
 
72
- it 'should 404 correctly (JSON)' do
82
+ it 'renders the expression (HTML)' do
73
83
 
74
- get '/_ruote/expressions/foo.json'
84
+ get "/_ruote/expressions/#{@nada_fei.sid}"
75
85
 
76
- last_response.should_not be_ok
77
- last_response.status.should be(404)
78
- end
79
- end
80
- end
86
+ last_response.status.should ==
87
+ 200
88
+ last_response.should have_selector(
89
+ 'input[name="_method"][type="hidden"][value="DELETE"]')
90
+ last_response.should have_selector(
91
+ 'input[type="submit"][value="pause"]')
92
+ end
81
93
 
82
- describe 'GET /_ruote/expressions/fei' do
94
+ it 'renders the expression (JSON)' do
83
95
 
84
- before(:each) do
96
+ get "/_ruote/expressions/#{@nada_fei.sid}.json"
85
97
 
86
- prepare_engine_with_participants
87
- end
98
+ last_response.should be_ok
88
99
 
89
- after(:each) do
100
+ #puts Rufus::Json.pretty_encode(last_response.json_body)
90
101
 
91
- shutdown_and_purge_engine
92
- end
102
+ last_response.json_body['expression']['links'].size.should == 4
93
103
 
94
- describe 'with running processes' do
104
+ last_response.json_body['expression'].keys.sort.should == %w[
105
+ applied_workitem class fei links name original_tree parent state
106
+ timeout_schedule_id tree variables
107
+ ]
108
+ end
95
109
 
96
- before(:each) do
110
+ it 'includes an etag header (HTML)' do
97
111
 
98
- @wfid = launch_nada_process
99
- @nada_fexp = RuoteKit.engine.process(@wfid).expressions.last
100
- @nada_fei = @nada_fexp.fei
101
- end
112
+ get "/_ruote/expressions/#{@nada_fei.sid}"
113
+
114
+ last_response.headers.should include('ETag')
115
+
116
+ last_response.headers['ETag'].should ==
117
+ "\"#{@nada_fexp.to_h['_rev'].to_s}\""
118
+ end
119
+
120
+ it 'includes an etag header (JSON)' do
102
121
 
103
- it 'should render the expression (HTML)' do
122
+ get "/_ruote/expressions/#{@nada_fei.sid}.json"
104
123
 
105
- get "/_ruote/expressions/#{@nada_fei.sid}"
124
+ last_response.headers.should include('ETag')
106
125
 
107
- last_response.should be_ok
126
+ last_response.headers['ETag'].should ==
127
+ "\"#{@nada_fexp.to_h['_rev'].to_s}\""
128
+ end
108
129
  end
109
130
 
110
- it 'should render the expression (JSON)' do
131
+ context 'without running processes' do
132
+
133
+ it 'goes 404 correctly (HTML)' do
111
134
 
112
- get "/_ruote/expressions/#{@nada_fei.sid}.json"
135
+ get '/workitems/foo/bar'
113
136
 
114
- last_response.should be_ok
137
+ last_response.should_not be_ok
138
+ last_response.status.should be(404)
139
+ end
115
140
 
116
- #puts Rufus::Json.pretty_encode(last_response.json_body)
141
+ it 'goes 404 correctly (JSON)' do
117
142
 
118
- last_response.json_body['expression']['links'].size.should == 4
143
+ get '/workitems/foo/bar.json'
119
144
 
120
- last_response.json_body['expression'].keys.sort.should == %w[
121
- applied_workitem class fei links name original_tree parent
122
- timeout_schedule_id tree variables
123
- ]
145
+ last_response.should_not be_ok
146
+ last_response.status.should be(404)
147
+ end
124
148
  end
125
149
 
126
- it 'should include an etag header (HTML)' do
150
+ context 'with an expression that has a schedule' do
127
151
 
128
- get "/_ruote/expressions/#{@nada_fei.sid}"
152
+ before(:each) do
129
153
 
130
- last_response.headers.should include('ETag')
154
+ @wfid = RuoteKit.engine.launch(Ruote.define do
155
+ alpha :timeout => '2y'
156
+ end)
131
157
 
132
- last_response.headers['ETag'].should ==
133
- "\"#{@nada_fexp.to_h['_rev'].to_s}\""
134
- end
158
+ RuoteKit.engine.wait_for(:alpha)
159
+
160
+ @fei = RuoteKit.engine.process(@wfid).expressions.last.fei
161
+ end
162
+
163
+ it 'renders the expression (HTML)' do
164
+
165
+ get "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}"
166
+
167
+ last_response.status.should be(200)
168
+
169
+ last_response.should have_selector(
170
+ 'table.details tr td', :content => 'timeout')
171
+ end
172
+
173
+ it 'renders the expression (JSON)' do
135
174
 
136
- it 'should include an etag header (JSON)' do
175
+ get "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json"
137
176
 
138
- get "/_ruote/expressions/#{@nada_fei.sid}.json"
177
+ last_response.status.should be(200)
139
178
 
140
- last_response.headers.should include('ETag')
179
+ #puts Rufus::Json.pretty_encode(last_response.json_body)
141
180
 
142
- last_response.headers['ETag'].should ==
143
- "\"#{@nada_fexp.to_h['_rev'].to_s}\""
181
+ last_response.json_body['expression'].keys.should include(
182
+ 'timeout_schedule_id')
183
+ end
144
184
  end
145
185
  end
146
186
 
147
- describe 'without running processes' do
187
+ describe 'DELETE /_ruote/expressions/:fei' do
148
188
 
149
- it 'should 404 correctly (HTML)' do
189
+ context 'with running processes' do
150
190
 
151
- get '/workitems/foo/bar'
191
+ before(:each) do
152
192
 
153
- last_response.should_not be_ok
154
- last_response.status.should be(404)
155
- end
193
+ @wfid = RuoteKit.engine.launch(Ruote.process_definition do
194
+ sequence do
195
+ alfred :on_cancel => 'bail_out'
196
+ echo 'done'
197
+ end
156
198
 
157
- it 'should 404 correctly (JSON)' do
199
+ define 'bail_out' do
200
+ echo 'bailed'
201
+ end
202
+ end)
158
203
 
159
- get '/workitems/foo/bar.json'
204
+ RuoteKit.engine.wait_for(:alfred)
160
205
 
161
- last_response.should_not be_ok
162
- last_response.status.should be(404)
163
- end
164
- end
206
+ @fei = engine.process(@wfid).expressions.last.fei
207
+ end
165
208
 
166
- describe 'with an expression that has a schedule' do
209
+ it 'cancels the expressions (HTML)' do
167
210
 
168
- before(:each) do
211
+ delete "/_ruote/expressions/#{@fei.sid}"
169
212
 
170
- register_participants
213
+ last_response.should be_redirect
214
+ last_response['Location'].should == "http://example.org/_ruote/expressions/#{@wfid}"
171
215
 
172
- @wfid = RuoteKit.engine.launch(Ruote.define do
173
- alpha :timeout => '2y'
174
- end)
216
+ wait_for(@wfid)
175
217
 
176
- RuoteKit.engine.wait_for(:alpha)
218
+ @tracer.to_s.should == "bailed\ndone"
219
+ end
177
220
 
178
- @fei = RuoteKit.engine.process(@wfid).expressions.last.fei
179
- end
221
+ it 'cancels the expressions (JSON)' do
180
222
 
181
- it 'should render the expression (HTML)' do
223
+ delete "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json"
182
224
 
183
- get "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}"
225
+ last_response.should be_ok
226
+ last_response.json_body['status'].should == 'ok'
184
227
 
185
- last_response.status.should be(200)
228
+ wait_for(@wfid)
186
229
 
187
- last_response.should have_selector(
188
- 'table.details tr td', :content => 'timeout')
189
- end
230
+ @tracer.to_s.should == "bailed\ndone"
231
+ end
232
+
233
+ it 'kills the expression (HTML)' do
234
+
235
+ delete "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}?_kill=1"
236
+
237
+ last_response.should be_redirect
238
+ last_response['Location'].should == "http://example.org/_ruote/expressions/#{@wfid}"
239
+
240
+ wait_for(@wfid)
241
+
242
+ @tracer.to_s.should == 'done'
243
+ end
244
+
245
+ it 'kills the expression (JSON)' do
246
+
247
+ delete "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json?_kill=1"
248
+
249
+ last_response.should be_ok
250
+ last_response.json_body['status'].should == 'ok'
251
+
252
+ wait_for(@wfid)
253
+
254
+ @tracer.to_s.should == 'done'
255
+ end
256
+
257
+ it 'goes 412 when the etags do not match (HTML)' do
258
+
259
+ delete(
260
+ "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
261
+ nil,
262
+ { 'HTTP_IF_MATCH' => '"foo"' }
263
+ )
264
+
265
+ last_response.status.should == 412
266
+ end
267
+
268
+ it 'goes 412 when the etags do not match (JSON)' do
269
+
270
+ delete(
271
+ "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
272
+ nil,
273
+ {
274
+ 'HTTP_IF_MATCH' => '"foo"',
275
+ 'CONTENT_TYPE' => 'application/json',
276
+ }
277
+ )
190
278
 
191
- it 'should render the expression (JSON)' do
279
+ last_response.status.should == 412
280
+ end
281
+
282
+ it 'does not go 412 when the etags do match (HTML)' do
283
+
284
+ exp = RuoteKit.engine.process(@wfid).expressions.find { |e|
285
+ e.fei.expid == @fei.expid
286
+ }
287
+
288
+ delete(
289
+ "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
290
+ nil,
291
+ { 'HTTP_IF_MATCH' => ('"%s"' % exp.to_h['_rev'] ) }
292
+ )
293
+
294
+ last_response.status.should_not == 412
295
+ end
192
296
 
193
- get "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json"
297
+ it 'does not go 412 when the etags do match (JSON)' do
194
298
 
195
- last_response.status.should be(200)
299
+ exp = RuoteKit.engine.process(@wfid).expressions.find { |e|
300
+ e.fei.expid == @fei.expid
301
+ }
196
302
 
197
- #puts Rufus::Json.pretty_encode(last_response.json_body)
303
+ delete(
304
+ "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
305
+ nil,
306
+ {
307
+ 'HTTP_IF_MATCH' => ('"%s"' % exp.to_h['_rev'] ),
308
+ 'CONTENT_TYPE' => 'application/json',
309
+ }
310
+ )
198
311
 
199
- last_response.json_body['expression'].keys.should include(
200
- 'timeout_schedule_id')
312
+ last_response.status.should_not == 412
313
+ end
201
314
  end
202
- end
203
- end
204
315
 
205
- describe 'DELETE /_ruote/expressions/fei' do
316
+ context 'without running processes' do
206
317
 
207
- before(:each) do
318
+ it 'goes 404 correctly (HTML)' do
208
319
 
209
- prepare_engine_with_participants
210
- end
320
+ delete '/_ruote/expressions/foo/bar'
211
321
 
212
- after(:each) do
322
+ last_response.should_not be_ok
323
+ last_response.status.should be(404)
324
+ end
213
325
 
214
- shutdown_and_purge_engine
326
+ it 'goes 404 correctly (JSON)' do
327
+
328
+ delete '/_ruote/expressions/foo/bar.json'
329
+
330
+ last_response.should_not be_ok
331
+ last_response.status.should be(404)
332
+ end
333
+ end
215
334
  end
216
335
 
217
- describe 'with running processes' do
336
+ describe 'PUT /_ruote/expressions/:fei' do
218
337
 
219
338
  before(:each) do
220
339
 
221
- @wfid = RuoteKit.engine.launch(Ruote.process_definition do
222
- sequence do
223
- alfred :on_cancel => 'bail_out'
224
- echo 'done'
225
- end
340
+ @wfid = RuoteKit.engine.launch(
226
341
 
227
- define 'bail_out' do
228
- echo 'bailed'
342
+ Ruote.process_definition do
343
+ alpha
229
344
  end
230
- end)
345
+ )
231
346
 
232
- RuoteKit.engine.wait_for(:alfred)
347
+ RuoteKit.engine.wait_for(:alpha)
348
+ RuoteKit.engine.wait_for(1)
233
349
 
234
- @fei = engine.process(@wfid).expressions.last.fei
350
+ @exp = RuoteKit.engine.process(@wfid).expressions.last
235
351
  end
236
352
 
237
- it 'should cancel the expressions (HTML)' do
353
+ context 're_apply' do
238
354
 
239
- delete "/_ruote/expressions/#{@fei.sid}"
355
+ it 're-applies (HTML)' do
240
356
 
241
- last_response.should be_redirect
242
- last_response['Location'].should == "/_ruote/expressions/#{@wfid}"
357
+ at0 = RuoteKit.engine.storage_participant.first.dispatched_at
243
358
 
244
- wait_for(@wfid)
359
+ put(
360
+ "/_ruote/expressions/#{@exp.fei.sid}",
361
+ :fields => '{}')
245
362
 
246
- @tracer.to_s.should == "bailed\ndone"
247
- end
363
+ last_response.status.should be(302)
364
+ last_response.location.should == "http://example.org/_ruote/expressions/#{@wfid}"
248
365
 
249
- it 'should cancel the expressions (JSON)' do
366
+ #RuoteKit.engine.wait_for(:alpha)
367
+ sleep 0.500
250
368
 
251
- delete "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json"
369
+ at1 = RuoteKit.engine.storage_participant.first.dispatched_at
252
370
 
253
- last_response.should be_ok
254
- last_response.json_body['status'].should == 'ok'
371
+ at1.should_not == at0
372
+ end
255
373
 
256
- wait_for(@wfid)
374
+ it 're-applies (JSON)' do
257
375
 
258
- @tracer.to_s.should == "bailed\ndone"
259
- end
376
+ #RuoteKit.engine.noisy = true
260
377
 
261
- it 'should kill the expression (HTML)' do
378
+ at0 = RuoteKit.engine.storage_participant.first.dispatched_at
262
379
 
263
- delete "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}?_kill=1"
380
+ put(
381
+ "/_ruote/expressions/#{@exp.fei.sid}.json",
382
+ Rufus::Json.encode({}),
383
+ { 'CONTENT_TYPE' => 'application/json' })
264
384
 
265
- last_response.should be_redirect
266
- last_response['Location'].should == "/_ruote/expressions/#{@wfid}"
385
+ last_response.status.should be(200)
267
386
 
268
- #sleep 0.4
269
- wait_for(@wfid)
387
+ #RuoteKit.engine.wait_for(:alpha)
388
+ sleep 0.500
270
389
 
271
- @tracer.to_s.should == 'done'
272
- end
390
+ at1 = RuoteKit.engine.storage_participant.first.dispatched_at
273
391
 
274
- it 'should kill the expression (JSON)' do
392
+ at1.should_not == at0
393
+ end
275
394
 
276
- delete "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json?_kill=1"
395
+ it 're-applies with different fields (HTML)' do
277
396
 
278
- last_response.should be_ok
279
- last_response.json_body['status'].should == 'ok'
397
+ wi = RuoteKit.engine.storage_participant.first
398
+ wi.fields['car'].should be(nil)
280
399
 
281
- #sleep 0.4
282
- wait_for(@wfid)
400
+ put(
401
+ "/_ruote/expressions/#{@exp.fei.sid}",
402
+ :fields => '{"car":"daimler-benz"}')
283
403
 
284
- @tracer.to_s.should == 'done'
285
- end
404
+ last_response.status.should be(302)
405
+ last_response.location.should == "http://example.org/_ruote/expressions/#{@wfid}"
286
406
 
287
- it 'should 412 when the etags do not match (HTML)' do
407
+ #RuoteKit.engine.wait_for(:alpha)
408
+ sleep 0.500
288
409
 
289
- delete(
290
- "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
291
- nil,
292
- { 'HTTP_IF_MATCH' => '"foo"' }
293
- )
410
+ wi = RuoteKit.engine.storage_participant.first
294
411
 
295
- last_response.status.should == 412
296
- end
412
+ wi.fields['car'].should == 'daimler-benz'
413
+ end
297
414
 
298
- it 'should 412 when the etags do not match (JSON)' do
415
+ it 're-applies with different fields (JSON)' do
299
416
 
300
- delete(
301
- "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
302
- nil,
303
- {
304
- 'HTTP_IF_MATCH' => '"foo"',
305
- 'CONTENT_TYPE' => 'application/json',
306
- }
307
- )
417
+ wi = RuoteKit.engine.storage_participant.first
418
+ wi.fields['car'].should be(nil)
308
419
 
309
- last_response.status.should == 412
310
- end
420
+ put(
421
+ "/_ruote/expressions/#{@exp.fei.sid}.json",
422
+ Rufus::Json.encode({ 'fields' => { 'car' => 'bentley' } }),
423
+ { 'CONTENT_TYPE' => 'application/json' })
311
424
 
312
- it 'should not 412 when the etags do match (HTML)' do
313
- exp = RuoteKit.engine.process(@wfid).expressions.find { |e|
314
- e.fei.expid == @fei.expid
315
- }
425
+ last_response.status.should be(200)
316
426
 
317
- delete(
318
- "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
319
- nil,
320
- { 'HTTP_IF_MATCH' => ('"%s"' % exp.to_h['_rev'] ) }
321
- )
427
+ #RuoteKit.engine.wait_for(:alpha)
428
+ sleep 0.500
322
429
 
323
- last_response.status.should_not == 412
324
- end
430
+ wi = RuoteKit.engine.storage_participant.first
325
431
 
326
- it 'should not 412 when the etags do match (JSON)' do
327
- exp = RuoteKit.engine.process(@wfid).expressions.find { |e|
328
- e.fei.expid == @fei.expid
329
- }
330
-
331
- delete(
332
- "/_ruote/expressions/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
333
- nil,
334
- {
335
- 'HTTP_IF_MATCH' => ('"%s"' % exp.to_h['_rev'] ),
336
- 'CONTENT_TYPE' => 'application/json',
337
- }
338
- )
432
+ wi.fields['car'].should == 'bentley'
433
+ end
339
434
 
340
- last_response.status.should_not == 412
341
- end
342
- end
435
+ it 're-applies when passed {"expression":{"fields":...}} (JSON)' do
343
436
 
344
- describe 'without running processes' do
437
+ exp = { 'expression' => { 'fields' => { 'car' => 'BMW' } } }
345
438
 
346
- it 'should 404 correctly (HTML)' do
439
+ put(
440
+ "/_ruote/expressions/#{@exp.fei.sid}.json",
441
+ Rufus::Json.encode(exp),
442
+ { 'CONTENT_TYPE' => 'application/json' })
347
443
 
348
- delete '/_ruote/expressions/foo/bar'
444
+ last_response.status.should be(200)
349
445
 
350
- last_response.should_not be_ok
351
- last_response.status.should be(404)
352
- end
446
+ #RuoteKit.engine.wait_for(:alpha)
447
+ sleep 0.500
353
448
 
354
- it 'should 404 correctly (JSON)' do
449
+ wi = RuoteKit.engine.storage_participant.first
355
450
 
356
- delete '/_ruote/expressions/foo/bar.json'
451
+ wi.fields['car'].should == 'BMW'
452
+ end
357
453
 
358
- last_response.should_not be_ok
359
- last_response.status.should be(404)
360
- end
361
- end
362
- end
454
+ it 're-applies with a different tree (HTML)' do
363
455
 
364
- describe 'PUT /_ruote/expressions/fei' do
456
+ put(
457
+ "/_ruote/expressions/#{@exp.fei.sid}",
458
+ :tree => '["charly", {}, []]')
365
459
 
366
- before(:each) do
460
+ last_response.status.should be(302)
461
+ last_response.location.should == "http://example.org/_ruote/expressions/#{@wfid}"
367
462
 
368
- prepare_engine_with_participants
463
+ #RuoteKit.engine.wait_for(:alpha)
464
+ sleep 0.500
465
+
466
+ wi = RuoteKit.engine.storage_participant.first
369
467
 
370
- @wfid = RuoteKit.engine.launch(
468
+ wi.participant_name.should == 'charly'
371
469
 
372
- Ruote.process_definition do
373
- alpha
470
+ RuoteKit.engine.process(@wfid).current_tree.should == ['define', {}, [
471
+ [ 'participant', { '_triggered' => 'on_re_apply', 'ref' => 'charly' }, [] ] ] ]
374
472
  end
375
- )
376
473
 
377
- RuoteKit.engine.wait_for(:alpha)
378
- RuoteKit.engine.wait_for(1)
474
+ it 're-applies with a different tree (JSON)' do
379
475
 
380
- @exp = RuoteKit.engine.process(@wfid).expressions.last
381
- end
476
+ wi = RuoteKit.engine.storage_participant.first
477
+ wi.participant_name.should == 'alpha'
382
478
 
383
- after(:each) do
479
+ put(
480
+ "/_ruote/expressions/#{@exp.fei.sid}.json",
481
+ Rufus::Json.encode({ 'tree' => [ 'bravo', {}, [] ] }),
482
+ { 'CONTENT_TYPE' => 'application/json' })
384
483
 
385
- shutdown_and_purge_engine
386
- end
484
+ last_response.status.should be(200)
387
485
 
388
- it 'should re-apply (HTML)' do
486
+ #RuoteKit.engine.wait_for(:alpha)
487
+ sleep 0.500
389
488
 
390
- at0 = RuoteKit.engine.storage_participant.first.dispatched_at
489
+ wi = RuoteKit.engine.storage_participant.first
391
490
 
392
- put(
393
- "/_ruote/expressions/#{@exp.fei.sid}",
394
- :fields => '{}')
491
+ wi.participant_name.should == 'bravo'
395
492
 
396
- last_response.status.should be(302)
397
- last_response.location.should == "/_ruote/expressions/#{@wfid}"
493
+ RuoteKit.engine.process(@wfid).current_tree.should == [ 'define', {}, [
494
+ [ 'participant', { '_triggered' => 'on_re_apply', 'ref' => 'bravo' }, [] ] ] ]
495
+ end
496
+ end
398
497
 
399
- #RuoteKit.engine.wait_for(:alpha)
400
- sleep 0.500
498
+ context 'pausing and resuming' do
401
499
 
402
- at1 = RuoteKit.engine.storage_participant.first.dispatched_at
500
+ it 'pauses the expression (branch) (HTML)' do
403
501
 
404
- at1.should_not == at0
405
- end
502
+ put(
503
+ "/_ruote/expressions/#{@exp.fei.sid}",
504
+ :state => 'paused')
406
505
 
407
- it 'should re-apply (JSON)' do
506
+ last_response.status.should ==
507
+ 302
508
+ last_response.location.should ==
509
+ "http://example.org/_ruote/expressions/#{@exp.fei.sid}"
408
510
 
409
- #RuoteKit.engine.noisy = true
511
+ sleep 0.500
410
512
 
411
- at0 = RuoteKit.engine.storage_participant.first.dispatched_at
513
+ exp = RuoteKit.engine.ps(@wfid).expressions.last
412
514
 
413
- put(
414
- "/_ruote/expressions/#{@exp.fei.sid}.json",
415
- Rufus::Json.encode({}),
416
- { 'CONTENT_TYPE' => 'application/json' })
515
+ exp.state.should == 'paused'
516
+ end
417
517
 
418
- last_response.status.should be(200)
518
+ it 'pauses the expression (branch) (JSON)' do
419
519
 
420
- #RuoteKit.engine.wait_for(:alpha)
421
- sleep 0.500
520
+ put(
521
+ "/_ruote/expressions/#{@exp.fei.sid}.json",
522
+ '{"state":"paused"}',
523
+ { 'CONTENT_TYPE' => 'application/json' })
422
524
 
423
- at1 = RuoteKit.engine.storage_participant.first.dispatched_at
525
+ last_response.status.should ==
526
+ 302
527
+ last_response.location.should ==
528
+ "http://example.org/_ruote/expressions/#{@exp.fei.sid}.json"
424
529
 
425
- at1.should_not == at0
426
- end
530
+ sleep 0.500
427
531
 
428
- it 'should re-apply with different fields (HTML)' do
532
+ exp = RuoteKit.engine.ps(@wfid).expressions.last
429
533
 
430
- wi = RuoteKit.engine.storage_participant.first
431
- wi.fields['car'].should be(nil)
534
+ exp.state.should == 'paused'
535
+ end
432
536
 
433
- put(
434
- "/_ruote/expressions/#{@exp.fei.sid}",
435
- :fields => '{"car":"daimler-benz"}')
537
+ it 'resumes the expression (branch) (HTML)' do
436
538
 
437
- last_response.status.should be(302)
438
- last_response.location.should == "/_ruote/expressions/#{@wfid}"
539
+ RuoteKit.engine.pause(@exp.fei)
439
540
 
440
- #RuoteKit.engine.wait_for(:alpha)
441
- sleep 0.500
541
+ sleep 0.500
442
542
 
443
- wi = RuoteKit.engine.storage_participant.first
543
+ RuoteKit.engine.ps(@wfid).expressions[-1].state.should == 'paused'
444
544
 
445
- wi.fields['car'].should == 'daimler-benz'
446
- end
545
+ put(
546
+ "/_ruote/expressions/#{@exp.fei.sid}",
547
+ :state => 'resuming')
447
548
 
448
- it 'should re-apply with different fields (JSON)' do
549
+ last_response.status.should ==
550
+ 302
551
+ last_response.location.should ==
552
+ "http://example.org/_ruote/expressions/#{@exp.fei.sid}"
449
553
 
450
- wi = RuoteKit.engine.storage_participant.first
451
- wi.fields['car'].should be(nil)
554
+ sleep 0.500
452
555
 
453
- put(
454
- "/_ruote/expressions/#{@exp.fei.sid}.json",
455
- Rufus::Json.encode({ 'fields' => { 'car' => 'bentley' } }),
456
- { 'CONTENT_TYPE' => 'application/json' })
556
+ RuoteKit.engine.ps(@wfid).expressions[-1].state.should == nil
557
+ end
457
558
 
458
- last_response.status.should be(200)
559
+ it 'resumes the expression (branch) (JSON)' do
459
560
 
460
- #RuoteKit.engine.wait_for(:alpha)
461
- sleep 0.500
561
+ RuoteKit.engine.pause(@exp.fei)
462
562
 
463
- wi = RuoteKit.engine.storage_participant.first
563
+ sleep 0.500
464
564
 
465
- wi.fields['car'].should == 'bentley'
466
- end
565
+ RuoteKit.engine.ps(@wfid).expressions[-1].state.should == 'paused'
566
+
567
+ put(
568
+ "/_ruote/expressions/#{@exp.fei.sid}.json",
569
+ '{"state":"resuming"}',
570
+ { 'CONTENT_TYPE' => 'application/json' })
467
571
 
468
- it 'should re-apply when passed {"expression":{"fields":...}} (JSON)' do
572
+ last_response.status.should ==
573
+ 302
574
+ last_response.location.should ==
575
+ "http://example.org/_ruote/expressions/#{@exp.fei.sid}.json"
469
576
 
470
- exp = { 'expression' => { 'fields' => { 'car' => 'BMW' } } }
577
+ sleep 0.500
471
578
 
472
- put(
473
- "/_ruote/expressions/#{@exp.fei.sid}.json",
474
- Rufus::Json.encode(exp),
475
- { 'CONTENT_TYPE' => 'application/json' })
579
+ RuoteKit.engine.ps(@wfid).expressions[-1].state.should == nil
580
+ end
581
+ end
476
582
 
477
- last_response.status.should be(200)
583
+ context 'pausing as a breakpoint' do
478
584
 
479
- #RuoteKit.engine.wait_for(:alpha)
480
- sleep 0.500
585
+ before(:each) do
481
586
 
482
- wi = RuoteKit.engine.storage_participant.first
587
+ @wfid = RuoteKit.engine.launch(Ruote.define do
588
+ sequence do
589
+ nada
590
+ end
591
+ end)
483
592
 
484
- wi.fields['car'].should == 'BMW'
485
- end
593
+ RuoteKit.engine.wait_for(:nada)
594
+ RuoteKit.engine.wait_for(1)
486
595
 
487
- it 'should re-apply with a different tree (HTML)' do
596
+ @exp = RuoteKit.engine.ps(@wfid).expressions[-2]
597
+ end
488
598
 
489
- put(
490
- "/_ruote/expressions/#{@exp.fei.sid}",
491
- :tree => '["charly", {}, []]')
599
+ it 'pauses the expression (breakpoint) (HTML)' do
492
600
 
493
- last_response.status.should be(302)
494
- last_response.location.should == "/_ruote/expressions/#{@wfid}"
601
+ put(
602
+ "/_ruote/expressions/#{@exp.fei.sid}",
603
+ :state => 'paused', :breakpoint => true)
495
604
 
496
- #RuoteKit.engine.wait_for(:alpha)
497
- sleep 0.500
605
+ last_response.status.should ==
606
+ 302
607
+ last_response.location.should ==
608
+ "http://example.org/_ruote/expressions/#{@exp.fei.sid}"
498
609
 
499
- wi = RuoteKit.engine.storage_participant.first
610
+ sleep 0.500
500
611
 
501
- wi.participant_name.should == 'charly'
612
+ states = RuoteKit.engine.ps(@wfid).expressions.collect { |fexp|
613
+ [ fexp.fei.expid, fexp.state || 'running' ]
614
+ }.join(' ')
502
615
 
503
- RuoteKit.engine.process(@wfid).current_tree.should == [ 'define', {}, [
504
- [ 'participant', { '_triggered' => 'on_re_apply', 'ref' => 'charly' }, [] ] ] ]
505
- end
616
+ states.should == '0 running 0_0 paused 0_0_0 running'
617
+ end
506
618
 
507
- it 'should re-apply with a different tree (JSON)' do
619
+ it 'pauses the expression (breakpoint) (JSON)' do
508
620
 
509
- wi = RuoteKit.engine.storage_participant.first
510
- wi.participant_name.should == 'alpha'
621
+ put(
622
+ "/_ruote/expressions/#{@exp.fei.sid}",
623
+ Rufus::Json.dump({ 'state' => 'paused', 'breakpoint' => true }),
624
+ { 'CONTENT_TYPE' => 'application/json' })
511
625
 
512
- put(
513
- "/_ruote/expressions/#{@exp.fei.sid}.json",
514
- Rufus::Json.encode({ 'tree' => [ 'bravo', {}, [] ] }),
515
- { 'CONTENT_TYPE' => 'application/json' })
626
+ last_response.status.should ==
627
+ 302
628
+ last_response.location.should ==
629
+ "http://example.org/_ruote/expressions/#{@exp.fei.sid}.json"
516
630
 
517
- last_response.status.should be(200)
631
+ sleep 0.500
518
632
 
519
- #RuoteKit.engine.wait_for(:alpha)
520
- sleep 0.500
633
+ states = RuoteKit.engine.ps(@wfid).expressions.collect { |fexp|
634
+ [ fexp.fei.expid, fexp.state || 'running' ]
635
+ }.join(' ')
521
636
 
522
- wi = RuoteKit.engine.storage_participant.first
637
+ states.should == '0 running 0_0 paused 0_0_0 running'
638
+ end
639
+ end
523
640
 
524
- wi.participant_name.should == 'bravo'
641
+ context 'broken JSON' do
525
642
 
526
- RuoteKit.engine.process(@wfid).current_tree.should == [ 'define', {}, [
527
- [ 'participant', { '_triggered' => 'on_re_apply', 'ref' => 'bravo' }, [] ] ] ]
528
- end
643
+ it 'goes 400 when passed broken JSON (HTML)' do
529
644
 
530
- it 'should 400 when passed bogus JSON (HTML)' do
645
+ put(
646
+ "/_ruote/expressions/#{@exp.fei.sid}",
647
+ :fields => "{broken}")
531
648
 
532
- put(
533
- "/_ruote/expressions/#{@exp.fei.sid}",
534
- :fields => "{bogus}")
649
+ last_response.status.should == 400
650
+ end
535
651
 
536
- last_response.status.should == 400
537
- end
652
+ it 'goes 400 when passed broken JSON (JSON)' do
538
653
 
539
- it 'should 400 when passed bogus JSON (JSON)' do
654
+ put(
655
+ "/_ruote/expressions/#{@exp.fei.sid}.json",
656
+ '{"fields":{broken}}',
657
+ { 'CONTENT_TYPE' => 'application/json' })
540
658
 
541
- put(
542
- "/_ruote/expressions/#{@exp.fei.sid}.json",
543
- '{"fields":{bogus}}',
544
- { 'CONTENT_TYPE' => 'application/json' })
659
+ last_response.status.should be(400)
660
+ last_response.json_body['http_error']['code'].should == 400
661
+ last_response.json_body['http_error']['message'].should == 'bad request'
662
+ end
663
+ end
545
664
 
546
- last_response.status.should be(400)
547
- last_response.json_body['http_error']['code'].should == 400
548
- last_response.json_body['http_error']['message'].should == 'bad request'
549
- end
665
+ context 'with etags' do
550
666
 
551
- it 'should 412 when the etags do not match (HTML)' do
667
+ it 'goes 412 when the etags do not match (HTML)' do
552
668
 
553
- put(
554
- "/_ruote/expressions/#{@exp.fei.sid}",
555
- { :fields => '{}' },
556
- { 'HTTP_IF_MATCH' => '"foo"' }
557
- )
669
+ put(
670
+ "/_ruote/expressions/#{@exp.fei.sid}",
671
+ { :fields => '{}' },
672
+ { 'HTTP_IF_MATCH' => '"foo"' }
673
+ )
558
674
 
559
- last_response.status.should == 412
560
- end
675
+ last_response.status.should == 412
676
+ end
561
677
 
562
- it 'should 412 when the etags do not match (JSON)' do
678
+ it 'goes 412 when the etags do not match (JSON)' do
563
679
 
564
- put(
565
- "/_ruote/expressions/#{@exp.fei.sid}",
566
- Rufus::Json.encode({}),
567
- {
568
- 'CONTENT_TYPE' => 'application/json',
569
- 'HTTP_IF_MATCH' => '"foo"'
570
- }
571
- )
680
+ put(
681
+ "/_ruote/expressions/#{@exp.fei.sid}",
682
+ Rufus::Json.encode({}),
683
+ {
684
+ 'CONTENT_TYPE' => 'application/json',
685
+ 'HTTP_IF_MATCH' => '"foo"'
686
+ }
687
+ )
572
688
 
573
- last_response.status.should == 412
574
- end
689
+ last_response.status.should == 412
690
+ end
575
691
 
576
- it 'should not 412 when the etags match (HTML)' do
692
+ it 'does not go 412 when the etags match (HTML)' do
577
693
 
578
- rev = @exp.to_h['_rev']
694
+ rev = @exp.to_h['_rev']
579
695
 
580
- put(
581
- "/_ruote/expressions/#{@exp.fei.sid}",
582
- { :fields => '{}' },
583
- { 'HTTP_IF_MATCH' => ('"%s"' % rev) }
584
- )
696
+ put(
697
+ "/_ruote/expressions/#{@exp.fei.sid}",
698
+ { :fields => '{}' },
699
+ { 'HTTP_IF_MATCH' => ('"%s"' % rev) }
700
+ )
585
701
 
586
- last_response.status.should_not == 412
587
- end
702
+ last_response.status.should_not == 412
703
+ end
588
704
 
589
- it 'should not 412 when the etags match (JSON)' do
705
+ it 'does not go 412 when the etags match (JSON)' do
590
706
 
591
- rev = @exp.to_h['_rev']
707
+ rev = @exp.to_h['_rev']
592
708
 
593
- put(
594
- "/_ruote/expressions/#{@exp.fei.sid}",
595
- Rufus::Json.encode({}),
596
- {
597
- 'CONTENT_TYPE' => 'application/json',
598
- 'HTTP_IF_MATCH' => ('"%s"' % rev )
599
- }
600
- )
709
+ put(
710
+ "/_ruote/expressions/#{@exp.fei.sid}",
711
+ Rufus::Json.encode({}),
712
+ {
713
+ 'CONTENT_TYPE' => 'application/json',
714
+ 'HTTP_IF_MATCH' => ('"%s"' % rev )
715
+ }
716
+ )
601
717
 
602
- last_response.status.should_not == 412
718
+ last_response.status.should_not == 412
719
+ end
720
+ end
603
721
  end
604
722
  end
605
723