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,121 +1,137 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+ require 'spec_helper'
3
3
 
4
4
 
5
- describe 'GET /_ruote/schedules' do
5
+ describe '/_ruote/schedules' do
6
6
 
7
7
  before(:each) do
8
-
9
8
  prepare_engine_with_participants
10
-
11
- @wfid0 = RuoteKit.engine.launch(Ruote.define do
12
- wait :for => '3d'
13
- end)
14
- @wfid1 = RuoteKit.engine.launch(Ruote.define do
15
- sequence do
16
- alpha :timeout => '2d'
17
- end
18
- end)
19
- @wfid2 = RuoteKit.engine.launch(Ruote.define do
20
- nada
21
- end)
22
-
23
- RuoteKit.engine.wait_for(:alpha)
24
9
  end
25
-
26
10
  after(:each) do
27
-
28
11
  shutdown_and_purge_engine
29
12
  end
30
13
 
31
- it 'should list schedules (HTML)' do
14
+ describe 'GET /_ruote/schedules' do
32
15
 
33
- get '/_ruote/schedules'
16
+ before(:each) do
34
17
 
35
- last_response.status.should be(200)
18
+ @wfid0 = RuoteKit.engine.launch(Ruote.define do
19
+ wait :for => '3d'
20
+ end)
21
+ @wfid1 = RuoteKit.engine.launch(Ruote.define do
22
+ sequence do
23
+ alpha :timeout => '2d'
24
+ end
25
+ end)
26
+ @wfid2 = RuoteKit.engine.launch(Ruote.define do
27
+ nada
28
+ end)
36
29
 
37
- last_response.should have_selector(
38
- 'a[rel="http://ruote.rubyforge.org/rels.html#process_schedules"]')
30
+ RuoteKit.engine.wait_for(:alpha)
31
+ end
39
32
 
40
- last_response.should contain('1 to 2 of 2 schedules')
41
- end
33
+ it 'lists schedules (HTML)' do
34
+
35
+ get '/_ruote/schedules'
42
36
 
43
- it 'should list schedules (JSON)' do
37
+ last_response.status.should be(200)
44
38
 
45
- get '/_ruote/schedules.json'
39
+ last_response.should have_selector(
40
+ 'a[rel="http://ruote.rubyforge.org/rels.html#process_schedules"]')
46
41
 
47
- last_response.status.should be(200)
42
+ last_response.should contain('1 to 2 of 2 schedules')
43
+ end
48
44
 
49
- json = last_response.json_body
50
- #puts Rufus::Json.pretty_encode(json)
45
+ it 'lists schedules (JSON)' do
51
46
 
52
- schedules = json['schedules']
47
+ get '/_ruote/schedules.json'
53
48
 
54
- schedules.size.should == 2
49
+ last_response.status.should be(200)
55
50
 
56
- schedules.first.keys.sort.should == %w[
57
- _id action at flavour links original owner put_at target type wfid
58
- ]
51
+ json = last_response.json_body
52
+ #puts Rufus::Json.pretty_encode(json)
59
53
 
60
- schedules.first['target'].should be_kind_of(Hash)
61
- schedules.first['owner'].should be_kind_of(Hash)
54
+ schedules = json['schedules']
62
55
 
63
- hrefs = schedules.collect { |s| s['links'].first['href'] }
64
- prefixes = hrefs.collect { |h| h.split('!').first }.sort
65
- suffixes = hrefs.collect { |h| h.split('!').last }.sort
56
+ schedules.size.should == 2
66
57
 
67
- hrefs = schedules.collect { |s|
68
- s['links'].first['href']
69
- }.collect { |h|
70
- pieces = h.split('!')
71
- pieces.first + '/' + pieces.last
72
- }.sort
58
+ schedules.first.keys.sort.should == %w[
59
+ _id action at flavour links original owner put_at target type wfid
60
+ ]
73
61
 
74
- hrefs.should ==
75
- [ "/_ruote/expressions/0_0/#{@wfid0}",
76
- "/_ruote/expressions/0_0_0/#{@wfid1}" ]
62
+ schedules.first['target'].should be_kind_of(Hash)
63
+ schedules.first['owner'].should be_kind_of(Hash)
64
+
65
+ hrefs = schedules.collect { |s| s['links'].first['href'] }
66
+ prefixes = hrefs.collect { |h| h.split('!').first }.sort
67
+ suffixes = hrefs.collect { |h| h.split('!').last }.sort
68
+
69
+ hrefs = schedules.collect { |s|
70
+ s['links'].first['href']
71
+ }.collect { |h|
72
+ pieces = h.split('!')
73
+ pieces.first + '/' + pieces.last
74
+ }.sort
75
+
76
+ hrefs.should ==
77
+ [ "/_ruote/expressions/0_0/#{@wfid0}",
78
+ "/_ruote/expressions/0_0_0/#{@wfid1}" ]
79
+ end
77
80
  end
78
- end
79
81
 
