ruby_odata 0.1.4 → 0.1.5

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.
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+ <error
3
+ xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
4
+ <code></code>
5
+ <message xml:lang="en-US">Type 'RubyODataService.Category' does not have a property named 'Price' or there is no type with 'Price' name.</message>
6
+ </error>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+ <error
3
+ xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
4
+ <code></code>
5
+ <message xml:lang="en-US">Only properties specified in $expand can be traversed in $select query options. Property .</message>
6
+ </error>
@@ -0,0 +1,92 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <feed xml:base="http://win7dev:8989/SampleService/RubyOData.svc/"
3
+ xmlns="http://www.w3.org/2005/Atom"
4
+ xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
5
+ xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
6
+ xmlns:georss="http://www.georss.org/georss"
7
+ xmlns:gml="http://www.opengis.net/gml">
8
+ <id>http://win7dev:8989/SampleService/RubyOdata.svc/Products</id>
9
+ <title type="text">Products</title>
10
+ <updated>2013-07-19T12:29:11Z</updated>
11
+ <link rel="self" title="Products" href="Products" />
12
+ <entry>
13
+ <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(1)</id>
14
+ <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
15
+ <link rel="edit" title="Product" href="Products(1)" />
16
+ <title />
17
+ <updated>2013-07-19T12:29:11Z</updated>
18
+ <author>
19
+ <name />
20
+ </author>
21
+ <content type="application/xml">
22
+ <m:properties>
23
+ <d:Name>Widget 0001</d:Name>
24
+ <d:Price m:type="Edm.Decimal">75.50</d:Price>
25
+ </m:properties>
26
+ </content>
27
+ </entry>
28
+ <entry>
29
+ <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(2)</id>
30
+ <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
31
+ <link rel="edit" title="Product" href="Products(2)" />
32
+ <title />
33
+ <updated>2013-07-19T12:29:11Z</updated>
34
+ <author>
35
+ <name />
36
+ </author>
37
+ <content type="application/xml">
38
+ <m:properties>
39
+ <d:Name>Widget 0002</d:Name>
40
+ <d:Price m:type="Edm.Decimal">100.00</d:Price>
41
+ </m:properties>
42
+ </content>
43
+ </entry>
44
+ <entry>
45
+ <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(3)</id>
46
+ <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
47
+ <link rel="edit" title="Product" href="Products(3)" />
48
+ <title />
49
+ <updated>2013-07-19T12:29:11Z</updated>
50
+ <author>
51
+ <name />
52
+ </author>
53
+ <content type="application/xml">
54
+ <m:properties>
55
+ <d:Name>Widget 0003</d:Name>
56
+ <d:Price m:type="Edm.Decimal">10.25</d:Price>
57
+ </m:properties>
58
+ </content>
59
+ </entry>
60
+ <entry>
61
+ <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(4)</id>
62
+ <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
63
+ <link rel="edit" title="Product" href="Products(4)" />
64
+ <title />
65
+ <updated>2013-07-19T12:29:11Z</updated>
66
+ <author>
67
+ <name />
68
+ </author>
69
+ <content type="application/xml">
70
+ <m:properties>
71
+ <d:Name>Widget 0004</d:Name>
72
+ <d:Price m:type="Edm.Decimal">100.00</d:Price>
73
+ </m:properties>
74
+ </content>
75
+ </entry>
76
+ <entry>
77
+ <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(5)</id>
78
+ <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
79
+ <link rel="edit" title="Product" href="Products(5)" />
80
+ <title />
81
+ <updated>2013-07-19T12:29:11Z</updated>
82
+ <author>
83
+ <name />
84
+ </author>
85
+ <content type="application/xml">
86
+ <m:properties>
87
+ <d:Name>Widget 0005</d:Name>
88
+ <d:Price m:type="Edm.Decimal">75.50</d:Price>
89
+ </m:properties>
90
+ </content>
91
+ </entry>
92
+ </feed>
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module OData
4
4
  describe PropertyMetadata do
5
5
  describe "#initialize" do
6
- it "parses an EDMX property with the essentials (name, type, nullable, nav_prop)" do
6
+ it "parses an EDMX property with the essentials (name, type, nullable, nav_prop)" do
7
7
  property_element = RSpecSupport::ElementHelpers.string_to_element('<Property Name="Id" Type="Edm.String" Nullable="false" />')
8
8
  property_metadata = PropertyMetadata.new property_element
9
9
  property_metadata.name.should eq "Id"
@@ -15,30 +15,30 @@ module OData
15
15
  property_element = RSpecSupport::ElementHelpers.string_to_element('<Property Name="Id" Type="Edm.String" Nullable="true" />')
