amee 2.6.0 → 2.7.0

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 (46) hide show
  1. data/Gemfile +18 -0
  2. data/README +2 -2
  3. data/Rakefile +31 -0
  4. data/VERSION +1 -0
  5. data/amee-ruby.gemspec +147 -0
  6. data/examples/view_profile_item.rb +32 -0
  7. data/lib/amee.rb +0 -1
  8. data/lib/amee/profile_item.rb +27 -6
  9. data/spec/amee_spec.rb +25 -0
  10. data/spec/cache_spec.rb +152 -0
  11. data/spec/connection_spec.rb +295 -0
  12. data/spec/data_category_spec.rb +259 -0
  13. data/spec/data_item_spec.rb +224 -0
  14. data/spec/data_item_value_history_spec.rb +311 -0
  15. data/spec/data_item_value_spec.rb +231 -0
  16. data/spec/data_object_spec.rb +9 -0
  17. data/spec/drill_down_spec.rb +163 -0
  18. data/spec/fixtures/AD63A83B4D41.json +1 -0
  19. data/spec/fixtures/AD63A83B4D41.xml +1 -0
  20. data/spec/fixtures/create_item.json +1 -0
  21. data/spec/fixtures/create_item.xml +1 -0
  22. data/spec/fixtures/data.json +1 -0
  23. data/spec/fixtures/data.xml +1 -0
  24. data/spec/fixtures/data_home_energy_quantity.xml +146 -0
  25. data/spec/fixtures/data_home_energy_quantity_biodiesel.xml +177 -0
  26. data/spec/fixtures/data_transport_car_generic_drill_fuel_diesel.xml +33 -0
  27. data/spec/fixtures/empty.json +1 -0
  28. data/spec/fixtures/empty.xml +1 -0
  29. data/spec/fixtures/parse_test.xml +22 -0
  30. data/spec/fixtures/v0_data_transport_transport_drill_transportType_Car1.xml +20 -0
  31. data/spec/item_definition_spec.rb +313 -0
  32. data/spec/item_value_definition_spec.rb +253 -0
  33. data/spec/logger_spec.rb +16 -0
  34. data/spec/object_spec.rb +44 -0
  35. data/spec/parse_helper_spec.rb +72 -0
  36. data/spec/profile_category_spec.rb +565 -0
  37. data/spec/profile_item_spec.rb +451 -0
  38. data/spec/profile_item_value_spec.rb +196 -0
  39. data/spec/profile_object_spec.rb +24 -0
  40. data/spec/profile_spec.rb +88 -0
  41. data/spec/rails_spec.rb +48 -0
  42. data/spec/spec.opts +2 -0
  43. data/spec/spec_helper.rb +56 -0
  44. data/spec/user_spec.rb +249 -0
  45. metadata +189 -55
  46. data/lib/amee/version.rb +0 -10