80
- describe 'GET /_ruote/schedules/wfid' do
82
+ describe 'GET /_ruote/schedules/:wfid' do
81
83
 
82
- before(:each) do
84
+ before(:each) do
83
85
 
84
- prepare_engine_with_participants
86
+ @wfid0 = RuoteKit.engine.launch(Ruote.define do
87
+ wait :for => '3d'
88
+ end)
89
+ @wfid1 = RuoteKit.engine.launch(Ruote.define do
90
+ sequence do
91
+ alpha :timeout => '2d'
92
+ end
93
+ end)
85
94
 
86
- @wfid0 = RuoteKit.engine.launch(Ruote.define do
87
- wait :for => '3d'
88
- end)
89
- @wfid1 = RuoteKit.engine.launch(Ruote.define do
90
- sequence do
91
- alpha :timeout => '2d'
92
- end
93
- end)
95
+ RuoteKit.engine.wait_for(:alpha)
94
96
 
95
- RuoteKit.engine.wait_for(:alpha)
96
- end
97
+ @wfid2 = RuoteKit.engine.launch(Ruote.define do
98
+ bravo :timers => '1d: x, 2d: timeout'
99
+ end)
97
100
 
98
- after(:each) do
101
+ RuoteKit.engine.wait_for(:bravo)
102
+ end
99
103
 
100
- shutdown_and_purge_engine
101
- end
104
+ it 'lists schedules (HTML)' do
102
105
 
103
- it 'should list schedules (HTML)' do
106
+ get "/_ruote/schedules/#{@wfid1}"
104
107
 
105
- get "/_ruote/schedules/#{@wfid1}"
108
+ last_response.status.should be(200)
109
+ end
106
110
 
107
- last_response.status.should be(200)
108
- end
111
+ it 'lists schedules (JSON)' do
112
+
113
+ get "/_ruote/schedules/#{@wfid0}.json"
114
+
115
+ last_response.status.should be(200)
116
+
117
+ #puts Rufus::Json.pretty_encode(last_response.json_body)
118
+
119
+ last_response.json_body['schedules'].size.should == 1
120
+ end
121
+
122
+ it 'list schedules with timers (nil target) (HTML)' do
109
123
 
110
- it 'should list schedules (JSON)' do
124
+ get "/_ruote/schedules/#{@wfid2}"
111
125
 
112
- get "/_ruote/schedules/#{@wfid0}.json"
126
+ last_response.status.should be(200)
127
+ end
113
128
 
114
- last_response.status.should be(200)
129
+ it 'list schedules with timers (nil target) (JSON)' do
115
130
 
116
- #puts Rufus::Json.pretty_encode(last_response.json_body)
131
+ get "/_ruote/schedules/#{@wfid2}.json"
117
132
 
118
- last_response.json_body['schedules'].size.should == 1
133
+ last_response.status.should be(200)
134
+ end
119
135
  end
120
136
  end
121
137
 
@@ -1,542 +1,551 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+ require 'spec_helper'
3
3
 
4
4
 
5
- def workitem_count(from, to, of)
6
- [
7
- from, 'to', to, 'of', of, 'workitems'
8
- ].collect { |e|
9
- e.to_s
10
- }.join("\n ")
11
- end
12
-
13
-
14
- describe 'GET /_ruote/workitems' do
5
+ describe '/_ruote/workitems' do
15
6
 
16
7
  before(:each) do
17
-
18
8
  prepare_engine
19
9
  end
20
-
21
10
  after(:each) do
22
-
23
11
  shutdown_and_purge_engine
24
12
  end
25
13
 
26
- describe 'without any workitems' do
14
+ def workitem_count(from, to, of)
27
15
 
28
- it 'should report no workitems (HTML)' do
29
-
30
- get '/_ruote/workitems'
16
+ /\s#{from}\s+to\s+#{to}\s+of\s+#{of}\s/
17
+ end
31
18
 
32
- last_response.should be_ok
19
+ describe 'GET /_ruote/workitems' do
33
20
 
34
- last_response.should match(workitem_count(0, 0, 0))
35
- end
21
+ context 'without any workitems' do
36
22
 
37
- it 'should report no workitems (JSON)' do
23
+ it 'reports no workitems (HTML)' do
38
24
 
39
- get '/_ruote/workitems.json'
25
+ get '/_ruote/workitems'
40
26
 
41
- last_response.should be_ok
42
- json = last_response.json_body
27
+ last_response.should be_ok
43
28
 
44
- json.should have_key('workitems')
45
- json['workitems'].should be_empty
46
- end
47
- end
29
+ last_response.should match(workitem_count(0, 0, 0))
30
+ end
48
31
 
49
- describe 'with workitems' do
32
+ it 'reports no workitems (JSON)' do
50
33
 
51
- before(:each) do
34
+ get '/_ruote/workitems.json'
52
35
 
53
- register_participants
36
+ last_response.should be_ok
37
+ json = last_response.json_body
54
38
 
