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