@@ -0,0 +1,295 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe AMEE::Connection do
4
+
5
+ it "requires server name, username, and password" do
6
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil)
7
+ lambda{AMEE::Connection.new(nil, nil, nil)}.should raise_error
8
+ lambda{AMEE::Connection.new(nil, 'username', nil)}.should raise_error
9
+ lambda{AMEE::Connection.new(nil, nil, 'password')}.should raise_error
10
+ lambda{AMEE::Connection.new(nil, 'username', 'password')}.should raise_error
11
+ lambda{AMEE::Connection.new('server.example.com', nil, nil)}.should raise_error
12
+ lambda{AMEE::Connection.new('server.example.com', 'username', nil)}.should raise_error
13
+ lambda{AMEE::Connection.new('server.example.com', nil, 'password')}.should raise_error
14
+ c = AMEE::Connection.new('server.example.com', 'username', 'password')
15
+ c.should be_valid
16
+ end
17
+
18
+ it "has default timeout of 60 seconds" do
19
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil)
20
+ c = AMEE::Connection.new('server.example.com', 'username', 'password')
21
+ c.timeout.should be(60)
22
+ end
23
+
24
+ it "can set timeout" do
25
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil)
26
+ c = AMEE::Connection.new('server.example.com', 'username', 'password')
27
+ c.timeout = 30
28
+ c.timeout.should be(30)
29
+ end
30
+
31
+ it "can set timeout on creation" do
32
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil)
33
+ c = AMEE::Connection.new('server.example.com', 'username', 'password', :timeout => 30)
34
+ c.timeout.should be(30)
35
+ end
36
+
37
+ end
38
+
39
+ describe AMEE::Connection, "with authentication" do
40
+
41
+ it "should start out unauthenticated" do
42
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil)
43
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
44
+ amee.authenticated?.should be_false
45
+ end
46
+
47
+ it "detects the API version (1)" do
48
+ flexmock(Net::HTTP).new_instances do |mock|
49
+ mock.should_receive(:start => nil)
50
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => '0', :'[]' => 'dummy_auth_token_data'))
51
+ mock.should_receive(:finish => nil)
52
+ end
53
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
54
+ amee.authenticate
55
+ amee.authenticated?.should be_true
56
+ amee.version.should == 1.0
57
+ end
58
+
59
+ it "detects the API version (2 - XML)" do
60
+ flexmock(Net::HTTP).new_instances do |mock|
61
+ mock.should_receive(:start => nil)
62
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => '<?xml version="1.0" encoding="UTF-8"?><Resources><SignInResource><Next>/auth</Next><User uid="DB2C6DA7EAA7"><Status>ACTIVE</Status><Type>STANDARD</Type><GroupNames><GroupName>amee</GroupName><GroupName>Standard</GroupName><GroupName>All</GroupName></GroupNames><ApiVersion>2.0</ApiVersion></User></SignInResource></Resources>', :'[]' => 'dummy_auth_token_data'))
63
+ mock.should_receive(:finish => nil)
64
+ end
65
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
66
+ amee.authenticate
67
+ amee.authenticated?.should be_true
68
+ amee.version.should == 2.0
69
+ end
70
+
71
+ it "detects the API version (2 - JSON)" do
72
+ flexmock(Net::HTTP).new_instances do |mock|
73
+ mock.should_receive(:start => nil)
74
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => '{ "next" : "/auth","user" : { "apiVersion" : "2.0","groupNames" : [ "amee","Standard","All"],"status" : "ACTIVE","type" : "STANDARD","uid" : "DB2C6DA7EAA7"}}', :'[]' => 'dummy_auth_token_data'))
75
+ mock.should_receive(:finish => nil)
76
+ end
77
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
78
+ amee.authenticate
79
+ amee.authenticated?.should be_true
80
+ amee.version.should == 2.0
81
+ end
82
+
83
+ it "should be able to get private URLs" do
84
+ flexmock(Net::HTTP).new_instances do |mock|
85
+ mock.should_receive(:start => nil)
86
+ mock.should_receive(:request).and_return(flexmock(:code => '401', :body => '')).once
87
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => '', :'[]' => 'dummy_auth_token_data')).once
88
+ mock.should_receive(:request).and_return { |request|
89
+ if request['authToken'] == 'dummy_auth_token_data'
90
+ flexmock(:code => '200', :body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DataCategoryResource><Path/><DataCategory created="2007-07-27 09:30:44.0" modified="2007-07-27 09:30:44.0" uid="CD310BEBAC52"><Name>Root</Name><Path/><Environment uid="5F5887BCF726"/></DataCategory><Children><DataCategories><DataCategory uid="BBA3AC3E795E"><Name>Home</Name><Path>home</Path></DataCategory><DataCategory uid="9E5362EAB0E7"><Name>Metadata</Name><Path>metadata</Path></DataCategory><DataCategory uid="6153F468BE05"><Name>Test</Name><Path>test</Path></DataCategory><DataCategory uid="263FC0186834"><Name>Transport</Name><Path>transport</Path></DataCategory><DataCategory uid="2957AE9B6E6B"><Name>User</Name><Path>user</Path></DataCategory></DataCategories></Children></DataCategoryResource></Resources>')
91
+ else
92
+ flexmock(:code => '401', :body => '')
93
+ end
94
+ }.once
95
+ mock.should_receive(:finish => nil)
96
+ end
97
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
98
+ amee.get('/data') do |response|
99
+ response.should_not be_empty
100
+ end
101
+ amee.authenticated?.should be_true
102
+ end
103
+
104
+ it "should handle 404s gracefully" do
105
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil, :request => flexmock(:code => '404', :body => ""), :finish => nil)
106
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
107
+ lambda{amee.get('/missing_url')}.should raise_error(AMEE::NotFound, "The URL was not found on the server.\nRequest: GET /missing_url")
108
+ end
109
+
110
+ it "should raise error if permission for operation is denied" do
111
+ flexmock(Net::HTTP).new_instances do |mock|
112
+ mock.should_receive(:start => nil)
113
+ mock.should_receive(:request).and_return(flexmock(:code => '403', :body => '{}'))
114
+ mock.should_receive(:finish => nil)
115
+ end
116
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
117
+ lambda {
118
+ amee.get('/data')
119
+ }.should raise_error(AMEE::PermissionDenied,"You do not have permission to perform the requested operation.
120
+ Request: GET /data
121
+ Response: {}")
122
+ end
123
+
124
+ it "should raise error if authentication succeeds, but permission for operation is denied" do
125
+ flexmock(Net::HTTP).new_instances do |mock|
126
+ mock.should_receive(:start => nil)
127
+ mock.should_receive(:request).and_return(flexmock(:code => '401', :body => ''),
128
+ flexmock(:code => '200', :body => '', :'[]' => 'dummy_auth_token_data'),
129
+ flexmock(:code => '403', :body => '{}'))
130
+ mock.should_receive(:finish => nil)
131
+ end
132
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
133
+ lambda {
134
+ amee.get('/data')
135
+ }.should raise_error(AMEE::PermissionDenied,"You do not have permission to perform the requested operation.
136
+ Request: GET /data
137
+ Response: {}")
138
+ amee.authenticated?.should be_true
139
+ end
140
+
141
+ it "should raise error if unhandled errors occur in connection" do
142
+ flexmock(Net::HTTP).new_instances do |mock|
143
+ mock.should_receive(:start => nil)
144
+ mock.should_receive(:request).and_return(flexmock(:code => '500', :body => '{}'))
145
+ mock.should_receive(:finish => nil)
146
+ end
147
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
148
+ lambda {
149
+ amee.get('/data')
150
+ }.should raise_error(AMEE::UnknownError,"An error occurred while talking to AMEE: HTTP response code 500.
151
+ Request: GET /data
152
+ Response: {}")
153
+ end
154
+
155
+ end
156
+
157
+ describe AMEE::Connection, "with retry enabled" do
158
+
159
+ [
160
+ Timeout::Error,
161
+ Errno::EINVAL,
162
+ Errno::ECONNRESET,
163
+ EOFError,
164
+ Net::HTTPBadResponse,
165
+ Net::HTTPHeaderSyntaxError,
166
+ Net::ProtocolError
167
+ ].each do |e|
168
+
169
+ it "should retry after #{e.name} the correct number of times" do
170
+ flexmock(Net::HTTP).new_instances do |mock|
171
+ mock.should_receive(:start => nil)
172
+ mock.should_receive(:request).and_raise(e.new).twice
173
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => '{}')).once
174
+ mock.should_receive(:finish => nil)
175
+ end
176
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password', :retries => 2)
177
+ lambda {
178
+ amee.get('/data')
179
+ }.should_not raise_error
180
+ end
181
+
182
+ it "should retry #{e.name} the correct number of times and raise error on failure" do
183
+ flexmock(Net::HTTP).new_instances do |mock|
184
+ mock.should_receive(:start => nil)
185
+ mock.should_receive(:request).and_raise(e.new).times(3)
186
+ mock.should_receive(:finish => nil)
187
+ end
188
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password', :retries => 2)
189
+ lambda {
190
+ amee.get('/data')
191
+ }.should raise_error(e)
192
+ end
193
+ end
194
+
195
+ [
196
+ '502',
197
+ '503',
198
+ '504'
199
+ ].each do |e|
200
+
201
+ it "should retry after #{e} the correct number of times" do
202
+ flexmock(Net::HTTP).new_instances do |mock|
203
+ mock.should_receive(:start => nil)
204
+ mock.should_receive(:request).and_return(flexmock(:code => e, :body => '{}')).twice
205
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => '{}')).once
206
+ mock.should_receive(:finish => nil)
207
+ end
208
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password', :retries => 2)
209
+ lambda {
210
+ amee.get('/data')
211
+ }.should_not raise_error
212
+ end
213
+
214
+ it "should retry #{e} the correct number of times and raise error on failure" do
215
+ flexmock(Net::HTTP).new_instances do |mock|
216
+ mock.should_receive(:start => nil)
217
+ mock.should_receive(:request).and_return(flexmock(:code => e, :body => '{}')).times(3)
218
+ mock.should_receive(:finish => nil)
219
+ end
220
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password', :retries => 2)
221
+ lambda {
222
+ amee.get('/data')
223
+ }.should raise_error(AMEE::ConnectionFailed)
224
+ end
225
+ end
226
+
227
+ end
228
+
229
+ describe AMEE::Connection, "with incorrect server name" do
230
+
231
+ it "should raise a useful error" do
232
+ flexmock(Net::HTTP).new_instances.should_receive(:start).and_raise(SocketError.new)
233
+ amee = AMEE::Connection.new('badservername.example.com', 'username', 'password')
234
+ lambda{
235
+ amee.get('/')
236
+ }.should raise_error(AMEE::ConnectionFailed, "Connection failed. Check server name or network connection.")
237
+ end
238
+
239
+ end
240
+
241
+ describe AMEE::Connection, "with bad authentication information" do
242
+
243
+ it "should be capable of making requests for public URLs" do
244
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil, :request => flexmock(:code => '200', :body => ""), :finish => nil)
245
+ amee = AMEE::Connection.new('server.example.com', 'wrong', 'details')
246
+ lambda{amee.get('/')}.should_not raise_error
247
+ end
248
+
249
+ it "should get an authentication failure when accessing private URLs" do
250
+ flexmock(Net::HTTP).new_instances.should_receive(:start => nil, :request => flexmock(:code => '401', :body => "", :'[]' => nil), :finish => nil)
251
+ amee = AMEE::Connection.new('server.example.com', 'wrong', 'details')
252
+ lambda{amee.get('/data')}.should raise_error(AMEE::AuthFailed, "Authentication failed. Please check your username and password. (tried wrong,details)")
253
+ end
254
+
255
+ end
256
+
257
+ describe AMEE::Connection, "with authentication , doing write-requests" do
258
+
259
+ it "should be able to send post requests" do
260
+ flexmock(Net::HTTP).new_instances do |mock|
261
+ mock.should_receive(:start => nil)
262
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => ''))
263
+ mock.should_receive(:finish => nil)
264
+ end
265
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
266
+ amee.post('/profiles', :test => 1, :test2 => 2) do |response|
267
+ response.should be_empty
268
+ end
269
+ end
270
+
271
+ it "should be able to send put requests" do
272
+ flexmock(Net::HTTP).new_instances do |mock|
273
+ mock.should_receive(:start => nil)
274
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => ''))
275
+ mock.should_receive(:finish => nil)
276
+ end
277
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
278
+ amee.put('/profiles/ABC123', :test => 1, :test2 => 2) do |response|
279
+ response.should be_empty
280
+ end
281
+ end
282
+
283
+ it "should be able to send delete requests" do
284
+ flexmock(Net::HTTP).new_instances do |mock|
285
+ mock.should_receive(:start => nil)
286
+ mock.should_receive(:request).and_return(flexmock(:code => '200', :body => ''))
287
+ mock.should_receive(:finish => nil)
288
+ end
289
+ amee = AMEE::Connection.new('server.example.com', 'username', 'password')
290
+ amee.delete('/profiles/ABC123') do |response|
291
+ response.should be_empty
292
+ end
293
+ end
294
+
295
+ end
@@ -0,0 +1,259 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe AMEE::Data::Category do
4
+
5
+ before(:each) do
6
+ @cat = AMEE::Data::Category.new
7
+ end
8
+
9
+ it "should have common AMEE object properties" do
10
+ @cat.is_a?(AMEE::Data::Object).should be_true
11
+ end
12
+
13
+ it "should have children" do
14
+ @cat.should respond_to(:children)
15
+ end
16
+
17
+ it "should have items" do
18
+ @cat.should respond_to(:items)
19
+ end
20
+
21
+ it "should initialize AMEE::Object data on creation" do
22
+ uid = 'ABCD1234'
23
+ @cat = AMEE::Data::Category.new(:uid => uid)
24
+ @cat.uid.should == uid
25
+ end
26
+
27
+ it "can be created with hash of data" do
28
+ children = ["one", "two"]
29
+ items = ["three", "four"]
30
+ @cat = AMEE::Data::Category.new(:children => children, :items => items)
31
+ @cat.children.should == children
32
+ @cat.items.should == items
33
+ end
34
+
35
+ end
36
+
37
+ describe AMEE::Data::Category, "accessing AMEE V0" do
38
+
39
+ it "should provide access to root of Data API" do
40
+ connection = flexmock "connection"
41
+ connection.should_receive(:retries).and_return(0)
42
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DataCategoryResource><DataCategory created="2007-04-16 17:50:43.0" modified="2007-04-16 17:50:43.0" uid="63EA08D29C63"><name>Root</name><path/></DataCategory><Children><DataCategories><DataCategory uid="5376F191D80E"><name>Metadata</name><path>metadata</path></DataCategory><DataCategory uid="33F9A55AA555"><name>Transport</name><path>transport</path></DataCategory><DataCategory uid="248D8617A389"><name>Home</name><path>home</path></DataCategory></DataCategories></Children></DataCategoryResource></Resources>'))
43
+ @root = AMEE::Data::Category.root(connection)
44
+ @root.name.should == "Root"
45
+ @root.path.should == ""
46
+ @root.full_path.should == "/data"
47
+ @root.uid.should == "63EA08D29C63"
48
+ @root.created.should == DateTime.new(2007,4,16,17,50,43)
49
+ @root.modified.should == DateTime.new(2007,4,16,17,50,43)
50
+ @root.pager.should be_nil
51
+ @root.children.size.should be(3)
52
+ @root.children[0][:uid].should == "5376F191D80E"
53
+ @root.children[0][:name].should == "Metadata"
54
+ @root.children[0][:path].should == "metadata"
55
+ end
56
+
57
+ it "should parse data items" do
58
+ connection = flexmock "connection"
59
+ connection.should_receive(:retries).and_return(0)
60
+ connection.should_receive(:get).with("/data/home/fuel", {:itemsPerPage => 10}).and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DataCategoryResource><DataCategory created="2007-04-16 17:50:43.0" modified="2007-04-16 17:50:43.0" uid="8B5A3EF67252"><name>Fuel</name><path>fuel</path></DataCategory><Children><DataCategories/><DataItems><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="9DC114F06AB2"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>2.5</fuelKgCO2PerLitre><label>Biodiesel</label><fuelType>Biodiesel</fuelType><fuelSource>AMEE 2007</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="B1F3D29987BF"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>0.1316</fuelKgCO2perKg><fuelKgCO2PerLitre>0</fuelKgCO2PerLitre><label>Biomass</label><fuelType>Biomass</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="D29131D9FA60"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>2.506</fuelKgCO2perKg><fuelKgCO2PerLitre>0</fuelKgCO2PerLitre><label>Coal</label><fuelType>Coal</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="3406EECDCDF8"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>2.6287</fuelKgCO2PerLitre><label>Diesel</label><fuelType>Diesel</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="FFAD4D7A54D7"><fuelKgCO2PerKWh>0.537</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>0</fuelKgCO2PerLitre><label>Electricity</label><fuelType>Electricity</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="160B6EAA8739"><fuelKgCO2PerKWh>0.2055</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>0</fuelKgCO2PerLitre><label>Gas</label><fuelType>Gas</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="22824F2E4FF7"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>2.516</fuelKgCO2PerLitre><label>Kerosene</label><fuelType>Kerosene</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="B55687DB4AC9"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>1.495</fuelKgCO2PerLitre><label>LPG</label><fuelType>LPG</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="D12017B42CC3"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>2.518</fuelKgCO2PerLitre><label>Oil</label><fuelType>Oil</fuelType><fuelSource>defra 2008</fuelSource></DataItem><DataItem created="2007-04-16 18:03:47.0" modified="2007-04-16 18:03:47.0" uid="62110A147736"><fuelKgCO2PerKWh>0</fuelKgCO2PerKWh><fuelKgCO2perKg>0</fuelKgCO2perKg><fuelKgCO2PerLitre>2.3167</fuelKgCO2PerLitre><label>Petrol</label><fuelType>Petrol</fuelType><fuelSource>defra 2008</fuelSource></DataItem></DataItems></Children></DataCategoryResource></Resources>'))
61
+ @data = AMEE::Data::Category.get(connection, "/data/home/fuel")
62
+ @data.uid.should == "8B5A3EF67252"
63
+ @data.items.size.should be(10)
64
+ @data.items[0][:uid].should == "9DC114F06AB2"
65
+ @data.items[0][:label].should == "Biodiesel"
66
+ @data.items[0][:path].should == "9DC114F06AB2"
67
+ @data.items[0][:fuelKgCO2PerLitre].should == "2.5"
68
+ @data.pager.should be_nil
69
+ end
70
+
71
+ end
72
+
73
+ describe AMEE::Data::Category, "with an authenticated XML connection" do
74
+
75
+ it "should provide access to root of Data API" do
76
+ connection = flexmock "connection"
77
+ connection.should_receive(:retries).and_return(0)
78
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.xml')))
79
+ @root = AMEE::Data::Category.root(connection)
80
+ @root.name.should == "Root"
81
+ @root.path.should == ""
82
+ @root.full_path.should == "/data"
83
+ @root.uid.should == "CD310BEBAC52"
84
+ @root.created.should == DateTime.new(2007,7,27,9,30,44)
85
+ @root.modified.should == DateTime.new(2007,7,27,9,30,44)
86
+ @root.children.size.should be(5)
87
+ @root.children[0][:uid].should == "BBA3AC3E795E"
88
+ @root.children[0][:name].should == "Home"
89
+ @root.children[0][:path].should == "home"
90
+ @root.pager.should be_nil
91
+ end
92
+
93
+ it "should provide access to child objects" do
94
+ connection = flexmock "connection"
95
+ connection.should_receive(:retries).and_return(0)
96
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.xml')))
97
+ connection.should_receive(:get).with("/data/transport", {:itemsPerPage => 10}).and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DataCategoryResource><Path>/transport</Path><DataCategory created="2007-07-27 09:30:44.0" modified="2007-07-27 09:30:44.0" uid="263FC0186834"><Name>Transport</Name><Path>transport</Path><Environment uid="5F5887BCF726"/><DataCategory uid="CD310BEBAC52"><Name>Root</Name><Path/></DataCategory></DataCategory><Children><DataCategories><DataCategory uid="3C4705614170"><Name>Bus</Name><Path>bus</Path></DataCategory><DataCategory uid="1D95119FB149"><Name>Car</Name><Path>car</Path></DataCategory><DataCategory uid="83C4FAF4826A"><Name>Motorcycle</Name><Path>motorcycle</Path></DataCategory><DataCategory uid="AFB73A5D2E45"><Name>Other</Name><Path>Other</Path></DataCategory><DataCategory uid="6F3692D81CD9"><Name>Plane</Name><Path>plane</Path></DataCategory><DataCategory uid="06DE08988C53"><Name>Taxi</Name><Path>taxi</Path></DataCategory><DataCategory uid="B1A64213FA9D"><Name>Train</Name><Path>train</Path></DataCategory></DataCategories></Children></DataCategoryResource></Resources>'))
98
+ @root = AMEE::Data::Category.root(connection)
99
+ @transport = @root.child('transport')
100
+ @transport.path.should == "/transport"
101
+ @transport.itemdef.should == nil
102
+ @transport.full_path.should == "/data/transport"
103
+ @transport.uid.should == "263FC0186834"
104
+ @transport.children.size.should be(7)
105
+ @transport.pager.should be_nil
106
+ end
107
+
108
+ it "should parse data items" do
109
+ connection = flexmock "connection"
110
+ connection.should_receive(:retries).and_return(0)
111
+ connection.should_receive(:get).with("/data/transport/plane/generic", {:itemsPerPage => 10}).and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DataCategoryResource><Path>/transport/plane/generic</Path><DataCategory created="2007-08-01 09:00:23.0" modified="2007-08-01 09:00:23.0" uid="FBA97B70DBDF"><Name>Generic</Name><Path>generic</Path><Environment uid="5F5887BCF726"/><DataCategory uid="6F3692D81CD9"><Name>Plane</Name><Path>plane</Path></DataCategory><ItemDefinition uid="441BF4BEA15B"/></DataCategory><Children><DataCategories/><DataItems><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="AD63A83B4D41"><kgCO2PerPassengerJourney>0</kgCO2PerPassengerJourney><type>domestic</type><label>domestic</label><size>-</size><path>AD63A83B4D41</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0.158</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="FFC7A05D54AD"><kgCO2PerPassengerJourney>73</kgCO2PerPassengerJourney><type>domestic</type><label>domestic, one way</label><size>one way</size><path>FFC7A05D54AD</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="F5498AD6FC75"><kgCO2PerPassengerJourney>146</kgCO2PerPassengerJourney><type>domestic</type><label>domestic, return</label><size>return</size><path>F5498AD6FC75</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="7D4220DF72F9"><kgCO2PerPassengerJourney>0</kgCO2PerPassengerJourney><type>long haul</type><label>long haul</label><size>-</size><path>7D4220DF72F9</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0.105</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="46117F6C0B7E"><kgCO2PerPassengerJourney>801</kgCO2PerPassengerJourney><type>long haul</type><label>long haul, one way</label><size>one way</size><path>46117F6C0B7E</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="96D538B1B246"><kgCO2PerPassengerJourney>1602</kgCO2PerPassengerJourney><type>long haul</type><label>long haul, return</label><size>return</size><path>96D538B1B246</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="9DA419052FDF"><kgCO2PerPassengerJourney>0</kgCO2PerPassengerJourney><type>short haul</type><label>short haul</label><size>-</size><path>9DA419052FDF</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0.13</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="84B4A14C7424"><kgCO2PerPassengerJourney>170</kgCO2PerPassengerJourney><type>short haul</type><label>short haul, one way</label><size>one way</size><path>84B4A14C7424</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="8DA1BEAA1013"><kgCO2PerPassengerJourney>340</kgCO2PerPassengerJourney><type>short haul</type><label>short haul, return</label><size>return</size><path>8DA1BEAA1013</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem></DataItems><Pager><Start>0</Start><From>1</From><To>9</To><Items>9</Items><CurrentPage>1</CurrentPage><RequestedPage>1</RequestedPage><NextPage>-1</NextPage><PreviousPage>-1</PreviousPage><LastPage>1</LastPage><ItemsPerPage>10</ItemsPerPage><ItemsFound>9</ItemsFound></Pager></Children></DataCategoryResource></Resources>'))
112
+ @data = AMEE::Data::Category.get(connection, "/data/transport/plane/generic")
113
+ @data.uid.should == "FBA97B70DBDF"
114
+ @data.itemdef.should == "441BF4BEA15B"
115
+ @data.items.size.should be(9)
116
+ @data.items[0][:uid].should == "AD63A83B4D41"
117
+ @data.items[0][:label].should == "domestic"
118
+ @data.items[0][:path].should == "AD63A83B4D41"
119
+ @data.items[0][:source].should == "DfT INAS Division, 29 March 2007"
120
+ @data.pager.should_not be_nil
121
+ end
122
+
123
+ it "should be able to get the itemdef" do
124
+ connection = flexmock "connection"
125
+ connection.should_receive(:retries).and_return(0)
126
+ connection.should_receive(:get).with("/data/transport/plane/generic", {:itemsPerPage => 10}).and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DataCategoryResource><Path>/transport/plane/generic</Path><DataCategory created="2007-08-01 09:00:23.0" modified="2007-08-01 09:00:23.0" uid="FBA97B70DBDF"><Name>Generic</Name><Path>generic</Path><Environment uid="5F5887BCF726"/><DataCategory uid="6F3692D81CD9"><Name>Plane</Name><Path>plane</Path></DataCategory><ItemDefinition uid="441BF4BEA15B"/></DataCategory><Children><DataCategories/><DataItems><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="AD63A83B4D41"><kgCO2PerPassengerJourney>0</kgCO2PerPassengerJourney><type>domestic</type><label>domestic</label><size>-</size><path>AD63A83B4D41</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0.158</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="FFC7A05D54AD"><kgCO2PerPassengerJourney>73</kgCO2PerPassengerJourney><type>domestic</type><label>domestic, one way</label><size>one way</size><path>FFC7A05D54AD</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="F5498AD6FC75"><kgCO2PerPassengerJourney>146</kgCO2PerPassengerJourney><type>domestic</type><label>domestic, return</label><size>return</size><path>F5498AD6FC75</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="7D4220DF72F9"><kgCO2PerPassengerJourney>0</kgCO2PerPassengerJourney><type>long haul</type><label>long haul</label><size>-</size><path>7D4220DF72F9</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0.105</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="46117F6C0B7E"><kgCO2PerPassengerJourney>801</kgCO2PerPassengerJourney><type>long haul</type><label>long haul, one way</label><size>one way</size><path>46117F6C0B7E</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="96D538B1B246"><kgCO2PerPassengerJourney>1602</kgCO2PerPassengerJourney><type>long haul</type><label>long haul, return</label><size>return</size><path>96D538B1B246</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="9DA419052FDF"><kgCO2PerPassengerJourney>0</kgCO2PerPassengerJourney><type>short haul</type><label>short haul</label><size>-</size><path>9DA419052FDF</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0.13</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="84B4A14C7424"><kgCO2PerPassengerJourney>170</kgCO2PerPassengerJourney><type>short haul</type><label>short haul, one way</label><size>one way</size><path>84B4A14C7424</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem><DataItem created="2007-08-01 09:00:41.0" modified="2007-08-01 09:00:41.0" uid="8DA1BEAA1013"><kgCO2PerPassengerJourney>340</kgCO2PerPassengerJourney><type>short haul</type><label>short haul, return</label><size>return</size><path>8DA1BEAA1013</path><source>DfT INAS Division, 29 March 2007</source><kgCO2PerPassengerKm>0</kgCO2PerPassengerKm></DataItem></DataItems><Pager><Start>0</Start><From>1</From><To>9</To><Items>9</Items><CurrentPage>1</CurrentPage><RequestedPage>1</RequestedPage><NextPage>-1</NextPage><PreviousPage>-1</PreviousPage><LastPage>1</LastPage><ItemsPerPage>10</ItemsPerPage><ItemsFound>9</ItemsFound></Pager></Children></DataCategoryResource></Resources>'))
127
+ connection.should_receive(:get).with("/definitions/itemDefinitions/441BF4BEA15B",{}).and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8" standalone="no"?><Resources><ItemDefinitionResource><ItemDefinition created="2007-07-27 09:30:44.0" modified="2007-07-27 09:30:44.0" uid="441BF4BEA15B"><Name>Plane Generic</Name><DrillDown>type,size</DrillDown><Environment uid="5F5887BCF726"/></ItemDefinition></ItemDefinitionResource></Resources>')).once
128
+ @data = AMEE::Data::Category.get(connection, "/data/transport/plane/generic")
129
+ @data.uid.should == "FBA97B70DBDF"
130
+ @data.itemdef.should == "441BF4BEA15B"
131
+ @itemdef=@data.item_definition
132
+ @itemdef.uid.should =="441BF4BEA15B"
133
+ end
134
+
135
+ it "should fail gracefully with bad XML" do
136
+ connection = flexmock "connection"
137
+ connection.should_receive(:retries).and_return(0)
138
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.xml').first(12)))
139
+ connection.should_receive(:expire).with("/data").once
140
+ lambda{AMEE::Data::Category.get(connection, "/data")}.should raise_error(REXML::ParseException)
141
+ end
142
+
143
+ it "should retry if bad XML is received first time" do
144
+ connection = flexmock "connection"
145
+ connection.should_receive(:retries).and_return(2)
146
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.xml').first(12))).twice
147
+ connection.should_receive(:expire).with("/data").twice
148
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.xml'))).once
149
+ lambda{AMEE::Data::Category.get(connection, "/data")}.should_not raise_error
150
+ end
151
+
152
+ it "should fail gracefully with bad data in XML" do
153
+ connection = flexmock "connection"
154
+ connection.should_receive(:retries).and_return(0)
155
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('empty.xml')))
156
+ connection.should_receive(:expire).with("/data").once
157
+ lambda{AMEE::Data::Category.get(connection, "/data")}.should raise_error(AMEE::BadData)
158
+ end
159
+
160
+ it "provides access to drilldown resource" do
161
+ connection = flexmock "connection"
162
+ connection.should_receive(:retries).and_return(0)
163
+ connection.should_receive(:get).with("/data/transport/car/generic", {:itemsPerPage => 10}).and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DataCategoryResource><Path>/transport/car/generic</Path><DataCategory created="2007-07-27 09:30:44.0" modified="2007-07-27 09:30:44.0" uid="87E55DA88017"><Name>Generic</Name><Path>generic</Path><Environment uid="5F5887BCF726"/><DataCategory uid="1D95119FB149"><Name>Car</Name><Path>car</Path></DataCategory><ItemDefinition uid="123C4A18B5D6"/></DataCategory><Children><DataCategories><DataCategory uid="417DD367E9AA"><Name>Electric</Name><Path>electric</Path></DataCategory></DataCategories><DataItems><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="4F6CBCEE95F7"><fuel>diesel</fuel><kgCO2PerKm>0.23</kgCO2PerKm><label>diesel, large</label><kgCO2PerKmUS>0.23</kgCO2PerKmUS><size>large</size><path>4F6CBCEE95F7</path><source>NAEI / Company Reporting Guidelines</source></DataItem><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="7E2B2426C927"><fuel>diesel</fuel><kgCO2PerKm>0.163</kgCO2PerKm><label>diesel, medium</label><kgCO2PerKmUS>0.163</kgCO2PerKmUS><size>medium</size><path>7E2B2426C927</path><source>NAEI / Company Reporting Guidelines</source></DataItem><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="57E6AC080BF4"><fuel>diesel</fuel><kgCO2PerKm>0.131</kgCO2PerKm><label>diesel, small</label><kgCO2PerKmUS>0.131</kgCO2PerKmUS><size>small</size><path>57E6AC080BF4</path><source>NAEI / Company Reporting Guidelines</source></DataItem><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="CEA465039777"><fuel>petrol</fuel><kgCO2PerKm>0.257</kgCO2PerKm><label>petrol, large</label><kgCO2PerKmUS>0.349</kgCO2PerKmUS><size>large</size><path>CEA465039777</path><source>"UK NAEI / Company Reporting Guidelines; US EPA/dgen"</source></DataItem><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="9A9E8852220B"><fuel>petrol</fuel><kgCO2PerKm>0.188</kgCO2PerKm><label>petrol, medium</label><kgCO2PerKmUS>0.27</kgCO2PerKmUS><size>medium</size><path>9A9E8852220B</path><source>"UK NAEI / Company Reporting Guidelines; US EPA/dgen"</source></DataItem><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="66DB66447D2F"><fuel>petrol</fuel><kgCO2PerKm>0.159</kgCO2PerKm><label>petrol, small</label><kgCO2PerKmUS>0.224</kgCO2PerKmUS><size>small</size><path>66DB66447D2F</path><source>"UK NAEI / Company Reporting Guidelines; US EPA/dgen"</source></DataItem><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="69A44DCA9845"><fuel>petrol hybrid</fuel><kgCO2PerKm>0.195</kgCO2PerKm><label>petrol hybrid, large</label><kgCO2PerKmUS>0.195</kgCO2PerKmUS><size>large</size><path>69A44DCA9845</path><source>VCA CO2 database is source of original gCO2/km data</source></DataItem><DataItem created="2007-07-27 11:04:57.0" modified="2007-07-27 11:04:57.0" uid="7DC4C91CD8DA"><fuel>petrol hybrid</fuel><kgCO2PerKm>0.11</kgCO2PerKm><label>petrol hybrid, medium</label><kgCO2PerKmUS>0.11</kgCO2PerKmUS><size>medium</size><path>7DC4C91CD8DA</path><source>VCA CO2 database is source of original gCO2/km data</source></DataItem></DataItems><Pager><Start>0</Start><From>1</From><To>8</To><Items>8</Items><CurrentPage>1</CurrentPage><RequestedPage>1</RequestedPage><NextPage>-1</NextPage><PreviousPage>-1</PreviousPage><LastPage>1</LastPage><ItemsPerPage>10</ItemsPerPage><ItemsFound>8</ItemsFound></Pager></Children></DataCategoryResource></Resources>'))
164
+ connection.should_receive(:get).with("/data/transport/car/generic/drill").and_return(flexmock(:body => '<?xml version="1.0" encoding="UTF-8"?><Resources><DrillDownResource><DataCategory uid="87E55DA88017"><Name>Generic</Name><Path>generic</Path></DataCategory><ItemDefinition uid="123C4A18B5D6"/><Selections/><Choices><Name>fuel</Name><Choices><Choice><Name>diesel</Name><Value>diesel</Value></Choice><Choice><Name>petrol</Name><Value>petrol</Value></Choice><Choice><Name>petrol hybrid</Name><Value>petrol hybrid</Value></Choice></Choices></Choices></DrillDownResource></Resources>'))
165
+ lambda{
166
+ cat = AMEE::Data::Category.get(connection, "/data/transport/car/generic")
167
+ cat.drill
168
+ }.should_not raise_error
169
+ end
170
+
171
+ end
172
+
173
+ describe AMEE::Data::Category, "with an authenticated JSON connection" do
174
+
175
+ it "should provide access to root of Data API" do
176
+ connection = flexmock "connection"
177
+ connection.should_receive(:retries).and_return(0)
178
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.json')))
179
+ @root = AMEE::Data::Category.root(connection)
180
+ @root.name.should == "Root"
181
+ @root.path.should == ""
182
+ @root.full_path.should == "/data"
183
+ @root.uid.should == "CD310BEBAC52"
184
+ @root.created.should == DateTime.new(2007,7,27,9,30,44)
185
+ @root.modified.should == DateTime.new(2007,7,27,9,30,44)
186
+ @root.children.size.should be(5)
187
+ @root.children[0][:uid].should == "BBA3AC3E795E"
188
+ @root.children[0][:name].should == "Home"
189
+ @root.children[0][:path].should == "home"
190
+ @root.pager.should be_nil
191
+ end
192
+
193
+ it "should provide access to child objects" do
194
+ connection = flexmock "connection"
195
+ connection.should_receive(:retries).and_return(0)
196
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.json')))
197
+ connection.should_receive(:get).with("/data/transport", {:itemsPerPage => 10}).and_return(flexmock(:body => '{"dataCategory":{"modified":"2007-07-27 09:30:44.0","created":"2007-07-27 09:30:44.0","dataCategory":{"uid":"CD310BEBAC52","path":"","name":"Root"},"uid":"263FC0186834","environment":{"uid":"5F5887BCF726"},"path":"transport","name":"Transport"},"path":"/transport","children":{"pager":{},"dataCategories":[{"uid":"3C4705614170","path":"bus","name":"Bus"},{"uid":"1D95119FB149","path":"car","name":"Car"},{"uid":"83C4FAF4826A","path":"motorcycle","name":"Motorcycle"},{"uid":"AFB73A5D2E45","path":"Other","name":"Other"},{"uid":"6F3692D81CD9","path":"plane","name":"Plane"},{"uid":"06DE08988C53","path":"taxi","name":"Taxi"},{"uid":"B1A64213FA9D","path":"train","name":"Train"}],"dataItems":{}}}'))
198
+ @root = AMEE::Data::Category.root(connection)
199
+ @transport = @root.child('transport')
200
+ @transport.path.should == "/transport"
201
+ @transport.itemdef.should == nil
202
+ @transport.full_path.should == "/data/transport"
203
+ @transport.uid.should == "263FC0186834"
204
+ @transport.children.size.should be(7)
205
+ @transport.pager.should be_nil
206
+ end
207
+
208
+ it "should parse data items" do
209
+ connection = flexmock "connection"
210
+ connection.should_receive(:retries).and_return(0)
211
+ connection.should_receive(:get).with("/data/transport/plane/generic", {:itemsPerPage => 10}).and_return(flexmock(:body => '{"dataCategory":{"modified":"2007-08-01 09:00:23.0","created":"2007-08-01 09:00:23.0","itemDefinition":{"uid":"441BF4BEA15B"},"dataCategory":{"uid":"6F3692D81CD9","path":"plane","name":"Plane"},"uid":"FBA97B70DBDF","environment":{"uid":"5F5887BCF726"},"path":"generic","name":"Generic"},"path":"/transport/plane/generic","children":{"pager":{"to":9,"lastPage":1,"start":0,"nextPage":-1,"items":9,"itemsPerPage":10,"from":1,"previousPage":-1,"requestedPage":1,"currentPage":1,"itemsFound":9},"dataCategories":[],"dataItems":{"rows":[{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"domestic","label":"domestic","uid":"AD63A83B4D41","path":"AD63A83B4D41","size":"-","kgCO2PerPassengerJourney":"0","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0.158"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"domestic","label":"domestic, one way","uid":"FFC7A05D54AD","path":"FFC7A05D54AD","size":"one way","kgCO2PerPassengerJourney":"73","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"domestic","label":"domestic, return","uid":"F5498AD6FC75","path":"F5498AD6FC75","size":"return","kgCO2PerPassengerJourney":"146","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"long haul","label":"long haul","uid":"7D4220DF72F9","path":"7D4220DF72F9","size":"-","kgCO2PerPassengerJourney":"0","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0.105"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"long haul","label":"long haul, one way","uid":"46117F6C0B7E","path":"46117F6C0B7E","size":"one way","kgCO2PerPassengerJourney":"801","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"long haul","label":"long haul, return","uid":"96D538B1B246","path":"96D538B1B246","size":"return","kgCO2PerPassengerJourney":"1602","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"short haul","label":"short haul","uid":"9DA419052FDF","path":"9DA419052FDF","size":"-","kgCO2PerPassengerJourney":"0","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0.13"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"short haul","label":"short haul, one way","uid":"84B4A14C7424","path":"84B4A14C7424","size":"one way","kgCO2PerPassengerJourney":"170","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0"},{"modified":"2007-08-01 09:00:41.0","created":"2007-08-01 09:00:41.0","type":"short haul","label":"short haul, return","uid":"8DA1BEAA1013","path":"8DA1BEAA1013","size":"return","kgCO2PerPassengerJourney":"340","source":"DfT INAS Division, 29 March 2007","kgCO2PerPassengerKm":"0"}],"label":"DataItems"}}}'))
212
+ @data = AMEE::Data::Category.get(connection, "/data/transport/plane/generic")
213
+ @data.uid.should == "FBA97B70DBDF"
214
+ @data.itemdef.should == "441BF4BEA15B"
215
+ @data.items.size.should be(9)
216
+ @data.items[0][:uid].should == "AD63A83B4D41"
217
+ @data.items[0][:label].should == "domestic"
218
+ @data.items[0][:path].should == "AD63A83B4D41"
219
+ @data.items[0][:source].should == "DfT INAS Division, 29 March 2007"
220
+ @data.pager.should_not be_nil
221
+ end
222
+
223
+ it "should fail gracefully with bad JSON" do
224
+ connection = flexmock "connection"
225
+ connection.should_receive(:retries).and_return(0)
226
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => "{"))
227
+ connection.should_receive(:expire).with("/data").once
228
+ lambda{AMEE::Data::Category.get(connection, "/data")}.should raise_error(JSON::ParserError)
229
+ end
230
+
231
+ it "should retry if bad JSON is received first time" do
232
+ connection = flexmock "connection"
233
+ connection.should_receive(:retries).and_return(2)
234
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => "{")).twice
235
+ connection.should_receive(:expire).with("/data").twice
236
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('data.json'))).once
237
+ lambda{AMEE::Data::Category.get(connection, "/data")}.should_not raise_error
238
+ end
239
+
240
+ it "should fail gracefully with bad data in json" do
241
+ connection = flexmock "connection"
242
+ connection.should_receive(:retries).and_return(0)
243
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_return(flexmock(:body => fixture('empty.json')))
244
+ connection.should_receive(:expire).with("/data").once
245
+ lambda{AMEE::Data::Category.get(connection, "/data")}.should raise_error(AMEE::BadData)
246
+ end
247
+
248
+ end
249
+
250
+ describe AMEE::Data::Category, "with an authenticated connection" do
251
+
252
+ it "should fail gracefully on other GET errors" do
253
+ connection = flexmock "connection"
254
+ connection.should_receive(:retries).and_return(0)
255
+ connection.should_receive(:get).with("/data", {:itemsPerPage => 10}).and_raise(Timeout::Error)
256
+ lambda{AMEE::Data::Category.get(connection, "/data")}.should raise_error(Timeout::Error)
257
+ end
258
+
259
+ end