55
- @wfid = RuoteKit.engine.launch(Ruote.process_definition do
56
- sequence do
57
- nada :activity => 'Work your magic'
58
- end
59
- end)
60
-
61
- RuoteKit.engine.wait_for(:nada)
62
- RuoteKit.engine.wait_for(1)
39
+ json.should have_key('workitems')
40
+ json['workitems'].should be_empty
41
+ end
63
42
  end
64
43
 
65
- it 'should have a list of workitems (HTML)' do
44
+ context 'with workitems' do
66
45
 
67
- get '/_ruote/workitems'
46
+ before(:each) do
68
47
 
69
- last_response.should match(workitem_count(1, 1, 1))
70
- end
48
+ register_participants
71
49
 
72
- it 'should have a list of workitems (JSON)' do
50
+ @wfid = RuoteKit.engine.launch(Ruote.process_definition do
51
+ sequence do
52
+ nada :activity => 'Work your magic'
53
+ end
54
+ end)
73
55
 
74
- get '/_ruote/workitems.json'
56
+ RuoteKit.engine.wait_for(:nada)
57
+ RuoteKit.engine.wait_for(1)
58
+ end
75
59
 
76
- last_response.should be_ok
77
- json = last_response.json_body
60
+ it 'returns a list of workitems (HTML)' do
78
61
 
79
- json['workitems'].size.should == 1
62
+ get '/_ruote/workitems'
80
63
 
81
- wi = json['workitems'][0]
64
+ last_response.should match(workitem_count(1, 1, 1))
65
+ last_response.should have_selector('td', :content => @wfid)
66
+ end
82
67
 
83
- wi.keys.should include('fei', 'participant_name', 'fields')
84
- wi['wfid'].should == @wfid
85
- wi['participant_name'].should == 'nada'
86
- wi['fields']['params']['activity'].should == 'Work your magic'
87
- end
88
- end
89
- end
68
+ it 'returns a list of workitems (JSON)' do
90
69
 
91
- describe 'GET /_ruote/workitems/wfid' do
70
+ get '/_ruote/workitems.json'
92
71
 
93
- before(:each) do
72
+ last_response.status.should == 200
94
73
 
95
- prepare_engine
96
- end
74
+ json = last_response.json_body
97
75
 
98
- after(:each) do
76
+ json['workitems'].size.should == 1
99
77
 
100
- shutdown_and_purge_engine
101
- end
78
+ wi = json['workitems'][0]
102
79
 
103
- describe 'with workitems' do
80
+ wi.keys.should include('fei', 'participant_name', 'fields')
81
+ wi['wfid'].should == @wfid
82
+ wi['participant_name'].should == 'nada'
83
+ wi['fields']['params']['activity'].should == 'Work your magic'
84
+ end
104
85
 
105
- before(:each) do
86
+ it 'respects skip and limit (HTML)' do
106
87
 
107
- register_participants
88
+ get '/_ruote/workitems?limit=100&skip=0'
108
89
 
109
- @wfid = RuoteKit.engine.launch(Ruote.process_definition do
110
- concurrence do
111
- nada :activity => 'This'
112
- nada :activity => 'Or that'
113
- end
114
- end)
90
+ last_response.should match(workitem_count(1, 1, 1))
91
+ last_response.should have_selector('td', :content => @wfid)
92
+ end
115
93
 
116
- RuoteKit.engine.wait_for(:nada)
117
- RuoteKit.engine.wait_for(1)
118
- end
94
+ it 'respects skip and limit (JSON)' do
119
95
 
120
- it 'should list the workitems (HTML)' do
96
+ get '/_ruote/workitems.json?limit=100&skip=0'
121
97
 
122
- get "/_ruote/workitems/#{@wfid}"
98
+ last_response.status.should == 200
123
99
 
124
- last_response.should be_ok
100
+ json = last_response.json_body
125
101
 
126
- last_response.should have_selector(
127
- 'div#pagination', :content => '2 workitems')
102
+ json['workitems'].size.should == 1
103
+ end
128
104
  end
105
+ end
129
106
 
130
- it 'should list the workitems (JSON)' do
107
+ describe 'GET /_ruote/workitems/:wfid' do
131
108
 
132
- get "/_ruote/workitems/#{@wfid}.json"
109
+ context 'with workitems' do
133
110
 
134
- last_response.should be_ok
111
+ before(:each) do
135
112
 
136
- json = last_response.json_body
113
+ register_participants
137
114
 
138
- json.should have_key('workitems')
139
- json['workitems'].should_not be_empty
140
- end
141
- end
115
+ @wfid = RuoteKit.engine.launch(Ruote.process_definition do
116
+ concurrence do
117
+ nada :activity => 'This'
118
+ nada :activity => 'Or that'
119
+ end
120
+ end)
142
121
 
143
- describe 'without workitems' do
122
+ RuoteKit.engine.wait_for(:nada)
123
+ RuoteKit.engine.wait_for(1)
124
+ end
144
125
 
145
- it 'should report no workitems (HTML)' do
126
+ it 'lists the workitems (HTML)' do
146
127
 
