ruby_odata 0.0.10 → 0.1.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.
- data/.gitignore +9 -3
- data/.travis.yml +4 -0
- data/CHANGELOG.rdoc +18 -1
- data/README.rdoc +77 -19
- data/config/cucumber.yml +4 -3
- data/features/basic_auth.feature +5 -7
- data/features/batch_request.feature +11 -11
- data/features/complex_types.feature +11 -11
- data/features/query_builder.feature +27 -18
- data/features/service.feature +8 -8
- data/features/service_manage.feature +27 -12
- data/features/service_methods.feature +37 -0
- data/features/ssl.feature +4 -4
- data/features/step_definitions/pickle_steps.rb +100 -0
- data/features/step_definitions/service_steps.rb +99 -65
- data/features/support/constants.rb +3 -0
- data/features/support/custom_helpers.rb +54 -0
- data/features/support/env.rb +0 -10
- data/features/support/hooks.rb +1 -1
- data/features/support/pickle.rb +82 -0
- data/features/type_conversion.feature +10 -10
- data/lib/ruby_odata.rb +4 -1
- data/lib/ruby_odata/association.rb +36 -0
- data/lib/ruby_odata/class_builder.rb +96 -16
- data/lib/ruby_odata/helpers.rb +10 -0
- data/lib/ruby_odata/operation.rb +7 -5
- data/lib/ruby_odata/property_metadata.rb +11 -6
- data/lib/ruby_odata/query_builder.rb +20 -1
- data/lib/ruby_odata/service.rb +407 -94
- data/lib/ruby_odata/version.rb +1 -1
- data/ruby_odata.gemspec +2 -0
- data/spec/association_spec.rb +48 -0
- data/spec/class_builder_spec.rb +11 -2
- data/spec/fixtures/inheritance/edmx_pluralsight.xml +111 -0
- data/spec/fixtures/inheritance/result_pluralsight_courses.xml +229 -0
- data/spec/fixtures/links/result_links_query.xml +6 -0
- data/spec/fixtures/partial/partial_feed_metadata.xml +25 -0
- data/spec/fixtures/partial/partial_feed_part_1.xml +42 -0
- data/spec/fixtures/partial/partial_feed_part_2.xml +42 -0
- data/spec/fixtures/partial/partial_feed_part_3.xml +40 -0
- data/spec/fixtures/sample_service/edmx_categories_products.xml +1 -0
- data/spec/fixtures/sample_service/result_category_names.xml +5 -0
- data/spec/fixtures/sample_service/result_entity_category_web_get.xml +29 -0
- data/spec/fixtures/sample_service/result_entity_single_category_web_get.xml +23 -0
- data/spec/fixtures/sample_service/result_first_category_id.xml +2 -0
- data/spec/fixtures/sample_service/result_multiple_category_products.xml +57 -0
- data/spec/fixtures/sample_service/result_single_category.xml +18 -0
- data/spec/fixtures/sample_service/result_single_product.xml +26 -0
- data/spec/fixtures/sample_service/result_single_product_not_found.xml +4 -0
- data/spec/fixtures/sap/edmx_sap_demo_flight.xml +62 -58
- data/spec/property_metadata_spec.rb +9 -2
- data/spec/query_builder_spec.rb +11 -0
- data/spec/revised_service_spec.rb +197 -0
- data/spec/service_spec.rb +463 -4
- data/test/RubyODataService/RubyODataService.sln +20 -0
- data/test/RubyODataService/RubyODataService/App_Start/EntityFramework.SqlServerCompact.cs +12 -0
- data/test/RubyODataService/RubyODataService/BasicAuth/RubyOData.svc +3 -0
- data/test/RubyODataService/RubyODataService/BasicAuth/RubyOData.svc.cs +107 -0
- data/test/RubyODataService/RubyODataService/Global.asax +1 -0
- data/test/RubyODataService/RubyODataService/Global.asax.cs +49 -0
- data/test/RubyODataService/RubyODataService/Models/AuditFields.cs +16 -0
- data/test/RubyODataService/RubyODataService/Models/Category.cs +16 -0
- data/test/RubyODataService/RubyODataService/Models/Product.cs +20 -0
- data/test/RubyODataService/RubyODataService/Properties/AssemblyInfo.cs +35 -0
- data/test/RubyODataService/RubyODataService/RubyOData.svc +3 -0
- data/test/RubyODataService/RubyODataService/RubyOData.svc.cs +57 -0
- data/test/RubyODataService/RubyODataService/RubyODataContext.cs +16 -0
- data/test/RubyODataService/RubyODataService/RubyODataService.csproj +159 -0
- data/test/RubyODataService/RubyODataService/RubyODataService.csproj.user +31 -0
- data/test/RubyODataService/RubyODataService/Web.Debug.config +30 -0
- data/test/RubyODataService/RubyODataService/Web.Release.config +31 -0
- data/test/RubyODataService/RubyODataService/Web.config +27 -0
- data/test/RubyODataService/RubyODataService/bin/EntityFramework.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Edm.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/Microsoft.Data.OData.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Services.Client.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Services.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Spatial.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/RubyODataService.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/System.Data.SqlServerCe.Entity.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/System.Data.SqlServerCe.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/System.Spatial.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/WebActivator.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest +6 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/README_ENU.txt +0 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/msvcr90.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/sqlcecompact40.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/sqlceer40EN.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/sqlceme40.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/sqlceqp40.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/amd64/sqlcese40.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest +6 -0
- data/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/README_ENU.txt +0 -0
- data/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/msvcr90.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/x86/sqlcecompact40.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/x86/sqlceer40EN.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/x86/sqlceme40.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/x86/sqlceqp40.dll +0 -0
- data/test/RubyODataService/RubyODataService/bin/x86/sqlcese40.dll +0 -0
- data/test/RubyODataService/RubyODataService/packages.config +7 -0
- data/test/RubyODataService/packages/EntityFramework.4.2.0.0/EntityFramework.4.2.0.0.nupkg +0 -0
- data/test/RubyODataService/packages/EntityFramework.4.2.0.0/lib/net40/EntityFramework.dll +0 -0
- data/test/RubyODataService/packages/EntityFramework.4.2.0.0/lib/net40/EntityFramework.xml +13488 -0
- data/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/Content/App_Start/EntityFramework.SqlServerCompact.cs.pp +12 -0
- data/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/EULA_ENU.rtf +969 -0
- data/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/EntityFramework.SqlServerCompact.4.1.8482.2.nupkg +0 -0
- data/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/lib/System.Data.SqlServerCe.Entity.dll +0 -0
- data/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/tools/install.ps1 +3 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Content/web.config.transform +8 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest +6 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/README_ENU.txt +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/msvcr90.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlcecompact40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceer40EN.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceme40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceqp40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlcese40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest +6 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/README_ENU.txt +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/msvcr90.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlcecompact40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceer40EN.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceme40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceqp40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlcese40.dll +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/SQLCE_EULA_ENU.rtf +778 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/SqlServerCompact.4.0.8482.1.nupkg +0 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Tools/GetSqlCEPostBuildCmd.ps1 +12 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Tools/install.ps1 +11 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Tools/uninstall.ps1 +9 -0
- data/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/lib/System.Data.SqlServerCe.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/DataSvcUtil.exe +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/License.rtf +708 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Edm.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Edm.xml +4150 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.OData.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.OData.xml +1969 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Client.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Client.xml +1442 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Design.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Design.xml +191 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.xml +2559 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Spatial.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Spatial.xml +15 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.VsDesigner.DataServices.Adapter.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/README.txt +6 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/System.Spatial.dll +0 -0
- data/test/RubyODataService/packages/WCF DataServices October 2011 CTP/System.Spatial.xml +2276 -0
- data/test/RubyODataService/packages/WebActivator.1.0.0.0/WebActivator.1.0.0.0.nupkg +0 -0
- data/test/RubyODataService/packages/WebActivator.1.0.0.0/lib/WebActivator.dll +0 -0
- data/test/RubyODataService/packages/repositories.config +4 -0
- data/test/applicationhost.config.template +2 -2
- data/test/blueprints.rb +5 -4
- data/test/iisExpress x64.bat b/data/test/iisExpress → x64.bat +0 -0
- data/test/iisExpress x86.bat b/data/test/iisExpress → x86.bat +0 -0
- data/test/setpath.rb +13 -3
- data/test/usage_samples/querying.rb +45 -0
- data/test/usage_samples/reflection.rb +16 -0
- data/test/usage_samples/sample_data.rb +30 -0
- metadata +327 -36
- data/test/Cassini x64.bat +0 -1
- data/test/Cassini x86.bat +0 -1
- data/test/SampleService/App_Code/AuditFields.cs +0 -13
- data/test/SampleService/App_Code/Entities.cs +0 -145
- data/test/SampleService/App_Code/Model.Designer.cs +0 -578
- data/test/SampleService/App_Code/Model.edmx +0 -157
- data/test/SampleService/App_Code/ModelContainerExtended.cs +0 -32
- data/test/SampleService/App_Data/_TestDB.mdf +0 -0
- data/test/SampleService/App_Data/_TestDB_Log.ldf +0 -0
- data/test/SampleService/BasicAuth/Entities.svc +0 -1
- data/test/SampleService/Entities.svc +0 -1
- data/test/SampleService/web.config +0 -37
data/spec/query_builder_spec.rb
CHANGED
@@ -18,6 +18,17 @@ module OData
|
|
18
18
|
builder.top(10)
|
19
19
|
builder.query.should eq "Products?$top=10&x=1&y=2"
|
20
20
|
end
|
21
|
+
it "should properly handle queries for links" do
|
22
|
+
builder = QueryBuilder.new 'Categories(1)'
|
23
|
+
builder.links('Products')
|
24
|
+
builder.query.should eq "Categories(1)/$links/Products"
|
25
|
+
end
|
26
|
+
it "should properly handle queries for links with additional operations" do
|
27
|
+
builder = QueryBuilder.new 'Categories(1)'
|
28
|
+
builder.links('Products')
|
29
|
+
builder.top(5)
|
30
|
+
builder.query.should eq "Categories(1)/$links/Products?$top=5"
|
31
|
+
end
|
21
32
|
end
|
22
33
|
end
|
23
34
|
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module OData
|
4
|
+
describe Service do
|
5
|
+
before(:all) do
|
6
|
+
stub_request(:get, /http:\/\/test\.com\/test\.svc\/\$metadata(?:\?.+)?/).
|
7
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
8
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/edmx_categories_products.xml", __FILE__)), :headers => {})
|
9
|
+
|
10
|
+
@cat_prod_service = OData::Service.new "http://test.com/test.svc"
|
11
|
+
end
|
12
|
+
subject { @cat_prod_service }
|
13
|
+
|
14
|
+
context "methods" do
|
15
|
+
it { should respond_to :update_object }
|
16
|
+
it { should respond_to :delete_object }
|
17
|
+
it { should respond_to :save_changes }
|
18
|
+
it { should respond_to :load_property }
|
19
|
+
it { should respond_to :add_link }
|
20
|
+
it { should respond_to :execute }
|
21
|
+
it { should respond_to :partial? }
|
22
|
+
it { should respond_to :next }
|
23
|
+
it { should respond_to :classes }
|
24
|
+
it { should respond_to :class_metadata }
|
25
|
+
it { should respond_to :collections }
|
26
|
+
it { should respond_to :options }
|
27
|
+
it { should respond_to :function_imports }
|
28
|
+
|
29
|
+
context "after parsing metadata" do
|
30
|
+
it { should respond_to :Products }
|
31
|
+
it { should respond_to :Categories }
|
32
|
+
it { should respond_to :AddToProducts }
|
33
|
+
it { should respond_to :AddToCategories }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context "collections method" do
|
37
|
+
subject { @cat_prod_service.collections }
|
38
|
+
it { should include 'Products' }
|
39
|
+
it { should include 'Categories' }
|
40
|
+
it "should expose the edmx type of objects" do
|
41
|
+
subject['Products'][:edmx_type].should eq 'RubyODataService.Product'
|
42
|
+
subject['Categories'][:edmx_type].should eq 'RubyODataService.Category'
|
43
|
+
end
|
44
|
+
it "should expose the local model type" do
|
45
|
+
subject['Products'][:type].should eq Product
|
46
|
+
subject['Categories'][:type].should eq Category
|
47
|
+
end
|
48
|
+
end
|
49
|
+
context "class metadata" do
|
50
|
+
subject { @cat_prod_service.class_metadata }
|
51
|
+
it { should_not be_empty}
|
52
|
+
it { should have_key 'Product' }
|
53
|
+
it { should have_key 'Category' }
|
54
|
+
context "should have keys for each property" do
|
55
|
+
subject { @cat_prod_service.class_metadata['Category'] }
|
56
|
+
it { should have_key 'Id' }
|
57
|
+
it { should have_key 'Name' }
|
58
|
+
it { should have_key 'Products' }
|
59
|
+
it "should return a PropertyMetadata object for each property" do
|
60
|
+
subject['Id'].should be_a PropertyMetadata
|
61
|
+
subject['Name'].should be_a PropertyMetadata
|
62
|
+
subject['Products'].should be_a PropertyMetadata
|
63
|
+
end
|
64
|
+
it "should have correct PropertyMetadata for Category.Id" do
|
65
|
+
meta = subject['Id']
|
66
|
+
meta.name.should eq 'Id'
|
67
|
+
meta.type.should eq 'Edm.Int32'
|
68
|
+
meta.nullable.should eq false
|
69
|
+
meta.fc_target_path.should be_nil
|
70
|
+
meta.fc_keep_in_content.should be_nil
|
71
|
+
meta.nav_prop.should eq false
|
72
|
+
end
|
73
|
+
it "should have correct PropertyMetadata for Category.Name" do
|
74
|
+
meta = subject['Name']
|
75
|
+
meta.name.should eq 'Name'
|
76
|
+
meta.type.should eq 'Edm.String'
|
77
|
+
meta.nullable.should eq false
|
78
|
+
meta.fc_target_path.should be_nil
|
79
|
+
meta.fc_keep_in_content.should be_nil
|
80
|
+
meta.nav_prop.should eq false
|
81
|
+
end
|
82
|
+
it "should have correct PropertyMetadata for Category.Products" do
|
83
|
+
meta = subject['Products']
|
84
|
+
meta.name.should eq 'Products'
|
85
|
+
meta.type.should be_nil
|
86
|
+
meta.nullable.should eq true
|
87
|
+
meta.fc_target_path.should be_nil
|
88
|
+
meta.fc_keep_in_content.should be_nil
|
89
|
+
meta.nav_prop.should eq true
|
90
|
+
meta.association.should_not be_nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
context "function_imports method" do
|
95
|
+
subject { @cat_prod_service.function_imports }
|
96
|
+
it { should_not be_empty}
|
97
|
+
it { should have_key 'CleanDatabaseForTesting' }
|
98
|
+
it { should have_key 'EntityCategoryWebGet' }
|
99
|
+
it { should have_key 'EntitySingleCategoryWebGet' }
|
100
|
+
it "should expose the http method" do
|
101
|
+
subject['CleanDatabaseForTesting'][:http_method].should eq 'POST'
|
102
|
+
subject['EntityCategoryWebGet'][:http_method].should eq 'GET'
|
103
|
+
subject['EntitySingleCategoryWebGet'][:http_method].should eq 'GET'
|
104
|
+
end
|
105
|
+
it "should expose the return type" do
|
106
|
+
subject['CleanDatabaseForTesting'][:return_typo].should be_nil
|
107
|
+
subject['EntityCategoryWebGet'][:return_type].should eq Array
|
108
|
+
subject['EntityCategoryWebGet'][:inner_return_type].should eq Category
|
109
|
+
subject['EntitySingleCategoryWebGet'][:return_type].should eq Category
|
110
|
+
subject['EntitySingleCategoryWebGet'][:inner_return_type].should be_nil
|
111
|
+
subject['CategoryNames'][:return_type].should eq Array
|
112
|
+
subject['CategoryNames'][:inner_return_type].should eq String
|
113
|
+
end
|
114
|
+
it "should provide a hash of parameters" do
|
115
|
+
subject['EntityCategoryWebGet'][:parameters].should be_nil
|
116
|
+
subject['EntitySingleCategoryWebGet'][:parameters].should be_a Hash
|
117
|
+
subject['EntitySingleCategoryWebGet'][:parameters]['id'].should eq 'Edm.Int32'
|
118
|
+
end
|
119
|
+
context "after parsing function imports" do
|
120
|
+
subject { @cat_prod_service }
|
121
|
+
it { should respond_to :CleanDatabaseForTesting }
|
122
|
+
it { should respond_to :EntityCategoryWebGet }
|
123
|
+
it { should respond_to :EntitySingleCategoryWebGet }
|
124
|
+
it { should respond_to :CategoryNames }
|
125
|
+
end
|
126
|
+
context "error checking" do
|
127
|
+
subject { @cat_prod_service }
|
128
|
+
it "should throw an exception if a parameter is passed in to a method that doesn't require one" do
|
129
|
+
lambda { subject.EntityCategoryWebGet(1) }.should raise_error(ArgumentError, "wrong number of arguments (1 for 0)")
|
130
|
+
end
|
131
|
+
it "should throw and exception if more parameters are passed in than required by the function" do
|
132
|
+
lambda { subject.EntitySingleCategoryWebGet(1,2) }.should raise_error(ArgumentError, "wrong number of arguments (2 for 1)")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
context "url and http method checks" do
|
136
|
+
subject { @cat_prod_service }
|
137
|
+
before { stub_request(:any, /http:\/\/test\.com\/test\.svc\/(.*)/) }
|
138
|
+
it "should call the correct url with the correct http method for a post with no parameters" do
|
139
|
+
subject.CleanDatabaseForTesting
|
140
|
+
a_request(:post, "http://test.com/test.svc/CleanDatabaseForTesting").should have_been_made
|
141
|
+
end
|
142
|
+
it "should call the correct url with the correct http method for a get with no parameters" do
|
143
|
+
subject.EntityCategoryWebGet
|
144
|
+
a_request(:get, "http://test.com/test.svc/EntityCategoryWebGet").should have_been_made
|
145
|
+
end
|
146
|
+
it "should call the correct url with the correct http method for a get with parameters" do
|
147
|
+
subject.EntitySingleCategoryWebGet(1)
|
148
|
+
a_request(:get, "http://test.com/test.svc/EntitySingleCategoryWebGet?id=1").should have_been_made
|
149
|
+
end
|
150
|
+
end
|
151
|
+
context "function import result parsing" do
|
152
|
+
subject { @cat_prod_service }
|
153
|
+
before(:each) do
|
154
|
+
stub_request(:post, "http://test.com/test.svc/CleanDatabaseForTesting").to_return(:status => 204)
|
155
|
+
|
156
|
+
stub_request(:get, "http://test.com/test.svc/EntityCategoryWebGet").
|
157
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_entity_category_web_get.xml", __FILE__)), :headers => {})
|
158
|
+
|
159
|
+
stub_request(:get, "http://test.com/test.svc/EntitySingleCategoryWebGet?id=1").
|
160
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_entity_single_category_web_get.xml", __FILE__)), :headers => {})
|
161
|
+
|
162
|
+
stub_request(:get, "http://test.com/test.svc/CategoryNames").
|
163
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_category_names.xml", __FILE__)), :headers => {})
|
164
|
+
|
165
|
+
stub_request(:get, "http://test.com/test.svc/FirstCategoryId").
|
166
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_first_category_id.xml", __FILE__)), :headers => {})
|
167
|
+
end
|
168
|
+
it "should return true if a function import post that returns successfully and doesn't have a return value (HTTP 204)" do
|
169
|
+
result = subject.CleanDatabaseForTesting
|
170
|
+
result.should be_true
|
171
|
+
end
|
172
|
+
it "should return a collection of entities for a collection" do
|
173
|
+
result = subject.EntityCategoryWebGet
|
174
|
+
result.should be_an Enumerable
|
175
|
+
result.first.should be_a Category
|
176
|
+
result.first.Name.should eq "Test Category"
|
177
|
+
end
|
178
|
+
it "should return a single entity if it isn't a collection" do
|
179
|
+
result = subject.EntitySingleCategoryWebGet(1)
|
180
|
+
result.should be_a Category
|
181
|
+
result.Name.should eq "Test Category"
|
182
|
+
end
|
183
|
+
it "should return a collection of primitive types" do
|
184
|
+
result = subject.CategoryNames
|
185
|
+
result.should be_an Enumerable
|
186
|
+
result.first.should be_a String
|
187
|
+
result.first.should eq "Test Category 1"
|
188
|
+
end
|
189
|
+
it "should return a single primitive type" do
|
190
|
+
result = subject.FirstCategoryId
|
191
|
+
result.should be_a Fixnum
|
192
|
+
result.should eq 1
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
data/spec/service_spec.rb
CHANGED
@@ -37,7 +37,6 @@ module OData
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
41
40
|
describe "additional query string parameters" do
|
42
41
|
before(:each) do
|
43
42
|
# Required for the build_classes method
|
@@ -83,7 +82,27 @@ module OData
|
|
83
82
|
svc.save_changes
|
84
83
|
a_request(:post, "http://test.com/test.svc/$batch?x=1&y=2").should have_been_made
|
85
84
|
end
|
86
|
-
|
85
|
+
it "should pass the parameters as part of an add link" do
|
86
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :additional_params => { :x=>1, :y=>2 } }
|
87
|
+
existing_flight1 = ZDemoFlight.new
|
88
|
+
existing_flight1.__metadata = { :uri => "http://test.com/test.svc/flight_dataCollection/1" }
|
89
|
+
existing_flight2 = ZDemoFlight.new
|
90
|
+
existing_flight2.__metadata = { :uri => "http://test.com/test.svc/flight_dataCollection/2" }
|
91
|
+
svc.add_link(existing_flight1, "flight_data_r", existing_flight2)
|
92
|
+
svc.save_changes
|
93
|
+
a_request(:post, "http://test.com/test.svc/flight_dataCollection/1/$links/flight_data_r?x=1&y=2").should have_been_made
|
94
|
+
end
|
95
|
+
it "should pass the parameters as part of a function import with a parameter" do
|
96
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :additional_params => { :x=>1, :y=>2 } }
|
97
|
+
svc.get_flight(1)
|
98
|
+
a_request(:get, "http://test.com/test.svc/get_flight?id=1&x=1&y=2").should have_been_made
|
99
|
+
end
|
100
|
+
it "should pass the parameters as part of a function import without parameters" do
|
101
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :additional_params => { :x=>1, :y=>2 } }
|
102
|
+
svc.get_top_flight
|
103
|
+
a_request(:get, "http://test.com/test.svc/get_top_flight?x=1&y=2").should have_been_made
|
104
|
+
end
|
105
|
+
end
|
87
106
|
|
88
107
|
describe "lowercase collections" do
|
89
108
|
before(:each) do
|
@@ -124,7 +143,7 @@ module OData
|
|
124
143
|
end
|
125
144
|
end
|
126
145
|
|
127
|
-
describe "collections, objects, etc" do
|
146
|
+
describe "collections, objects, metadata etc" do
|
128
147
|
before(:each) do
|
129
148
|
# Metadata
|
130
149
|
stub_request(:get, "http://test.com/test.svc/$metadata").
|
@@ -244,9 +263,449 @@ module OData
|
|
244
263
|
product.Category.should_not be_an Array
|
245
264
|
end
|
246
265
|
end
|
266
|
+
|
267
|
+
describe "navigation properties" do
|
268
|
+
it "should fill in PropertyMetadata for navigation properties" do
|
269
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
270
|
+
svc.class_metadata['Product'].should have_key 'Category'
|
271
|
+
end
|
272
|
+
end
|
247
273
|
end
|
248
|
-
end
|
249
274
|
|
275
|
+
describe "single layer inheritance" do
|
276
|
+
before(:each) do
|
277
|
+
# Metadata
|
278
|
+
stub_request(:get, "http://test.com/test.svc/$metadata").
|
279
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
280
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/inheritance/edmx_pluralsight.xml", __FILE__)), :headers => {})
|
281
|
+
|
282
|
+
# Content - Courses
|
283
|
+
stub_request(:get, /http:\/\/test\.com\/test\.svc\/Courses(?:.*)/).
|
284
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
285
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/inheritance/result_pluralsight_courses.xml", __FILE__)), :headers => {})
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should build all inherited attributes" do
|
289
|
+
OData::Service.new "http://test.com/test.svc/"
|
290
|
+
methods = Course.instance_methods.reject {|m| Object.methods.index(m)}
|
291
|
+
|
292
|
+
# Ruby 1.9 uses symbols, and 1.8 uses strings, so this normalizes the data
|
293
|
+
methods.map! {|m| m.to_sym}
|
294
|
+
|
295
|
+
methods.should include(:Title)
|
296
|
+
methods.should include(:Description)
|
297
|
+
methods.should include(:VideoLength)
|
298
|
+
methods.should include(:Category)
|
299
|
+
|
300
|
+
methods.should include(:Title=)
|
301
|
+
methods.should include(:Description=)
|
302
|
+
methods.should include(:VideoLength=)
|
303
|
+
methods.should include(:Category=)
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should not build abstract classes" do
|
307
|
+
OData::Service.new "http://test.com/test.svc/"
|
308
|
+
defined?(ModelItemBase).should eq nil
|
309
|
+
end
|
310
|
+
|
311
|
+
it "should fill inherited properties" do
|
312
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
313
|
+
svc.Courses
|
314
|
+
courses = svc.execute
|
315
|
+
course = courses.first
|
316
|
+
course.Title.should_not be_nil
|
317
|
+
course.Description.should_not be_nil
|
318
|
+
course.VideoLength.should_not be_nil
|
319
|
+
course.Category.should_not be_nil
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe "handling partial collections" do
|
324
|
+
before(:each) do
|
325
|
+
# Metadata
|
326
|
+
stub_request(:get, "http://test.com/test.svc/$metadata").
|
327
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
328
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/partial/partial_feed_metadata.xml", __FILE__)), :headers => {})
|
329
|
+
|
330
|
+
# Content - Partial
|
331
|
+
stub_request(:get, "http://test.com/test.svc/Partials").
|
332
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
333
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/partial/partial_feed_part_1.xml", __FILE__)), :headers => {})
|
334
|
+
|
335
|
+
stub_request(:get, "http://test.com/test.svc/Partials?$skiptoken='ERNSH'").
|
336
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
337
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/partial/partial_feed_part_2.xml", __FILE__)), :headers => {})
|
338
|
+
|
339
|
+
stub_request(:get, "http://test.com/test.svc/Partials?$skiptoken='ERNSH2'").
|
340
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
341
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/partial/partial_feed_part_3.xml", __FILE__)), :headers => {})
|
342
|
+
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should return the whole collection by default" do
|
346
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
347
|
+
svc.Partials
|
348
|
+
results = svc.execute
|
349
|
+
results.count.should eq 3
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should return only the partial when specified by options" do
|
353
|
+
svc = OData::Service.new("http://test.com/test.svc/", :eager_partial => false)
|
354
|
+
svc.Partials
|
355
|
+
results = svc.execute
|
356
|
+
results.count.should eq 1
|
357
|
+
svc.should be_partial
|
358
|
+
while svc.partial?
|
359
|
+
results.concat svc.next
|
360
|
+
end
|
361
|
+
results.count.should eq 3
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe "link queries" do
|
366
|
+
before(:each) do
|
367
|
+
# Required for the build_classes method
|
368
|
+
stub_request(:get, /http:\/\/test\.com\/test\.svc\/\$metadata(?:\?.+)?/).
|
369
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
370
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/edmx_categories_products.xml", __FILE__)), :headers => {})
|
371
|
+
|
372
|
+
stub_request(:get, "http://test.com/test.svc/Categories(1)/$links/Products").
|
373
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
374
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/links/result_links_query.xml", __FILE__)), :headers => {})
|
375
|
+
end
|
376
|
+
it "should be able to parse the results of a links query" do
|
377
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
378
|
+
svc.Categories(1).links('Products')
|
379
|
+
results = svc.execute
|
380
|
+
results.count.should eq 3
|
381
|
+
results.first.should be_a_kind_of(URI)
|
382
|
+
results[0].path.should eq "/SampleService/RubyOData.svc/Products(1)"
|
383
|
+
results[1].path.should eq "/SampleService/RubyOData.svc/Products(2)"
|
384
|
+
results[2].path.should eq "/SampleService/RubyOData.svc/Products(3)"
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
describe "sample service" do
|
389
|
+
before(:each) do
|
390
|
+
# Required for the build_classes method
|
391
|
+
stub_request(:get, /http:\/\/test\.com\/test\.svc\/\$metadata(?:\?.+)?/).
|
392
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
393
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/edmx_categories_products.xml", __FILE__)), :headers => {})
|
394
|
+
|
395
|
+
stub_request(:get, /http:\/\/test\.com\/test\.svc\/Products\(\d\)/).
|
396
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
397
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_single_product.xml", __FILE__)), :headers => {})
|
398
|
+
|
399
|
+
stub_request(:get, /http:\/\/test\.com\/test\.svc\/Products\(\d{2,}\)/).
|
400
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
401
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_single_product_not_found.xml", __FILE__)), :headers => {})
|
402
|
+
|
403
|
+
stub_request(:get, "http://test.com/test.svc/Products(1)/Category").
|
404
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
405
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_single_category.xml", __FILE__)), :headers => {})
|
406
|
+
|
407
|
+
stub_request(:get, "http://test.com/test.svc/Categories(1)").
|
408
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
409
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_single_category.xml", __FILE__)), :headers => {})
|
410
|
+
|
411
|
+
stub_request(:get, "http://test.com/test.svc/Categories(1)/Products").
|
412
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).
|
413
|
+
to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/result_multiple_category_products.xml", __FILE__)), :headers => {})
|
414
|
+
|
415
|
+
stub_request(:post, "http://test.com/test.svc/Categories(1)/$links/Products").to_return(:status => 204)
|
416
|
+
stub_request(:post, "http://test.com/test.svc/$batch").to_return(:status => 202)
|
417
|
+
end
|
418
|
+
|
419
|
+
describe "lazy loading" do
|
420
|
+
after(:each) do
|
421
|
+
Object.send(:remove_const, 'Product') if Object.const_defined? 'Product'
|
422
|
+
Object.send(:remove_const, 'Category') if Object.const_defined? 'Category'
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should have a load property method" do
|
426
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
427
|
+
svc.should respond_to(:load_property)
|
428
|
+
end
|
429
|
+
|
430
|
+
it "should throw an exception if the object isn't tracked" do
|
431
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
432
|
+
new_object = Product.new
|
433
|
+
lambda { svc.load_property(new_object, "Category") }.should raise_error(ArgumentError, "You cannot load a property on an entity that isn't tracked")
|
434
|
+
end
|
435
|
+
|
436
|
+
it "should throw an exception if there isn't a method matching the navigation property passed in" do
|
437
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
438
|
+
svc.Products(1)
|
439
|
+
product = svc.execute.first
|
440
|
+
lambda { svc.load_property(product, "NoMatchingMethod") }.should raise_error(ArgumentError, "'NoMatchingMethod' is not a valid navigation property")
|
441
|
+
end
|
442
|
+
|
443
|
+
it "should throw an exception if the method passed in is a standard property (non-navigation)" do
|
444
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
445
|
+
svc.Products(1)
|
446
|
+
product = svc.execute.first
|
447
|
+
lambda { svc.load_property(product, "Name") }.should raise_error(ArgumentError, "'Name' is not a valid navigation property")
|
448
|
+
end
|
449
|
+
|
450
|
+
it "should fill a single navigation property" do
|
451
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
452
|
+
svc.Products(1)
|
453
|
+
product = svc.execute.first
|
454
|
+
svc.load_property(product, "Category")
|
455
|
+
product.Category.should_not be_nil
|
456
|
+
product.Category.Id.should eq 1
|
457
|
+
product.Category.Name.should eq 'Category 1'
|
458
|
+
end
|
459
|
+
|
460
|
+
it "should fill a collection navigation property" do
|
461
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
462
|
+
svc.Categories(1)
|
463
|
+
category = svc.execute.first
|
464
|
+
svc.load_property(category, "Products")
|
465
|
+
category.Products.first.should be_a Product
|
466
|
+
category.Products[0].Id.should eq 1
|
467
|
+
category.Products[1].Id.should eq 2
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
describe "find, create, add, update, and delete" do
|
472
|
+
after(:each) do
|
473
|
+
Object.send(:remove_const, 'Product') if Object.const_defined? 'Product'
|
474
|
+
Object.send(:remove_const, 'Category') if Object.const_defined? 'Category'
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should implement an AddTo method for collection" do
|
478
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
479
|
+
svc.should respond_to :AddToCategories
|
480
|
+
svc.should respond_to :AddToProducts
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should create objects with an initialize method that can build the object from a hash" do
|
484
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
485
|
+
product = Product.new 'Id' => 1000, 'Name' => 'New Product'
|
486
|
+
product.Id.should eq 1000
|
487
|
+
product.Name.should eq 'New Product'
|
488
|
+
end
|
489
|
+
|
490
|
+
it "should create objects that rejects keys that don't have corresponding methods" do
|
491
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
492
|
+
lambda { Product.new 'NotAProperty' => true }.should raise_error NoMethodError
|
493
|
+
end
|
494
|
+
|
495
|
+
it "should create objects that expose a properties class method that lists the properties for the object" do
|
496
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
497
|
+
Product.properties.should include 'Id'
|
498
|
+
Product.properties.should include 'Name'
|
499
|
+
Product.properties.should include 'Category'
|
500
|
+
end
|
501
|
+
|
502
|
+
it "should have full metadata for a property returned from the properties method" do
|
503
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
504
|
+
Product.properties['Category'].should be_a PropertyMetadata
|
505
|
+
Product.properties['Category'].nav_prop.should be_true
|
506
|
+
end
|
507
|
+
|
508
|
+
it "should create objects that expose an id property" do
|
509
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
510
|
+
svc.Products(1)
|
511
|
+
product = svc.execute.first
|
512
|
+
product.should respond_to :id
|
513
|
+
end
|
514
|
+
|
515
|
+
it "should extract the id from the metadata" do
|
516
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
517
|
+
svc.Products(1)
|
518
|
+
product = svc.execute.first
|
519
|
+
product.id.should eq 1
|
520
|
+
end
|
521
|
+
|
522
|
+
describe "Class.first method" do
|
523
|
+
it "should exist on the create server objects" do
|
524
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
525
|
+
Product.should respond_to :first
|
526
|
+
end
|
527
|
+
it "should return nil if an id isn't passed in" do
|
528
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
529
|
+
product = Product.first(nil)
|
530
|
+
product.should be_nil
|
531
|
+
end
|
532
|
+
it "should return nil if an id isn't found" do
|
533
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
534
|
+
product = Product.first(1234567890)
|
535
|
+
product.should be_nil
|
536
|
+
end
|
537
|
+
it "should return a product if an id is found" do
|
538
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
539
|
+
product = Product.first(1)
|
540
|
+
product.should_not be_nil
|
541
|
+
end
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
describe "namespaces" do
|
546
|
+
after(:each) do
|
547
|
+
VisoftInc::Sample::Models.send(:remove_const, 'Product') if VisoftInc::Sample::Models.const_defined? 'Product'
|
548
|
+
VisoftInc::Sample::Models.send(:remove_const, 'Category') if VisoftInc::Sample::Models.const_defined? 'Category'
|
549
|
+
|
550
|
+
VisoftInc::Sample.send(:remove_const, 'Models') if VisoftInc::Sample.const_defined? 'Models'
|
551
|
+
VisoftInc.send(:remove_const, 'Sample') if VisoftInc.const_defined? 'Sample'
|
552
|
+
Object.send(:remove_const, 'VisoftInc') if Object.const_defined? 'VisoftInc'
|
553
|
+
end
|
554
|
+
|
555
|
+
it "should create models in the specified namespace if the option is set (using a .NET style namespace with dots)" do
|
556
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :namespace => 'VisoftInc.Sample.Models' }
|
557
|
+
defined?(VisoftInc::Sample::Models::Product).nil?.should be_false, 'VisoftInc::Sample::Models::Product was expected to be defined, but was not'
|
558
|
+
defined?(VisoftInc::Sample::Models::Category).nil?.should be_false, 'VisoftInc::Sample::Models::Category was expected to be defined, but was not'
|
559
|
+
end
|
560
|
+
|
561
|
+
it "should create models in the specified namespace if the option is set (using Ruby style namespaces with double colons)" do
|
562
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :namespace => 'VisoftInc::Sample::Models' }
|
563
|
+
defined?(VisoftInc::Sample::Models::Product).nil?.should be_false, 'VisoftInc::Sample::Models::Product was expected to be defined, but was not'
|
564
|
+
defined?(VisoftInc::Sample::Models::Category).nil?.should be_false, 'VisoftInc::Sample::Models::Category was expected to be defined, but was not'
|
565
|
+
end
|
566
|
+
|
567
|
+
it "should fill object defined in a namespace" do
|
568
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :namespace => 'VisoftInc::Sample::Models' }
|
569
|
+
svc.Categories(1)
|
570
|
+
categories = svc.execute
|
571
|
+
categories.should_not be_nil
|
572
|
+
category = categories.first
|
573
|
+
category.Id.should eq 1
|
574
|
+
category.Name.should eq 'Category 1'
|
575
|
+
end
|
576
|
+
|
577
|
+
it "should fill the class_metadata hash" do
|
578
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :namespace => 'VisoftInc::Sample::Models' }
|
579
|
+
svc.class_metadata.should_not be_empty
|
580
|
+
end
|
581
|
+
|
582
|
+
it "should add a key (based on the name) for each property class_metadata hash" do
|
583
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :namespace => 'VisoftInc::Sample::Models' }
|
584
|
+
svc.class_metadata['VisoftInc::Sample::Models::Product'].should have_key 'Id'
|
585
|
+
svc.class_metadata['VisoftInc::Sample::Models::Product'].should have_key 'Name'
|
586
|
+
svc.class_metadata['VisoftInc::Sample::Models::Product'].should have_key 'Description'
|
587
|
+
end
|
588
|
+
|
589
|
+
it "should lazy load objects defined in a namespace" do
|
590
|
+
svc = OData::Service.new "http://test.com/test.svc/", { :namespace => 'VisoftInc::Sample::Models' }
|
591
|
+
svc.Categories(1)
|
592
|
+
category = svc.execute.first
|
593
|
+
svc.load_property category, 'Products'
|
594
|
+
category.Products.should_not be_nil
|
595
|
+
category.Products.first.Id.should eq 1
|
596
|
+
category.Products.first.Name.should eq 'Widget 1'
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
describe "add_link method" do
|
601
|
+
it "should exist as a method on the service" do
|
602
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
603
|
+
svc.should respond_to(:add_link)
|
604
|
+
end
|
605
|
+
|
606
|
+
it "shouldn't be allowed if a parent isn't tracked" do
|
607
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
608
|
+
category = Category.new :Name => 'New Category'
|
609
|
+
property = nil # Not needed for this test
|
610
|
+
product = nil # Not needed for this test
|
611
|
+
lambda { svc.add_link(category, property, product) }.should raise_error(ArgumentError, "You cannot add a link on an entity that isn't tracked (Category)")
|
612
|
+
end
|
613
|
+
|
614
|
+
it "shouldn't be allowed if a property isn't found on the parent" do
|
615
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
616
|
+
svc.Categories(1)
|
617
|
+
category = svc.execute.first
|
618
|
+
property = 'NotAProperty'
|
619
|
+
product = nil # Not needed for this test
|
620
|
+
lambda { svc.add_link(category, property, product) }.should raise_error(ArgumentError, "'NotAProperty' is not a valid navigation property for Category")
|
621
|
+
end
|
622
|
+
|
623
|
+
it "shouldn't be allowed if a property isn't a navigation property on the parent" do
|
624
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
625
|
+
svc.Categories(1)
|
626
|
+
category = svc.execute.first
|
627
|
+
property = 'Name'
|
628
|
+
product = nil # Not needed for this test
|
629
|
+
lambda { svc.add_link(category, property, product) }.should raise_error(ArgumentError, "'Name' is not a valid navigation property for Category")
|
630
|
+
end
|
631
|
+
|
632
|
+
it "shouldn't be allowed if a child isn't tracked" do
|
633
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
634
|
+
svc.Categories(1)
|
635
|
+
category = svc.execute.first
|
636
|
+
property = 'Products'
|
637
|
+
product = Product.new :Name => 'Widget 1'
|
638
|
+
lambda { svc.add_link(category, property, product) }.should raise_error(ArgumentError, "You cannot add a link on a child entity that isn't tracked (Product)")
|
639
|
+
end
|
640
|
+
|
641
|
+
it "should perform a post against the correct URL with the correct body on a single_save" do
|
642
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
643
|
+
svc.Categories(1)
|
644
|
+
category = svc.execute.first
|
645
|
+
svc.Products(1)
|
646
|
+
product = svc.execute.first
|
647
|
+
property = 'Products'
|
648
|
+
svc.add_link(category, property, product)
|
649
|
+
svc.save_changes
|
650
|
+
a_request(:post, "http://test.com/test.svc/Categories(1)/$links/Products").
|
651
|
+
with(:body => { "uri" => "http://test.com/test.svc/Products(1)" },
|
652
|
+
:headers => {'Content-Type' => 'application/json'}).should have_been_made
|
653
|
+
end
|
654
|
+
|
655
|
+
it "should add the child to the parent's navigation property on a single_save" do
|
656
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
657
|
+
svc.Categories(1)
|
658
|
+
category = svc.execute.first
|
659
|
+
svc.Products(1)
|
660
|
+
product = svc.execute.first
|
661
|
+
property = 'Products'
|
662
|
+
svc.add_link(category, property, product)
|
663
|
+
svc.save_changes
|
664
|
+
category.Products.should include product
|
665
|
+
end
|
666
|
+
|
667
|
+
it "should add the parent to the child's navigation property on a single_save" do
|
668
|
+
svc = OData::Service.new "http://test.com/test.svc/"
|
669
|
+
svc.Categories(1)
|
670
|
+
category = svc.execute.first
|
671
|
+
svc.Products(1)
|
672
|
+
product = svc.execute.first
|
673
|
+
property = 'Products'
|
674
|
+
svc.add_link(category, property, product)
|
675
|
+
svc.save_changes
|
676
|
+
product.Category.should eq category
|
677
|
+
end
|
678
|
+
|
679
|
+
describe "batch_save" do
|
680
|
+
before(:each) do
|
681
|
+
@svc = OData::Service.new "http://test.com/test.svc/"
|
682
|
+
@category = Category.first(1)
|
683
|
+
@product = Product.first(1)
|
684
|
+
new_category = Category.new
|
685
|
+
@svc.AddToCategories(new_category)
|
686
|
+
@svc.add_link(@category, 'Products', @product)
|
687
|
+
@svc.save_changes
|
688
|
+
end
|
689
|
+
|
690
|
+
it "should perform a post with the correct URL and body on a batch_save" do
|
691
|
+
WebMock.should have_requested(:post, "http://test.com/test.svc/$batch").with { |request|
|
692
|
+
request.body.include? "POST http://test.com/test.svc/Categories(1)/$links/Products HTTP/1.1"
|
693
|
+
request.body.include? '{"uri":"http://test.com/test.svc/Products(1)"}'
|
694
|
+
}
|
695
|
+
end
|
696
|
+
context "child is a part of the parent's collection" do
|
697
|
+
subject { @category.Products }
|
698
|
+
it { should include @product }
|
699
|
+
end
|
700
|
+
context "parent object should be filled in on the child" do
|
701
|
+
subject { @product.Category }
|
702
|
+
it { should eq @category }
|
703
|
+
end
|
704
|
+
end
|
705
|
+
end
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
250
709
|
describe_private OData::Service do
|
251
710
|
describe "parse value" do
|
252
711
|
before(:each) do
|