16
16
  property_metadata = PropertyMetadata.new property_element
17
17
  property_metadata.nullable.should eq true
18
- end
19
- it "parses an EDMX property with nil for missing attributes" do
18
+ end
19
+ it "parses an EDMX property with nil for missing attributes" do
20
20
  property_element = RSpecSupport::ElementHelpers.string_to_element('<Property Name="Id" Type="Edm.String" Nullable="false" />')
21
21
  property_metadata = PropertyMetadata.new property_element
22
22
  property_metadata.fc_target_path.should be_nil
23
23
  property_metadata.fc_keep_in_content.should be_nil
24
24
  end
25
- it "parses an EDMX property with false for missing Nullable attribute" do
25
+ it "parses an EDMX property with false for missing Nullable attribute" do
26
26
  property_element = RSpecSupport::ElementHelpers.string_to_element('<Property Name="Id" Type="Edm.String" />')
27
27
  property_metadata = PropertyMetadata.new property_element
28
28
  property_metadata.nullable.should eq false
29
- end
30
- it "parses an EDMX property with the fc_target_path and fc_keep_in_content attribute" do
29
+ end
30
+ it "parses an EDMX property with the fc_target_path and fc_keep_in_content attribute" do
31
31
  property_element = RSpecSupport::ElementHelpers.string_to_element('<Property xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" Name="Title" Type="Edm.String" Nullable="true" m:FC_TargetPath="SyndicationTitle" m:FC_ContentKind="text" m:FC_KeepInContent="false" />')
32
32
  property_metadata = PropertyMetadata.new property_element
33
33
  property_metadata.fc_target_path.should eq "SyndicationTitle"
34
34
  property_metadata.fc_keep_in_content.should eq false
35
35
  end
36
- it "parses an EDMX property where fc_keep_in_content is true" do
36
+ it "parses an EDMX property where fc_keep_in_content is true" do
37
37
  property_element = RSpecSupport::ElementHelpers.string_to_element('<Property xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" Name="Title" Type="Edm.String" Nullable="true" m:FC_TargetPath="SyndicationTitle" m:FC_ContentKind="text" m:FC_KeepInContent="true" />')
38
38
  property_metadata = PropertyMetadata.new property_element
39
39
  property_metadata.fc_keep_in_content.should eq true
40
40
  end
41
- it "parses an EDMX navigation property with the name and the nav_prop set to true" do
41
+ it "parses an EDMX navigation property with the name and the nav_prop set to true" do
42
42
  property_element = RSpecSupport::ElementHelpers.string_to_element('<NavigationProperty Name="Category" Relationship="Model.CategoryProduct" FromRole="Product" ToRole="Category" />')
43
43
  property_metadata = PropertyMetadata.new property_element
44
44
  property_metadata.name.should eq "Category"
@@ -30,11 +30,16 @@ module OData
30
30
  builder.top(5)
31
31
  builder.query.should eq "Categories(1)/$links/Products?$top=5"
32
32
  end
33
- it "should throw an execption if count was already called on the builder" do
33
+ it "should throw an exception if count was already called on the builder" do
34
34
  builder = QueryBuilder.new "Categories(1)"
35
35
  builder.count
36
36
  lambda { builder.links("Products") }.should raise_error(OData::NotSupportedError, "You cannot call both the `links` method and the `count` method in the same query.")
37
37
  end
38
+ it "should throw an exception if select was already called on the builder" do
39
+ builder = QueryBuilder.new "Products"
40
+ builder.select "Price"
41
+ lambda { builder.links("Products") }.should raise_error(OData::NotSupportedError, "You cannot call both the `links` method and the `select` method in the same query.")
42
+ end
38
43
  end
39
44
 
40
45
  describe "#count" do
@@ -53,11 +58,64 @@ module OData
53
58
  builder.count
54
59
  builder.query.should eq "Products/$count?$filter=Name+eq+%27Widget+1%27"
55
60
  end
56
- it "should throw an execption if links was already called on the builder" do
61
+ it "should throw an exception if links was already called on the builder" do
57
62
  builder = QueryBuilder.new "Categories(1)"
58
63
  builder.links("Products")
59
64
  lambda { builder.count }.should raise_error(OData::NotSupportedError, "You cannot call both the `links` method and the `count` method in the same query.")
60
65
  end