147
- get '/_ruote/workitems/foo'
128
+ get "/_ruote/workitems/#{@wfid}"
148
129
 
149
- last_response.should be_ok
130
+ last_response.should be_ok
150
131
 
151
- last_response.should have_selector(
152
- 'div#pagination', :content => '0 workitems')
153
- end
132
+ last_response.should have_selector(
133
+ 'div#pagination', :content => '2 workitems')
134
+ end
154
135
 
155
- it 'should report an empty list (JSON)' do
136
+ it 'lists the workitems (JSON)' do
156
137
 
157
- get '/_ruote/workitems/foo.json'
138
+ get "/_ruote/workitems/#{@wfid}.json"
158
139
 
159
- last_response.should be_ok
140
+ last_response.should be_ok
160
141
 
161
- json = last_response.json_body
142
+ json = last_response.json_body
162
143
 
163
- json.should have_key('workitems')
164
- json['workitems'].should be_empty
144
+ json.should have_key('workitems')
145
+ json['workitems'].should_not be_empty
146
+ end
165
147
  end
166
- end
167
- end
168
148
 
169
- describe 'GET /_ruote/workitems/expid!subid!wfid' do
149
+ context 'without workitems' do
170
150
 
171
- before(:each) do
151
+ it 'reports no workitems (HTML)' do
172
152
 
173
- prepare_engine_with_participants
174
- end
153
+ get '/_ruote/workitems/foo'
175
154
 
176
- after(:each) do
155
+ last_response.should be_ok
177
156
 
178
- shutdown_and_purge_engine
179
- end
157
+ last_response.should have_selector(
158
+ 'div#pagination', :content => '0 workitems')
159
+ end
180
160
 
181
- describe 'with a workitem' do
161
+ it 'reports an empty list (JSON)' do
182
162
 
183
- before(:each) do
163
+ get '/_ruote/workitems/foo.json'
184
164
 
185
- @wfid = RuoteKit.engine.launch(Ruote.process_definition do
186
- sequence do
187
- nada :activity => 'Work your magic'
188
- end
189
- end)
165
+ last_response.should be_ok
190
166
 
191
- RuoteKit.engine.wait_for(:nada)
167
+ json = last_response.json_body
192
168
 
193
- @fei = engine.process(@wfid).expressions.last.fei
169
+ json.should have_key('workitems')
170
+ json['workitems'].should be_empty
171
+ end
194
172
  end
173
+ end
195
174
 
196
- it 'should return it (HTML)' do
175
+ describe 'GET /_ruote/workitems/expid!subid!wfid' do
197
176
 
198
- get "/_ruote/workitems/#{@fei.sid}"
177
+ context 'with a workitem' do
199
178
 
200
- last_response.should be_ok
201
- end
179
+ before(:each) do
202
180
 
203
- it 'should return it (JSON)' do
181
+ register_participants
204
182
 
205
- get "/_ruote/workitems/#{@fei.sid}.json"
183
+ @wfid = RuoteKit.engine.launch(
184
+ Ruote.process_definition(:name => 'x', :rev => 'y') do
185
+ sequence do
186
+ nada :activity => 'Work your magic'
187
+ end
188
+ end)
206
189
 
207
- last_response.should be_ok
208
- end
190
+ RuoteKit.engine.wait_for(:nada)
209
191
 
210
- it 'should provide a workitem with the correct links (JSON)' do
192
+ @fei = engine.process(@wfid).expressions.last.fei
193
+ end
211
194
 
212
- get "/_ruote/workitems/#{@fei.sid}.json"
195
+ it 'returns it (HTML)' do
213
196
 
214
- last_response.json_body['workitem']['links'].collect { |li|
215
- li['rel']
216
- }.should == %w[
217
- self
218
- http://ruote.rubyforge.org/rels.html#process
219
- http://ruote.rubyforge.org/rels.html#process_expressions
220
- http://ruote.rubyforge.org/rels.html#process_errors
221
- ]
222
- end
197
+ get "/_ruote/workitems/#{@fei.sid}"
223
198
 
224
- it 'should include an etag header (HTML)' do
199
+ last_response.should be_ok
200
+ end
225
201
 
226
- get "/_ruote/workitems/#{@fei.sid}"
202
+ it 'returns it (JSON)' do
227
203
 
228
- last_response.headers.should include('ETag')
229
- last_response.headers['ETag'].should == "\"#{find_workitem(@wfid, @nada_exp_id).to_h['_rev'].to_s}\""
230
- end
204
+ get "/_ruote/workitems/#{@fei.sid}.json"
231
205
 
232
- it 'should include an etag header (JSON)' do
206
+ last_response.should be_ok
207
+ end
233
208
 
