├── .coveralls.yml
├── .gitignore
├── .rspec
├── .simplecov
├── .travis.yml
├── .yardopts
├── CHANGELOG.md
├── Gemfile
├── Guardfile
├── LICENSE
├── README.md
├── Rakefile
├── config
└── cucumber.yml
├── features
├── basic_auth.feature
├── batch_request.feature
├── cassettes
│ ├── basic_auth_protected_resource.yml
│ ├── batch_request_additions.yml
│ ├── batch_request_deletes.yml
│ ├── batch_request_updates.yml
│ ├── clean_database_for_testing.yml
│ ├── cucumber_tags
│ │ ├── basic_auth.yml
│ │ ├── batch_request.yml
│ │ ├── complex_types.yml
│ │ ├── error_handling.yml
│ │ ├── query_builder.yml
│ │ ├── service_manage.yml
│ │ ├── service_methods.yml
│ │ ├── ssl.yml
│ │ └── type_conversion.yml
│ ├── service_manage_additions.yml
│ ├── service_manage_deletions.yml
│ ├── service_manage_deletions_2.yml
│ └── unsecured_metadata.yml
├── complex_types.feature
├── error_handling.feature
├── query_builder.feature
├── service.feature
├── service_manage.feature
├── service_methods.feature
├── ssl.feature
├── step_definitions
│ ├── pickle_steps.rb
│ └── service_steps.rb
├── support
│ ├── constants.rb
│ ├── custom_helpers.rb
│ ├── env.rb
│ ├── hooks.rb
│ ├── pickle.rb
│ └── vcr.rb
└── type_conversion.feature
├── gemfiles
└── Gemfile.ruby187
├── lib
├── ruby_odata.rb
└── ruby_odata
│ ├── association.rb
│ ├── class_builder.rb
│ ├── exceptions.rb
│ ├── helpers.rb
│ ├── operation.rb
│ ├── property_metadata.rb
│ ├── query_builder.rb
│ ├── resource.rb
│ ├── service.rb
│ └── version.rb
├── ruby_odata.gemspec
├── spec
├── association_spec.rb
├── class_builder_spec.rb
├── fixtures
│ ├── decimal
│ │ └── metadata.xml
│ ├── edmx_empty.xml
│ ├── edmx_lowercase.xml
│ ├── error_without_message.xml
│ ├── feed_customization
│ │ ├── edmx_feed_customization.xml
│ │ ├── result_feed_customization_categories_expand.xml
│ │ └── result_feed_customization_products_expand.xml
│ ├── inheritance
│ │ ├── edmx_pluralsight.xml
│ │ └── result_pluralsight_courses.xml
│ ├── int64_ids
│ │ ├── edmx_boat_service.xml
│ │ ├── edmx_car_service.xml
│ │ ├── result_boats.xml
│ │ └── result_cars.xml
│ ├── links
│ │ └── result_links_query.xml
│ ├── ms_system_center
│ │ ├── edmx_ms_system_center.xml
│ │ ├── edmx_ms_system_center_v2.xml
│ │ ├── hardware_profiles.xml
│ │ ├── virtual_machines.xml
│ │ └── vm_templates.xml
│ ├── nested_expands
│ │ ├── edmx_northwind.xml
│ │ └── northwind_products_category_expands.xml
│ ├── partial
│ │ ├── partial_feed_metadata.xml
│ │ ├── partial_feed_part_1.xml
│ │ ├── partial_feed_part_2.xml
│ │ └── partial_feed_part_3.xml
│ ├── sample_service
│ │ ├── edmx_categories_products.xml
│ │ ├── result_category_names.xml
│ │ ├── result_entity_category_web_get.xml
│ │ ├── result_entity_single_category_web_get.xml
│ │ ├── result_first_category_id.xml
│ │ ├── result_multiple_category_products.xml
│ │ ├── result_select_categories_expand.xml
│ │ ├── result_select_categories_no_property.xml
│ │ ├── result_select_categories_travsing_no_expand.xml
│ │ ├── result_select_products_name_price.xml
│ │ ├── result_single_category.xml
│ │ ├── result_single_product.xml
│ │ └── result_single_product_not_found.xml
│ ├── sap
│ │ ├── edmx_sap_demo_flight.xml
│ │ └── result_sap_demo_flight_missing_category.xml
│ └── v4
│ │ ├── edmx_metadata.xml
│ │ └── result_categories.xml
├── property_metadata_spec.rb
├── query_builder_spec.rb
├── revised_service_spec.rb
├── service_spec.rb
├── service_v4_spec.rb
├── spec_helper.rb
└── support
│ ├── describe_private.rb
│ ├── element_helpers.rb
│ └── sample_service_matcher.rb
└── test
├── RubyODataService
├── RubyODataService.sln
├── RubyODataService
│ ├── App_Data
│ │ └── .gitkeep
│ ├── App_Start
│ │ └── EntityFramework.SqlServerCompact.cs
│ ├── BasicAuth
│ │ ├── RubyOData.svc
│ │ └── RubyOData.svc.cs
│ ├── Global.asax
│ ├── Global.asax.cs
│ ├── Models
│ │ ├── AuditFields.cs
│ │ ├── Category.cs
│ │ └── Product.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── RubyOData.svc
│ ├── RubyOData.svc.cs
│ ├── RubyODataContext.cs
│ ├── RubyODataService.csproj
│ ├── RubyODataService.csproj.user
│ ├── Web.Debug.config
│ ├── Web.Release.config
│ ├── Web.config
│ ├── bin
│ │ ├── EntityFramework.dll
│ │ ├── Microsoft.Data.Edm.dll
│ │ ├── Microsoft.Data.OData.dll
│ │ ├── Microsoft.Data.Services.Client.dll
│ │ ├── Microsoft.Data.Services.dll
│ │ ├── Microsoft.Data.Spatial.dll
│ │ ├── RubyODataService.dll
│ │ ├── System.Data.SqlServerCe.Entity.dll
│ │ ├── System.Data.SqlServerCe.dll
│ │ ├── System.Spatial.dll
│ │ ├── WebActivator.dll
│ │ ├── amd64
│ │ │ ├── Microsoft.VC90.CRT
│ │ │ │ ├── Microsoft.VC90.CRT.manifest
│ │ │ │ ├── README_ENU.txt
│ │ │ │ └── msvcr90.dll
│ │ │ ├── sqlcecompact40.dll
│ │ │ ├── sqlceer40EN.dll
│ │ │ ├── sqlceme40.dll
│ │ │ ├── sqlceqp40.dll
│ │ │ └── sqlcese40.dll
│ │ └── x86
│ │ │ ├── Microsoft.VC90.CRT
│ │ │ ├── Microsoft.VC90.CRT.manifest
│ │ │ ├── README_ENU.txt
│ │ │ └── msvcr90.dll
│ │ │ ├── sqlcecompact40.dll
│ │ │ ├── sqlceer40EN.dll
│ │ │ ├── sqlceme40.dll
│ │ │ ├── sqlceqp40.dll
│ │ │ └── sqlcese40.dll
│ └── packages.config
└── packages
│ ├── EntityFramework.4.2.0.0
│ ├── EntityFramework.4.2.0.0.nupkg
│ └── lib
│ │ └── net40
│ │ ├── EntityFramework.dll
│ │ └── EntityFramework.xml
│ ├── EntityFramework.SqlServerCompact.4.1.8482.2
│ ├── Content
│ │ └── App_Start
│ │ │ └── EntityFramework.SqlServerCompact.cs.pp
│ ├── EULA_ENU.rtf
│ ├── EntityFramework.SqlServerCompact.4.1.8482.2.nupkg
│ ├── lib
│ │ └── System.Data.SqlServerCe.Entity.dll
│ └── tools
│ │ └── install.ps1
│ ├── SqlServerCompact.4.0.8482.1
│ ├── Content
│ │ └── web.config.transform
│ ├── NativeBinaries
│ │ ├── amd64
│ │ │ ├── Microsoft.VC90.CRT
│ │ │ │ ├── Microsoft.VC90.CRT.manifest
│ │ │ │ ├── README_ENU.txt
│ │ │ │ └── msvcr90.dll
│ │ │ ├── sqlcecompact40.dll
│ │ │ ├── sqlceer40EN.dll
│ │ │ ├── sqlceme40.dll
│ │ │ ├── sqlceqp40.dll
│ │ │ └── sqlcese40.dll
│ │ └── x86
│ │ │ ├── Microsoft.VC90.CRT
│ │ │ ├── Microsoft.VC90.CRT.manifest
│ │ │ ├── README_ENU.txt
│ │ │ └── msvcr90.dll
│ │ │ ├── sqlcecompact40.dll
│ │ │ ├── sqlceer40EN.dll
│ │ │ ├── sqlceme40.dll
│ │ │ ├── sqlceqp40.dll
│ │ │ └── sqlcese40.dll
│ ├── SQLCE_EULA_ENU.rtf
│ ├── SqlServerCompact.4.0.8482.1.nupkg
│ ├── Tools
│ │ ├── GetSqlCEPostBuildCmd.ps1
│ │ ├── install.ps1
│ │ └── uninstall.ps1
│ └── lib
│ │ └── System.Data.SqlServerCe.dll
│ ├── WCF DataServices October 2011 CTP
│ ├── DataSvcUtil.exe
│ ├── License.rtf
│ ├── Microsoft.Data.Edm.dll
│ ├── Microsoft.Data.Edm.xml
│ ├── Microsoft.Data.OData.dll
│ ├── Microsoft.Data.OData.xml
│ ├── Microsoft.Data.Services.Client.dll
│ ├── Microsoft.Data.Services.Client.xml
│ ├── Microsoft.Data.Services.Design.dll
│ ├── Microsoft.Data.Services.Design.xml
│ ├── Microsoft.Data.Services.dll
│ ├── Microsoft.Data.Services.xml
│ ├── Microsoft.Data.Spatial.dll
│ ├── Microsoft.Data.Spatial.xml
│ ├── Microsoft.VsDesigner.DataServices.Adapter.dll
│ ├── README.txt
│ ├── System.Spatial.dll
│ └── System.Spatial.xml
│ ├── WebActivator.1.0.0.0
│ ├── WebActivator.1.0.0.0.nupkg
│ └── lib
│ │ ├── WebActivator.dll
│ │ └── WebActivator.pdb
│ └── repositories.config
├── applicationhost.config.template
├── blueprints.rb
├── iisExpress x64.bat
├── iisExpress x86.bat
├── setpath.rb
└── usage_samples
├── querying.rb
├── reflection.rb
└── sample_data.rb
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | service_name: travis-ci
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .yardoc
2 | .idea
3 | .idea/*
4 | rerun.txt
5 | tmp
6 | tmp/*
7 | .eprj
8 | pkg/*
9 | doc/*
10 | *.gem
11 | .bundle
12 | Gemfile.lock
13 | Gemfile.*.lock
14 | pkg/*
15 | test/applicationhost.config
16 | .rvmrc
17 | .ruby-version
18 | .ruby-gemset
19 | .DS_Store
20 | *ReSharper*
21 | *.suo
22 | obj
23 | *.pdb
24 | test/RubyODataService/RubyODataService/bin/*.xml
25 | test/RubyODataService/RubyODataService/App_Data/*.sdf
26 | coverage/*
27 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
--------------------------------------------------------------------------------
/.simplecov:
--------------------------------------------------------------------------------
1 | if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('1.9') && ENV['COVERAGE']
2 | require 'simplecov'
3 | require 'coveralls'
4 |
5 | SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6 | SimpleCov::Formatter::HTMLFormatter
7 | ]
8 |
9 | SimpleCov.start
10 | end
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | matrix:
2 | include:
3 | # - rvm: 1.8.7
4 | # gemfile: gemfiles/Gemfile.ruby187
5 | - rvm: 1.9.3
6 | gemfile: Gemfile
7 | - rvm: 2.0.0
8 | gemfile: Gemfile
9 | - rvm: 2.2.2
10 | gemfile: Gemfile
11 |
12 | script: "bundle exec rake test_with_coveralls"
--------------------------------------------------------------------------------
/.yardopts:
--------------------------------------------------------------------------------
1 | --no-cache
2 | --verbose
3 | --markup markdown
4 | --readme README.md
5 | --hide-void-return
6 | lib/**/*.rb
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | # Specify your gem's dependencies in ruby_odata.gemspec
4 | gemspec
5 |
6 | gem 'faraday_middleware', github: 'lostisland/faraday_middleware'
7 |
--------------------------------------------------------------------------------
/Guardfile:
--------------------------------------------------------------------------------
1 | # A sample Guardfile
2 | # More info at https://github.com/guard/guard#readme
3 |
4 | guard 'rspec', cmd: "bundle exec rspec" do
5 | watch(%r{^spec/.+_spec\.rb$})
6 | watch(%r{^lib/ruby_odata/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7 | watch('spec/spec_helper.rb') { "spec" }
8 | end
9 |
10 | guard 'cucumber', :all_after_pass => false, :all_on_start => false do
11 | watch(%r{^features/.+\.feature$})
12 | watch(%r{^features/support/.+$}) { 'features' }
13 | watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
14 | end
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2013 Visoft, Inc.
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'bundler'
2 | require 'rspec/core/rake_task'
3 | require 'cucumber/rake/task'
4 |
5 | desc "Run specs"
6 | RSpec::Core::RakeTask.new do |t|
7 | t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
8 | # Put spec opts in a file named .rspec in root
9 | end
10 |
11 | desc "Run features"
12 | Cucumber::Rake::Task.new(:features) do |t|
13 | t.cucumber_opts = "features --format progress"
14 | end
15 |
16 | Bundler::GemHelper.install_tasks
17 | task :default => [:spec, :features]
18 |
19 | desc "Run with code coverage"
20 | task :coverage do
21 | ENV['COVERAGE'] = 'true' if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('1.9')
22 |
23 | Rake::Task["spec"].execute
24 | Rake::Task["features"].execute
25 | end
26 |
27 | desc "Run test with coveralls"
28 | task :test_with_coveralls => [:coverage, 'coveralls_push_workaround']
29 | task :coveralls_push_workaround do
30 | if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('1.9')
31 | require 'coveralls/rake/task'
32 | Coveralls::RakeTask.new
33 | Rake::Task["coveralls:push"].invoke
34 | end
35 | end
--------------------------------------------------------------------------------
/config/cucumber.yml:
--------------------------------------------------------------------------------
1 | <%
2 | rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
3 | rerun_opts = rerun.to_s.strip.empty? ? "--format progress features" : "--format pretty #{rerun}"
4 | std_opts = "--format progress features --tags ~@wip"
5 | %>
6 | default: <%= std_opts %> features
7 | wip: --tags @wip:3 --wip features
8 | rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
--------------------------------------------------------------------------------
/features/basic_auth.feature:
--------------------------------------------------------------------------------
1 | @basic_auth
2 | Feature: Service Should Access Basic Auth Protected Resources
3 |
4 | Background:
5 | Given a HTTP BasicAuth ODataService exists using username "admin" and password "passwd"
6 | And blueprints exist for the service
7 |
8 | Scenario: Service should respond to valid collections
9 | Then I should be able to call "Products" on the service
10 |
11 | Scenario: Entity should fill values on protected resource
12 | Given I call "AddToCategories" on the service with a new "Category" object with Name: "Auth Test Category"
13 | And I save changes
14 | And I call "Categories" on the service with args: "1"
15 | When I run the query within a cassette named "basic_auth_protected_resource"
16 | Then the method "Id" on the first result should equal: "1"
17 | And the method "Name" on the first result should equal: "Auth Test Category"
18 |
19 | Scenario: Should get 401 if invalid credentials provided to protected URL
20 | Given a HTTP BasicAuth ODataService exists using username "admin" and password "bad_pwd" it should throw an exception with message "the server responded with status 401"
21 |
22 | Scenario: Should get 401 if no credentials provided to protected URL
23 | Given a HTTP BasicAuth ODataService exists it should throw an exception with message "the server responded with status 401"
24 |
--------------------------------------------------------------------------------
/features/batch_request.feature:
--------------------------------------------------------------------------------
1 | @batch_request
2 | Feature: Batch request
3 | In order to minimize network traffic
4 | As a user of the library
5 | I want to be able to batch changes (Add/Update/Delete) and persist the batch instead of one at a time
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 | Scenario: Save Changes should allow for batch additions
12 | Given I call "AddToProducts" on the service with a new "Product" object with Name: "Product 1"
13 | And I call "AddToProducts" on the service with a new "Product" object with Name: "Product 2"
14 | When I save changes
15 | Then the save result should equal: "true"
16 | When I call "Products" on the service
17 | And I order by: "Name"
18 | And I run the query within a cassette named "batch_request_additions"
19 | Then the result should be:
20 | | Name |
21 | | Product 1 |
22 | | Product 2 |
23 |
24 | Scenario: Save Changes should allow for batch updates
25 | Given I call "AddToProducts" on the service with a new "Product" object with Name: "Product 1"
26 | And I call "AddToProducts" on the service with a new "Product" object with Name: "Product 2"
27 | When I save changes
28 | When I call "Products" on the service
29 | And I filter the query with: "Name eq 'Product 1'"
30 | And I run the query
31 | And I set "Name" on the first result to "Product 1 - Updated"
32 | And I call "update_object" on the service with the first last query result
33 | When I call "Products" on the service
34 | And I filter the query with: "Name eq 'Product 2'"
35 | And I run the query
36 | And I set "Name" on the first result to "Product 2 - Updated"
37 | And I call "update_object" on the service with the first last query result
38 | When I save changes
39 | When I call "Products" on the service
40 | And I order by: "Name"
41 | And I run the query within a cassette named "batch_request_updates"
42 | Then the result should be:
43 | | Name |
44 | | Product 1 - Updated |
45 | | Product 2 - Updated |
46 |
47 | Scenario: Save Changes should allow for batch deletes
48 | Given I call "AddToProducts" on the service with a new "Product" object with Name: "Product 1"
49 | And I call "AddToProducts" on the service with a new "Product" object with Name: "Product 2"
50 | And I call "AddToProducts" on the service with a new "Product" object with Name: "Product 3"
51 | And I call "AddToProducts" on the service with a new "Product" object with Name: "Product 4"
52 | When I save changes
53 | When I call "Products" on the service
54 | And I filter the query with: "Name eq 'Product 2'"
55 | And I run the query
56 | And I call "delete_object" on the service with the first last query result
57 | When I call "Products" on the service
58 | And I filter the query with: "Name eq 'Product 3'"
59 | And I run the query
60 | And I call "delete_object" on the service with the first last query result
61 | When I save changes
62 | When I call "Products" on the service
63 | And I order by: "Name"
64 | And I run the query within a cassette named "batch_request_deletes"
65 | Then the result should be:
66 | | Name |
67 | | Product 1 |
68 | | Product 4 |
69 |
70 | Scenario: Save Changes should allow for a mix of adds, updates, and deletes to be batched
71 | Given the following products exist:
72 | | Name |
73 | | Product 1 |
74 | | Product 2 |
75 | And I call "AddToProducts" on the service with a new "Product" object with Name: "Product 3"
76 | And I call "AddToProducts" on the service with a new "Product" object with Name: "Product 4"
77 | When I call "Products" on the service
78 | And I filter the query with: "Name eq 'Product 1'"
79 | And I run the query
80 | And I set "Name" on the first result to "Product 1 - Updated"
81 | And I call "update_object" on the service with the first last query result
82 | When I call "Products" on the service
83 | And I filter the query with: "Name eq 'Product 2'"
84 | And I run the query
85 | And I call "delete_object" on the service with the first last query result
86 | When I save changes
87 | When I call "Products" on the service
88 | And I order by: "Name"
89 | And I run the query
90 | Then the result should be:
91 | | Name |
92 | | Product 1 - Updated |
93 | | Product 3 |
94 | | Product 4 |
95 |
96 |
--------------------------------------------------------------------------------
/features/cassettes/basic_auth_protected_resource.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://10.10.0.17:8989/SampleService/BasicAuth/RubyOData.svc/Categories(1)
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby
12 | Accept:
13 | - "*/*; q=0.5, application/xml"
14 | Authorization:
15 | - Basic YWRtaW46cGFzc3dk
16 | Accept-Encoding:
17 | - gzip,deflate
18 | response:
19 | status:
20 | code: 200
21 | message: ''
22 | headers:
23 | Cache-Control:
24 | - private
25 | Content-Length:
26 | - '1274'
27 | Content-Type:
28 | - application/atom+xml;type=entry;charset=utf-8
29 | Server:
30 | - Microsoft-IIS/8.0
31 | Set-Cookie:
32 | - ASP.NET_SessionId=3jiy4xpsmuspq01b2k3jdbi5; path=/; HttpOnly
33 | X-Content-Type-Options:
34 | - nosniff
35 | Dataserviceversion:
36 | - 1.0;
37 | X-Aspnet-Version:
38 | - 4.0.30319
39 | X-Powered-By:
40 | - ASP.NET
41 | Date:
42 | - Sun, 26 Apr 2015 16:29:23 GMT
43 | body:
44 | encoding: UTF-8
45 | string: http://10.10.0.17:8989/SampleService/BasicAuth/RubyOData.svc/Categories(1)2015-04-26T16:29:24Z1Auth
54 | Test Category2015-04-26T16:29:24.162015-04-26T16:29:24.16Machinist
57 | http_version:
58 | recorded_at: Sun, 26 Apr 2015 16:29:24 GMT
59 | recorded_with: VCR 2.5.0
60 |
--------------------------------------------------------------------------------
/features/cassettes/batch_request_additions.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products?$orderby=Name
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby
12 | Accept:
13 | - "*/*; q=0.5, application/xml"
14 | Accept-Encoding:
15 | - gzip,deflate
16 | response:
17 | status:
18 | code: 200
19 | message: ''
20 | headers:
21 | Cache-Control:
22 | - private
23 | Content-Length:
24 | - '2714'
25 | Content-Type:
26 | - application/atom+xml;type=feed;charset=utf-8
27 | Server:
28 | - Microsoft-IIS/8.0
29 | Set-Cookie:
30 | - ASP.NET_SessionId=fdxheq5p1ihklukb1qr503qn; path=/; HttpOnly
31 | X-Content-Type-Options:
32 | - nosniff
33 | Dataserviceversion:
34 | - 1.0;
35 | X-Aspnet-Version:
36 | - 4.0.30319
37 | X-Powered-By:
38 | - ASP.NET
39 | Date:
40 | - Sun, 26 Apr 2015 16:29:24 GMT
41 | body:
42 | encoding: UTF-8
43 | string: http://10.10.0.17:8989/SampleService/RubyOData.svc/ProductsProducts2015-04-26T16:29:25Zhttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)2015-04-26T16:29:25Z1Product
54 | 1Test Widget10.2512015-04-26T16:29:25.052015-04-26T16:29:25.05Machinisthttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(2)2015-04-26T16:29:25Z2Product
63 | 2Test Widget25.0022015-04-26T16:29:25.052015-04-26T16:29:25.05Machinist
67 | http_version:
68 | recorded_at: Sun, 26 Apr 2015 16:29:25 GMT
69 | recorded_with: VCR 2.5.0
70 |
--------------------------------------------------------------------------------
/features/cassettes/batch_request_deletes.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products?$orderby=Name
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby
12 | Accept:
13 | - "*/*; q=0.5, application/xml"
14 | Accept-Encoding:
15 | - gzip,deflate
16 | response:
17 | status:
18 | code: 200
19 | message: ''
20 | headers:
21 | Cache-Control:
22 | - private
23 | Content-Length:
24 | - '2714'
25 | Content-Type:
26 | - application/atom+xml;type=feed;charset=utf-8
27 | Server:
28 | - Microsoft-IIS/8.0
29 | Set-Cookie:
30 | - ASP.NET_SessionId=qdt3u3osyrmligcxgcyujpa5; path=/; HttpOnly
31 | X-Content-Type-Options:
32 | - nosniff
33 | Dataserviceversion:
34 | - 1.0;
35 | X-Aspnet-Version:
36 | - 4.0.30319
37 | X-Powered-By:
38 | - ASP.NET
39 | Date:
40 | - Sun, 26 Apr 2015 16:29:26 GMT
41 | body:
42 | encoding: UTF-8
43 | string: http://10.10.0.17:8989/SampleService/RubyOData.svc/ProductsProducts2015-04-26T16:29:26Zhttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)2015-04-26T16:29:26Z1Product
54 | 1Test Widget10.2512015-04-26T16:29:26.382015-04-26T16:29:26.38Machinisthttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(4)2015-04-26T16:29:26Z4Product
63 | 4Test Widget50.0042015-04-26T16:29:26.382015-04-26T16:29:26.38Machinist
67 | http_version:
68 | recorded_at: Sun, 26 Apr 2015 16:29:26 GMT
69 | recorded_with: VCR 2.5.0
70 |
--------------------------------------------------------------------------------
/features/cassettes/batch_request_updates.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products?$orderby=Name
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby
12 | Accept:
13 | - "*/*; q=0.5, application/xml"
14 | Accept-Encoding:
15 | - gzip,deflate
16 | response:
17 | status:
18 | code: 200
19 | message: ''
20 | headers:
21 | Cache-Control:
22 | - private
23 | Content-Length:
24 | - '2735'
25 | Content-Type:
26 | - application/atom+xml;type=feed;charset=utf-8
27 | Server:
28 | - Microsoft-IIS/8.0
29 | Set-Cookie:
30 | - ASP.NET_SessionId=oydoxso1ufajqrivi1owc1y3; path=/; HttpOnly
31 | X-Content-Type-Options:
32 | - nosniff
33 | Dataserviceversion:
34 | - 1.0;
35 | X-Aspnet-Version:
36 | - 4.0.30319
37 | X-Powered-By:
38 | - ASP.NET
39 | Date:
40 | - Sun, 26 Apr 2015 16:29:25 GMT
41 | body:
42 | encoding: UTF-8
43 | string: http://10.10.0.17:8989/SampleService/RubyOData.svc/ProductsProducts2015-04-26T16:29:26Zhttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)2015-04-26T16:29:26Z1Product
54 | 1 - UpdatedTest Widget25.0012015-04-26T16:29:25.662015-04-26T16:29:25.66Machinisthttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(2)2015-04-26T16:29:26Z2Product
63 | 2 - UpdatedTest Widget100.0022015-04-26T16:29:25.662015-04-26T16:29:25.66Machinist
67 | http_version:
68 | recorded_at: Sun, 26 Apr 2015 16:29:26 GMT
69 | recorded_with: VCR 2.5.0
70 |
--------------------------------------------------------------------------------
/features/cassettes/clean_database_for_testing.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: post
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/CleanDatabaseForTesting
6 | body:
7 | encoding: ASCII-8BIT
8 | string: ''
9 | headers:
10 | Accept:
11 | - "*/*; q=0.5, application/xml"
12 | Accept-Encoding:
13 | - gzip, deflate
14 | Content-Length:
15 | - '0'
16 | Content-Type:
17 | - application/x-www-form-urlencoded
18 | User-Agent:
19 | - Ruby
20 | response:
21 | status:
22 | code: 204
23 | message: No Content
24 | headers:
25 | Cache-Control:
26 | - private
27 | Server:
28 | - Microsoft-IIS/8.0
29 | Set-Cookie:
30 | - ASP.NET_SessionId=lnczwpi1jb4qmzrinl510zak; path=/; HttpOnly
31 | X-Content-Type-Options:
32 | - nosniff
33 | Dataserviceversion:
34 | - 1.0;
35 | X-Aspnet-Version:
36 | - 4.0.30319
37 | X-Powered-By:
38 | - ASP.NET
39 | Date:
40 | - Sun, 26 Apr 2015 16:30:01 GMT
41 | body:
42 | encoding: UTF-8
43 | string: ''
44 | http_version:
45 | recorded_at: Sun, 26 Apr 2015 16:30:02 GMT
46 | recorded_with: VCR 2.5.0
47 |
--------------------------------------------------------------------------------
/features/cassettes/cucumber_tags/error_handling.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: post
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products
6 | body:
7 | encoding: UTF-8
8 | string: '{"Name":"Widget 0017","Description":"Test Widget","Price":"","Category":{"Name":"Category
9 | 0018","AuditFields":{"CreatedBy":"Machinist"}},"AuditFields":{"CreatedBy":"Machinist"}}'
10 | headers:
11 | User-Agent:
12 | - Ruby
13 | Accept:
14 | - "*/*; q=0.5, application/xml"
15 | Content-Type:
16 | - application/json
17 | Accept-Encoding:
18 | - gzip,deflate
19 | response:
20 | status:
21 | code: 400
22 | message: ''
23 | headers:
24 | Cache-Control:
25 | - private
26 | Content-Length:
27 | - '1205'
28 | Content-Type:
29 | - application/xml
30 | Server:
31 | - Microsoft-IIS/8.0
32 | Set-Cookie:
33 | - ASP.NET_SessionId=ovdkiqkijkte14faqnyqcfll; path=/; HttpOnly
34 | X-Content-Type-Options:
35 | - nosniff
36 | Dataserviceversion:
37 | - 1.0;
38 | X-Aspnet-Version:
39 | - 4.0.30319
40 | X-Powered-By:
41 | - ASP.NET
42 | Date:
43 | - Sun, 26 Apr 2015 16:29:31 GMT
44 | body:
45 | encoding: ASCII-8BIT
46 | string: !binary |-
47 | PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiIHN0YW5kYWxv
48 | bmU9InllcyI/PjxlcnJvciB4bWxucz0iaHR0cDovL3NjaGVtYXMubWljcm9z
49 | b2Z0LmNvbS9hZG8vMjAwNy8wOC9kYXRhc2VydmljZXMvbWV0YWRhdGEiPjxj
50 | b2RlPjwvY29kZT48bWVzc2FnZSB4bWw6bGFuZz0icGwtUEwiPkVycm9yIHBy
51 | b2Nlc3NpbmcgcmVxdWVzdCBzdHJlYW0uIEVycm9yIGVuY291bnRlcmVkIGlu
52 | IGNvbnZlcnRpbmcgdGhlIHZhbHVlIGZyb20gcmVxdWVzdCBwYXlsb2FkIGZv
53 | ciBwcm9wZXJ0eSAnUHJpY2UnIHRvIHR5cGUgJ0RlY2ltYWwnLCB3aGljaCBp
54 | cyB0aGUgcHJvcGVydHkncyBleHBlY3RlZCB0eXBlLiBTZWUgaW5uZXIgZXhj
55 | ZXB0aW9uIGZvciBtb3JlIGRldGFpbC48L21lc3NhZ2U+PGlubmVyZXJyb3I+
56 | PG1lc3NhZ2U+TmllcHJhd2lkxYJvd3kgZm9ybWF0IGNpxIVndSB3ZWrFm2Np
57 | b3dlZ28uPC9tZXNzYWdlPjx0eXBlPlN5c3RlbS5Gb3JtYXRFeGNlcHRpb248
58 | L3R5cGU+PHN0YWNrdHJhY2U+ICAgdyBTeXN0ZW0uTnVtYmVyLlN0cmluZ1Rv
59 | TnVtYmVyKFN0cmluZyBzdHIsIE51bWJlclN0eWxlcyBvcHRpb25zLCBOdW1i
60 | ZXJCdWZmZXImYW1wOyBudW1iZXIsIE51bWJlckZvcm1hdEluZm8gaW5mbywg
61 | Qm9vbGVhbiBwYXJzZURlY2ltYWwpJiN4RDsKICAgdyBTeXN0ZW0uTnVtYmVy
62 | LlBhcnNlRGVjaW1hbChTdHJpbmcgdmFsdWUsIE51bWJlclN0eWxlcyBvcHRp
63 | b25zLCBOdW1iZXJGb3JtYXRJbmZvIG51bWZtdCkmI3hEOwogICB3IFN5c3Rl
64 | bS5Db252ZXJ0LlRvRGVjaW1hbChTdHJpbmcgdmFsdWUsIElGb3JtYXRQcm92
65 | aWRlciBwcm92aWRlcikmI3hEOwogICB3IFN5c3RlbS5TdHJpbmcuU3lzdGVt
66 | LklDb252ZXJ0aWJsZS5Ub0RlY2ltYWwoSUZvcm1hdFByb3ZpZGVyIHByb3Zp
67 | ZGVyKSYjeEQ7CiAgIHcgU3lzdGVtLkNvbnZlcnQuQ2hhbmdlVHlwZShPYmpl
68 | Y3QgdmFsdWUsIFR5cGUgY29udmVyc2lvblR5cGUsIElGb3JtYXRQcm92aWRl
69 | ciBwcm92aWRlcikmI3hEOwogICB3IFN5c3RlbS5EYXRhLlNlcnZpY2VzLlNl
70 | cmlhbGl6ZXJzLkpzb25EZXNlcmlhbGl6ZXIuQ29udmVydFZhbHVlcyhPYmpl
71 | Y3QgdmFsdWUsIFN0cmluZyBwcm9wZXJ0eU5hbWUsIFR5cGUgdHlwZVRvQmVD
72 | b252ZXJ0ZWQsIERhdGFTZXJ2aWNlUHJvdmlkZXJXcmFwcGVyIHByb3ZpZGVy
73 | KTwvc3RhY2t0cmFjZT48L2lubmVyZXJyb3I+PC9lcnJvcj4=
74 | http_version:
75 | recorded_at: Sun, 26 Apr 2015 16:29:31 GMT
76 | recorded_with: VCR 2.5.0
77 |
--------------------------------------------------------------------------------
/features/cassettes/service_manage_additions.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: post
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products
6 | body:
7 | encoding: UTF-8
8 | string: '{"Name":"Sample Product","Description":"Test Widget","Price":"75.50","Category":{"Name":"Category
9 | 0059","AuditFields":{"CreatedBy":"Machinist"}},"AuditFields":{"CreatedBy":"Machinist"}}'
10 | headers:
11 | User-Agent:
12 | - Ruby
13 | Accept:
14 | - "*/*; q=0.5, application/xml"
15 | Content-Type:
16 | - application/json
17 | Accept-Encoding:
18 | - gzip,deflate
19 | response:
20 | status:
21 | code: 201
22 | message: ''
23 | headers:
24 | Cache-Control:
25 | - private
26 | Content-Length:
27 | - '1447'
28 | Content-Type:
29 | - application/atom+xml;type=entry;charset=utf-8
30 | Location:
31 | - http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)
32 | Server:
33 | - Microsoft-IIS/8.0
34 | Set-Cookie:
35 | - ASP.NET_SessionId=yi20lwcen2khadra1on4ncpm; path=/; HttpOnly
36 | X-Content-Type-Options:
37 | - nosniff
38 | Dataserviceversion:
39 | - 1.0;
40 | X-Aspnet-Version:
41 | - 4.0.30319
42 | X-Powered-By:
43 | - ASP.NET
44 | Date:
45 | - Sun, 26 Apr 2015 16:29:49 GMT
46 | body:
47 | encoding: UTF-8
48 | string: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)2015-04-26T16:29:50Z1Sample
57 | ProductTest Widget75.5012015-04-26T16:29:49.786157Z2015-04-26T16:29:49.786157ZMachinist
61 | http_version:
62 | recorded_at: Sun, 26 Apr 2015 16:29:50 GMT
63 | recorded_with: VCR 2.5.0
64 |
--------------------------------------------------------------------------------
/features/cassettes/service_manage_deletions.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby
12 | Accept:
13 | - "*/*; q=0.5, application/xml"
14 | Accept-Encoding:
15 | - gzip,deflate
16 | response:
17 | status:
18 | code: 200
19 | message: ''
20 | headers:
21 | Cache-Control:
22 | - private
23 | Content-Length:
24 | - '1437'
25 | Content-Type:
26 | - application/atom+xml;type=entry;charset=utf-8
27 | Server:
28 | - Microsoft-IIS/8.0
29 | Set-Cookie:
30 | - ASP.NET_SessionId=pizgaagzomtggnagi5xlmbmv; path=/; HttpOnly
31 | X-Content-Type-Options:
32 | - nosniff
33 | Dataserviceversion:
34 | - 1.0;
35 | X-Aspnet-Version:
36 | - 4.0.30319
37 | X-Powered-By:
38 | - ASP.NET
39 | Date:
40 | - Sun, 26 Apr 2015 16:29:50 GMT
41 | body:
42 | encoding: UTF-8
43 | string: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)2015-04-26T16:29:51Z1Test
52 | ProductTest Widget25.0012015-04-26T16:29:51.2872015-04-26T16:29:51.287Machinist
56 | http_version:
57 | recorded_at: Sun, 26 Apr 2015 16:29:51 GMT
58 | recorded_with: VCR 2.5.0
59 |
--------------------------------------------------------------------------------
/features/cassettes/service_manage_deletions_2.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby
12 | Accept:
13 | - "*/*; q=0.5, application/xml"
14 | Accept-Encoding:
15 | - gzip,deflate
16 | response:
17 | status:
18 | code: 200
19 | message: ''
20 | headers:
21 | Cache-Control:
22 | - private
23 | Content-Length:
24 | - '1445'
25 | Content-Type:
26 | - application/atom+xml;type=entry;charset=utf-8
27 | Server:
28 | - Microsoft-IIS/8.0
29 | Set-Cookie:
30 | - ASP.NET_SessionId=pjn1eic4di3f3u3vdpispb55; path=/; HttpOnly
31 | X-Content-Type-Options:
32 | - nosniff
33 | Dataserviceversion:
34 | - 1.0;
35 | X-Aspnet-Version:
36 | - 4.0.30319
37 | X-Powered-By:
38 | - ASP.NET
39 | Date:
40 | - Sun, 26 Apr 2015 16:29:51 GMT
41 | body:
42 | encoding: UTF-8
43 | string: http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)2015-04-26T16:29:51Z1Changed
52 | Test ProductTest Widget25.0012015-04-26T16:29:51.2872015-04-26T16:29:51.287Machinist
56 | http_version:
57 | recorded_at: Sun, 26 Apr 2015 16:29:51 GMT
58 | recorded_with: VCR 2.5.0
59 |
--------------------------------------------------------------------------------
/features/cassettes/unsecured_metadata.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://10.10.0.17:8989/SampleService/RubyOData.svc/$metadata
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby
12 | Accept:
13 | - "*/*; q=0.5, application/xml"
14 | Accept-Encoding:
15 | - gzip,deflate
16 | response:
17 | status:
18 | code: 200
19 | message: ''
20 | headers:
21 | Cache-Control:
22 | - private
23 | Content-Length:
24 | - '4055'
25 | Content-Type:
26 | - application/xml;charset=utf-8
27 | Server:
28 | - Microsoft-IIS/8.0
29 | Set-Cookie:
30 | - ASP.NET_SessionId=q4q3bi2ftgf1n4xdsw3weviz; path=/; HttpOnly
31 | X-Content-Type-Options:
32 | - nosniff
33 | Dataserviceversion:
34 | - 1.0;
35 | X-Aspnet-Version:
36 | - 4.0.30319
37 | X-Powered-By:
38 | - ASP.NET
39 | Date:
40 | - Sun, 26 Apr 2015 16:30:01 GMT
41 | body:
42 | encoding: UTF-8
43 | string:
87 | http_version:
88 | recorded_at: Sun, 26 Apr 2015 16:30:02 GMT
89 | recorded_with: VCR 2.5.0
90 |
--------------------------------------------------------------------------------
/features/complex_types.feature:
--------------------------------------------------------------------------------
1 | @complex_types
2 | Feature: Complex types
3 | In order to fully support OData services
4 | As a user of ruby_odata
5 | I want to be able to manage objects with complex types
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 | Scenario: The proxy must generate classes for complex types if they exist
12 | Then a class named "AuditFields" should exist
13 |
14 | Scenario: Complex properties on an entity must be the correct type
15 | Given I call "AddToProducts" on the service with a new "Product" object
16 | And I save changes
17 | And I call "Products" on the service with args: "1"
18 | When I run the query
19 | Then the first result should have a method: "AuditFields"
20 | And the method "AuditFields" on the first result should be of type "AuditFields"
21 |
22 | Scenario: Complex properties on an entity must be filled
23 | Given I call "AddToProducts" on the service with a new "Product" object
24 | And I save changes
25 | And I call "Products" on the service with args: "1"
26 | When I run the query
27 | Then the first result should have a method: "AuditFields"
28 | When I call "CreateDate" for "AuditFields" on the first result
29 | Then the operation should not be null
30 |
31 | # TODO: This scenario should have the AuditFields.CreatedBy field set in the Given
32 | # instead it is set by the blueprint
33 | Scenario: Complex properties should be able to be added
34 | Given I call "AddToProducts" on the service with a new "Product" object
35 | And I save changes
36 | And I call "Products" on the service with args: "1"
37 | When I run the query
38 | Then the method "CreatedBy" on the first result's method "AuditFields" should equal: "Machinist"
39 |
40 | Scenario: Complex properties should be able to be updated
41 | Given I call "AddToProducts" on the service with a new "Product" object
42 | And I save changes
43 | And I call "Products" on the service with args: "1"
44 | When I run the query
45 | When I set "CreatedBy" on the first result's method "AuditFields" to "This Test"
46 | And I call "update_object" on the service with the first last query result
47 | And I save changes
48 | Then the save result should equal: "true"
49 | When I call "Products" on the service with args: "1"
50 | And I run the query
51 | Then the method "CreatedBy" on the first result's method "AuditFields" should equal: "This Test"
52 |
53 |
54 |
--------------------------------------------------------------------------------
/features/error_handling.feature:
--------------------------------------------------------------------------------
1 | @error_handling
2 | Feature: Error handling
3 | In order to assist debugging
4 | As a user
5 | I want more debug information when an error occurs communicating with the server
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 | Scenario: Violate a data type conversion (empty string to decimal)
12 | Given I call "AddToProducts" on the service with a new "Product" object with Price: ""
13 | When I save changes it should throw an exception with message containing "Error encountered in converting the value"
14 |
--------------------------------------------------------------------------------
/features/query_builder.feature:
--------------------------------------------------------------------------------
1 | @query_builder
2 | Feature: Query Builder
3 | In order to query OData services
4 | As a user
5 | I want to be able to perform valid OData protocol operations
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 | # Expand
12 | Scenario: Navigation Properties should be able to be eager loaded
13 | Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
14 | And I save changes
15 | And I call "AddToProducts" on the service with a new "Product" object with Category: "@@LastSave.first"
16 | And I save changes
17 | And I call "Products" on the service with args: "1"
18 | And I expand the query to include "Category"
19 | When I run the query
20 | Then the method "Category" on the first result should be of type "Category"
21 | And the method "Name" on the first result's method "Category" should equal: "Test Category"
22 | And the method "Id" on the first result's method "Category" should equal: "1"
23 |
24 |
25 | # Filters
26 | Scenario: Filters should be allowed on the root level entity
27 | # Filter
28 | Given I call "AddToProducts" on the service with a new "Product" object with Name: "Test Product"
29 | When I save changes
30 | When I call "Products" on the service
31 | And I filter the query with: "Name eq 'Test Product'"
32 | And I run the query
33 | Then the method "Name" on the first result should equal: "Test Product"
34 |
35 |
36 | # Order By
37 | Scenario: Order by should be allowed on the root level entity
38 | Given the following products exist:
39 | | Name |
40 | | Product 2 |
41 | | Product 4 |
42 | | Product 5 |
43 | | Product 1 |
44 | | Product 3 |
45 | When I call "Products" on the service
46 | And I order by: "Name"
47 | And I run the query
48 | Then the result should be:
49 | | Name |
50 | | Product 1 |
51 | | Product 2 |
52 | | Product 3 |
53 | | Product 4 |
54 | | Product 5 |
55 |
56 | Scenario: Order by should accept sorting descending
57 | Given the following products exist:
58 | | Name |
59 | | Product 2 |
60 | | Product 4 |
61 | | Product 5 |
62 | | Product 1 |
63 | | Product 3 |
64 | When I call "Products" on the service
65 | And I order by: "Name desc"
66 | And I run the query
67 | Then the result should be:
68 | | Name |
69 | | Product 5 |
70 | | Product 4 |
71 | | Product 3 |
72 | | Product 2 |
73 | | Product 1 |
74 |
75 | Scenario: Order by should access sorting acsending
76 | Given the following products exist:
77 | | Name |
78 | | Product 2 |
79 | | Product 4 |
80 | | Product 5 |
81 | | Product 1 |
82 | | Product 3 |
83 | When I call "Products" on the service
84 | And I order by: "Name asc"
85 | And I run the query
86 | Then the result should be:
87 | | Name |
88 | | Product 1 |
89 | | Product 2 |
90 | | Product 3 |
91 | | Product 4 |
92 | | Product 5 |
93 |
94 |
95 | # Skip
96 | Scenario: Skip should be allowed on the root level entity
97 | Given the following products exist:
98 | | Name |
99 | | Product 1 |
100 | | Product 2 |
101 | | Product 3 |
102 | | Product 4 |
103 | | Product 5 |
104 | When I call "Products" on the service
105 | And I skip 3
106 | And I run the query
107 | Then the result should be:
108 | | Name |
109 | | Product 4 |
110 | | Product 5 |
111 |
112 |
113 | # Top
114 | Scenario: Top should be allowed on the root level entity
115 | Given the following products exist:
116 | | Name |
117 | | Product 1 |
118 | | Product 2 |
119 | | Product 3 |
120 | | Product 4 |
121 | | Product 5 |
122 | When I call "Products" on the service
123 | And I ask for the top 3
124 | And I run the query
125 | Then the result should be:
126 | | Name |
127 | | Product 1 |
128 | | Product 2 |
129 | | Product 3 |
130 |
131 | Scenario: Top should be able to be used along with skip for paging
132 | Given the following products exist:
133 | | Name |
134 | | Product 1 |
135 | | Product 2 |
136 | | Product 3 |
137 | | Product 4 |
138 | | Product 5 |
139 | | Product 6 |
140 | When I call "Products" on the service
141 | And I skip 2
142 | And I ask for the top 2
143 | And I run the query
144 | Then the result should be:
145 | | Name |
146 | | Product 3 |
147 | | Product 4 |
148 |
149 |
150 | # Links
151 | Scenario: Navigation Properties should be able to represented as links
152 | Given a category: "cat1" exists with Name: "Test Category"
153 | And I save changes
154 | And the following products exist:
155 | | Name | Category |
156 | | Product 1 | category: "cat1" |
157 | | Product 2 | category: "cat1" |
158 | | Product 3 | category: "cat1" |
159 | When I call "Categories" on the service with args: "1"
160 | And I ask for the links for "Products"
161 | And I run the query
162 | Then the result count should be 3
163 | Then the method "path" on the first result should equal: "/SampleService/RubyOData.svc/Products(1)"
164 |
165 | # Count
166 | Scenario: Count should be able to be used on a root collection
167 | Given 4 products exist
168 | When I call "Products" on the service
169 | And I ask for the count
170 | And I run the query
171 | Then the integer result should be 4
172 |
173 | Scenario: Count should be able to be used on with a filter
174 | Given the following products exist:
175 | | Name |
176 | | Product 1 |
177 | | Product 2 |
178 | When I call "Products" on the service
179 | And I filter the query with: "Name eq 'Product 2'"
180 | And I ask for the count
181 | And I run the query
182 | Then the integer result should be 1
183 |
184 |
--------------------------------------------------------------------------------
/features/service.feature:
--------------------------------------------------------------------------------
1 | @service
2 | Feature: Service Should Generate a Proxy
3 | In order to consume the OData
4 | As a user
5 | I want to be able to access data
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 | Scenario: Service should respond to valid collections
12 | Then I should be able to call "Categories" on the service
13 |
14 | # Scenario: Service should not respond to an invalid collection
15 | # Then I should not be able to call "X" on the service
16 | #
17 | # Scenario: Service should respond to accessing a single entity by ID
18 | # Then I should be able to call "Categories" on the service with args: "1"
19 | #
20 | # Scenario: Access an entity by ID should return the entity type
21 | # Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
22 | # And I save changes
23 | # And I call "Categories" on the service with args: "1"
24 | # When I run the query
25 | # Then the first result should be of type "Category"
26 | #
27 | # Scenario: Entity should have the correct accessors
28 | # Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
29 | # And I save changes
30 | # And I call "Categories" on the service with args: "1"
31 | # When I run the query
32 | # Then the first result should have a method: "Id"
33 | # And the first result should have a method: "Name"
34 | #
35 | # Scenario: Entity should fill values
36 | # Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
37 | # And I save changes
38 | # And I call "Categories" on the service with args: "1"
39 | # When I run the query
40 | # Then the method "Id" on the first result should equal: "1"
41 | # And the method "Name" on the first result should equal: "Test Category"
42 | #
43 | # Scenario: Navigation Properties should be included in results
44 | # Given I call "AddToProducts" on the service with a new "Product" object
45 | # And I save changes
46 | # And I call "Products" on the service with args: "1"
47 | # When I run the query
48 | # Then the first result should have a method: "Category"
49 | # And the method "Category" on the first result should be nil
50 | #
51 |
--------------------------------------------------------------------------------
/features/service_manage.feature:
--------------------------------------------------------------------------------
1 | @service_manage
2 | Feature: Service management
3 | In order to manage entities
4 | As a admin
5 | I want to be able to add, edit, and delete entities
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 | Scenario: Service should respond to AddToEntityName for adding objects
12 | Given I call "AddToProducts" on the service with a new "Product" object with Name: "Sample Product"
13 | When I save changes within a cassette named "service_manage_additions"
14 | Then the first save result should be of type "Product"
15 | And the method "Name" on the first save result should equal: "Sample Product"
16 |
17 | Scenario: Service should allow for deletes
18 | Given I call "AddToProducts" on the service with a new "Product" object
19 | When I save changes
20 | Then the first save result should be of type "Product"
21 | When I call "delete_object" on the service with the first last save result
22 | And I save changes
23 | Then the save result should equal: "true"
24 | And no "Products" should exist
25 |
26 | Scenario: Untracked entities shouldn't be able to be deleted
27 | Given I call "delete_object" on the service with a new "Product" object it should throw an exception with message "You cannot delete a non-tracked entity"
28 |
29 | Scenario: Entities should be able to be updated
30 | Given I call "AddToProducts" on the service with a new "Product" object with Name: "Test Product"
31 | When I save changes
32 | And I call "Products" on the service with args: "1"
33 | And I run the query within a cassette named "service_manage_deletions"
34 | Then the method "Name" on the first result should equal: "Test Product"
35 | When I set "Name" on the first result to "Changed Test Product"
36 | Then the method "Name" on the first result should equal: "Changed Test Product"
37 | And I call "update_object" on the service with the first last query result
38 | And I save changes
39 | Then the save result should equal: "true"
40 | When I call "Products" on the service with args: "1"
41 | And I run the query within a cassette named "service_manage_deletions_2"
42 | Then the method "Name" on the first result should equal: "Changed Test Product"
43 |
44 | Scenario: Untracked entities shouldn't be able to be updated
45 | Given I call "update_object" on the service with a new "Product" object it should throw an exception with message "You cannot update a non-tracked entity"
46 |
47 | Scenario: Related entities shouldn't be recreated on a child add
48 | Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
49 | And I save changes
50 | And I call "AddToProducts" on the service with a new "Product" object with Category: "@@LastSave.first"
51 | And I save changes
52 | And I call "Products" on the service with args: "1"
53 | And I expand the query to include "Category"
54 | When I run the query
55 | Then the method "Id" on the first result's method "Category" should equal: "1"
56 |
57 | Scenario: Entities should be able to be linked together
58 | Given a category: "cat1" exists
59 | And a product: "prod1" exists
60 | When I add a link between category: "cat1" and product: "prod1" on "Products"
61 | And I save changes
62 | Then the product: "prod1" should be one of category: "cat1"'s Products
63 |
64 | Scenario: Entities should be able to be linked together on a batch save
65 | Given a category: "cat1" exists
66 | And a product: "prod1" exists
67 | When I add a link between category: "cat1" and product: "prod1" on "Products"
68 | And I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
69 | And I save changes
70 | Then the product: "prod1" should be one of category: "cat1"'s Products
71 |
--------------------------------------------------------------------------------
/features/service_methods.feature:
--------------------------------------------------------------------------------
1 | @service_methods
2 | Feature: Service methods
3 | In order to use a WCF Data Service more efficiently
4 | As a consumer
5 | I want to be able to utilize custom WCF DS methods
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 |
12 | Scenario: A custom web get (no parameters) that returns an entity
13 | Given a category exists
14 | And I call the service method "EntityCategoryWebGet"
15 | Then the first result should be of type "Category"
16 |
17 | Scenario: A custom web get (with parameters) that returns a single entity
18 | Given a category: "cat1" exists with Id: 1
19 | When I call the service method "EntitySingleCategoryWebGet" with 1
20 | Then the result should be of type "Category"
21 | And the method "Id" on the result should equal: "1"
22 |
23 | Scenario: A custom web get that returns a collection of primitive types
24 | Given the following categories exist:
25 | | Name |
26 | | Cat1 |
27 | | Cat2 |
28 | | Cat3 |
29 | When I call the service method "CategoryNames"
30 | Then the primitive results should be:
31 | | Cat1 |
32 | | Cat2 |
33 | | Cat3 |
34 |
35 | Scenario: A custom web get that returns a single primitive type
36 | Given a category exists
37 | When I call the service method "FirstCategoryId"
38 | Then the integer result should be 1
39 |
--------------------------------------------------------------------------------
/features/ssl.feature:
--------------------------------------------------------------------------------
1 | @ssl
2 | Feature: Service Should Access Basic Resources via SSL using a self-signed certificate
3 |
4 | Scenario: Service should respond to valid collections
5 | Given a HTTPS BasicAuth ODataService exists using self-signed certificate and username "admin" and password "passwd"
6 | And blueprints exist for the service
7 | Then I should be able to call "Products" on the service
8 |
9 | Scenario: Entity should fill values on protected resource
10 | Given a HTTPS BasicAuth ODataService exists using self-signed certificate and username "admin" and password "passwd"
11 | And blueprints exist for the service
12 | Given I call "AddToCategories" on the service with a new "Category" object with Name: "Auth Test Category"
13 | And I save changes
14 | And I call "Categories" on the service with args: "1"
15 | When I run the query
16 | Then the method "Id" on the first result should equal: "1"
17 | And the method "Name" on the first result should equal: "Auth Test Category"
18 |
19 | # TODO: Commented this scenario out because it requires the server to be online in order for the tests to run. Would like to move this to a mocked test that would accomplish the same thing...
20 | # Scenario: Should get SSL failure if SSL used with self-signed certificate and not passing "false" as :verify_ssl option
21 | # Given a HTTPS BasicAuth ODataService exists it should throw an exception with message containing "SSL Verification failed"
22 |
--------------------------------------------------------------------------------
/features/step_definitions/pickle_steps.rb:
--------------------------------------------------------------------------------
1 | # this file generated by script/generate pickle
2 |
3 | # create a model
4 | Given(/^#{capture_model} exists?(?: with #{capture_fields})?$/) do |name, fields|
5 | create_model(name, fields)
6 | end
7 |
8 | # create n models
9 | Given(/^(\d+) #{capture_plural_factory} exist(?: with #{capture_fields})?$/) do |count, plural_factory, fields|
10 | count.to_i.times { create_model(plural_factory.singularize, fields) }
11 | end
12 |
13 | # create models from a table
14 | Given(/^the following #{capture_plural_factory} exists?:?$/) do |plural_factory, table|
15 | create_models_from_table(plural_factory, table)
16 | end
17 |
18 | # find a model
19 | Then(/^#{capture_model} should exist(?: with #{capture_fields})?$/) do |name, fields|
20 | find_model!(name, fields)
21 | end
22 |
23 | # not find a model
24 | Then(/^#{capture_model} should not exist(?: with #{capture_fields})?$/) do |name, fields|
25 | expect(find_model(name, fields)).to be_nil
26 | end
27 |
28 | # find models with a table
29 | Then(/^the following #{capture_plural_factory} should exists?:?$/) do |plural_factory, table|
30 | expect(find_models_from_table(plural_factory, table)).to_not be_any(&:nil?)
31 | end
32 |
33 | # find exactly n models
34 | Then(/^(\d+) #{capture_plural_factory} should exist(?: with #{capture_fields})?$/) do |count, plural_factory, fields|
35 | find_models(plural_factory.singularize, fields).size.should == count.to_i
36 | end
37 |
38 | # assert equality of models
39 | Then(/^#{capture_model} should be #{capture_model}$/) do |a, b|
40 | model!(a).should == model!(b)
41 | end
42 |
43 | # assert model is in another model's has_many assoc
44 | Then(/^#{capture_model} should be (?:in|one of|amongst) #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
45 | expect(model_with_associations(owner).send(association)).to include(model!(target))
46 | end
47 |
48 | # assert model is not in another model's has_many assoc
49 | Then(/^#{capture_model} should not be (?:in|one of|amongst) #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
50 | model!(owner).send(association).should_not include(model!(target))
51 | end
52 |
53 | # assert model is another model's has_one/belongs_to assoc
54 | Then(/^#{capture_model} should be #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
55 | model!(owner).send(association).should == model!(target)
56 | end
57 |
58 | # assert model is not another model's has_one/belongs_to assoc
59 | Then(/^#{capture_model} should not be #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
60 | model!(owner).send(association).should_not == model!(target)
61 | end
62 |
63 | # assert model.predicate?
64 | Then(/^#{capture_model} should (?:be|have) (?:an? )?#{capture_predicate}$/) do |name, predicate|
65 | if model!(name).respond_to?("has_#{predicate.gsub(' ', '_')}")
66 | model!(name).should send("have_#{predicate.gsub(' ', '_')}")
67 | else
68 | model!(name).should send("be_#{predicate.gsub(' ', '_')}")
69 | end
70 | end
71 |
72 | # assert not model.predicate?
73 | Then(/^#{capture_model} should not (?:be|have) (?:an? )?#{capture_predicate}$/) do |name, predicate|
74 | if model!(name).respond_to?("has_#{predicate.gsub(' ', '_')}")
75 | model!(name).should_not send("have_#{predicate.gsub(' ', '_')}")
76 | else
77 | model!(name).should_not send("be_#{predicate.gsub(' ', '_')}")
78 | end
79 | end
80 |
81 | # model.attribute.should eql(value)
82 | # model.attribute.should_not eql(value)
83 | Then(/^#{capture_model}'s (\w+) (should(?: not)?) be #{capture_value}$/) do |name, attribute, expectation, expected|
84 | actual_value = model(name).send(attribute)
85 | expectation = expectation.gsub(' ', '_')
86 |
87 | case expected
88 | when 'nil', 'true', 'false'
89 | actual_value.send(expectation, send("be_#{expected}"))
90 | when /^[+-]?[0-9_]+(\.\d+)?$/
91 | actual_value.send(expectation, eql(expected.to_f))
92 | else
93 | actual_value.to_s.send(expectation, eql(eval(expected)))
94 | end
95 | end
96 |
97 | # assert size of association
98 | Then /^#{capture_model} should have (\d+) (\w+)$/ do |name, size, association|
99 | model!(name).send(association).size.should == size.to_i
100 | end
101 |
--------------------------------------------------------------------------------
/features/support/constants.rb:
--------------------------------------------------------------------------------
1 | HTTP_PORT_NUMBER = ENV.include?("ODATA_PORT") ? ENV["ODATA_PORT"] : 8989
2 | HTTPS_PORT_NUMBER = ENV.include?("ODATA_SSL_PORT") ? ENV["ODATA_SSL_PORT"] : 44300
3 | WEBSERVER = ENV.include?("ODATA_SERVER") ? ENV["ODATA_SERVER"] : 'localhost'
4 |
--------------------------------------------------------------------------------
/features/support/custom_helpers.rb:
--------------------------------------------------------------------------------
1 | module CustomHelpers
2 | # Used to access the first result of a query
3 | def first_result
4 | @service_result = @service_result.first if @service_result.is_a? Enumerable
5 | end
6 |
7 | # Used to access the first save result
8 | def first_save
9 | @saved_result = @saved_result.first if @saved_result.is_a? Enumerable
10 | end
11 |
12 | # Allows the string @@LastSave to be used when checking results
13 | def handle_last_save_fields(val)
14 | if val =~ /^@@LastSave.first$/
15 | val = @saved_result.first
16 | end
17 | if val =~ /^@@LastSave$/
18 | val = @saved_result
19 | end
20 | val
21 | end
22 |
23 | # Takes in comma-delimited fields string (like key: "value") and parses it into a hash
24 | def parse_fields_string(fields)
25 | fields_hash = {}
26 |
27 | if !fields.nil?
28 | fields.split(', ').each do |field|
29 | if field =~ /^(?:(\w+): "(.*)")$/
30 | key = $1
31 | val = handle_last_save_fields($2)
32 |
33 | fields_hash.merge!({key => val})
34 | end
35 | end
36 | end
37 | fields_hash
38 | end
39 |
40 | # Takes in a hash and convert special values (like @@LastSave) into the appropriate values
41 | def parse_fields_hash(fields)
42 | fields_hash = {}
43 |
44 | if !fields.nil?
45 | fields.each do |key, val|
46 | val = handle_last_save_fields(val)
47 | fields_hash.merge!({key => val})
48 | end
49 | end
50 | fields_hash
51 | end
52 |
53 | end
54 | World(CustomHelpers)
--------------------------------------------------------------------------------
/features/support/env.rb:
--------------------------------------------------------------------------------
1 | lib = File.expand_path(File.join(File.dirname(__FILE__), "../..", "lib"))
2 |
3 | require lib + '/ruby_odata'
4 | require 'machinist'
5 |
6 | require 'simplecov'
7 | # require 'coveralls'
8 |
9 | # Coveralls.wear_merged!
10 |
--------------------------------------------------------------------------------
/features/support/hooks.rb:
--------------------------------------------------------------------------------
1 | Before do
2 | VCR.use_cassette("clean_database_for_testing") do
3 | conn = Faraday.new(url: "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}")
4 | conn.post '/SampleService/RubyOData.svc/CleanDatabaseForTesting'
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/features/support/pickle.rb:
--------------------------------------------------------------------------------
1 | require "pickle/world"
2 | require "vcr"
3 | require File.expand_path("../../../lib/ruby_odata", __FILE__)
4 |
5 | module OData
6 | module PickleAdapter
7 | include Pickle::Adapter::Base
8 | @@service = nil
9 | def self.get_service
10 | return @@service if @@service
11 | VCR.use_cassette("unsecured_metadata") do
12 | return OData::Service.new "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.svc"
13 | end
14 | end
15 |
16 | # Do not consider these to be part of the class list
17 | def self.except_classes
18 | @@except_classes ||= []
19 | end
20 |
21 | # Gets a list of the available models for this adapter
22 | def self.model_classes
23 | self.get_service.classes.values
24 | end
25 |
26 | # get a list of column names for a given class
27 | def self.column_names(klass)
28 | klass.properties.keys
29 | end
30 |
31 | # Get an instance by id of the model
32 | def self.get_model(klass, id, expand = false)
33 | collection = klass.to_s.split('::').last.pluralize
34 | service = self.get_service
35 |
36 | query = service.send collection, id
37 |
38 | if expand then
39 | # Expand all navigation properties
40 | navigation_properties = klass.properties.select { |k, v| v.nav_prop }
41 | # Ruby 1.9 Hash.select returns a Hash, 1.8 returns an Array, so normalize the return type
42 | props = (navigation_properties.is_a? Hash) ? navigation_properties : Hash[*navigation_properties.flatten]
43 | props.keys.each do |prop|
44 | query.expand(prop)
45 | end
46 | end
47 |
48 | service.execute.first
49 | end
50 |
51 | # Find the first instance matching conditions
52 | def self.find_first_model(klass, conditions)
53 | collection = klass.to_s.split('::').last.pluralize
54 | service = self.get_service
55 |
56 | q = service.send collection
57 | q.filter(conditions)
58 | q.take(1)
59 | service.execute.first
60 | end
61 |
62 | # Find all models matching conditions
63 | def self.find_all_models(klass, conditions)
64 | collection = klass.to_s.split('::').last.pluralize
65 | service = self.get_service
66 |
67 | q = service.send collection
68 | q.filter(conditions)
69 | service.execute
70 | end
71 |
72 | # Create a model using attributes
73 | def self.create_model(klass, attributes)
74 | instance = klass.send :make, attributes
75 |
76 | collection = klass.to_s.split('::').last.pluralize
77 | service = self.get_service
78 | service.send "AddTo#{collection}", instance
79 | service.save_changes.first
80 | end
81 | end
82 | end
83 |
84 | module Pickle
85 | module Session
86 | # return a newly selected model with the navigation properties expanded
87 | def model_with_associations(name)
88 | model = created_model(name)
89 | return nil unless model
90 | OData::PickleAdapter.get_model(model.class, model.id, true)
91 | end
92 | end
93 | end
--------------------------------------------------------------------------------
/features/support/vcr.rb:
--------------------------------------------------------------------------------
1 | require "vcr"
2 | require File.expand_path("../../../spec/support/sample_service_matcher", __FILE__)
3 |
4 | VCR.configure do |c|
5 | c.hook_into :webmock
6 | c.cassette_library_dir = "features/cassettes"
7 | c.default_cassette_options = {
8 | record: :none,
9 | match_requests_on: [:method, OData::Support::SampleServiceMatcher]
10 | }
11 | end
12 |
13 | VCR.cucumber_tags do |t|
14 | t.tags "@basic_auth",
15 | "@batch_request",
16 | "@complex_types",
17 | "@error_handling",
18 | "@query_builder",
19 | "@service",
20 | "@service_manage",
21 | "@service_methods",
22 | "@ssl",
23 | "@type_conversion"
24 | end
25 |
--------------------------------------------------------------------------------
/features/type_conversion.feature:
--------------------------------------------------------------------------------
1 | @type_conversion
2 | Feature: Type conversion
3 | In order to accurately perform operations
4 | As a user of the API
5 | I want types returned to be accurately represented
6 |
7 | Background:
8 | Given a HTTP ODataService exists
9 | And blueprints exist for the service
10 |
11 | Scenario: Integers should be Fixnums
12 | Given I call "AddToProducts" on the service with a new "Product" object
13 | And I save changes
14 | When I call "Products" on the service
15 | And I run the query
16 | Then the "Id" method on the object should return a Fixnum
17 |
18 | Scenario: Decimals should be BigDecimals
19 | Given I call "AddToProducts" on the service with a new "Product" object
20 | And I save changes
21 | When I call "Products" on the service
22 | And I run the query
23 | Then the "Price" method on the object should return a BigDecimal
24 |
25 | Scenario: DateTimes should be Times
26 | Given I call "AddToProducts" on the service with a new "Product" object
27 | And I save changes
28 | When I call "Products" on the service
29 | And I run the query
30 | Then the "AuditFields.CreateDate" method on the object should return a Time
31 |
32 | Scenario: Verify that DateTimes don't change if not modified on an update
33 | Given I call "AddToProducts" on the service with a new "Product" object with Name: "Test Product"
34 | When I save changes
35 | And I call "Products" on the service with args: "1"
36 | And I run the query
37 | Then I store the first last query result for comparison
38 | When I set "Name" on the first result to "Changed Test Product"
39 | Then the method "Name" on the first result should equal: "Changed Test Product"
40 | And I call "update_object" on the service with the first last query result
41 | And I save changes
42 | Then the save result should equal: "true"
43 | When I call "Products" on the service with args: "1"
44 | And I run the query
45 | Then the new query first result's time "AuditFields.CreateDate" should equal the saved query result
46 |
47 | Scenario: DateTimes should be able to be null
48 | Given I call "AddToProducts" on the service with a new "Product" object
49 | And I save changes
50 | When I call "Products" on the service
51 | And I run the query
52 | Then the "DiscontinuedDate" method on the object should return a NilClass
53 |
--------------------------------------------------------------------------------
/gemfiles/Gemfile.ruby187:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | gemspec :path => '../'
4 |
5 | gem 'nokogiri', '~> 1.5.10'
6 | gem 'activesupport', '~> 3.0'
7 |
--------------------------------------------------------------------------------
/lib/ruby_odata.rb:
--------------------------------------------------------------------------------
1 | lib = File.dirname(__FILE__)
2 |
3 | $: << lib + "/ruby_odata/"
4 | require "rubygems"
5 | require "i18n"
6 | require "active_support" # Used for serializtion to JSON
7 | require "active_support/inflector"
8 | require "active_support/core_ext"
9 | require "cgi"
10 | require "excon"
11 | require "faraday_middleware"
12 | require "faraday"
13 | require "nokogiri"
14 | require "bigdecimal"
15 | require "bigdecimal/util"
16 | require "addressable/uri"
17 |
18 | require lib + "/ruby_odata/exceptions"
19 | require lib + "/ruby_odata/association"
20 | require lib + "/ruby_odata/property_metadata"
21 | require lib + "/ruby_odata/query_builder"
22 | require lib + "/ruby_odata/class_builder"
23 | require lib + "/ruby_odata/operation"
24 | require lib + "/ruby_odata/resource"
25 | require lib + "/ruby_odata/service"
26 | require lib + "/ruby_odata/helpers"
27 |
--------------------------------------------------------------------------------
/lib/ruby_odata/association.rb:
--------------------------------------------------------------------------------
1 | module OData
2 | # Internal class used to represent object associations
3 | class Association
4 |
5 | attr_reader :name, :namespace, :relationship, :from_role, :to_role
6 |
7 | def initialize(nav_prop_element, edmx)
8 | @edmx = edmx
9 |
10 | # Get the edm namespace because it varies by version
11 | root = @edmx.xpath("/edmx:Edmx").first
12 | @version = root['Version'].to_i
13 | edmxurl = root.namespaces['xmlns:edmx']
14 | ds = @edmx.xpath("edmx:Edmx/edmx:DataServices/*", "edmx" => edmxurl).first
15 | edm_ns = ds.namespaces['xmlns'].to_s
16 | @edmx_namespaces = { "edmx" => edmxurl, "edm" => edm_ns }
17 | parse_nav_prop(nav_prop_element)
18 | end
19 |
20 | private
21 |
22 | def parse_nav_prop(element)
23 | if @version >= 4
24 | else
25 | @relationship = element['Relationship']
26 | relationship_parts = @relationship.split('.')
27 | @name = relationship_parts.pop
28 | @namespace = relationship_parts.join('.')
29 | @from_role = role_hash(@name, element['FromRole'])
30 | @to_role = role_hash(@name, element['ToRole'])
31 | end
32 | end
33 |
34 | def role_hash(association_name, role_name)
35 | # Find the end role based on the assocation name
36 | role_xpath = "/edmx:Edmx/edmx:DataServices/edm:Schema[@Namespace='#{@namespace}']/edm:Association[@Name='#{association_name}']/edm:End[@Role='#{role_name}']"
37 | role_element = @edmx.xpath(role_xpath, @edmx_namespaces).first
38 | { role_name => {
39 | :edmx_type => "#{role_element['Type']}",
40 | :multiplicity => "#{role_element['Multiplicity']}"
41 | }}
42 | end
43 | end
44 | end
--------------------------------------------------------------------------------
/lib/ruby_odata/exceptions.rb:
--------------------------------------------------------------------------------
1 | module OData
2 | # Raised when a user attempts to do something that is not supported
3 | class NotSupportedError < StandardError; end
4 | # Raised when the service returns an error
5 | class ServiceError < StandardError
6 | attr_reader :http_code
7 | def initialize(code)
8 | @http_code = code
9 | end
10 | end
11 | end
--------------------------------------------------------------------------------
/lib/ruby_odata/helpers.rb:
--------------------------------------------------------------------------------
1 | module OData
2 | # Helper methods
3 | class Helpers
4 | # Helper to normalize the results of a select result; Ruby 1.9 Hash.select returns a Hash, 1.8 returns an Array
5 | # This is for Ruby 1.8 support, but should be removed in the future
6 | def self.normalize_to_hash(val)
7 | return nil if val.nil?
8 | (val.is_a? Hash) ? val : Hash[*val.flatten]
9 | end
10 |
11 | # Wrapper for URI escaping that switches between URI::Parser#escape and
12 | # URI.escape for 1.9-compatibility (thanks FakeWeb https://github.com/chrisk/fakeweb/blob/master/lib/fake_web/utility.rb#L40)
13 | def self.uri_escape(*args)
14 | if URI.const_defined?(:Parser)
15 | URI::Parser.new.escape(*args)
16 | else
17 | URI.escape(*args)
18 | end
19 | end
20 |
21 | # Nokogiri changed how it handles namespaced attributes with v1.5.1, this is for backwards compatibility to >= 1.4.2
22 | # Nokogiri now >=1.5.1 requires the namespace prefix is used
23 | def self.get_namespaced_attribute(node, attr_name, prefix)
24 | return node["#{prefix}:#{attr_name}"] || node[attr_name]
25 | end
26 | end
27 | end
--------------------------------------------------------------------------------
/lib/ruby_odata/operation.rb:
--------------------------------------------------------------------------------
1 | module OData
2 | # Internally used helper class for storing operations called against the service. This class shouldn't be used directly.
3 | class Operation
4 | attr_accessor :kind, :klass_name, :klass, :child_klass
5 |
6 | # Creates a new instance of the Operation class
7 | #
8 | # @param [String] kind the operation type (Standard: Add, Update, or Delete | Links: AddLink)
9 | # @param [String] klass_name the name/type of the class to operate against
10 | # @param [Object] klass the actual class
11 | # @param [Object, nil] child_klass used for link operations only
12 | def initialize(kind, klass_name, klass, child_klass = nil)
13 | @kind = kind
14 | @klass_name = klass_name
15 | @klass = klass
16 | @child_klass = child_klass
17 | end
18 | end
19 | end
--------------------------------------------------------------------------------
/lib/ruby_odata/property_metadata.rb:
--------------------------------------------------------------------------------
1 | module OData
2 | # Internally used helper class for storing an entity property's metadata. This class shouldn't be used directly.
3 | class PropertyMetadata
4 | # The property name
5 | attr_reader :name
6 | # The property EDM type
7 | attr_reader :type
8 | # Is the property nullable?
9 | attr_reader :nullable
10 | # Feed customization target path
11 | attr_reader :fc_target_path
12 | # Should the property appear in both the mapped schema path and the properties collection
13 | attr_reader :fc_keep_in_content
14 | # Is the property a navigation property?
15 | attr_reader :nav_prop
16 | # Applies only to navigation properties; the association corresponding to the property
17 | attr_accessor :association
18 | # Applies to the primary key(s)
19 | attr_accessor :is_key
20 |
21 | # Creates a new instance of the Class Property class
22 | #
23 | # @param [Nokogiri::XML::Node] property_element from the EDMX
24 |
25 | def initialize(property_element)
26 | @name = property_element['Name']
27 | @type = property_element['Type']
28 | @nullable = ((property_element['Nullable'] && property_element['Nullable'] == "true") || property_element.name == 'NavigationProperty') || false
29 | @fc_target_path = Helpers.get_namespaced_attribute(property_element, 'FC_TargetPath', 'm')
30 | keep_in_content = Helpers.get_namespaced_attribute(property_element, 'FC_KeepInContent', 'm')
31 | @fc_keep_in_content = (keep_in_content) ? (keep_in_content == "true") : nil
32 | @nav_prop = property_element.name == 'NavigationProperty'
33 | end
34 | end
35 | end
--------------------------------------------------------------------------------
/lib/ruby_odata/resource.rb:
--------------------------------------------------------------------------------
1 | module OData
2 | class Resource
3 | attr_reader :url, :options, :block
4 |
5 | def initialize(url, options={}, backwards_compatibility=nil, &block)
6 | @url = url
7 | @block = block
8 | @options = options.is_a?(Hash) ? options : { user: options, password: backwards_compatibility }
9 |
10 | @conn = Faraday.new(url: url, ssl: { verify: verify_ssl }) do |faraday|
11 | faraday.use :gzip
12 | faraday.response :raise_error
13 | faraday.adapter :excon
14 |
15 | faraday.options.timeout = timeout if timeout
16 | faraday.options.open_timeout = open_timeout if open_timeout
17 |
18 | faraday.headers = (faraday.headers || {}).merge(@options[:headers] || {})
19 | faraday.headers = (faraday.headers).merge({
20 | :accept => '*/*; q=0.5, application/xml',
21 | })
22 |
23 | faraday.basic_auth user, password if user# this adds to headers so must be behind
24 | end
25 |
26 | @conn.headers[:user_agent] = 'Ruby'
27 | end
28 |
29 | def get(additional_headers={})
30 | @conn.get do |req|
31 | req.url url
32 | req.headers = (headers || {}).merge(additional_headers)
33 | end
34 | end
35 |
36 | def head(additional_headers={})
37 | @conn.head do |req|
38 | req.url url
39 | req.headers = (headers || {}).merge(additional_headers)
40 | end
41 | end
42 |
43 | def post(payload, additional_headers={})
44 | @conn.post do |req|
45 | req.url url
46 | req.headers = (headers || {}).merge(additional_headers)
47 | req.body = prepare_payload payload
48 | end
49 | end
50 |
51 | def put(payload, additional_headers={})
52 | @conn.put do |req|
53 | req.url url
54 | req.headers = (headers || {}).merge(additional_headers)
55 | req.body = prepare_payload payload
56 | end
57 | end
58 |
59 | def patch(payload, additional_headers={})
60 | @conn.patch do |req|
61 | req.url url
62 | req.headers = (headers || {}).merge(additional_headers)
63 | req.body = prepare_payload payload
64 | end
65 | end
66 |
67 | def delete(additional_headers={})
68 | @conn.delete do |req|
69 | req.url url
70 | req.headers = (headers || {}).merge(additional_headers)
71 | end
72 | end
73 |
74 | def to_s
75 | url
76 | end
77 |
78 | def user
79 | options[:user]
80 | end
81 |
82 | def password
83 | options[:password]
84 | end
85 |
86 | def verify_ssl
87 | options[:verify_ssl]
88 | end
89 |
90 | def headers
91 | @conn.headers || {}
92 | end
93 |
94 | def timeout
95 | options[:timeout]
96 | end
97 |
98 | def open_timeout
99 | options[:open_timeout]
100 | end
101 |
102 | # Construct a subresource, preserving authentication.
103 | #
104 | # Example:
105 | #
106 | # site = RestClient::Resource.new('http://example.com', 'adam', 'mypasswd')
107 | # site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
108 | #
109 | # This is especially useful if you wish to define your site in one place and
110 | # call it in multiple locations:
111 | #
112 | # def orders
113 | # RestClient::Resource.new('http://example.com/orders', 'admin', 'mypasswd')
114 | # end
115 | #
116 | # orders.get # GET http://example.com/orders
117 | # orders['1'].get # GET http://example.com/orders/1
118 | # orders['1/items'].delete # DELETE http://example.com/orders/1/items
119 | #
120 | # Nest resources as far as you want:
121 | #
122 | # site = RestClient::Resource.new('http://example.com')
123 | # posts = site['posts']
124 | # first_post = posts['1']
125 | # comments = first_post['comments']
126 | # comments.post 'Hello', :content_type => 'text/plain'
127 | #
128 | def [](suburl, &new_block)
129 | case
130 | when block_given? then self.class.new(concat_urls(url, suburl), options, &new_block)
131 | when block then self.class.new(concat_urls(url, suburl), options, &block)
132 | else
133 | self.class.new(concat_urls(url, suburl), options)
134 | end
135 | end
136 |
137 | def concat_urls(url, suburl) # :nodoc:
138 | url = url.to_s
139 | suburl = suburl.to_s
140 | if url.slice(-1, 1) == '/' or suburl.slice(0, 1) == '/'
141 | url + suburl
142 | else
143 | "#{url}/#{suburl}"
144 | end
145 | end
146 |
147 | def prepare_payload payload
148 | JSON.generate(payload)
149 | rescue JSON::GeneratorError
150 | payload
151 | end
152 | end
153 | end
154 |
--------------------------------------------------------------------------------
/lib/ruby_odata/version.rb:
--------------------------------------------------------------------------------
1 | # The ruby_odata namespace
2 | module OData
3 | # The current version of ruby_odata
4 | VERSION = "0.2.0.beta1"
5 | end
6 |
--------------------------------------------------------------------------------
/ruby_odata.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | $:.push File.expand_path("../lib", __FILE__)
3 | require "ruby_odata/version"
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "ruby_odata"
7 | s.version = OData::VERSION
8 | s.platform = Gem::Platform::RUBY
9 | s.authors = ["Damien White"]
10 | s.email = ["damien.white@visoftinc.com"]
11 | s.homepage = %q{http://github.com/visoft/ruby_odata}
12 | s.summary = %q{Ruby consumer of OData services.}
13 | s.description = %q{An OData Client Library for Ruby. Use this to interact with OData services}
14 | s.license = "MIT"
15 |
16 | s.rubyforge_project = "ruby-odata"
17 |
18 | s.required_ruby_version = '>= 1.9.3'
19 |
20 | s.add_dependency("addressable", ">= 2.3.4")
21 | s.add_dependency("i18n", ">= 0.7.0")
22 | s.add_dependency("activesupport", ">= 3.0.0")
23 | s.add_dependency("excon", "~> 0.104.0")
24 | s.add_dependency("faraday_middleware")
25 | s.add_dependency("faraday", ">= 0.9.1")
26 | s.add_dependency("nokogiri", ">= 1.4.2")
27 |
28 | s.add_development_dependency("rake", ">= 12.0.0")
29 | s.add_development_dependency("rspec", ">= 3.4.4")
30 | s.add_development_dependency("rspec-its", "~> 1.2.0")
31 | s.add_development_dependency("cucumber", "~> 2.0.0")
32 | s.add_development_dependency("pickle", "~> 0.5.1")
33 | s.add_development_dependency("machinist", "~> 2.0")
34 | s.add_development_dependency("webmock", "~> 1.21.0")
35 | s.add_development_dependency("guard", "~> 2.12.5")
36 | s.add_development_dependency("guard-rspec", "~> 4.5.0")
37 | s.add_development_dependency("guard-cucumber", "~> 1.6.0")
38 | s.add_development_dependency("vcr", "~> 2.9.3")
39 | s.add_development_dependency("simplecov", "~> 0.7.1")
40 | s.add_development_dependency("coveralls", "~> 0.6.7")
41 | s.add_development_dependency("pry")
42 | s.add_development_dependency("pry-nav")
43 |
44 | s.files = `git ls-files`.split("\n")
45 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
46 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
47 | s.require_paths = ["lib"]
48 | end
49 |
--------------------------------------------------------------------------------
/spec/association_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module OData
4 | describe Association do
5 | before(:all) do
6 | stub_request(:get, /http:\/\/test\.com\/test\.svc\/\$metadata(?:\?.+)?/).
7 | with(:headers => DEFAULT_HEADERS).
8 | to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/sample_service/edmx_categories_products.xml", __FILE__)), :headers => {})
9 |
10 | @svc = OData::Service.new "http://test.com/test.svc/$metadata"
11 | @product_category = RSpecSupport::ElementHelpers.string_to_element('')
12 | end
13 | describe "#initialize singlular navigation property" do
14 | before { @association = Association.new @product_category, @svc.edmx }
15 | subject { @association }
16 |
17 | it "sets the association name" do
18 | subject.name.should eq 'Category_Products'
19 | end
20 |
21 | it "sets the association namespace" do
22 | subject.namespace.should eq 'RubyODataService'
23 | end
24 |
25 | it "sets the relationship name" do
26 | subject.relationship.should eq 'RubyODataService.Category_Products'
27 | end
28 |
29 | context "from_role method" do
30 | subject { @association.from_role }
31 | it { should have_key 'Category_Products_Target'}
32 | it "sets the edmx type" do
33 | subject['Category_Products_Target'][:edmx_type].should eq 'RubyODataService.Product'
34 | end
35 | it "sets the multiplicity" do
36 | subject['Category_Products_Target'][:multiplicity].should eq '*'
37 | end
38 | end
39 |
40 | context "to_role method" do
41 | subject { @association.to_role }
42 | it { should have_key 'Category_Products_Source'}
43 | it "sets the edmx type" do
44 | subject['Category_Products_Source'][:edmx_type].should eq 'RubyODataService.Category'
45 | end
46 | it "sets the multiplicity" do
47 | subject['Category_Products_Source'][:multiplicity].should eq '1'
48 | end
49 | end
50 | end
51 | end
52 | end
--------------------------------------------------------------------------------
/spec/class_builder_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module OData
4 | describe ClassBuilder do
5 | describe "#initialize" do
6 | before(:each) do
7 | @methods = []
8 | @nav_props = []
9 | @svc = nil
10 | @namespace = nil
11 | end
12 | it "handles lowercase entities" do
13 | klass = ClassBuilder.new 'product', @methods, @nav_props, @svc, @namespace
14 | result = klass.build
15 | result.should eq Product
16 | end
17 | it "should take in an instance of the service" do
18 | klass = ClassBuilder.new 'product', @methods, @nav_props, @svc, @namespace
19 | end
20 | end
21 | end
22 | end
--------------------------------------------------------------------------------
/spec/fixtures/edmx_empty.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/edmx_lowercase.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/spec/fixtures/error_without_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/feed_customization/edmx_feed_customization.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/spec/fixtures/int64_ids/edmx_boat_service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/spec/fixtures/int64_ids/edmx_car_service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/spec/fixtures/int64_ids/result_boats.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | http://test.com/test.svc/Boats
7 | Boats
8 | 2013-10-28T19:59:15Z
9 |
10 |
11 | http://test.com/test.svc/Boats(213L)
12 |
13 |
14 |
15 | 2013-10-28T19:59:15Z
16 |
17 |
18 |
19 |
20 |
21 | 213
22 | blue
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/spec/fixtures/int64_ids/result_cars.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | http://test.com/test.svc/Cars
7 | Cars
8 | 2013-10-28T19:59:15Z
9 |
10 |
11 | http://test.com/test.svc/Cars(213L)
12 |
13 |
14 |
15 | 2013-10-28T19:59:15Z
16 |
17 |
18 |
19 |
20 |
21 | 213
22 | peach
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/spec/fixtures/links/result_links_query.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | http://test.com/SampleService/RubyOData.svc/Products(1)
4 | http://test.com/SampleService/RubyOData.svc/Products(2)
5 | http://test.com/SampleService/RubyOData.svc/Products(3)
6 |
--------------------------------------------------------------------------------
/spec/fixtures/ms_system_center/hardware_profiles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | https://srv-spf-98.bs.unsi.no:8090/SC2012/VMM/Microsoft.Management.Odata.svc/HardwareProfiles
4 | HardwareProfiles
5 | 2013-06-16T10:01:46Z
6 |
7 |
8 | https://srv-spf-98.bs.unsi.no:8090/SC2012/VMM/Microsoft.Management.Odata.svc/HardwareProfiles(ID=guid'8967da8e-eaf0-4414-b1ab-0b8d7a848af7',StampId=guid'a68f9b8b-f8af-46b2-8636-255248c9b5ab')
9 |
10 |
11 |
12 |
13 |
14 |
15 | 2013-06-16T10:01:46Z
16 |
17 |
18 |
19 |
20 |
21 | a68f9b8b-f8af-46b2-8636-255248c9b5ab
22 | 8967da8e-eaf0-4414-b1ab-0b8d7a848af7
23 |
24 | 2013-06-04T17:28:29.597+02:00
25 | 2
26 | 100
27 | 0
28 |
29 |
30 | 0
31 | 20
32 | true
33 | false
34 | false
35 | 3500
36 | 2013-06-04T17:41:30.287+02:00
37 | [Hardware] - Linux Medium VM
38 | 0
39 |
40 | foo\bar
41 | Administrator
42 | 75700cd5-893e-4f68-ada7-50ef4668acc6
43 |
44 |
45 |
46 |
47 | Important Tenant
48 | ee41a0fc-fa48-4ed6-8403-f42a45529003
49 |
50 |
51 | 100
52 | false
53 |
54 | false
55 | Public
56 |
57 | false
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/spec/fixtures/partial/partial_feed_metadata.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/spec/fixtures/partial/partial_feed_part_1.xml:
--------------------------------------------------------------------------------
1 |
5 | Partials
6 | http://test.com/test.svc/Partials
7 | 2010-03-10T09:34:11Z
8 |
9 | 3
10 |
11 | http://test.com/test.svc/Partials
12 |
13 | 2010-03-10T09:34:11Z
14 |
15 |
16 |
17 |
18 |
22 |
24 |
25 |
26 | ALFKI
27 | Alfreds Futterkiste
28 | Maria Anders
29 | Sales Representative
30 | Obere Str. 57
31 | Berlin
32 |
33 | 12209
34 | Germany
35 | 030-0074321
36 | 030-0076545
37 |
38 |
39 |
40 |
42 |
--------------------------------------------------------------------------------
/spec/fixtures/partial/partial_feed_part_2.xml:
--------------------------------------------------------------------------------
1 |
5 | Partials
6 | http://test.com/test.svc/Partials
7 | 2010-03-10T09:34:11Z
8 |
9 | 2
10 |
11 | http://test.com/test.svc/Partials?$skiptoken='ERNSH'
12 |
13 | 2010-03-10T09:34:11Z
14 |
15 |
16 |
17 |
18 |
22 |
24 |
25 |
26 | ALFKI
27 | Alfreds Futterkiste
28 | Maria Sanders
29 | Sales Manager
30 | Obere Str. 57
31 | Berlin
32 |
33 | 12209
34 | Germany
35 | 030-0074321
36 | 030-0076545
37 |
38 |
39 |
40 |
42 |
--------------------------------------------------------------------------------
/spec/fixtures/partial/partial_feed_part_3.xml:
--------------------------------------------------------------------------------
1 |
5 | Partials
6 | http://test.com/test.svc/Partials
7 | 2010-03-10T09:34:11Z
8 |
9 | 2
10 |
11 | http://test.com/test.svc/Partials?$skiptoken='ERNSH2'
12 |
13 | 2010-03-10T09:34:11Z
14 |
15 |
16 |
17 |
18 |
22 |
24 |
25 |
26 | ALFKI
27 | Alfreds Futterkiste
28 | Maria Banders
29 | Sales Damager
30 | Obere Str. 57
31 | Berlin
32 |
33 | 12209
34 | Germany
35 | 030-0074321
36 | 030-0076545
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/edmx_categories_products.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_category_names.xml:
--------------------------------------------------------------------------------
1 |
2 | Test Category 1
3 | Test Category 2
4 | Test Category 3
5 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_entity_category_web_get.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | http://win7dev:8989/SampleService/RubyOData.svc/EntityCategoryWebGet
4 | EntityCategoryWebGet
5 | 2011-11-28T02:43:29Z
6 |
7 |
8 | http://win7dev:8989/SampleService/RubyOData.svc/Categories(1)
9 |
10 |
11 |
12 |
13 | 2011-11-28T02:43:29Z
14 |
15 |
16 |
17 |
18 |
19 | 1
20 | Test Category
21 |
22 | 2011-11-28T02:42:58.407
23 | 2011-11-28T02:42:58.407
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_entity_single_category_web_get.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | http://win7dev:8989/SampleService/RubyOData.svc/Categories(1)
4 |
5 |
6 |
7 |
8 | 2011-11-28T02:51:40Z
9 |
10 |
11 |
12 |
13 |
14 | 1
15 | Test Category
16 |
17 | 2011-11-28T02:42:58.407
18 | 2011-11-28T02:42:58.407
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_first_category_id.xml:
--------------------------------------------------------------------------------
1 |
2 | 1
3 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_multiple_category_products.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Products
4 | http://test.com/test.svc/Categories(1)/Products
5 | 2011-11-13T21:29:28Z
6 |
7 |
8 | http://test.com/test.svc/Products(1)
9 |
10 | 2011-11-13T21:29:28Z
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 1
20 | Widget 1
21 | Test Widget
22 | 7.5000
23 |
24 |
25 | 2011-11-13T05:00:23.547
26 | 2011-11-13T05:00:23.547
27 | Cucumber
28 |
29 |
30 |
31 |
32 |
33 | http://test.com/test.svc/Products(2)
34 |
35 | 2011-11-13T21:29:28Z
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 2
45 | Widget 2
46 | Test Widget 2
47 | 17.5000
48 |
49 |
50 | 2011-11-13T05:00:23.547
51 | 2011-11-13T05:00:23.547
52 | Cucumber
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_select_categories_no_property.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Type 'RubyODataService.Category' does not have a property named 'Price' or there is no type with 'Price' name.
6 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_select_categories_travsing_no_expand.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Only properties specified in $expand can be traversed in $select query options. Property .
6 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_select_products_name_price.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 | http://win7dev:8989/SampleService/RubyOdata.svc/Products
9 | Products
10 | 2013-07-19T12:29:11Z
11 |
12 |
13 | http://win7dev:8989/SampleService/RubyOData.svc/Products(1)
14 |
15 |
16 |
17 | 2013-07-19T12:29:11Z
18 |
19 |
20 |
21 |
22 |
23 | Widget 0001
24 | 75.50
25 |
26 |
27 |
28 |
29 | http://win7dev:8989/SampleService/RubyOData.svc/Products(2)
30 |
31 |
32 |
33 | 2013-07-19T12:29:11Z
34 |
35 |
36 |
37 |
38 |
39 | Widget 0002
40 | 100.00
41 |
42 |
43 |
44 |
45 | http://win7dev:8989/SampleService/RubyOData.svc/Products(3)
46 |
47 |
48 |
49 | 2013-07-19T12:29:11Z
50 |
51 |
52 |
53 |
54 |
55 | Widget 0003
56 | 10.25
57 |
58 |
59 |
60 |
61 | http://win7dev:8989/SampleService/RubyOData.svc/Products(4)
62 |
63 |
64 |
65 | 2013-07-19T12:29:11Z
66 |
67 |
68 |
69 |
70 |
71 | Widget 0004
72 | 100.00
73 |
74 |
75 |
76 |
77 | http://win7dev:8989/SampleService/RubyOData.svc/Products(5)
78 |
79 |
80 |
81 | 2013-07-19T12:29:11Z
82 |
83 |
84 |
85 |
86 |
87 | Widget 0005
88 | 75.50
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_single_category.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | http://test.com/test.svc/Categories(1)
4 |
5 | 2011-11-13T05:37:35Z
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 1
15 | Category 1
16 |
17 |
18 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_single_product.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | http://test.com/test.svc/Products(1)
4 |
5 | 2011-11-13T02:51:18Z
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 1
15 | Widget 1
16 | Test Widget
17 | 7.5000
18 |
19 |
20 | 2011-11-13T01:10:06.673
21 | 2011-11-13T01:10:06.673
22 | Cucumber
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/spec/fixtures/sample_service/result_single_product_not_found.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resource not found for the segment 'Products'.
4 |
--------------------------------------------------------------------------------
/spec/fixtures/sap/edmx_sap_demo_flight.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/spec/fixtures/sap/result_sap_demo_flight_missing_category.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | HTTP://GW.ESWORKPLACE.SAP.COM:80/sap/opu/sdata/sap/DEMO_FLIGHT/z_demo_flightCollection
4 |
5 | zDemoFlightCollection
6 | 2011-09-23T01:17:51Z
7 |
8 |
9 |
10 | 020408_AA001720081001
11 | Z_DEMO_FLIGHT
12 | HU2_800
13 | SAN FRANCISCO
14 | USD
15 | 0
16 | 2008-10-01T00:00:00
17 | PT11H00M00S
18 | 0
19 | 422.9400
20 | 0
21 | American Airlines
22 | 0
23 | NEW YORK
24 | JFK
25 | 00000000
26 | 0
27 | 0
28 |
29 | USD
30 |
31 | SFO
32 | PT14H01M00S
33 |
34 |
35 | HTTP://GW.ESWORKPLACE.SAP.COM:80/sap/opu/sdata/sap/DEMO_FLIGHT/z_demo_flightCollection(value='020408_AA001720081001',scheme_id='Z_DEMO_FLIGHT',scheme_agency_id='HU2_800')
36 |
37 |
38 |
39 |
40 | z_demo_flight
41 | 2011-09-23T01:17:51Z
42 |
43 |
44 |
45 |
46 |
47 | 020408_AA001720081029
48 | Z_DEMO_FLIGHT
49 | HU2_800
50 | SAN FRANCISCO
51 | USD
52 | 0
53 | 2008-10-29T00:00:00
54 | PT11H00M00S
55 | 0
56 | 422.9400
57 | 0
58 | American Airlines
59 | 0
60 | NEW YORK
61 | JFK
62 | 00000000
63 | 0
64 | 0
65 |
66 | USD
67 |
68 | SFO
69 | PT14H01M00S
70 |
71 |
72 | HTTP://GW.ESWORKPLACE.SAP.COM:80/sap/opu/sdata/sap/DEMO_FLIGHT/z_demo_flightCollection(value='020408_AA001720081029',scheme_id='Z_DEMO_FLIGHT',scheme_agency_id='HU2_800')
73 |
74 |
75 |
76 |
77 | z_demo_flight
78 | 2011-09-23T01:17:51Z
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/spec/fixtures/v4/result_categories.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/spec/fixtures/v4/result_categories.xml
--------------------------------------------------------------------------------
/spec/property_metadata_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module OData
4 | describe PropertyMetadata do
5 | describe "#initialize" do
6 | it "parses an EDMX property with the essentials (name, type, nullable, nav_prop)" do
7 | property_element = RSpecSupport::ElementHelpers.string_to_element('')
8 | property_metadata = PropertyMetadata.new property_element
9 | property_metadata.name.should eq "Id"
10 | property_metadata.type.should eq "Edm.String"
11 | property_metadata.nullable.should eq false
12 | property_metadata.nav_prop.should eq false
13 | end
14 | it "parses an EDMX property where nullable is true" do
15 | property_element = RSpecSupport::ElementHelpers.string_to_element('')
16 | property_metadata = PropertyMetadata.new property_element
17 | property_metadata.nullable.should eq true
18 | end
19 | it "parses an EDMX property with nil for missing attributes" do
20 | property_element = RSpecSupport::ElementHelpers.string_to_element('')
21 | property_metadata = PropertyMetadata.new property_element
22 | property_metadata.fc_target_path.should be_nil
23 | property_metadata.fc_keep_in_content.should be_nil
24 | end
25 | it "parses an EDMX property with false for missing Nullable attribute" do
26 | property_element = RSpecSupport::ElementHelpers.string_to_element('')
27 | property_metadata = PropertyMetadata.new property_element
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
31 | property_element = RSpecSupport::ElementHelpers.string_to_element('')
32 | property_metadata = PropertyMetadata.new property_element
33 | property_metadata.fc_target_path.should eq "SyndicationTitle"
34 | property_metadata.fc_keep_in_content.should eq false
35 | end
36 | it "parses an EDMX property where fc_keep_in_content is true" do
37 | property_element = RSpecSupport::ElementHelpers.string_to_element('')
38 | property_metadata = PropertyMetadata.new property_element
39 | property_metadata.fc_keep_in_content.should eq true
40 | end
41 | it "parses an EDMX navigation property with the name and the nav_prop set to true" do
42 | property_element = RSpecSupport::ElementHelpers.string_to_element('')
43 | property_metadata = PropertyMetadata.new property_element
44 | property_metadata.name.should eq "Category"
45 | property_metadata.nav_prop.should eq true
46 | end
47 | end
48 | end
49 | end
--------------------------------------------------------------------------------
/spec/service_v4_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe "V4 Service" do
4 | before(:all) do
5 | stub_request(:get, /http:\/\/test\.com\/test\.svc\/\$metadata(?:\?.+)?/).
6 | with(:headers => DEFAULT_HEADERS).
7 | to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/v4/edmx_metadata.xml", __FILE__)), :headers => {})
8 |
9 | stub_request(:get, "http://test.com/test.svc/Categories").
10 | to_return(:status => 200, :body => File.new(File.expand_path("../fixtures/v4/result_categories.xml", __FILE__)), :headers => {})
11 |
12 | @service = OData::Service.new "http://test.com/test.svc"
13 | end
14 | subject { @service }
15 |
16 | context "methods" do
17 | it { should respond_to :update_object }
18 | it { should respond_to :delete_object }
19 | it { should respond_to :save_changes }
20 | it { should respond_to :load_property }
21 | it { should respond_to :add_link }
22 | it { should respond_to :execute }
23 | it { should respond_to :partial? }
24 | it { should respond_to :next }
25 | it { should respond_to :classes }
26 | it { should respond_to :class_metadata }
27 | it { should respond_to :collections }
28 | it { should respond_to :options }
29 | it { should respond_to :function_imports }
30 |
31 | context "after parsing metadata" do
32 | it { should respond_to :Products }
33 | it { should respond_to :Categories }
34 | it { should respond_to :AddToProducts }
35 | it { should respond_to :AddToCategories }
36 | end
37 | end
38 |
39 | context "collections method" do
40 | subject { @service.collections }
41 | it { should include 'Products' }
42 | it { should include 'Categories' }
43 | it "should expose the edmx type of objects" do
44 | subject['Products'][:edmx_type].should eq 'ODataDemo.Product'
45 | subject['Categories'][:edmx_type].should eq 'ODataDemo.Category'
46 | end
47 | it "should expose the local model type" do
48 | subject['Products'][:type].should eq Product
49 | subject['Categories'][:type].should eq Category
50 | end
51 | end
52 |
53 | context "class metadata" do
54 | subject { @service.class_metadata }
55 | it { should_not be_empty}
56 | it { should have_key 'Product' }
57 | it { should have_key 'Category' }
58 |
59 | context "should have keys for each property" do
60 | subject { @service.class_metadata['Category'] }
61 | it { should have_key 'ID' }
62 | it { should have_key 'Name' }
63 | it { should have_key 'Products' }
64 | it "should return a PropertyMetadata object for each property" do
65 | subject['ID'].should be_an OData::PropertyMetadata
66 | subject['Name'].should be_an OData::PropertyMetadata
67 | subject['Products'].should be_an OData::PropertyMetadata
68 | end
69 | it "should have correct PropertyMetadata for Category.Id" do
70 | meta = subject['ID']
71 | meta.name.should eq 'ID'
72 | meta.type.should eq 'Edm.Int32'
73 | meta.nullable.should eq false
74 | meta.fc_target_path.should be_nil
75 | meta.fc_keep_in_content.should be_nil
76 | meta.nav_prop.should eq false
77 | meta.is_key.should eq true
78 | end
79 | it "should have correct PropertyMetadata for Category.Name" do
80 | meta = subject['Name']
81 | meta.name.should eq 'Name'
82 | meta.type.should eq 'Edm.String'
83 | meta.nullable.should eq false
84 | meta.fc_target_path.should be_nil
85 | meta.fc_keep_in_content.should be_nil
86 | meta.nav_prop.should eq false
87 | meta.is_key.should eq false
88 | end
89 | it "should have correct PropertyMetadata for Category.Products" do
90 | meta = subject['Products']
91 | meta.name.should eq 'Products'
92 | meta.type.should eq 'Collection(ODataDemo.Product)'
93 | meta.nullable.should eq true
94 | meta.fc_target_path.should be_nil
95 | meta.fc_keep_in_content.should be_nil
96 | meta.nav_prop.should eq true
97 | meta.association.should_not be_nil
98 | meta.is_key.should eq false
99 | end
100 | end
101 | end
102 | end
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'ruby_odata'
2 | require 'webmock/rspec'
3 | require 'simplecov'
4 | require 'rspec/its'
5 | # require 'coveralls'
6 | # Coveralls.wear_merged!
7 |
8 | Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
9 |
10 | WebMock.disable_net_connect!(allow_localhost: true)
11 | DEFAULT_HEADERS = {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip,deflate'}
12 |
13 |
--------------------------------------------------------------------------------
/spec/support/describe_private.rb:
--------------------------------------------------------------------------------
1 | def describe_private *args, &block
2 | example = describe *args, &block
3 | klass = args[0]
4 | if klass.is_a? Class
5 | saved_private_instance_methods = klass.private_instance_methods
6 | example.before do
7 | klass.class_eval { public *saved_private_instance_methods }
8 | end
9 | example.after do
10 | klass.class_eval { private *saved_private_instance_methods }
11 | end
12 | end
13 | end
--------------------------------------------------------------------------------
/spec/support/element_helpers.rb:
--------------------------------------------------------------------------------
1 | module RSpecSupport
2 | class ElementHelpers
3 | def self.string_to_element(element_string)
4 | Nokogiri::XML.parse(element_string).elements[0]
5 | end
6 | end
7 | end
--------------------------------------------------------------------------------
/spec/support/sample_service_matcher.rb:
--------------------------------------------------------------------------------
1 | require 'uri'
2 |
3 | module OData
4 | module Support
5 | class SampleServiceMatcher
6 | def self.call(req1, req2)
7 | regexp = /^(https?:\/\/(?:[^@]*@)?)[^:]*(:\d+\/.*$)/i
8 | request1 = req1.uri.match(regexp)
9 | request2 = req2.uri.match(regexp)
10 |
11 | (request1[1] == request2[1]) && (request1[2] == request2[2])
12 | end
13 | end
14 | end
15 | end
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RubyODataService", "RubyODataService\RubyODataService.csproj", "{C84F8120-25A8-4874-BAC2-9A19E114CFB2}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {C84F8120-25A8-4874-BAC2-9A19E114CFB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {C84F8120-25A8-4874-BAC2-9A19E114CFB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {C84F8120-25A8-4874-BAC2-9A19E114CFB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {C84F8120-25A8-4874-BAC2-9A19E114CFB2}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/App_Data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/App_Data/.gitkeep
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/App_Start/EntityFramework.SqlServerCompact.cs:
--------------------------------------------------------------------------------
1 | using System.Data.Entity;
2 | using System.Data.Entity.Infrastructure;
3 |
4 | [assembly: WebActivator.PreApplicationStartMethod(typeof(RubyODataService.App_Start.EntityFramework_SqlServerCompact), "Start")]
5 |
6 | namespace RubyODataService.App_Start {
7 | public static class EntityFramework_SqlServerCompact {
8 | public static void Start() {
9 | Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/BasicAuth/RubyOData.svc:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, Microsoft.Data.Services, Version=4.99.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Service="RubyODataService.RubyOData" %>
4 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/BasicAuth/RubyOData.svc.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Security.Principal;
4 | using System.Text;
5 | using System.Web;
6 |
7 | // ReSharper disable CheckNamespace
8 | namespace RubyODataService
9 | // ReSharper restore CheckNamespace
10 | {
11 | public class OurBasicAuthenticationModule : IHttpModule
12 | {
13 | public void Init(HttpApplication context)
14 | {
15 | context.AuthenticateRequest += context_AuthenticateRequest;
16 | }
17 |
18 | private void context_AuthenticateRequest(object sender, EventArgs e)
19 | {
20 | HttpApplication application = (HttpApplication)sender;
21 |
22 | // Only require authentication if BasicAuth is in the URI path
23 | if ((application.Context.Request.Url.AbsoluteUri.Contains("BasicAuth")) &&
24 | (!CustomBasicAuthenticationProvider.Authenticate(application.Context)))
25 | {
26 | application.Context.Response.Status = "401 Unauthorized";
27 | application.Context.Response.StatusCode = 401;
28 | application.Context.Response.AddHeader("WWW-Authenticate", "Basic");
29 | application.CompleteRequest();
30 | }
31 | }
32 |
33 | public void Dispose()
34 | {
35 | }
36 |
37 | }
38 |
39 | // class OurBasicAuthenticationModule: IHttpModule
40 |
41 | public class CustomBasicAuthenticationProvider
42 | {
43 | public static bool Authenticate(HttpContext context)
44 | {
45 | if (!HttpContext.Current.Request.Headers.AllKeys.Contains("Authorization"))
46 | return false;
47 |
48 | string authHeader = HttpContext.Current.Request.Headers["Authorization"];
49 |
50 | IPrincipal principal;
51 | if (TryGetPrincipal(authHeader, out principal))
52 | {
53 | HttpContext.Current.User = principal;
54 | return true;
55 | }
56 | return false;
57 | }
58 |
59 | private static bool TryGetPrincipal(string authHeader, out IPrincipal principal)
60 | {
61 | var creds = ParseAuthHeader(authHeader);
62 | if (creds != null && TryGetPrincipal(creds, out principal))
63 | return true;
64 |
65 | principal = null;
66 | return false;
67 | }
68 |
69 | private static bool TryGetPrincipal(string[] creds, out IPrincipal principal)
70 | {
71 | if (creds[0] == "admin" && creds[1] == "passwd")
72 | {
73 | principal = new GenericPrincipal(
74 | new GenericIdentity("Administrator"),
75 | new[] { "Administrator", "User" }
76 | );
77 | return true;
78 | }
79 | principal = null;
80 | return false;
81 | }
82 |
83 | private static string[] ParseAuthHeader(string authHeader)
84 | {
85 | // Check this is a Basic Auth header
86 | if (
87 | string.IsNullOrEmpty(authHeader) ||
88 | !authHeader.StartsWith("Basic")
89 | ) return null;
90 |
91 | // Pull out the Credentials with are seperated by ':' and Base64 encoded
92 | // Won't handle password with : in it, but that's OK for these tests
93 | var base64Credentials = authHeader.Substring(6);
94 | var credentials = Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials)).Split(new[] { ':' });
95 |
96 | if (credentials.Length != 2 ||
97 | string.IsNullOrEmpty(credentials[0]) ||
98 | string.IsNullOrEmpty(credentials[0])
99 | ) return null;
100 |
101 | return credentials;
102 | }
103 |
104 | }
105 |
106 | // class CustomBasicAuthenticationProvider
107 | }
108 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="RubyODataService.Global" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Global.asax.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Entity;
4 | using System.Linq;
5 | using System.Web;
6 | using System.Web.Security;
7 | using System.Web.SessionState;
8 |
9 | namespace RubyODataService
10 | {
11 | public class Global : System.Web.HttpApplication
12 | {
13 |
14 | protected void Application_Start(object sender, EventArgs e)
15 | {
16 | Database.SetInitializer(new DropCreateDatabaseAlways());
17 | }
18 |
19 | protected void Session_Start(object sender, EventArgs e)
20 | {
21 |
22 | }
23 |
24 | protected void Application_BeginRequest(object sender, EventArgs e)
25 | {
26 |
27 | }
28 |
29 | protected void Application_AuthenticateRequest(object sender, EventArgs e)
30 | {
31 |
32 | }
33 |
34 | protected void Application_Error(object sender, EventArgs e)
35 | {
36 |
37 | }
38 |
39 | protected void Session_End(object sender, EventArgs e)
40 | {
41 |
42 | }
43 |
44 | protected void Application_End(object sender, EventArgs e)
45 | {
46 |
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Models/AuditFields.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RubyODataService.Models
4 | {
5 | public class AuditFields
6 | {
7 | public AuditFields()
8 | {
9 | CreateDate = DateTime.UtcNow;
10 | ModifiedDate = DateTime.UtcNow;
11 | }
12 | public DateTime CreateDate { get; set; }
13 | public DateTime ModifiedDate { get; set; }
14 | public string CreatedBy { get; set; }
15 | }
16 | }
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Models/Category.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace RubyODataService.Models
4 | {
5 | public class Category
6 | {
7 | public Category()
8 | {
9 | AuditFields = new AuditFields();
10 | }
11 | public int Id { get; set; }
12 | public string Name { get; set; }
13 | public virtual ICollection Products { get; set; }
14 | public AuditFields AuditFields { get; set; }
15 | }
16 | }
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Models/Product.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RubyODataService.Models
4 | {
5 | public class Product
6 | {
7 | public Product()
8 | {
9 | AuditFields = new AuditFields();
10 | }
11 | public int Id { get; set; }
12 | public string Name { get; set; }
13 | public string Description { get; set; }
14 | public decimal Price { get; set; }
15 | public DateTime? DiscontinuedDate { get; set; }
16 | public int CategoryId { get; set; }
17 | public Category Category { get; set; }
18 | public AuditFields AuditFields { get; set; }
19 | }
20 | }
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("RubyODataService")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("RubyODataService")]
13 | [assembly: AssemblyCopyright("Copyright © 2011")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("6fc9bddf-fa99-4dc4-a66f-b8f15d3efb00")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/RubyOData.svc:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%@ ServiceHost Language="C#" Factory="System.Data.Services.DataServiceHostFactory, Microsoft.Data.Services, Version=4.99.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Service="RubyODataService.RubyOData" %>
4 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/RubyOData.svc.cs:
--------------------------------------------------------------------------------
1 | using System.Data.Services;
2 | using System.Data.Services.Common;
3 | using System.Linq;
4 | using System.ServiceModel;
5 | using System.ServiceModel.Web;
6 | using RubyODataService.Models;
7 | using System.Collections.Generic;
8 |
9 | namespace RubyODataService
10 | {
11 | [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
12 | public class RubyOData : DataService
13 | {
14 | // This method is called only once to initialize service-wide policies.
15 | public static void InitializeService(DataServiceConfiguration config)
16 | {
17 | config.SetEntitySetAccessRule("*", EntitySetRights.All);
18 | config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
19 | config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
20 | config.UseVerboseErrors = true;
21 | }
22 |
23 | ///
24 | /// Cleans the database for testing.
25 | ///
26 | [WebInvoke]
27 | public void CleanDatabaseForTesting()
28 | {
29 | CurrentDataSource.Database.Delete();
30 | CurrentDataSource.Database.CreateIfNotExists();
31 | }
32 |
33 | [WebGet]
34 | public IQueryable EntityCategoryWebGet()
35 | {
36 | return CurrentDataSource.Categories;
37 | }
38 |
39 | [WebGet]
40 | public IQueryable CategoryNames()
41 | {
42 | return CurrentDataSource.Categories.Select(c => c.Name);
43 | }
44 |
45 | [WebGet]
46 | public int? FirstCategoryId()
47 | {
48 | return CurrentDataSource.Categories.Select(c => c.Id).FirstOrDefault();
49 | }
50 |
51 | [WebGet]
52 | public Category EntitySingleCategoryWebGet(int id)
53 | {
54 | return CurrentDataSource.Categories.FirstOrDefault(c => c.Id == id);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/RubyODataContext.cs:
--------------------------------------------------------------------------------
1 | using System.Data.Entity;
2 | using RubyODataService.Models;
3 |
4 | namespace RubyODataService
5 | {
6 | public class RubyODataContext : DbContext
7 | {
8 | public RubyODataContext()
9 | {
10 | // Disable proxy creation, which doesn’t work well with data services.
11 | this.Configuration.ProxyCreationEnabled = false;
12 | }
13 | public DbSet Products { get; set; }
14 | public DbSet Categories { get; set; }
15 | }
16 | }
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/RubyODataService.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ShowAllFiles
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | CurrentPage
13 | True
14 | False
15 | False
16 | False
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | False
26 | True
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
29 |
30 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
30 |
31 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/EntityFramework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/EntityFramework.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Edm.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Edm.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/Microsoft.Data.OData.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/Microsoft.Data.OData.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Services.Client.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Services.Client.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Services.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Services.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Spatial.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/Microsoft.Data.Spatial.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/RubyODataService.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/RubyODataService.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/System.Data.SqlServerCe.Entity.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/System.Data.SqlServerCe.Entity.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/System.Data.SqlServerCe.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/System.Data.SqlServerCe.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/System.Spatial.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/System.Spatial.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/WebActivator.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/WebActivator.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Vy8CgQgbu3qH5JHTK0op4kR8114= QTJu3Gttpt8hhCktGelNeXj4Yp8= 1ruqF7/L+m1tqnJVscaOtNRNHIE=
6 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/README_ENU.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/README_ENU.txt
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/msvcr90.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/amd64/Microsoft.VC90.CRT/msvcr90.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/sqlcecompact40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/amd64/sqlcecompact40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/sqlceer40EN.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/amd64/sqlceer40EN.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/sqlceme40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/amd64/sqlceme40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/sqlceqp40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/amd64/sqlceqp40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/amd64/sqlcese40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/amd64/sqlcese40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | +CXED+6HzJlSphyMNOn27ujadC0= MyKED+9DyS+1XcMeaC0Zlw2vFZ0= EeyDE7og6WoPd2oBhYbMEnpFHhY=
6 |
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/README_ENU.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/README_ENU.txt
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/msvcr90.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/x86/Microsoft.VC90.CRT/msvcr90.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/sqlcecompact40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/x86/sqlcecompact40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/sqlceer40EN.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/x86/sqlceer40EN.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/sqlceme40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/x86/sqlceme40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/sqlceqp40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/x86/sqlceqp40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/bin/x86/sqlcese40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/RubyODataService/bin/x86/sqlcese40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/RubyODataService/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/EntityFramework.4.2.0.0/EntityFramework.4.2.0.0.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/EntityFramework.4.2.0.0/EntityFramework.4.2.0.0.nupkg
--------------------------------------------------------------------------------
/test/RubyODataService/packages/EntityFramework.4.2.0.0/lib/net40/EntityFramework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/EntityFramework.4.2.0.0/lib/net40/EntityFramework.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/Content/App_Start/EntityFramework.SqlServerCompact.cs.pp:
--------------------------------------------------------------------------------
1 | using System.Data.Entity;
2 | using System.Data.Entity.Infrastructure;
3 |
4 | [assembly: WebActivator.PreApplicationStartMethod(typeof($rootnamespace$.App_Start.EntityFramework_SqlServerCompact), "Start")]
5 |
6 | namespace $rootnamespace$.App_Start {
7 | public static class EntityFramework_SqlServerCompact {
8 | public static void Start() {
9 | Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/EntityFramework.SqlServerCompact.4.1.8482.2.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/EntityFramework.SqlServerCompact.4.1.8482.2.nupkg
--------------------------------------------------------------------------------
/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/lib/System.Data.SqlServerCe.Entity.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/lib/System.Data.SqlServerCe.Entity.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/EntityFramework.SqlServerCompact.4.1.8482.2/tools/install.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 | $project.Object.References.Add("System.Transactions") | Out-Null
3 | $project.Object.References.Add("System.Data.Entity") | Out-Null
4 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Content/web.config.transform:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Vy8CgQgbu3qH5JHTK0op4kR8114= QTJu3Gttpt8hhCktGelNeXj4Yp8= 1ruqF7/L+m1tqnJVscaOtNRNHIE=
6 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/README_ENU.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/README_ENU.txt
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/msvcr90.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/Microsoft.VC90.CRT/msvcr90.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlcecompact40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlcecompact40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceer40EN.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceer40EN.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceme40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceme40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceqp40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlceqp40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlcese40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/amd64/sqlcese40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | +CXED+6HzJlSphyMNOn27ujadC0= MyKED+9DyS+1XcMeaC0Zlw2vFZ0= EeyDE7og6WoPd2oBhYbMEnpFHhY=
6 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/README_ENU.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/README_ENU.txt
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/msvcr90.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/Microsoft.VC90.CRT/msvcr90.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlcecompact40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlcecompact40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceer40EN.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceer40EN.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceme40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceme40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceqp40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlceqp40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlcese40.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/NativeBinaries/x86/sqlcese40.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/SqlServerCompact.4.0.8482.1.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/SqlServerCompact.4.0.8482.1.nupkg
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Tools/GetSqlCEPostBuildCmd.ps1:
--------------------------------------------------------------------------------
1 | $solutionDir = [System.IO.Path]::GetDirectoryName($dte.Solution.FullName) + "\"
2 | $path = $installPath.Replace($solutionDir, "`$(SolutionDir)")
3 |
4 | $NativeAssembliesDir = Join-Path $path "NativeBinaries"
5 | $x86 = $(Join-Path $NativeAssembliesDir "x86\*.*")
6 | $x64 = $(Join-Path $NativeAssembliesDir "amd64\*.*")
7 |
8 | $SqlCEPostBuildCmd = "
9 | if not exist `"`$(TargetDir)x86`" md `"`$(TargetDir)x86`"
10 | xcopy /s /y `"$x86`" `"`$(TargetDir)x86`"
11 | if not exist `"`$(TargetDir)amd64`" md `"`$(TargetDir)amd64`"
12 | xcopy /s /y `"$x64`" `"`$(TargetDir)amd64`""
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Tools/install.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 |
3 | . (Join-Path $toolsPath "GetSqlCEPostBuildCmd.ps1")
4 |
5 | # Get the current Post Build Event cmd
6 | $currentPostBuildCmd = $project.Properties.Item("PostBuildEvent").Value
7 |
8 | # Append our post build command if it's not already there
9 | if (!$currentPostBuildCmd.Contains($SqlCEPostBuildCmd)) {
10 | $project.Properties.Item("PostBuildEvent").Value += $SqlCEPostBuildCmd
11 | }
12 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/Tools/uninstall.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 |
3 | . (Join-Path $toolsPath "GetSqlCEPostBuildCmd.ps1")
4 |
5 | # Get the current Post Build Event cmd
6 | $currentPostBuildCmd = $project.Properties.Item("PostBuildEvent").Value
7 |
8 | # Remove our post build command from it (if it's there)
9 | $project.Properties.Item("PostBuildEvent").Value = $currentPostBuildCmd.Replace($SqlCEPostBuildCmd, "")
10 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/lib/System.Data.SqlServerCe.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/SqlServerCompact.4.0.8482.1/lib/System.Data.SqlServerCe.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/DataSvcUtil.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/DataSvcUtil.exe
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Edm.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Edm.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.OData.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.OData.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Client.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Client.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Design.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.Design.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Services.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Spatial.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Spatial.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.Data.Spatial.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Data.Spatial
5 |
6 |
7 |
8 | Exposes a factory method to register the of this spatial provider.
9 |
10 |
11 | Create a new instance of for the provider.
12 | Returns the provider-specific implementation.
13 |
14 |
15 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.VsDesigner.DataServices.Adapter.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/Microsoft.VsDesigner.DataServices.Adapter.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/README.txt:
--------------------------------------------------------------------------------
1 | This is not a NuGet package.
2 |
3 | These assemblies come from the WCF Data Services October 2011 CTP
4 | You can find the full install here: http://www.microsoft.com/download/en/details.aspx?id=27728
5 | These files are used in order to serve the sample WCF Data Services site for integration testing of ruby_odata
6 | The reason for these new files is to that WCF DS can read Entity Framework 4.1's "Code First" approach.
7 |
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WCF DataServices October 2011 CTP/System.Spatial.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WCF DataServices October 2011 CTP/System.Spatial.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WebActivator.1.0.0.0/WebActivator.1.0.0.0.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WebActivator.1.0.0.0/WebActivator.1.0.0.0.nupkg
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WebActivator.1.0.0.0/lib/WebActivator.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WebActivator.1.0.0.0/lib/WebActivator.dll
--------------------------------------------------------------------------------
/test/RubyODataService/packages/WebActivator.1.0.0.0/lib/WebActivator.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/visoft/ruby_odata/7ef20c2f95bba1e150965b001f570853fc30c55c/test/RubyODataService/packages/WebActivator.1.0.0.0/lib/WebActivator.pdb
--------------------------------------------------------------------------------
/test/RubyODataService/packages/repositories.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/test/blueprints.rb:
--------------------------------------------------------------------------------
1 | class AuditFields
2 | extend Machinist::Machinable
3 | end
4 |
5 | class Product
6 | extend Machinist::Machinable
7 | end
8 |
9 | class Category
10 | extend Machinist::Machinable
11 | end
12 |
13 | AuditFields.blueprint do
14 | CreatedBy { "Machinist" }
15 | end
16 |
17 | Product.blueprint do
18 | Name { "Widget #{sn}" }
19 | Description { "Test Widget" }
20 | Price { ["10.25", "25.00", "50.00", "75.50", "100.00"].sample }
21 | Category { Category.make }
22 | AuditFields { AuditFields.make }
23 | end
24 |
25 | Category.blueprint do
26 | Name { "Category #{sn}" }
27 | AuditFields { AuditFields.make }
28 | end
--------------------------------------------------------------------------------
/test/iisExpress x64.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | rem IIS applicationhost.config doesn't seem to process enviroment variables, so we cant use one
3 | rem for our service path. A hack, but bust out ruby and manually replace the %SAMPLE_SERVICE_DIR%
4 | rem marker in the virtual directory path.
5 | ruby setpath.rb
6 | "%ProgramFiles(x86)%\iis express\iisexpress" /config:".\applicationhost.config"
7 |
8 |
--------------------------------------------------------------------------------
/test/iisExpress x86.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | rem IIS applicationhost.config doesn't seem to process enviroment variables, so we cant use one
3 | rem for our service path. A hack, but bust out ruby and manually replace the %SAMPLE_SERVICE_DIR%
4 | rem marker in the virtual directory path.
5 | ruby setpath.rb
6 | "%ProgramFiles%\iis express\iisexpress" /config:".\applicationhost.config"
7 |
8 |
--------------------------------------------------------------------------------
/test/setpath.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../../features/support/constants', __FILE__)
2 |
3 | # Open template config file and write in proper data
4 | puts "Replacing Configuration Data"
5 | File.open("applicationhost.config", "w") do |file|
6 | File.open("applicationhost.config.template", 'r').each do |line|
7 | line.gsub!("%SAMPLE_SERVICE_DIR%", "#{Dir.pwd.gsub("\/", "\\")}\\RubyODataService\\RubyODataService")
8 | line.gsub!("%HTTP_PORT_NUMBER%", "#{HTTP_PORT_NUMBER}")
9 | line.gsub!("%HTTPS_PORT_NUMBER%", "#{HTTPS_PORT_NUMBER}")
10 | line.gsub!("%WEBSERVER%", "#{WEBSERVER}")
11 | file.puts line
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/test/usage_samples/querying.rb:
--------------------------------------------------------------------------------
1 | #require 'ruby_odata'
2 | require File.expand_path('../../../lib/ruby_odata', __FILE__)
3 | require File.expand_path('../../../features/support/constants', __FILE__)
4 |
5 | svc = OData::Service.new "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.svc"
6 | ns_svc = OData::Service.new "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.svc", { :namespace => 'Models' }
7 |
8 | puts "Querying for a list of data"
9 | svc.Categories
10 | categories = svc.execute
11 | puts categories.to_json
12 |
13 | puts "Querying for a simple count"
14 | svc.Categories.count
15 | puts svc.execute
16 |
17 | puts "\n\nQuerying for a single result #execute"
18 | svc.Categories(1)
19 | category = svc.execute.first # Note the use of first here since execute will always return an enumerable
20 | puts category.to_json
21 |
22 | puts "\nAn easier way to do the same thing #Category.first(1)"
23 | category = Category.first(1)
24 | puts category.to_json
25 |
26 | puts "\n\nLazy Loading/Eager Loading"
27 | puts "\nWithout expanding the query"
28 | svc.Products(1)
29 | prod1 = svc.execute.first
30 | puts "#{prod1.to_json}\n"
31 | puts "\nLazy Loading"
32 | svc.load_property(prod1, "Category")
33 | puts "#{prod1.to_json}\n"
34 |
35 | puts "\nWith expanding the query (Eager Loading)"
36 | svc.Products(1).expand('Category')
37 | prod1 = svc.execute.first
38 | puts "#{prod1.to_json}\n"
39 |
40 | puts "\n\nNamespaced Entities (using the namespace Models)"
41 | puts "\nUsing the standard service to pull the first product"
42 | svc.Products(1)
43 | prod1 = svc.execute.first
44 | puts "The class return type from the standard service: #{prod1.class}"
45 |
46 | puts "\nUsing the namespaced service to pull the first product"
47 | ns_svc.Products(1)
48 | prod2 = ns_svc.execute.first
49 | puts "The class return type: #{prod2.class}\n"
50 |
--------------------------------------------------------------------------------
/test/usage_samples/reflection.rb:
--------------------------------------------------------------------------------
1 | require 'ruby_odata'
2 | require File.expand_path('../../../features/support/constants', __FILE__)
3 |
4 | svc = OData::Service.new "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.svc"
5 |
6 | puts "Retrieving collections exposed by a service:"
7 | puts svc.collections
8 |
9 | puts "\nClasses created by the service"
10 | puts svc.classes
11 |
12 | puts "\nFunction Imports (custom service methods) found on the service"
13 | puts svc.function_imports.to_json
14 |
15 | puts "\nRetrieving the properties for the Product class"
16 | puts Product.properties.to_json
17 |
--------------------------------------------------------------------------------
/test/usage_samples/sample_data.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../../../lib/ruby_odata', __FILE__)
2 | require File.expand_path('../../../features/support/constants', __FILE__)
3 | require "machinist"
4 |
5 | svc = OData::Service.new "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.svc"
6 | svc.CleanDatabaseForTesting #=> Comment this line out if you don't want to clear your test database
7 |
8 | # This needs to be required after the service creates the entities
9 | require File.expand_path('../../blueprints', __FILE__)
10 |
11 | cat1 = Category.make
12 | cat2 = Category.make
13 | svc.AddToCategories(cat1)
14 | svc.AddToCategories(cat2)
15 |
16 | c1p1 = Product.make :Category => cat1
17 | c1p2 = Product.make :Category => cat1
18 | c2p1 = Product.make :Category => cat2
19 | c2p2 = Product.make :Category => cat2
20 | c2p3 = Product.make :Category => cat2
21 |
22 | svc.AddToProducts(c1p1)
23 | svc.AddToProducts(c1p2)
24 | svc.AddToProducts(c2p1)
25 | svc.AddToProducts(c2p2)
26 | svc.AddToProducts(c2p3)
27 |
28 | svc.save_changes
--------------------------------------------------------------------------------