├── .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)<updated>2015-04-26T16:29:24Z</updated><author><name /></author><content 53 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">1</d:Id><d:Name>Auth 54 | Test Category</d:Name><d:AuditFields m:type="RubyODataService.AuditFields"><d:CreateDate 55 | m:type="Edm.DateTime">2015-04-26T16:29:24.16</d:CreateDate><d:ModifiedDate 56 | m:type="Edm.DateTime">2015-04-26T16:29:24.16</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry> 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: <?xml version="1.0" encoding="utf-8"?><feed xml:base="http://10.10.0.17:8989/SampleService/RubyOData.svc/" 44 | xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 45 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" 46 | xmlns:gml="http://www.opengis.net/gml"><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products</id><title 47 | type="text">Products2015-04-26T16:29:25Zhttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)<updated>2015-04-26T16:29:25Z</updated><author><name /></author><content 53 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">1</d:Id><d:Name>Product 54 | 1</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">10.25</d:Price><d:DiscontinuedDate 55 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">1</d:CategoryId><d:AuditFields 56 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:25.05</d:CreateDate><d:ModifiedDate 57 | m:type="Edm.DateTime">2015-04-26T16:29:25.05</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry><entry><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(2)</id><category 58 | term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" 59 | /><link rel="edit" title="Product" href="Products(2)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Category" 60 | type="application/atom+xml;type=entry" title="Category" href="Products(2)/Category" 61 | /><title /><updated>2015-04-26T16:29:25Z</updated><author><name /></author><content 62 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">2</d:Id><d:Name>Product 63 | 2</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">25.00</d:Price><d:DiscontinuedDate 64 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">2</d:CategoryId><d:AuditFields 65 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:25.05</d:CreateDate><d:ModifiedDate 66 | m:type="Edm.DateTime">2015-04-26T16:29:25.05</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry></feed> 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: <?xml version="1.0" encoding="utf-8"?><feed xml:base="http://10.10.0.17:8989/SampleService/RubyOData.svc/" 44 | xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 45 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" 46 | xmlns:gml="http://www.opengis.net/gml"><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products</id><title 47 | type="text">Products2015-04-26T16:29:26Zhttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)<updated>2015-04-26T16:29:26Z</updated><author><name /></author><content 53 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">1</d:Id><d:Name>Product 54 | 1</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">10.25</d:Price><d:DiscontinuedDate 55 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">1</d:CategoryId><d:AuditFields 56 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:26.38</d:CreateDate><d:ModifiedDate 57 | m:type="Edm.DateTime">2015-04-26T16:29:26.38</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry><entry><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(4)</id><category 58 | term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" 59 | /><link rel="edit" title="Product" href="Products(4)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Category" 60 | type="application/atom+xml;type=entry" title="Category" href="Products(4)/Category" 61 | /><title /><updated>2015-04-26T16:29:26Z</updated><author><name /></author><content 62 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">4</d:Id><d:Name>Product 63 | 4</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">50.00</d:Price><d:DiscontinuedDate 64 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">4</d:CategoryId><d:AuditFields 65 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:26.38</d:CreateDate><d:ModifiedDate 66 | m:type="Edm.DateTime">2015-04-26T16:29:26.38</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry></feed> 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: <?xml version="1.0" encoding="utf-8"?><feed xml:base="http://10.10.0.17:8989/SampleService/RubyOData.svc/" 44 | xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 45 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" 46 | xmlns:gml="http://www.opengis.net/gml"><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products</id><title 47 | type="text">Products2015-04-26T16:29:26Zhttp://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)<updated>2015-04-26T16:29:26Z</updated><author><name /></author><content 53 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">1</d:Id><d:Name>Product 54 | 1 - Updated</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">25.00</d:Price><d:DiscontinuedDate 55 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">1</d:CategoryId><d:AuditFields 56 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:25.66</d:CreateDate><d:ModifiedDate 57 | m:type="Edm.DateTime">2015-04-26T16:29:25.66</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry><entry><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(2)</id><category 58 | term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" 59 | /><link rel="edit" title="Product" href="Products(2)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Category" 60 | type="application/atom+xml;type=entry" title="Category" href="Products(2)/Category" 61 | /><title /><updated>2015-04-26T16:29:26Z</updated><author><name /></author><content 62 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">2</d:Id><d:Name>Product 63 | 2 - Updated</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">100.00</d:Price><d:DiscontinuedDate 64 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">2</d:CategoryId><d:AuditFields 65 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:25.66</d:CreateDate><d:ModifiedDate 66 | m:type="Edm.DateTime">2015-04-26T16:29:25.66</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry></feed> 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: <?xml version="1.0" encoding="utf-8"?><entry xml:base="http://10.10.0.17:8989/SampleService/RubyOData.svc/" 49 | xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 50 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" 51 | xmlns:gml="http://www.opengis.net/gml"><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)</id><category 52 | term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" 53 | /><link rel="edit" title="Product" href="Products(1)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Category" 54 | type="application/atom+xml;type=entry" title="Category" href="Products(1)/Category" 55 | /><title /><updated>2015-04-26T16:29:50Z</updated><author><name /></author><content 56 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">1</d:Id><d:Name>Sample 57 | Product</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">75.50</d:Price><d:DiscontinuedDate 58 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">1</d:CategoryId><d:AuditFields 59 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:49.786157Z</d:CreateDate><d:ModifiedDate 60 | m:type="Edm.DateTime">2015-04-26T16:29:49.786157Z</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry> 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: <?xml version="1.0" encoding="utf-8"?><entry xml:base="http://10.10.0.17:8989/SampleService/RubyOData.svc/" 44 | xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 45 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" 46 | xmlns:gml="http://www.opengis.net/gml"><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)</id><category 47 | term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" 48 | /><link rel="edit" title="Product" href="Products(1)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Category" 49 | type="application/atom+xml;type=entry" title="Category" href="Products(1)/Category" 50 | /><title /><updated>2015-04-26T16:29:51Z</updated><author><name /></author><content 51 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">1</d:Id><d:Name>Test 52 | Product</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">25.00</d:Price><d:DiscontinuedDate 53 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">1</d:CategoryId><d:AuditFields 54 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:51.287</d:CreateDate><d:ModifiedDate 55 | m:type="Edm.DateTime">2015-04-26T16:29:51.287</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry> 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: <?xml version="1.0" encoding="utf-8"?><entry xml:base="http://10.10.0.17:8989/SampleService/RubyOData.svc/" 44 | xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 45 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" 46 | xmlns:gml="http://www.opengis.net/gml"><id>http://10.10.0.17:8989/SampleService/RubyOData.svc/Products(1)</id><category 47 | term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" 48 | /><link rel="edit" title="Product" href="Products(1)" /><link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Category" 49 | type="application/atom+xml;type=entry" title="Category" href="Products(1)/Category" 50 | /><title /><updated>2015-04-26T16:29:51Z</updated><author><name /></author><content 51 | type="application/xml"><m:properties><d:Id m:type="Edm.Int32">1</d:Id><d:Name>Changed 52 | Test Product</d:Name><d:Description>Test Widget</d:Description><d:Price m:type="Edm.Decimal">25.00</d:Price><d:DiscontinuedDate 53 | m:type="Edm.DateTime" m:null="true" /><d:CategoryId m:type="Edm.Int32">1</d:CategoryId><d:AuditFields 54 | m:type="RubyODataService.AuditFields"><d:CreateDate m:type="Edm.DateTime">2015-04-26T16:29:51.287</d:CreateDate><d:ModifiedDate 55 | m:type="Edm.DateTime">2015-04-26T16:29:51.287</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry> 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: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"><edmx:DataServices 44 | m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><Schema 45 | Namespace="RubyODataService" xmlns="http://schemas.microsoft.com/ado/2008/09/edm"><EntityType 46 | Name="Product"><Key><PropertyRef Name="Id" /></Key><Property Name="Id" Type="Edm.Int32" 47 | Nullable="false" p6:StoreGeneratedPattern="Identity" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" 48 | /><Property Name="Name" Type="Edm.String" MaxLength="4000" FixedLength="false" 49 | Unicode="true" /><Property Name="Description" Type="Edm.String" MaxLength="4000" 50 | FixedLength="false" Unicode="true" /><Property Name="Price" Type="Edm.Decimal" 51 | Nullable="false" Precision="18" Scale="2" /><Property Name="DiscontinuedDate" 52 | Type="Edm.DateTime" /><Property Name="CategoryId" Type="Edm.Int32" Nullable="false" 53 | /><Property Name="AuditFields" Type="RubyODataService.AuditFields" Nullable="false" 54 | /><NavigationProperty Name="Category" Relationship="RubyODataService.Category_Products" 55 | ToRole="Category_Products_Source" FromRole="Category_Products_Target" /></EntityType><ComplexType 56 | Name="AuditFields"><Property Name="CreateDate" Type="Edm.DateTime" Nullable="false" 57 | /><Property Name="ModifiedDate" Type="Edm.DateTime" Nullable="false" /><Property 58 | Name="CreatedBy" Type="Edm.String" MaxLength="4000" FixedLength="false" Unicode="true" 59 | /></ComplexType><EntityType Name="Category"><Key><PropertyRef Name="Id" /></Key><Property 60 | Name="Id" Type="Edm.Int32" Nullable="false" p6:StoreGeneratedPattern="Identity" 61 | xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" /><Property 62 | Name="Name" Type="Edm.String" MaxLength="4000" FixedLength="false" Unicode="true" 63 | /><Property Name="AuditFields" Type="RubyODataService.AuditFields" Nullable="false" 64 | /><NavigationProperty Name="Products" Relationship="RubyODataService.Category_Products" 65 | ToRole="Category_Products_Target" FromRole="Category_Products_Source" /></EntityType><EntityType 66 | Name="EdmMetadata"><Key><PropertyRef Name="Id" /></Key><Property Name="Id" 67 | Type="Edm.Int32" Nullable="false" p6:StoreGeneratedPattern="Identity" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" 68 | /><Property Name="ModelHash" Type="Edm.String" MaxLength="4000" FixedLength="false" 69 | Unicode="true" /></EntityType><Association Name="Category_Products"><End Type="RubyODataService.Product" 70 | Role="Category_Products_Target" Multiplicity="*" /><End Type="RubyODataService.Category" 71 | Role="Category_Products_Source" Multiplicity="1"><OnDelete Action="Cascade" 72 | /></End><ReferentialConstraint><Principal Role="Category_Products_Source"><PropertyRef 73 | Name="Id" /></Principal><Dependent Role="Category_Products_Target"><PropertyRef 74 | Name="CategoryId" /></Dependent></ReferentialConstraint></Association><EntityContainer 75 | Name="RubyODataContext" m:IsDefaultEntityContainer="true"><EntitySet Name="Products" 76 | EntityType="RubyODataService.Product" /><EntitySet Name="Categories" EntityType="RubyODataService.Category" 77 | /><EntitySet Name="EdmMetadatas" EntityType="RubyODataService.EdmMetadata" 78 | /><AssociationSet Name="Category_Products" Association="RubyODataService.Category_Products"><End 79 | Role="Category_Products_Target" EntitySet="Products" /><End Role="Category_Products_Source" 80 | EntitySet="Categories" /></AssociationSet><FunctionImport Name="CleanDatabaseForTesting" 81 | m:HttpMethod="POST" /><FunctionImport Name="EntityCategoryWebGet" ReturnType="Collection(RubyODataService.Category)" 82 | EntitySet="Categories" m:HttpMethod="GET" /><FunctionImport Name="CategoryNames" 83 | ReturnType="Collection(Edm.String)" m:HttpMethod="GET" /><FunctionImport Name="FirstCategoryId" 84 | ReturnType="Edm.Int32" m:HttpMethod="GET" /><FunctionImport Name="EntitySingleCategoryWebGet" 85 | ReturnType="RubyODataService.Category" EntitySet="Categories" m:HttpMethod="GET"><Parameter 86 | Name="id" Type="Edm.Int32" /></FunctionImport></EntityContainer></Schema></edmx:DataServices></edmx:Edmx> 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('<NavigationProperty Name="Category" Relationship="RubyODataService.Category_Products" ToRole="Category_Products_Source" FromRole="Category_Products_Target"/>') 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 | <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> 2 | <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"> 3 | <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0"> 4 | <Schema Namespace="Model" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2008/09/edm"> 5 | </Schema> 6 | </edmx:DataServices> 7 | </edmx:Edmx> -------------------------------------------------------------------------------- /spec/fixtures/edmx_lowercase.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> 2 | <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"> 3 | <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0"> 4 | <Schema Namespace="acronymdbModel" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2008/09/edm"> 5 | <EntityType Name="acronym"> 6 | <Key> 7 | <PropertyRef Name="aid" /> 8 | </Key> 9 | <Property Name="aid" Type="Edm.Int32" Nullable="false" /> 10 | <Property Name="acrn" Type="Edm.String" Nullable="false" MaxLength="10" Unicode="true" FixedLength="true" /> 11 | <Property Name="meaning" Type="Edm.String" Nullable="false" MaxLength="500" Unicode="true" FixedLength="false" /> 12 | </EntityType> 13 | </Schema> 14 | <Schema Namespace="AcrnOData" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2008/09/edm"> 15 | <EntityContainer Name="acronymdbEntities" p7:LazyLoadingEnabled="true" m:IsDefaultEntityContainer="true" xmlns:p7="http://schemas.microsoft.com/ado/2009/02/edm/annotation"> 16 | <EntitySet Name="acronyms" EntityType="acronymdbModel.acronym" /> 17 | </EntityContainer> 18 | </Schema> 19 | </edmx:DataServices> 20 | </edmx:Edmx> -------------------------------------------------------------------------------- /spec/fixtures/error_without_message.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8" standalone="yes"?> 2 | <error 3 | xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 4 | <code></code> 5 | </error> 6 | -------------------------------------------------------------------------------- /spec/fixtures/feed_customization/edmx_feed_customization.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8" standalone="yes"?> 2 | <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"> 3 | <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="2.0"> 4 | <Schema Namespace="ODataDemo" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/05/edm"> 5 | <EntityType Name="Product"> 6 | <Key> 7 | <PropertyRef Name="ID" /> 8 | </Key> 9 | <Property Name="ID" Type="Edm.Int32" Nullable="false" /> 10 | <Property Name="Name" Type="Edm.String" Nullable="true" m:FC_TargetPath="SyndicationTitle" m:FC_ContentKind="text" m:FC_KeepInContent="false" /> 11 | <Property Name="Description" Type="Edm.String" Nullable="true" m:FC_TargetPath="SyndicationSummary" m:FC_ContentKind="text" m:FC_KeepInContent="false" /> 12 | <Property Name="ReleaseDate" Type="Edm.DateTime" Nullable="false" /> 13 | <Property Name="DiscontinuedDate" Type="Edm.DateTime" Nullable="true" /> 14 | <Property Name="Rating" Type="Edm.Int32" Nullable="false" /> 15 | <Property Name="Price" Type="Edm.Decimal" Nullable="false" /> 16 | <NavigationProperty Name="Category" Relationship="ODataDemo.Product_Category_Category_Products" FromRole="Product_Category" ToRole="Category_Products" /> 17 | <NavigationProperty Name="Supplier" Relationship="ODataDemo.Product_Supplier_Supplier_Products" FromRole="Product_Supplier" ToRole="Supplier_Products" /> 18 | </EntityType> 19 | <EntityType Name="Category"> 20 | <Key> 21 | <PropertyRef Name="ID" /> 22 | </Key> 23 | <Property Name="ID" Type="Edm.Int32" Nullable="false" /> 24 | <Property Name="Name" Type="Edm.String" Nullable="true" m:FC_TargetPath="SyndicationTitle" m:FC_ContentKind="text" m:FC_KeepInContent="true" /> 25 | <NavigationProperty Name="Products" Relationship="ODataDemo.Product_Category_Category_Products" FromRole="Category_Products" ToRole="Product_Category" /> 26 | </EntityType> 27 | <EntityType Name="Supplier"> 28 | <Key> 29 | <PropertyRef Name="ID" /> 30 | </Key> 31 | <Property Name="ID" Type="Edm.Int32" Nullable="false" /> 32 | <Property Name="Name" Type="Edm.String" Nullable="true" m:FC_TargetPath="SyndicationTitle" m:FC_ContentKind="text" m:FC_KeepInContent="true" /> 33 | <Property Name="Address" Type="ODataDemo.Address" Nullable="false" /> 34 | <Property Name="Concurrency" Type="Edm.Int32" Nullable="false" ConcurrencyMode="Fixed" /> 35 | <NavigationProperty Name="Products" Relationship="ODataDemo.Product_Supplier_Supplier_Products" FromRole="Supplier_Products" ToRole="Product_Supplier" /> 36 | </EntityType> 37 | <ComplexType Name="Address"> 38 | <Property Name="Street" Type="Edm.String" Nullable="true" /> 39 | <Property Name="City" Type="Edm.String" Nullable="true" /> 40 | <Property Name="State" Type="Edm.String" Nullable="true" /> 41 | <Property Name="ZipCode" Type="Edm.String" Nullable="true" /> 42 | <Property Name="Country" Type="Edm.String" Nullable="true" /> 43 | </ComplexType> 44 | <Association Name="Product_Category_Category_Products"> 45 | <End Role="Product_Category" Type="ODataDemo.Product" Multiplicity="*" /> 46 | <End Role="Category_Products" Type="ODataDemo.Category" Multiplicity="0..1" /> 47 | </Association> 48 | <Association Name="Product_Supplier_Supplier_Products"> 49 | <End Role="Product_Supplier" Type="ODataDemo.Product" Multiplicity="*" /> 50 | <End Role="Supplier_Products" Type="ODataDemo.Supplier" Multiplicity="0..1" /> 51 | </Association> 52 | <EntityContainer Name="DemoService" m:IsDefaultEntityContainer="true"> 53 | <EntitySet Name="Products" EntityType="ODataDemo.Product" /> 54 | <EntitySet Name="Categories" EntityType="ODataDemo.Category" /> 55 | <EntitySet Name="Suppliers" EntityType="ODataDemo.Supplier" /> 56 | <AssociationSet Name="Products_Category_Categories" Association="ODataDemo.Product_Category_Category_Products"> 57 | <End Role="Product_Category" EntitySet="Products" /> 58 | <End Role="Category_Products" EntitySet="Categories" /> 59 | </AssociationSet> 60 | <AssociationSet Name="Products_Supplier_Suppliers" Association="ODataDemo.Product_Supplier_Supplier_Products"> 61 | <End Role="Product_Supplier" EntitySet="Products" /> 62 | <End Role="Supplier_Products" EntitySet="Suppliers" /> 63 | </AssociationSet> 64 | <FunctionImport Name="GetProductsByRating" EntitySet="Products" ReturnType="Collection(ODataDemo.Product)" m:HttpMethod="GET"> 65 | <Parameter Name="rating" Type="Edm.Int32" Mode="In" /> 66 | </FunctionImport> 67 | </EntityContainer> 68 | </Schema> 69 | </edmx:DataServices> 70 | </edmx:Edmx> -------------------------------------------------------------------------------- /spec/fixtures/int64_ids/edmx_boat_service.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"> 3 | <edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="2.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 4 | <Schema Namespace="Model" xmlns="http://schemas.microsoft.com/ado/2009/11/edm"> 5 | <EntityType Name="Boat"> 6 | <Key> 7 | <PropertyRef Name="KeyId" /> 8 | </Key> 9 | <Property Name="KeyId" Type="Edm.Int64" Nullable="false" p6:StoreGeneratedPattern="Identity" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" /> 10 | <Property Name="color" Type="Edm.String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="false" /> 11 | </EntityType> 12 | </Schema> 13 | <Schema Namespace="WebApp" xmlns="http://schemas.microsoft.com/ado/2009/11/edm"> 14 | <EntityContainer Name="adoEntities" m:IsDefaultEntityContainer="true" p6:LazyLoadingEnabled="true" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation"> 15 | <EntitySet Name="Boats" EntityType="Model.Boat" /> 16 | </EntityContainer> 17 | </Schema> 18 | </edmx:DataServices> 19 | </edmx:Edmx> -------------------------------------------------------------------------------- /spec/fixtures/int64_ids/edmx_car_service.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"> 3 | <edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="2.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 4 | <Schema Namespace="Model" xmlns="http://schemas.microsoft.com/ado/2009/11/edm"> 5 | <EntityType Name="Car"> 6 | <Key> 7 | <PropertyRef Name="id" /> 8 | </Key> 9 | <Property Name="id" Type="Edm.Int64" Nullable="false" p6:StoreGeneratedPattern="Identity" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" /> 10 | <Property Name="color" Type="Edm.String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="false" /> 11 | <Property Name="num_spots" Type="Edm.Int32" /> 12 | <Property Name="striped" Type="Edm.Byte" /> 13 | </EntityType> 14 | </Schema> 15 | <Schema Namespace="WebApp" xmlns="http://schemas.microsoft.com/ado/2009/11/edm"> 16 | <EntityContainer Name="adoEntities" m:IsDefaultEntityContainer="true" p6:LazyLoadingEnabled="true" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation"> 17 | <EntitySet Name="Cars" EntityType="Model.Car" /> 18 | </EntityContainer> 19 | </Schema> 20 | </edmx:DataServices> 21 | </edmx:Edmx> -------------------------------------------------------------------------------- /spec/fixtures/int64_ids/result_boats.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <feed xml:base="http://test.com/test.svc/" 3 | xmlns="http://www.w3.org/2005/Atom" 4 | xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 5 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 6 | <id>http://test.com/test.svc/Boats</id> 7 | <title type="text">Boats 8 | 2013-10-28T19:59:15Z 9 | 10 | 11 | http://test.com/test.svc/Boats(213L) 12 | 13 | 14 | 15 | <updated>2013-10-28T19:59:15Z</updated> 16 | <author> 17 | <name /> 18 | </author> 19 | <content type="application/xml"> 20 | <m:properties> 21 | <d:KeyId m:type="Edm.Int64">213</d:KeyId> 22 | <d:color>blue</d:color> 23 | </m:properties> 24 | </content> 25 | </entry> 26 | </feed> -------------------------------------------------------------------------------- /spec/fixtures/int64_ids/result_cars.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <feed xml:base="http://test.com/test.svc/" 3 | xmlns="http://www.w3.org/2005/Atom" 4 | xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 5 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 6 | <id>http://test.com/test.svc/Cars</id> 7 | <title type="text">Cars 8 | 2013-10-28T19:59:15Z 9 | 10 | 11 | http://test.com/test.svc/Cars(213L) 12 | 13 | 14 | 15 | <updated>2013-10-28T19:59:15Z</updated> 16 | <author> 17 | <name /> 18 | </author> 19 | <content type="application/xml"> 20 | <m:properties> 21 | <d:id m:type="Edm.Int64">213</d:id> 22 | <d:color>peach</d:color> 23 | <d:num_spots m:type="Edm.Int32" m:null="true" /> 24 | <d:striped m:type="Edm.Byte" m:null="true" /> 25 | </m:properties> 26 | </content> 27 | </entry> 28 | </feed> -------------------------------------------------------------------------------- /spec/fixtures/links/result_links_query.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> 2 | <links xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices"> 3 | <uri>http://test.com/SampleService/RubyOData.svc/Products(1)</uri> 4 | <uri>http://test.com/SampleService/RubyOData.svc/Products(2)</uri> 5 | <uri>http://test.com/SampleService/RubyOData.svc/Products(3)</uri> 6 | </links> -------------------------------------------------------------------------------- /spec/fixtures/ms_system_center/hardware_profiles.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <feed xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" xml:base="https://srv-spf-98.bs.unsi.no:8090/SC2012/VMM/Microsoft.Management.Odata.svc/"> 3 | <id>https://srv-spf-98.bs.unsi.no:8090/SC2012/VMM/Microsoft.Management.Odata.svc/HardwareProfiles</id> 4 | <title type="text">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 | <updated>2013-06-16T10:01:46Z</updated> 16 | <author> 17 | <name/> 18 | </author> 19 | <content type="application/xml"> 20 | <m:properties> 21 | <d:StampId m:type="Edm.Guid">a68f9b8b-f8af-46b2-8636-255248c9b5ab</d:StampId> 22 | <d:ID m:type="Edm.Guid">8967da8e-eaf0-4414-b1ab-0b8d7a848af7</d:ID> 23 | <d:AccessedTime m:null="true"/> 24 | <d:AddedTime m:type="Edm.DateTime">2013-06-04T17:28:29.597+02:00</d:AddedTime> 25 | <d:CPUCount m:type="Edm.Byte">2</d:CPUCount> 26 | <d:CPUMax m:type="Edm.Int32">100</d:CPUMax> 27 | <d:CPUReserve m:type="Edm.Int32">0</d:CPUReserve> 28 | <d:CPUTypeId m:null="true"/> 29 | <d:CreationTime m:null="true"/> 30 | <d:DiskIO m:type="Edm.Int32">0</d:DiskIO> 31 | <d:ExpectedCPUUtilization m:type="Edm.Int32">20</d:ExpectedCPUUtilization> 32 | <d:Enabled m:type="Edm.Boolean">true</d:Enabled> 33 | <d:LimitCPUForMigration m:type="Edm.Boolean">false</d:LimitCPUForMigration> 34 | <d:LimitCPUFunctionality m:type="Edm.Boolean">false</d:LimitCPUFunctionality> 35 | <d:Memory m:type="Edm.Int32">3500</d:Memory> 36 | <d:ModifiedTime m:type="Edm.DateTime">2013-06-04T17:41:30.287+02:00</d:ModifiedTime> 37 | <d:Name>[Hardware] - Linux Medium VM</d:Name> 38 | <d:NetworkUtilization m:type="Edm.Int32">0</d:NetworkUtilization> 39 | <d:Owner m:type="VMM.UserAndRole"> 40 | <d:UserName>foo\bar</d:UserName> 41 | <d:RoleName>Administrator</d:RoleName> 42 | <d:RoleID m:type="Edm.Guid">75700cd5-893e-4f68-ada7-50ef4668acc6</d:RoleID> 43 | </d:Owner> 44 | <d:GrantedToList m:type="Collection(VMM.UserAndRole)"> 45 | <d:element> 46 | <d:UserName m:null="true"/> 47 | <d:RoleName>Important Tenant</d:RoleName> 48 | <d:RoleID m:type="Edm.Guid">ee41a0fc-fa48-4ed6-8403-f42a45529003</d:RoleID> 49 | </d:element> 50 | </d:GrantedToList> 51 | <d:RelativeWeight m:type="Edm.Int32">100</d:RelativeWeight> 52 | <d:ShareSCSIBus m:type="Edm.Boolean">false</d:ShareSCSIBus> 53 | <d:TotalVHDCapacity m:null="true"/> 54 | <d:UndoDisksEnabled m:type="Edm.Boolean">false</d:UndoDisksEnabled> 55 | <d:Accessibility>Public</d:Accessibility> 56 | <d:Description/> 57 | <d:NumLockEnabled m:type="Edm.Boolean">false</d:NumLockEnabled> 58 | </m:properties> 59 | </content> 60 | </entry> 61 | </feed> 62 | -------------------------------------------------------------------------------- /spec/fixtures/partial/partial_feed_metadata.xml: -------------------------------------------------------------------------------- 1 | <edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0"> 2 | <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0"> 3 | <Schema xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2008/09/edm"> 4 | <EntityType Name="Partial"> 5 | <Key> 6 | <PropertyRef Name="CustomerID"/> 7 | </Key> 8 | <Property Name="CustomerID" Type="Edm.String" Nullable="false" MaxLength="5" Unicode="true" FixedLength="true"/> 9 | <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" Unicode="true" FixedLength="false"/> 10 | <Property Name="ContactName" Type="Edm.String" Nullable="true" MaxLength="30" Unicode="true" FixedLength="false"/> 11 | <Property Name="ContactTitle" Type="Edm.String" Nullable="true" MaxLength="30" Unicode="true" FixedLength="false"/> 12 | <Property Name="Address" Type="Edm.String" Nullable="true" MaxLength="60" Unicode="true" FixedLength="false"/> 13 | <Property Name="City" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false"/> 14 | <Property Name="Region" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false"/> 15 | <Property Name="PostalCode" Type="Edm.String" Nullable="true" MaxLength="10" Unicode="true" FixedLength="false"/> 16 | <Property Name="Country" Type="Edm.String" Nullable="true" MaxLength="15" Unicode="true" FixedLength="false"/> 17 | <Property Name="Phone" Type="Edm.String" Nullable="true" MaxLength="24" Unicode="true" FixedLength="false"/> 18 | <Property Name="Fax" Type="Edm.String" Nullable="true" MaxLength="24" Unicode="true" FixedLength="false"/> 19 | </EntityType> 20 | <EntityContainer xmlns:p7="http://schemas.microsoft.com/ado/2009/02/edm/annotation" p7:LazyLoadingEnabled="true" m:IsDefaultEntityContainer="true"> 21 | <EntitySet Name="Partials" EntityType="Partial"/> 22 | </EntityContainer> 23 | </Schema> 24 | </edmx:DataServices> 25 | </edmx:Edmx> -------------------------------------------------------------------------------- /spec/fixtures/partial/partial_feed_part_1.xml: -------------------------------------------------------------------------------- 1 | <feed xml:base="http://test.com/test.svc/" 2 | xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 3 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 4 | xmlns="http://www.w3.org/2005/Atom"> 5 | <title type="text">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 | <updated>2010-03-10T09:34:11Z</updated> 14 | <author> 15 | <name /> 16 | </author> 17 | <link rel="edit" title="Customer" href="Customers('ALFKI')" /> 18 | <link 19 | rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/CustomerDemographics" 20 | type="application/atom+xml;type=feed" 21 | title="CustomerDemographics" href="Partials/CustomerDemographics" /> 22 | <category term="Partial" 23 | scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 24 | <content type="application/xml"> 25 | <m:properties> 26 | <d:CustomerID>ALFKI</d:CustomerID> 27 | <d:CompanyName>Alfreds Futterkiste</d:CompanyName> 28 | <d:ContactName>Maria Anders</d:ContactName> 29 | <d:ContactTitle>Sales Representative</d:ContactTitle> 30 | <d:Address>Obere Str. 57</d:Address> 31 | <d:City>Berlin</d:City> 32 | <d:Region m:null="true" /> 33 | <d:PostalCode>12209</d:PostalCode> 34 | <d:Country>Germany</d:Country> 35 | <d:Phone>030-0074321</d:Phone> 36 | <d:Fax>030-0076545</d:Fax> 37 | </m:properties> 38 | </content> 39 | </entry> 40 | <link rel="next" 41 | href="http://test.com/test.svc/Partials?$skiptoken='ERNSH'" /> 42 | </feed> -------------------------------------------------------------------------------- /spec/fixtures/partial/partial_feed_part_2.xml: -------------------------------------------------------------------------------- 1 | <feed xml:base="http://test.com/test.svc/" 2 | xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 3 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 4 | xmlns="http://www.w3.org/2005/Atom"> 5 | <title type="text">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 | <updated>2010-03-10T09:34:11Z</updated> 14 | <author> 15 | <name /> 16 | </author> 17 | <link rel="edit" title="Customer" href="Partials?$skiptoken='ERNSH'" /> 18 | <link 19 | rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/CustomerDemographics" 20 | type="application/atom+xml;type=feed" 21 | title="CustomerDemographics" href="Partials/CustomerDemographics" /> 22 | <category term="Partial" 23 | scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 24 | <content type="application/xml"> 25 | <m:properties> 26 | <d:CustomerID>ALFKI</d:CustomerID> 27 | <d:CompanyName>Alfreds Futterkiste</d:CompanyName> 28 | <d:ContactName>Maria Sanders</d:ContactName> 29 | <d:ContactTitle>Sales Manager</d:ContactTitle> 30 | <d:Address>Obere Str. 57</d:Address> 31 | <d:City>Berlin</d:City> 32 | <d:Region m:null="true" /> 33 | <d:PostalCode>12209</d:PostalCode> 34 | <d:Country>Germany</d:Country> 35 | <d:Phone>030-0074321</d:Phone> 36 | <d:Fax>030-0076545</d:Fax> 37 | </m:properties> 38 | </content> 39 | </entry> 40 | <link rel="next" 41 | href="http://test.com/test.svc/Partials?$skiptoken='ERNSH2'" /> 42 | </feed> -------------------------------------------------------------------------------- /spec/fixtures/partial/partial_feed_part_3.xml: -------------------------------------------------------------------------------- 1 | <feed xml:base="http://test.com/test.svc/" 2 | xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 3 | xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 4 | xmlns="http://www.w3.org/2005/Atom"> 5 | <title type="text">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 | <updated>2010-03-10T09:34:11Z</updated> 14 | <author> 15 | <name /> 16 | </author> 17 | <link rel="edit" title="Customer" href="Partials?$skiptoken='ERNSH2'" /> 18 | <link 19 | rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/CustomerDemographics" 20 | type="application/atom+xml;type=feed" 21 | title="CustomerDemographics" href="Partials/CustomerDemographics" /> 22 | <category term="Partial" 23 | scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 24 | <content type="application/xml"> 25 | <m:properties> 26 | <d:CustomerID>ALFKI</d:CustomerID> 27 | <d:CompanyName>Alfreds Futterkiste</d:CompanyName> 28 | <d:ContactName>Maria Banders</d:ContactName> 29 | <d:ContactTitle>Sales Damager</d:ContactTitle> 30 | <d:Address>Obere Str. 57</d:Address> 31 | <d:City>Berlin</d:City> 32 | <d:Region m:null="true" /> 33 | <d:PostalCode>12209</d:PostalCode> 34 | <d:Country>Germany</d:Country> 35 | <d:Phone>030-0074321</d:Phone> 36 | <d:Fax>030-0076545</d:Fax> 37 | </m:properties> 38 | </content> 39 | </entry> 40 | </feed> -------------------------------------------------------------------------------- /spec/fixtures/sample_service/edmx_categories_products.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1"?><edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"><edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><Schema Namespace="RubyODataService" xmlns="http://schemas.microsoft.com/ado/2008/09/edm"><EntityType Name="Product"><Key><PropertyRef Name="Id" /></Key><Property Name="Id" Type="Edm.Int32" Nullable="false" p6:StoreGeneratedPattern="Identity" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" /><Property Name="Name" Type="Edm.String" MaxLength="4000" FixedLength="false" Unicode="true" /><Property Name="Description" Type="Edm.String" MaxLength="4000" FixedLength="false" Unicode="true" /><Property Name="Price" Type="Edm.Decimal" Nullable="false" Precision="18" Scale="2" /><Property Name="DiscontinuedDate" Type="Edm.DateTime" /><Property Name="CategoryId" Type="Edm.Int32" Nullable="false" /><Property Name="AuditFields" Type="RubyODataService.AuditFields" Nullable="false" /><NavigationProperty Name="Category" Relationship="RubyODataService.Category_Products" ToRole="Category_Products_Source" FromRole="Category_Products_Target" /></EntityType><ComplexType Name="AuditFields"><Property Name="CreateDate" Type="Edm.DateTime" Nullable="false" /><Property Name="ModifiedDate" Type="Edm.DateTime" Nullable="false" /><Property Name="CreatedBy" Type="Edm.String" MaxLength="4000" FixedLength="false" Unicode="true" /></ComplexType><EntityType Name="Category"><Key><PropertyRef Name="Id" /></Key><Property Name="Id" Type="Edm.Int32" Nullable="false" p6:StoreGeneratedPattern="Identity" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" /><Property Name="Name" Type="Edm.String" MaxLength="4000" FixedLength="false" Unicode="true" /><Property Name="AuditFields" Type="RubyODataService.AuditFields" Nullable="false" /><NavigationProperty Name="Products" Relationship="RubyODataService.Category_Products" ToRole="Category_Products_Target" FromRole="Category_Products_Source" /></EntityType><EntityType Name="EdmMetadata"><Key><PropertyRef Name="Id" /></Key><Property Name="Id" Type="Edm.Int32" Nullable="false" p6:StoreGeneratedPattern="Identity" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation" /><Property Name="ModelHash" Type="Edm.String" MaxLength="4000" FixedLength="false" Unicode="true" /></EntityType><Association Name="Category_Products"><End Type="RubyODataService.Product" Role="Category_Products_Target" Multiplicity="*" /><End Type="RubyODataService.Category" Role="Category_Products_Source" Multiplicity="1"><OnDelete Action="Cascade" /></End><ReferentialConstraint><Principal Role="Category_Products_Source"><PropertyRef Name="Id" /></Principal><Dependent Role="Category_Products_Target"><PropertyRef Name="CategoryId" /></Dependent></ReferentialConstraint></Association><EntityContainer Name="RubyODataContext" m:IsDefaultEntityContainer="true"><EntitySet Name="Products" EntityType="RubyODataService.Product" /><EntitySet Name="Categories" EntityType="RubyODataService.Category" /><EntitySet Name="EdmMetadatas" EntityType="RubyODataService.EdmMetadata" /><AssociationSet Name="Category_Products" Association="RubyODataService.Category_Products"><End Role="Category_Products_Target" EntitySet="Products" /><End Role="Category_Products_Source" EntitySet="Categories" /></AssociationSet><FunctionImport Name="CleanDatabaseForTesting" m:HttpMethod="POST" /><FunctionImport Name="EntityCategoryWebGet" ReturnType="Collection(RubyODataService.Category)" EntitySet="Categories" m:HttpMethod="GET" /><FunctionImport Name="CategoryNames" ReturnType="Collection(Edm.String)" m:HttpMethod="GET" /><FunctionImport Name="FirstCategoryId" ReturnType="Edm.Int32" m:HttpMethod="GET" /><FunctionImport Name="EntitySingleCategoryWebGet" ReturnType="RubyODataService.Category" EntitySet="Categories" m:HttpMethod="GET"><Parameter Name="id" Type="Edm.Int32" /></FunctionImport></EntityContainer></Schema></edmx:DataServices></edmx:Edmx> -------------------------------------------------------------------------------- /spec/fixtures/sample_service/result_category_names.xml: -------------------------------------------------------------------------------- 1 | <CategoryNames xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices"> 2 | <element>Test Category 1</element> 3 | <element>Test Category 2</element> 4 | <element>Test Category 3</element> 5 | </CategoryNames> -------------------------------------------------------------------------------- /spec/fixtures/sample_service/result_entity_category_web_get.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1"?> 2 | <feed xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" xml:base="http://win7dev:8989/SampleService/RubyOData.svc/"> 3 | <id>http://win7dev:8989/SampleService/RubyOData.svc/EntityCategoryWebGet</id> 4 | <title type="text">EntityCategoryWebGet 5 | 2011-11-28T02:43:29Z 6 | 7 | 8 | http://win7dev:8989/SampleService/RubyOData.svc/Categories(1) 9 | 10 | 11 | 12 | 13 | <updated>2011-11-28T02:43:29Z</updated> 14 | <author> 15 | <name/> 16 | </author> 17 | <content type="application/xml"> 18 | <m:properties> 19 | <d:Id m:type="Edm.Int32">1</d:Id> 20 | <d:Name>Test Category</d:Name> 21 | <d:AuditFields m:type="RubyODataService.AuditFields"> 22 | <d:CreateDate m:type="Edm.DateTime">2011-11-28T02:42:58.407</d:CreateDate> 23 | <d:ModifiedDate m:type="Edm.DateTime">2011-11-28T02:42:58.407</d:ModifiedDate> 24 | <d:CreatedBy m:null="true"/> 25 | </d:AuditFields> 26 | </m:properties> 27 | </content> 28 | </entry> 29 | </feed> -------------------------------------------------------------------------------- /spec/fixtures/sample_service/result_entity_single_category_web_get.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1"?> 2 | <entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" xml:base="http://win7dev:8989/SampleService/RubyOData.svc/"> 3 | <id>http://win7dev:8989/SampleService/RubyOData.svc/Categories(1)</id> 4 | <category term="RubyODataService.Category" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/> 5 | <link rel="edit" title="Category" href="Categories(1)"/> 6 | <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Products" type="application/atom+xml;type=feed" title="Products" href="Categories(1)/Products"/> 7 | <title/> 8 | <updated>2011-11-28T02:51:40Z</updated> 9 | <author> 10 | <name/> 11 | </author> 12 | <content type="application/xml"> 13 | <m:properties> 14 | <d:Id m:type="Edm.Int32">1</d:Id> 15 | <d:Name>Test Category</d:Name> 16 | <d:AuditFields m:type="RubyODataService.AuditFields"> 17 | <d:CreateDate m:type="Edm.DateTime">2011-11-28T02:42:58.407</d:CreateDate> 18 | <d:ModifiedDate m:type="Edm.DateTime">2011-11-28T02:42:58.407</d:ModifiedDate> 19 | <d:CreatedBy m:null="true"/> 20 | </d:AuditFields> 21 | </m:properties> 22 | </content> 23 | </entry> -------------------------------------------------------------------------------- /spec/fixtures/sample_service/result_first_category_id.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1"?> 2 | <d:FirstCategoryId xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:type="Edm.Int32">1</d:FirstCategoryId> 3 | -------------------------------------------------------------------------------- /spec/fixtures/sample_service/result_multiple_category_products.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> 2 | <feed xml:base="http://test.com/test.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"> 3 | <title type="text">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 | <updated>2013-07-19T12:29:11Z</updated> 18 | <author> 19 | <name /> 20 | </author> 21 | <content type="application/xml"> 22 | <m:properties> 23 | <d:Name>Widget 0001</d:Name> 24 | <d:Price m:type="Edm.Decimal">75.50</d:Price> 25 | </m:properties> 26 | </content> 27 | </entry> 28 | <entry> 29 | <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(2)</id> 30 | <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 31 | <link rel="edit" title="Product" href="Products(2)" /> 32 | <title /> 33 | <updated>2013-07-19T12:29:11Z</updated> 34 | <author> 35 | <name /> 36 | </author> 37 | <content type="application/xml"> 38 | <m:properties> 39 | <d:Name>Widget 0002</d:Name> 40 | <d:Price m:type="Edm.Decimal">100.00</d:Price> 41 | </m:properties> 42 | </content> 43 | </entry> 44 | <entry> 45 | <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(3)</id> 46 | <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 47 | <link rel="edit" title="Product" href="Products(3)" /> 48 | <title /> 49 | <updated>2013-07-19T12:29:11Z</updated> 50 | <author> 51 | <name /> 52 | </author> 53 | <content type="application/xml"> 54 | <m:properties> 55 | <d:Name>Widget 0003</d:Name> 56 | <d:Price m:type="Edm.Decimal">10.25</d:Price> 57 | </m:properties> 58 | </content> 59 | </entry> 60 | <entry> 61 | <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(4)</id> 62 | <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 63 | <link rel="edit" title="Product" href="Products(4)" /> 64 | <title /> 65 | <updated>2013-07-19T12:29:11Z</updated> 66 | <author> 67 | <name /> 68 | </author> 69 | <content type="application/xml"> 70 | <m:properties> 71 | <d:Name>Widget 0004</d:Name> 72 | <d:Price m:type="Edm.Decimal">100.00</d:Price> 73 | </m:properties> 74 | </content> 75 | </entry> 76 | <entry> 77 | <id>http://win7dev:8989/SampleService/RubyOData.svc/Products(5)</id> 78 | <category term="RubyODataService.Product" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> 79 | <link rel="edit" title="Product" href="Products(5)" /> 80 | <title /> 81 | <updated>2013-07-19T12:29:11Z</updated> 82 | <author> 83 | <name /> 84 | </author> 85 | <content type="application/xml"> 86 | <m:properties> 87 | <d:Name>Widget 0005</d:Name> 88 | <d:Price m:type="Edm.Decimal">75.50</d:Price> 89 | </m:properties> 90 | </content> 91 | </entry> 92 | </feed> -------------------------------------------------------------------------------- /spec/fixtures/sample_service/result_single_category.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> 2 | <entry xml:base="http://test.com/test.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"> 3 | <id>http://test.com/test.svc/Categories(1)</id> 4 | <title type="text"> 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 --------------------------------------------------------------------------------