234
- get "/_ruote/workitems/#{@fei.sid}.json"
209
+ it 'provides a workitem with the correct links (JSON)' do
210
+
211
+ get "/_ruote/workitems/#{@fei.sid}.json"
212
+
213
+ last_response.json_body['workitem']['links'].collect { |li|
214
+ li['rel']
215
+ }.should == %w[
216
+ self
217
+ http://ruote.rubyforge.org/rels.html#process
218
+ http://ruote.rubyforge.org/rels.html#expression
219
+ http://ruote.rubyforge.org/rels.html#process_expressions
220
+ http://ruote.rubyforge.org/rels.html#process_errors
221
+ ]
222
+
223
+ link_for(
224
+ last_response.json_body['workitem']['links'], 'self'
225
+ ).should ==
226
+ "/_ruote/workitems/#{@fei.sid}"
227
+
228
+ link_for(
229
+ last_response.json_body['workitem']['links'], '#expression'
230
+ ).should ==
231
+ "/_ruote/expressions/#{@fei.sid}"
232
+
233
+ link_for(
234
+ last_response.json_body['workitem']['links'], '#process_expressions'
235
+ ).should ==
236
+ "/_ruote/expressions/#{@fei.wfid}"
237
+ end
235
238
 
236
- last_response.headers.should include('ETag')
237
- last_response.headers['ETag'].should == "\"#{find_workitem(@wfid, @nada_exp_id).to_h['_rev'].to_s}\""
238
- end
239
- end
239
+ it 'includes an etag header (HTML)' do
240
240
 
241
- describe 'without a workitem' do
241
+ get "/_ruote/workitems/#{@fei.sid}"
242
242
 
243
- it 'should return a 404 (HTML)' do
243
+ last_response.headers.should include('ETag')
244
+ last_response.headers['ETag'].should == "\"#{find_workitem(@wfid, @nada_exp_id).to_h['_rev'].to_s}\""
245
+ end
244
246
 
245
- get '/_ruote/workitems/foo/bar'
247
+ it 'includes an etag header (JSON)' do
246
248
 
247
- last_response.should_not be_ok
248
- last_response.status.should be(404)
249
- end
249
+ get "/_ruote/workitems/#{@fei.sid}.json"
250
250
 
251
- it 'should return a 404 (JSON)' do
251
+ last_response.headers.should include('ETag')
252
+ last_response.headers['ETag'].should == "\"#{find_workitem(@wfid, @nada_exp_id).to_h['_rev'].to_s}\""
253
+ end
254
+
255
+ it 'includes a wf_name and a wf_revision (JSON)' do
252
256
 
253
- get '/_ruote/workitems/foo/bar.json'
257
+ get "/_ruote/workitems/#{@fei.sid}.json"
254
258
 
255
- last_response.should_not be_ok
256
- last_response.status.should be(404)
259
+ last_response.json_body['workitem']['wf_name'].should_not == nil
260
+ last_response.json_body['workitem']['wf_revision'].should_not == nil
261
+ end
257
262
  end
258
- end
259
- end
260
263
 
261
- describe 'PUT /_ruote/workitems/fei' do
264
+ context 'without a workitem' do
262
265
 
263
- before(:each) do
266
+ it 'returns a 404 (HTML)' do
264
267
 
265
- prepare_engine_with_participants
268
+ get '/_ruote/workitems/foo/bar'
266
269
 
267
- @wfid = RuoteKit.engine.launch(Ruote.process_definition do
268
- sequence do
269
- nada :activity => 'Work your magic'
270
- echo '${f:foo}'
270
+ last_response.should_not be_ok
271
+ last_response.status.should be(404)
271
272
  end
272
- end)
273
273
 
274
- RuoteKit.engine.wait_for(:nada)
274
+ it 'returns a 404 (JSON)' do
275
275
 
276
- @fei = engine.process(@wfid).expressions.last.fei
276
+ get '/_ruote/workitems/foo/bar.json'
277
277
 
278
- @fields = {
279
- 'params' => { 'activity' => 'Work your magic' }, 'foo' => 'bar'
280
- }
281
- end
282
-
283
- after(:each) do
284
-
285
- shutdown_and_purge_engine
278
+ last_response.should_not be_ok
279
+ last_response.status.should be(404)
280
+ end
281
+ end
286
282
  end
287
283
 
288
- it 'should update the workitem fields (HTML)' do
284
+ describe 'PUT /_ruote/workitems/:fei' do
289
285
 
290
- put(
291
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
292
- :fields => Rufus::Json.encode(@fields))
286
+ before(:each) do
293
287
 
294
- last_response.should be_redirect
288
+ register_participants
295
289
 
296
- last_response['Location'].should ==
297
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}"
290
+ @wfid = RuoteKit.engine.launch(Ruote.process_definition do
291
+ sequence do
292
+ nada :activity => 'Work your magic'
293
+ echo '${f:foo}'
294
+ end
295
+ end)
298
296
 
299
- find_workitem(@wfid, @nada_exp_id).fields.should == @fields
297
+ RuoteKit.engine.wait_for(:nada)
300
298
 
301
- sleep 0.4
299
+ @fei = engine.process(@wfid).expressions.last.fei
302
300
 
303
- @tracer.to_s.should == ''
304
- end
301
+ @fields = {
302
+ 'params' => { 'activity' => 'Work your magic' }, 'foo' => 'bar'
303
+ }
304
+ end
305
305
 