66
+ it "should throw an exception if select was already called on the builder" do
67
+ builder = QueryBuilder.new "Products"
68
+ builder.select("Price")
69
+ lambda { builder.count }.should raise_error(OData::NotSupportedError, "You cannot call both the `select` method and the `count` method in the same query.")
70
+ end
71
+ end
72
+
73
+ describe "#select" do
74
+ it "should accept the select method" do
75
+ builder = QueryBuilder.new "Products"
76
+ lambda { builder.select }.should_not raise_error
77
+ end
78
+ it "should properly handle the select method" do
79
+ builder = QueryBuilder.new "Products"
80
+ builder.select "Price", "Rating"
81
+ builder.query.should eq "Products?$select=Price,Rating"
82
+ end
83
+ it "shouldn't add duplicate properties" do
84
+ builder = QueryBuilder.new "Products"
85
+ builder.select "Price", "Rating", "Price"
86
+ builder.query.should eq "Products?$select=Price,Rating"
87
+ end
88
+ it "should properly handle the select method with additional operators" do
89
+ builder = QueryBuilder.new "Products"
90
+ builder.filter("Name eq 'Widget 1'")
91
+ builder.select("Price", "Rating")
92
+ builder.query.should eq "Products?$select=Price,Rating&$filter=Name+eq+%27Widget+1%27"
93
+ end
94
+ it "should throw an exception if links was already called on the builder" do
95
+ builder = QueryBuilder.new "Categories(1)"
96
+ builder.links("Products")
97
+ lambda { builder.select("Price") }.should raise_error(OData::NotSupportedError, "You cannot call both the `links` method and the `select` method in the same query.")
98
+ end
99
+ it "should throw an exception if count was already called on the builder" do
100
+ builder = QueryBuilder.new "Products"
101
+ builder.count
102
+ lambda { builder.select("Price") }.should raise_error(OData::NotSupportedError, "You cannot call both the `count` method and the `select` method in the same query.")
103
+ end
104
+ it "should return itself" do
105
+ builder = QueryBuilder.new "Products"
106
+ result = builder.select("Price", "Rating")
107
+ result.should be_a(QueryBuilder)
108
+ end
109
+ it "should automatically add $expand for nested selects" do
110
+ builder = QueryBuilder.new "Categories"
111
+ result = builder.select "Name", "Products/Name"
112
+ result.query.should eq "Categories?$select=Name,Products/Name&$expand=Products"
113
+ end
114
+ it "should automatically add $expand for deeply nested selects" do
115
+ builder = QueryBuilder.new "Products"
116
+ result = builder.select "ProductName", "Order_Details/OrderID", "Order_Details/Order/Customer/CompanyName"
117
+ result.query.should eq "Products?$select=ProductName,Order_Details/OrderID,Order_Details/Order/Customer/CompanyName&$expand=Order_Details,Order_Details/Order/Customer"
118
+ end
61
119
  end
62
120
 
63
121
  describe "#navigate" do
@@ -10,7 +10,7 @@ module OData
10
10
  @cat_prod_service = OData::Service.new "http://test.com/test.svc"
11
11
  end
12
12
  subject { @cat_prod_service }
13
-
13
+
14
14
  context "methods" do
15
15
  it { should respond_to :update_object }
16
16
  it { should respond_to :delete_object }
@@ -25,7 +25,7 @@ module OData
25
25
  it { should respond_to :collections }
26
26
  it { should respond_to :options }
27
27
  it { should respond_to :function_imports }
28
-
28
+
29
29
  context "after parsing metadata" do
30
30
  it { should respond_to :Products }
31
31
  it { should respond_to :Categories }
@@ -43,7 +43,7 @@ module OData
43
43
  end
44
44
  it "should expose the local model type" do
45
45
  subject['Products'][:type].should eq Product
46
- subject['Categories'][:type].should eq Category
46
+ subject['Categories'][:type].should eq Category
47
47
  end
48
48
  end
49
49
  context "class metadata" do
@@ -51,6 +51,7 @@ module OData
51
51
  it { should_not be_empty}
52
52
  it { should have_key 'Product' }
53
53
  it { should have_key 'Category' }
54
+
54
55
  context "should have keys for each property" do
55
56
  subject { @cat_prod_service.class_metadata['Category'] }
56
57
  it { should have_key 'Id' }
@@ -69,6 +70,7 @@ module OData
69
70
  meta.fc_target_path.should be_nil
70
71
  meta.fc_keep_in_content.should be_nil
71
72
  meta.nav_prop.should eq false
73
+ meta.is_key.should eq true
72
74
  end
73
75
  it "should have correct PropertyMetadata for Category.Name" do
74
76
  meta = subject['Name']
@@ -78,6 +80,7 @@ module OData
78
80
  meta.fc_target_path.should be_nil
79
81
  meta.fc_keep_in_content.should be_nil
