ruote-kit 2.2.0.3 → 2.3.0.2

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 (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