306
- it 'should update the workitem fields (JSON)' do
306
+ it 'updates the workitem fields (HTML)' do
307
307
 
308
- params = { 'fields' => @fields }
308
+ put(
309
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
310
+ :fields => Rufus::Json.encode(@fields))
309
311
 
310
- put(
311
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
312
- Rufus::Json.encode(params),
313
- { 'CONTENT_TYPE' => 'application/json' })
312
+ last_response.should be_redirect
314
313
 
315
- last_response.should be_ok
314
+ last_response['Location'].should ==
315
+ "http://example.org/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}"
316
316
 
317
- find_workitem(@wfid, @nada_exp_id).fields.should == @fields
317
+ find_workitem(@wfid, @nada_exp_id).fields.should == @fields
318
318
 
319
- sleep 0.4
319
+ sleep 0.4
320
320
 
321
- @tracer.to_s.should == ''
322
- end
321
+ @tracer.to_s.should == ''
322
+ end
323
323
 
324
- it 'should update the fields when passed {"workitem":...} (JSON)' do
324
+ it 'updates the workitem fields (JSON)' do
325
325
 
326
- params = { 'workitem' => { 'fields' => @fields } }
326
+ params = { 'fields' => @fields }
327
327
 
328
- put(
329
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
330
- Rufus::Json.encode(params),
331
- { 'CONTENT_TYPE' => 'application/json' })
328
+ put(
329
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
330
+ Rufus::Json.encode(params),
331
+ { 'CONTENT_TYPE' => 'application/json' })
332
332
 
333
- last_response.should be_ok
333
+ last_response.should be_ok
334
334
 
335
- find_workitem(@wfid, @nada_exp_id).fields.should == @fields
336
- end
335
+ find_workitem(@wfid, @nada_exp_id).fields.should == @fields
337
336
 
338
- it 'should reply to the engine (HTML)' do
337
+ sleep 0.4
339
338
 
340
- fields = Rufus::Json.encode(@fields)
339
+ @tracer.to_s.should == ''
340
+ end
341
341
 
342
- put(
343
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
344
- :fields => fields,
345
- :_proceed => '1')
342
+ it 'updates the fields when passed {"workitem":...} (JSON)' do
346
343
 
347
- last_response.should be_redirect
348
- last_response['Location'].should == "/_ruote/workitems/#{@wfid}"
344
+ params = { 'workitem' => { 'fields' => @fields } }
349
345
 
350
- #engine.context[:s_logger].wait_for([
351
- # [ :processes, :terminated, { :wfid => @wfid } ],
352
- # [ :errors, nil, { :wfid => @wfid } ]
353
- #])
354
- sleep 0.5
346
+ put(
347
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
348
+ Rufus::Json.encode(params),
349
+ { 'CONTENT_TYPE' => 'application/json' })
355
350
 
356
- @tracer.to_s.should == 'bar'
357
- end
351
+ last_response.should be_ok
358
352
 
359
- it 'should reply to the engine (JSON)' do
353
+ find_workitem(@wfid, @nada_exp_id).fields.should == @fields
354
+ end
360
355
 
361
- params = { 'fields' => @fields, '_proceed' => '1' }
356
+ it 'replies to the engine (HTML)' do
362
357
 
363
- put(
364
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
365
- Rufus::Json.encode(params),
366
- { 'CONTENT_TYPE' => 'application/json' })
358
+ fields = Rufus::Json.encode(@fields)
367
359
 
368
- last_response.should be_ok
360
+ put(
361
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
362
+ :fields => fields,
363
+ :_proceed => '1')
369
364
 
370
- #engine.context[:s_logger].wait_for([
371
- # [ :processes, :terminated, { :wfid => @wfid } ],
372
- # [ :errors, nil, { :wfid => @wfid } ]
373
- #])
374
- sleep 0.5
365
+ last_response.should be_redirect
366
+ last_response['Location'].should == "http://example.org/_ruote/workitems/#{@wfid}"
375
367
 
376
- @tracer.to_s.should == 'bar'
377
- end
368
+ #engine.context[:s_logger].wait_for([
369
+ # [ :processes, :terminated, { :wfid => @wfid } ],
370
+ # [ :errors, nil, { :wfid => @wfid } ]
371
+ #])
372
+ sleep 0.5
378
373
 
379
- it 'should 400 when passed bogus JSON fields (HTML)' do
374
+ @tracer.to_s.should == 'bar'
375
+ end
380
376
 
381
- put(
382
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
383
- :fields => '{"bogus"}')
377
+ it 'replies to the engine (JSON)' do
384
378
 
385
- last_response.status.should be(400)
386
- end
379
+ params = { 'fields' => @fields, '_proceed' => '1' }
387
380
 
388
- it 'should 400 when passed bogus JSON fields (JSON)' do
381
+ put(
382
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
383
+ Rufus::Json.encode(params),
384
+ { 'CONTENT_TYPE' => 'application/json' })
389
385
 