80
82
  meta.nav_prop.should eq false
83
+ meta.is_key.should eq false
81
84
  end
82
85
  it "should have correct PropertyMetadata for Category.Products" do
83
86
  meta = subject['Products']
@@ -88,6 +91,7 @@ module OData
88
91
  meta.fc_keep_in_content.should be_nil
89
92
  meta.nav_prop.should eq true
90
93
  meta.association.should_not be_nil
94
+ meta.is_key.should eq false
91
95
  end
92
96
  end
93
97
  end
@@ -115,7 +119,7 @@ module OData
115
119
  subject['EntityCategoryWebGet'][:parameters].should be_nil
116
120
  subject['EntitySingleCategoryWebGet'][:parameters].should be_a Hash
117
121
  subject['EntitySingleCategoryWebGet'][:parameters]['id'].should eq 'Edm.Int32'
118
- end
122
+ end
119
123
  context "after parsing function imports" do
120
124
  subject { @cat_prod_service }
121
125
  it { should respond_to :CleanDatabaseForTesting }
@@ -152,10 +156,10 @@ module OData
152
156
  subject { @cat_prod_service }
153
157
  before(:each) do
154
158
  stub_request(:post, "http://test.com/test.svc/CleanDatabaseForTesting").to_return(:status => 204)
155
-
159
+
156
160
  stub_request(:get, "http://test.com/test.svc/EntityCategoryWebGet").
157
161
  to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_entity_category_web_get.xml", __FILE__)), :headers => {})
158
-
162
+
159
163
  stub_request(:get, "http://test.com/test.svc/EntitySingleCategoryWebGet?id=1").
160
164
  to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_entity_single_category_web_get.xml", __FILE__)), :headers => {})
161
165
 
@@ -194,4 +198,89 @@ module OData
194
198
  end
195
199
  end
196
200
  end
201
+
202
+ describe Service do
203
+ describe "Collection with an int64 key Named 'id'" do
204
+
205
+ before(:all) do
206
+ stub_request(:get, "http://test.com/test.svc/$metadata").
207
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
208
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/int64_ids/edmx_car_service.xml", __FILE__)), :headers => {})
209
+ @svc = OData::Service.new "http://test.com/test.svc/"
210
+ end
211
+
212
+ context "has the correct metadata" do
213
+ before(:all) do
214
+ @id_meta = @svc.class_metadata['Car']['id']
215
+ end
216
+
217
+ subject { @id_meta }
218
+
219
+ its(:name) { should eq('id') }
220
+ its(:type) { should eq('Edm.Int64') }
221
+ its(:nullable) { should be_false }
222
+ its(:fc_target_path) { should be_nil }
223
+ its(:fc_keep_in_content) { should be_nil }
224
+ end
225
+
226
+ context "can parse Id correctly" do
227
+ before(:each) do
228
+ stub_request(:get, "http://test.com/test.svc/Cars(213L)").
229
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
230
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/int64_ids/result_cars.xml", __FILE__)), :headers => {})
231
+
232
+ @svc.Cars(213)
233
+ results = @svc.execute
234
+ @car = results.first
235
+ end
236
+
237
+ subject { @car }
238
+
239
+ its(:id) { should eq(213) }
240
+ its(:color) { should eq('peach') }
241
+ end
242
+ end
243
+
244
+ describe "Collection with an int64 key named 'KeyId'" do
245
+
246
+ before(:all) do
247
+ stub_request(:get, "http://test.com/test.svc/$metadata").
248
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
249
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/int64_ids/edmx_boat_service.xml", __FILE__)), :headers => {})
250
+ @svc = OData::Service.new "http://test.com/test.svc/"
251
+ end
252
+
253
+ context "has the correct metadata" do
254
+ before(:all) do
255
+ @id_meta = @svc.class_metadata['Boat']['KeyId']
256
+ end
257
+
258
+ subject { @id_meta }
259
+
260
+ its(:name) { should eq('KeyId') }
261
+ its(:type) { should eq('Edm.Int64') }
262
+ its(:nullable) { should be_false }
263
+ its(:fc_target_path) { should be_nil }
264
+ its(:fc_keep_in_content) { should be_nil }
265
+ end
266
+
267
+ context "can parse Id correctly" do
268
+ before(:each) do
269
+ stub_request(:get, "http://test.com/test.svc/Boats(213L)").
270
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
271
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/int64_ids/result_boats.xml", __FILE__)), :headers => {})
272
+
273
+ @svc.Boats(213)
274
+ results = @svc.execute
275
+ @boat = results.first
276
+ end
277
+
278
+ subject { @boat }
279
+
280
+ its(:id) { should eq(213) }
281
+ its(:color) { should eq('blue') }
282
+ end
283
+ end
284
+
285
+ end
197
286
  end