390
- put(
391
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
392
- "{'bogus'}",
393
- { 'CONTENT_TYPE' => 'application/json' })
386
+ last_response.should be_ok
394
387
 
395
- last_response.status.should be(400)
396
- end
388
+ #engine.context[:s_logger].wait_for([
389
+ # [ :processes, :terminated, { :wfid => @wfid } ],
390
+ # [ :errors, nil, { :wfid => @wfid } ]
391
+ #])
392
+ sleep 0.5
397
393
 
398
- it 'should 412 if the etags do not match (HTML)' do
394
+ @tracer.to_s.should == 'bar'
395
+ end
399
396
 
400
- workitem = find_workitem(@wfid, @nada_exp_id)
401
- old_rev = workitem.to_h['_rev']
397
+ it 'goes 400 when passed bogus JSON fields (HTML)' do
402
398
 
403
- workitem.fields = {'baz' => 'bar'}.merge!(@fields)
404
- RuoteKit.engine.storage_participant.update(workitem)
399
+ put(
400
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
401
+ :fields => '{"bogus"}')
405
402
 
406
- put(
407
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
408
- { :fields => Rufus::Json.encode(@fields) },
409
- { 'HTTP_IF_MATCH' => ('"%s"' % old_rev) }
410
- )
403
+ last_response.status.should be(400)
404
+ end
411
405
 
412
- last_response.status.should be(412)
413
- end
406
+ it 'goes 400 when passed bogus JSON fields (JSON)' do
414
407
 
415
- it 'should 412 if the etags do not match (JSON)' do
408
+ put(
409
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
410
+ "{'bogus'}",
411
+ { 'CONTENT_TYPE' => 'application/json' })
416
412
 
417
- workitem = find_workitem(@wfid, @nada_exp_id)
413
+ last_response.status.should be(400)
414
+ end
418
415
 
419
- old_rev = workitem.to_h['_rev']
416
+ it 'goes 412 if the etags do not match (HTML)' do
420
417
 
421
- workitem.fields = {'baz' => 'bar'}.merge!(@fields)
422
- RuoteKit.engine.storage_participant.update(workitem)
418
+ workitem = find_workitem(@wfid, @nada_exp_id)
419
+ old_rev = workitem.to_h['_rev']
423
420
 
424
- params = { 'workitem' => { 'fields' => @fields } }
421
+ workitem.fields = {'baz' => 'bar'}.merge!(@fields)
422
+ RuoteKit.engine.storage_participant.update(workitem)
425
423
 
426
- put(
427
- "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
428
- Rufus::Json.encode(params),
429
- {
430
- 'CONTENT_TYPE' => 'application/json',
431
- 'HTTP_IF_MATCH' => ('"%s"' % old_rev)
432
- }
433
- )
424
+ put(
425
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}",
426
+ { :fields => Rufus::Json.encode(@fields) },
427
+ { 'HTTP_IF_MATCH' => ('"%s"' % old_rev) }
428
+ )
434
429
 
435
- last_response.status.should be(412)
436
- end
437
- end
430
+ last_response.status.should be(412)
431
+ end
438
432
 
439
- describe 'Filtering workitems' do
433
+ it 'goes 412 if the etags do not match (JSON)' do
440
434
 
441
- before(:each) do
435
+ workitem = find_workitem(@wfid, @nada_exp_id)
442
436
 
443
- prepare_engine_with_participants
437
+ old_rev = workitem.to_h['_rev']
444
438
 
445
- @wfid = RuoteKit.engine.launch(Ruote.process_definition do
446
- set 'foo' => 'bar'
447
- concurrence do
448
- sequence do
449
- set 'wands' => 101
450
- set 'hinkypinky' => 'honkytonky'
451
- jack :activity => 'Fetch a pale'
452
- end
453
- sequence do
454
- set 'hinkypinky' => 'honkytonky'
455
- jill :activity => 'Chase Jack'
456
- end
457
- well :activity => 'Ready water'
458
- end
459
- end)
439
+ workitem.fields = {'baz' => 'bar'}.merge!(@fields)
440
+ RuoteKit.engine.storage_participant.update(workitem)
460
441
 
461
- RuoteKit.engine.wait_for(:jack)
462
- RuoteKit.engine.wait_for(1)
463
- end
442
+ params = { 'workitem' => { 'fields' => @fields } }
464
443
 
465
- after(:each) do
444
+ put(
445
+ "/_ruote/workitems/#{@fei.expid}!#{@fei.subid}!#{@wfid}.json",
446
+ Rufus::Json.encode(params),
447
+ {
448
+ 'CONTENT_TYPE' => 'application/json',
449
+ 'HTTP_IF_MATCH' => ('"%s"' % old_rev)
450
+ }
451
+ )
466
452
 
467
- shutdown_and_purge_engine
453
+ last_response.status.should be(412)
454
+ end
468
455
  end
469
456
 
470
- describe 'on participants' do
457
+ describe 'Filtering workitems' do
471
458
 
472
- it 'should narrow results down to a single participant (JSON)' do
459
+ before(:each) do
473
460
 
474
- get '/_ruote/workitems.json', :participant => 'jack'
461
+ register_participants
475
462
 
476
- last_response.should be_ok
463
+ @wfid = RuoteKit.engine.launch(Ruote.process_definition do
464
+ set 'foo' => 'bar'
465
+ concurrence do
466
+ sequence do
467
+ set 'wands' => 101
468
+ set 'hinkypinky' => 'honkytonky'
469
+ jack :activity => 'Fetch a pale'
470
+ end
471
+ sequence do
472
+ set 'hinkypinky' => 'honkytonky'
473
+ jill :activity => 'Chase Jack'
474
+ end
475
+ well :activity => 'Ready water'
476
+ end
477
+ end)
477
478
 
478
- last_response.json_body['workitems'].size.should == 1
479
+ RuoteKit.engine.wait_for(:jack)
480
+ RuoteKit.engine.wait_for(1)
479
481
  end
480
482
 
481
- it 'should narrow results down to a single participant (HTML)' do
483
+ context 'on participants' do
482
484
 
483
- get '/_ruote/workitems', :participant => 'jack'
485
+ it 'narrows results down to a single participant (JSON)' do
484
486
 
485
- last_response.should be_ok
487
+ get '/_ruote/workitems.json', :participant => 'jack'
486
488
 
487
- last_response.should match(workitem_count(1, 3, 3))
488
- end
489
+ last_response.should be_ok
490
+ last_response.json_body['workitems'].size.should == 1
491
+ end
489
492
 
490
- end
493
+ it 'narrows results down to a single participant (HTML)' do
491
494
 
492
- describe 'on field values' do
495
+ get '/_ruote/workitems', :participant => 'jack'
493
496
 
494
- it 'should find workitems with fields set to a given value (JSON)' do
497
+ last_response.should be_ok
498
+ last_response.should match(workitem_count(1, 3, 3))
499
+ end
495
500
 
496
- get '/_ruote/workitems.json', :hinkypinky => 'honkytonky'
501
+ end
497
502
 
498
- last_response.should be_ok
503
+ context 'on field values' do
499
504
 
500
- last_response.json_body['workitems'].size.should == 2
501
- end
505
+ it 'finds workitems with fields set to a given value (JSON)' do
502
506
 
503
- it 'should find workitems with fields set to a given value (HTML)' do
507
+ get '/_ruote/workitems.json', :hinkypinky => 'honkytonky'
504
508
 
505
- get '/_ruote/workitems', :hinkypinky => 'honkytonky'
509
+ last_response.should be_ok
510
+ last_response.json_body['workitems'].size.should == 2
511
+ end
506
512
 
507
- last_response.should be_ok
508
- end
513
+ it 'finds workitems with fields set to a given value (HTML)' do
509
514
 
510
- it 'should respect JSON encoded filter vars (JSON)' do
515
+ get '/_ruote/workitems', :hinkypinky => 'honkytonky'
511
516
 
512
- get '/_ruote/workitems.json', :wands => 101
517
+ last_response.should be_ok
518
+ end
513
519
 
514
- last_response.should be_ok
520
+ it 'respects JSON encoded filter vars (JSON)' do
515
521
 
516
- last_response.json_body['workitems'].size.should == 1
517
- end
522
+ get '/_ruote/workitems.json', :wands => 101
518
523
 
519
- it 'should respect JSON encoded filter vars (HTML)' do
524
+ last_response.should be_ok
525
+ last_response.json_body['workitems'].size.should == 1
526
+ end
520
527
 
521
- get '/_ruote/workitems', :wands => 101
528
+ it 'respects JSON encoded filter vars (HTML)' do
522
529
 
523
- last_response.should be_ok
524
- end
530
+ get '/_ruote/workitems', :wands => 101
525
531
 
526
- it "should combine search criteria by 'and' (JSON)" do
532
+ last_response.should be_ok
533
+ end
527
534
 
528
- get '/_ruote/workitems.json', :hinkypinky => 'honkytonky', :wands => 101
535
+ it "should combine search criteria by 'and' (JSON)" do
529
536
 
530
- last_response.should be_ok
537
+ get '/_ruote/workitems.json', :hinkypinky => 'honkytonky', :wands => 101
531
538
 
532
- last_response.json_body['workitems'].size.should == 1
533
- end
539
+ last_response.should be_ok
540
+ last_response.json_body['workitems'].size.should == 1
541
+ end
534
542
 
535
- it "should combine search criteria by 'and' (HMTL)" do
543
+ it "should combine search criteria by 'and' (HMTL)" do
536
544
 
537
- get '/_ruote/workitems', :hinkypinky => 'honkytonky', :wands => 101
545
+ get '/_ruote/workitems', :hinkypinky => 'honkytonky', :wands => 101
538
546
 
539
- last_response.should be_ok
547
+ last_response.should be_ok
548
+ end
540
549
  end
541
550
  end
542
551
  end