data/spec/service_spec.rb CHANGED
@@ -770,7 +770,7 @@ module OData
770
770
  svc.VirtualMachines
771
771
  results = svc.execute
772
772
  @json = results.first.as_json
773
- end
773
+ end
774
774
 
775
775
  it "Should quote Edm.Int64 properties" do
776
776
  @json["PerfDiskBytesWrite"].should be_a(String)
@@ -808,7 +808,7 @@ module OData
808
808
  to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/ms_system_center/vm_templates.xml", __FILE__)), :headers => {})
809
809
 
810
810
  end
811
-
811
+
812
812
  it "should successfully parse null valued string properties" do
813
813
  svc = OData::Service.new "http://test.com/test.svc/", { :username => "blabla", :password=> "", :verify_ssl => false, :namespace => "VMM" }
814
814
  svc.VirtualMachines
@@ -905,8 +905,85 @@ module OData
905
905
  products.first.Category.Products.first.ProductName.should eq "Chai"
906
906
  end
907
907
  end
908
- end
909
908
 
909
+ describe "handling of custom select queries" do
910
+
911
+ context "when results are found" do
912
+ before(:each) do
913
+ stub_request(:get, "http://test.com/test.svc/$metadata").
914
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
915
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/edmx_categories_products.xml", __FILE__)), :headers => {})
916
+
917
+ stub_request(:get, "http://test.com/test.svc/Products?$select=Name,Price").
918
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
919
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_select_products_name_price.xml", __FILE__)), :headers => {})
920
+ end
921
+
922
+ subject do
923
+ svc = OData::Service.new "http://test.com/test.svc/"
924
+ svc.Products.select "Name", "Price"
925
+ svc.execute
926
+ end
927
+
928
+ it { should be_an Array }
929
+ it { should_not be_empty }
930
+ its(:first) { should be_a Product }
931
+ end
932
+
933
+ context "when there isn't a property by the name specified" do
934
+ before(:each) do
935
+ stub_request(:get, "http://test.com/test.svc/$metadata").
936
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
937
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/edmx_categories_products.xml", __FILE__)), :headers => {})
938
+
939
+ stub_request(:get, "http://test.com/test.svc/Categories?$select=Price").
940
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
941
+ to_return(:status => 400, :body => File.new(File.expand_path("../fixtures/sample_service/result_select_categories_no_property.xml", __FILE__)), :headers => {})
942
+ end
943
+
944
+ it "raises an exception" do
945
+ svc = OData::Service.new "http://test.com/test.svc/"
946
+ svc.Categories.select "Price"
947
+ expect { svc.execute }.to raise_error(OData::ServiceError) { |error|
948
+ error.http_code.should eq 400
949
+ error.message.should eq "Type 'RubyODataService.Category' does not have a property named 'Price' or there is no type with 'Price' name."
950
+ }
951
+ end
952
+ end
953
+
954
+ context "when a property requires $expand to traverse" do
955
+ before(:each) do
956
+ stub_request(:get, "http://test.com/test.svc/$metadata").
957
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
958
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/edmx_categories_products.xml", __FILE__)), :headers => {})
959
+
960
+ stub_request(:get, "http://test.com/test.svc/Categories?$select=Name,Products/Name").
961
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
962
+ to_return(:status => 400, :body => File.new(File.expand_path("../fixtures/sample_service/result_select_categories_travsing_no_expand.xml", __FILE__)), :headers => {})
963
+
964
+ stub_request(:get, "http://test.com/test.svc/Categories?$select=Name,Products/Name&$expand=Products").
965
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
966
+ to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_select_categories_expand.xml", __FILE__)), :headers => {})
967
+ end
968
+
969
+ it "doesn't error" do
970
+ svc = OData::Service.new "http://test.com/test.svc/"
971
+ svc.Categories.select "Name", "Products/Name"
972
+ expect { svc.execute }.to_not raise_error(OData::ServiceError)
973
+ end
974
+
975
+ it "returns the classes with the properties filled in" do
976
+ svc = OData::Service.new "http://test.com/test.svc/"
977
+ svc.Categories.select "Name", "Products/Name"
978
+ results = svc.execute
979
+ category = results.first
980
+ category.Name.should eq "Category 0001"
981
+ product = category.Products.first
982
+ product.Name.should eq "Widget 0001"
983
+ end
984
+ end
985
+ end
986
+ end
910
987
  describe_private OData::Service do
911
988
  describe "parse value" do
912
989
  before(:each) do