ruby_odata 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. data/.gitignore +3 -2
  2. data/.travis.yml +2 -1
  3. data/.yardopts +6 -0
  4. data/CHANGELOG.md +102 -0
  5. data/Guardfile +14 -0
  6. data/README.md +285 -0
  7. data/Rakefile +0 -7
  8. data/features/basic_auth.feature +3 -2
  9. data/features/batch_request.feature +7 -6
  10. data/features/cassettes/basic_auth_protected_resource.yml +57 -0
  11. data/features/cassettes/batch_request_additions.yml +69 -0
  12. data/features/cassettes/batch_request_deletes.yml +69 -0
  13. data/features/cassettes/batch_request_updates.yml +69 -0
  14. data/features/cassettes/clean_database_for_testing.yml +46 -0
  15. data/features/cassettes/cucumber_tags/basic_auth.yml +297 -0
  16. data/features/cassettes/cucumber_tags/batch_request.yml +1459 -0
  17. data/features/cassettes/cucumber_tags/complex_types.yml +326 -0
  18. data/features/cassettes/cucumber_tags/error_handling.yml +64 -0
  19. data/features/cassettes/cucumber_tags/query_builder.yml +2025 -0
  20. data/features/cassettes/cucumber_tags/service.yml +234 -0
  21. data/features/cassettes/cucumber_tags/service_manage.yml +937 -0
  22. data/features/cassettes/cucumber_tags/service_methods.yml +647 -0
  23. data/features/cassettes/cucumber_tags/ssl.yml +203 -0
  24. data/features/cassettes/cucumber_tags/type_conversion.yml +337 -0
  25. data/features/cassettes/service_manage_additions.yml +65 -0
  26. data/features/cassettes/service_manage_deletions.yml +58 -0
  27. data/features/cassettes/service_manage_deletions_2.yml +58 -0
  28. data/features/cassettes/unsecured_metadata.yml +89 -0
  29. data/features/complex_types.feature +4 -3
  30. data/features/error_handling.feature +14 -0
  31. data/features/query_builder.feature +30 -9
  32. data/features/service.feature +4 -3
  33. data/features/service_manage.feature +6 -5
  34. data/features/service_methods.feature +3 -2
  35. data/features/ssl.feature +8 -8
  36. data/features/step_definitions/service_steps.rb +38 -24
  37. data/features/support/env.rb +1 -3
  38. data/features/support/hooks.rb +3 -2
  39. data/features/support/pickle.rb +29 -18
  40. data/features/support/vcr.rb +24 -0
  41. data/features/type_conversion.feature +16 -17
  42. data/lib/ruby_odata/association.rb +7 -6
  43. data/lib/ruby_odata/class_builder.rb +6 -7
  44. data/lib/ruby_odata/exceptions.rb +4 -0
  45. data/lib/ruby_odata/helpers.rb +11 -0
  46. data/lib/ruby_odata/operation.rb +5 -6
  47. data/lib/ruby_odata/property_metadata.rb +4 -5
  48. data/lib/ruby_odata/query_builder.rb +98 -63
  49. data/lib/ruby_odata/service.rb +118 -103
  50. data/lib/ruby_odata/version.rb +3 -1
  51. data/lib/ruby_odata.rb +20 -18
  52. data/ruby_odata.gemspec +16 -12
  53. data/spec/query_builder_spec.rb +78 -14
  54. data/spec/service_spec.rb +83 -83
  55. data/spec/support/sample_service_matcher.rb +15 -0
  56. data/test/RubyODataService/RubyODataService/App_Data/.gitkeep +0 -0
  57. data/test/blueprints.rb +15 -9
  58. data/test/usage_samples/querying.rb +5 -1
  59. data/test/usage_samples/sample_data.rb +1 -3
  60. metadata +213 -39
  61. data/CHANGELOG.rdoc +0 -88
  62. data/README.rdoc +0 -259
@@ -0,0 +1,58 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://win7dev:8989/SampleService/RubyOData.svc/Products(1)
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Cache-Control:
22
+ - no-cache
23
+ Content-Length:
24
+ - '1431'
25
+ Content-Type:
26
+ - application/atom+xml;type=entry;charset=utf-8
27
+ Server:
28
+ - Microsoft-IIS/7.5
29
+ Set-Cookie:
30
+ - ASP.NET_SessionId=pqd44q53aamnklanqbym2pcu; 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
+ - Tue, 07 Aug 2012 21:47:37 GMT
41
+ body:
42
+ encoding: US-ASCII
43
+ string: <?xml version="1.0" encoding="utf-8"?><entry xml:base="http://win7dev: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://win7dev: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>2012-08-07T21:47:38Z</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">10.25</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">2012-08-07T21:47:38.157</d:CreateDate><d:ModifiedDate
55
+ m:type="Edm.DateTime">2012-08-07T21:47:38.157</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry>
56
+ http_version: !!null
57
+ recorded_at: Tue, 07 Aug 2012 21:47:38 GMT
58
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,58 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://win7dev:8989/SampleService/RubyOData.svc/Products(1)
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Cache-Control:
22
+ - no-cache
23
+ Content-Length:
24
+ - '1439'
25
+ Content-Type:
26
+ - application/atom+xml;type=entry;charset=utf-8
27
+ Server:
28
+ - Microsoft-IIS/7.5
29
+ Set-Cookie:
30
+ - ASP.NET_SessionId=1jtoo2ua0isload4ewywcbyh; 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
+ - Tue, 07 Aug 2012 21:47:37 GMT
41
+ body:
42
+ encoding: US-ASCII
43
+ string: <?xml version="1.0" encoding="utf-8"?><entry xml:base="http://win7dev: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://win7dev: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>2012-08-07T21:47:38Z</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">10.25</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">2012-08-07T21:47:38.157</d:CreateDate><d:ModifiedDate
55
+ m:type="Edm.DateTime">2012-08-07T21:47:38.157</d:ModifiedDate><d:CreatedBy>Machinist</d:CreatedBy></d:AuditFields></m:properties></content></entry>
56
+ http_version: !!null
57
+ recorded_at: Tue, 07 Aug 2012 21:47:38 GMT
58
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,89 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://win7dev:8989/SampleService/RubyOData.svc/$metadata
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Cache-Control:
22
+ - no-cache
23
+ Content-Length:
24
+ - '4055'
25
+ Content-Type:
26
+ - application/xml;charset=utf-8
27
+ Server:
28
+ - Microsoft-IIS/7.5
29
+ Set-Cookie:
30
+ - ASP.NET_SessionId=tvkikr3xqyy43kcx0mk1uwdr; 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
+ - Tue, 07 Aug 2012 21:47:40 GMT
41
+ body:
42
+ encoding: US-ASCII
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: !!null
88
+ recorded_at: Tue, 07 Aug 2012 21:47:41 GMT
89
+ recorded_with: VCR 2.2.4
@@ -1,3 +1,4 @@
1
+ @complex_types
1
2
  Feature: Complex types
2
3
  In order to fully support OData services
3
4
  As a user of ruby_odata
@@ -12,7 +13,7 @@ Scenario: The proxy must generate classes for complex types if they exist
12
13
 
13
14
  Scenario: Complex properties on an entity must be the correct type
14
15
  Given I call "AddToProducts" on the service with a new "Product" object
15
- And I save changes
16
+ And I save changes
16
17
  And I call "Products" on the service with args: "1"
17
18
  When I run the query
18
19
  Then the first result should have a method: "AuditFields"
@@ -25,10 +26,10 @@ Scenario: Complex properties on an entity must be filled
25
26
  When I run the query
26
27
  Then the first result should have a method: "AuditFields"
27
28
  When I call "CreateDate" for "AuditFields" on the first result
28
- Then the operation should not be null
29
+ Then the operation should not be null
29
30
 
30
31
  # TODO: This scenario should have the AuditFields.CreatedBy field set in the Given
31
- # instead it is set by the blueprint
32
+ # instead it is set by the blueprint
32
33
  Scenario: Complex properties should be able to be added
33
34
  Given I call "AddToProducts" on the service with a new "Product" object
34
35
  And I save changes
@@ -0,0 +1,14 @@
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 "HTTP Error 400"
14
+
@@ -1,7 +1,8 @@
1
+ @query_builder
1
2
  Feature: Query Builder
2
3
  In order to query OData services
3
4
  As a user
4
- I want to be able to perform valid OData protocol operations
5
+ I want to be able to perform valid OData protocol operations
5
6
 
6
7
  Background:
7
8
  Given a HTTP ODataService exists
@@ -12,7 +13,7 @@ Scenario: Navigation Properties should be able to be eager loaded
12
13
  Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
13
14
  And I save changes
14
15
  And I call "AddToProducts" on the service with a new "Product" object with Category: "@@LastSave.first"
15
- And I save changes
16
+ And I save changes
16
17
  And I call "Products" on the service with args: "1"
17
18
  And I expand the query to include "Category"
18
19
  When I run the query
@@ -99,14 +100,14 @@ Scenario: Skip should be allowed on the root level entity
99
100
  | Product 2 |
100
101
  | Product 3 |
101
102
  | Product 4 |
102
- | Product 5 |
103
+ | Product 5 |
103
104
  When I call "Products" on the service
104
105
  And I skip 3
105
106
  And I run the query
106
107
  Then the result should be:
107
108
  | Name |
108
109
  | Product 4 |
109
- | Product 5 |
110
+ | Product 5 |
110
111
 
111
112
 
112
113
  # Top
@@ -117,14 +118,14 @@ Scenario: Top should be allowed on the root level entity
117
118
  | Product 2 |
118
119
  | Product 3 |
119
120
  | Product 4 |
120
- | Product 5 |
121
+ | Product 5 |
121
122
  When I call "Products" on the service
122
123
  And I ask for the top 3
123
124
  And I run the query
124
125
  Then the result should be:
125
126
  | Name |
126
127
  | Product 1 |
127
- | Product 2 |
128
+ | Product 2 |
128
129
  | Product 3 |
129
130
 
130
131
  Scenario: Top should be able to be used along with skip for paging
@@ -134,8 +135,8 @@ Scenario: Top should be able to be used along with skip for paging
134
135
  | Product 2 |
135
136
  | Product 3 |
136
137
  | Product 4 |
137
- | Product 5 |
138
- | Product 6 |
138
+ | Product 5 |
139
+ | Product 6 |
139
140
  When I call "Products" on the service
140
141
  And I skip 2
141
142
  And I ask for the top 2
@@ -143,7 +144,7 @@ Scenario: Top should be able to be used along with skip for paging
143
144
  Then the result should be:
144
145
  | Name |
145
146
  | Product 3 |
146
- | Product 4 |
147
+ | Product 4 |
147
148
 
148
149
 
149
150
  # Links
@@ -160,3 +161,23 @@ Scenario: Navigation Properties should be able to represented as links
160
161
  And I run the query
161
162
  Then the result count should be 3
162
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
+
@@ -1,3 +1,4 @@
1
+ @service
1
2
  Feature: Service Should Generate a Proxy
2
3
  In order to consume the OData
3
4
  As a user
@@ -30,7 +31,7 @@ Scenario: Entity should have the correct accessors
30
31
  When I run the query
31
32
  Then the first result should have a method: "Id"
32
33
  And the first result should have a method: "Name"
33
-
34
+
34
35
  Scenario: Entity should fill values
35
36
  Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
36
37
  And I save changes
@@ -39,9 +40,9 @@ Scenario: Entity should fill values
39
40
  Then the method "Id" on the first result should equal: "1"
40
41
  And the method "Name" on the first result should equal: "Test Category"
41
42
 
42
- Scenario: Navigation Properties should be included in results
43
+ Scenario: Navigation Properties should be included in results
43
44
  Given I call "AddToProducts" on the service with a new "Product" object
44
- And I save changes
45
+ And I save changes
45
46
  And I call "Products" on the service with args: "1"
46
47
  When I run the query
47
48
  Then the first result should have a method: "Category"
@@ -1,3 +1,4 @@
1
+ @service_manage
1
2
  Feature: Service management
2
3
  In order to manage entities
3
4
  As a admin
@@ -9,7 +10,7 @@ Background:
9
10
 
10
11
  Scenario: Service should respond to AddToEntityName for adding objects
11
12
  Given I call "AddToProducts" on the service with a new "Product" object with Name: "Sample Product"
12
- When I save changes
13
+ When I save changes within a cassette named "service_manage_additions"
13
14
  Then the first save result should be of type "Product"
14
15
  And the method "Name" on the first save result should equal: "Sample Product"
15
16
 
@@ -19,7 +20,7 @@ Scenario: Service should allow for deletes
19
20
  Then the first save result should be of type "Product"
20
21
  When I call "delete_object" on the service with the first last save result
21
22
  And I save changes
22
- Then the save result should equal: "true"
23
+ Then the save result should equal: "true"
23
24
  And no "Products" should exist
24
25
 
25
26
  Scenario: Untracked entities shouldn't be able to be deleted
@@ -29,7 +30,7 @@ Scenario: Entities should be able to be updated
29
30
  Given I call "AddToProducts" on the service with a new "Product" object with Name: "Test Product"
30
31
  When I save changes
31
32
  And I call "Products" on the service with args: "1"
32
- And I run the query
33
+ And I run the query within a cassette named "service_manage_deletions"
33
34
  Then the method "Name" on the first result should equal: "Test Product"
34
35
  When I set "Name" on the first result to "Changed Test Product"
35
36
  Then the method "Name" on the first result should equal: "Changed Test Product"
@@ -37,7 +38,7 @@ Scenario: Entities should be able to be updated
37
38
  And I save changes
38
39
  Then the save result should equal: "true"
39
40
  When I call "Products" on the service with args: "1"
40
- And I run the query
41
+ And I run the query within a cassette named "service_manage_deletions_2"
41
42
  Then the method "Name" on the first result should equal: "Changed Test Product"
42
43
 
43
44
  Scenario: Untracked entities shouldn't be able to be updated
@@ -47,7 +48,7 @@ Scenario: Related entities shouldn't be recreated on a child add
47
48
  Given I call "AddToCategories" on the service with a new "Category" object with Name: "Test Category"
48
49
  And I save changes
49
50
  And I call "AddToProducts" on the service with a new "Product" object with Category: "@@LastSave.first"
50
- And I save changes
51
+ And I save changes
51
52
  And I call "Products" on the service with args: "1"
52
53
  And I expand the query to include "Category"
53
54
  When I run the query
@@ -1,3 +1,4 @@
1
+ @service_methods
1
2
  Feature: Service methods
2
3
  In order to use a WCF Data Service more efficiently
3
4
  As a consumer
@@ -5,9 +6,9 @@ Feature: Service methods
5
6
 
6
7
  Background:
7
8
  Given a HTTP ODataService exists
8
- And blueprints exist for the service
9
+ And blueprints exist for the service
10
+
9
11
 
10
-
11
12
  Scenario: A custom web get (no parameters) that returns an entity
12
13
  Given a category exists
13
14
  And I call the service method "EntityCategoryWebGet"
data/features/ssl.feature CHANGED
@@ -1,13 +1,14 @@
1
+ @ssl
1
2
  Feature: Service Should Access Basic Resources via SSL using a self-signed certificate
2
-
3
- Background:
4
- Given a HTTPS BasicAuth ODataService exists using self-signed certificate and username "admin" and password "passwd"
5
- And blueprints exist for the service
6
3
 
7
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
8
7
  Then I should be able to call "Products" on the service
9
8
 
10
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
11
12
  Given I call "AddToCategories" on the service with a new "Category" object with Name: "Auth Test Category"
12
13
  And I save changes
13
14
  And I call "Categories" on the service with args: "1"
@@ -15,7 +16,6 @@ Scenario: Entity should fill values on protected resource
15
16
  Then the method "Id" on the first result should equal: "1"
16
17
  And the method "Name" on the first result should equal: "Auth Test Category"
17
18
 
18
- Scenario: Should get SSL failure if SSL used with self-signed certificate and not passing "false" as :verify_ssl option
19
- Given a HTTPS BasicAuth ODataService exists it should throw an exception with message containing "SSL Verification failed"
20
-
21
-
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"
@@ -2,20 +2,22 @@ STANDARD_URL = "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.
2
2
  BASICAUTH_URL = "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/BasicAuth/RubyOData.svc"
3
3
  HTTPS_BASICAUTH_URL = "https://#{WEBSERVER}:#{HTTPS_PORT_NUMBER}/SampleService/BasicAuth/RubyOData.svc"
4
4
 
5
- When /^(.*) first (last query )?result('s)?(.*)$/ do |pre, last_query, apos, post|
6
- step = "#{pre} #{last_query}result#{apos}#{post}"
5
+ When /^(.*) first (last query )?result(\'s)?(.*)$/ do |pre, last_query, apos, post|
6
+ the_step = "#{pre} #{last_query}result#{apos}#{post}"
7
7
  first_result
8
- When step
8
+ step the_step
9
9
  end
10
10
 
11
11
  When /^(.*) first (last )?save result(.*)$/ do |pre, last, post|
12
- step = "#{pre} #{last}save result#{post}"
12
+ the_step = "#{pre} #{last}save result#{post}"
13
13
  first_save
14
- When step
14
+ step the_step
15
15
  end
16
16
 
17
17
  Given /^a HTTP ODataService exists$/ do
18
- @service = OData::Service.new(STANDARD_URL)
18
+ VCR.use_cassette("unsecured_metadata") do
19
+ @service = OData::Service.new(STANDARD_URL)
20
+ end
19
21
  end
20
22
 
21
23
  Given /^a HTTP BasicAuth ODataService exists$/ do
@@ -30,11 +32,11 @@ Given /^a HTTP BasicAuth ODataService exists using username "([^\"]*)" and passw
30
32
  @service = OData::Service.new(BASICAUTH_URL, { :username => username, :password => password })
31
33
  end
32
34
 
33
- Given /^a HTTP BasicAuth ODataService exists using username "([^\"]*)" and password "([^\"]*)" it should throw an exception with message "([^\"]*)"$/ do |username, password, msg|
35
+ Given /^a HTTP BasicAuth ODataService exists using username "([^\"]*)" and password "([^\"]*)" it should throw an exception with message "([^\"]*)"$/ do |username, password, msg|
34
36
  lambda { @service = OData::Service.new(BASICAUTH_URL, { :username => username, :password => password }) }.should raise_error(msg)
35
37
  end
36
38
 
37
- Given /^a HTTP BasicAuth ODataService exists it should throw an exception with message containing "([^\"]*)"$/ do |msg|
39
+ Given /^a HTTP BasicAuth ODataService exists it should throw an exception with message containing "([^\"]*)"$/ do |msg|
38
40
  lambda { @service = OData::Service.new(BASICAUTH_URL) }.should raise_error(/#{msg}.*/)
39
41
  end
40
42
 
@@ -42,7 +44,7 @@ Given /^a HTTPS BasicAuth ODataService exists it should throw an exception with
42
44
  lambda { @service = OData::Service.new(HTTPS_BASICAUTH_URL) }.should raise_error(/#{msg}.*/)
43
45
  end
44
46
 
45
- Given /^a HTTP BasicAuth ODataService exists it should throw an exception with message "([^\"]*)"$/ do |msg|
47
+ Given /^a HTTP BasicAuth ODataService exists it should throw an exception with message "([^\"]*)"$/ do |msg|
46
48
  lambda { @service = OData::Service.new(BASICAUTH_URL) }.should raise_error(msg)
47
49
  end
48
50
 
@@ -55,7 +57,7 @@ When /^I call "([^\"]*)" on the service$/ do |method|
55
57
  end
56
58
 
57
59
  Then /^the result should be "([^\"]*)"$/ do |result|
58
- @service_result.should eq result
60
+ @service_result.should eq result
59
61
  end
60
62
 
61
63
  Then /^the integer result should be ([^\"]*)$/ do |result|
@@ -122,18 +124,22 @@ When /^I ask for the top (\d+)$/ do |top|
122
124
  @service_query.top(top)
123
125
  end
124
126
 
127
+ When /^I ask for the count$/ do
128
+ @service_query.count
129
+ end
130
+
125
131
  When /^I ask for the links for "([^\"]*)"$/ do |nav_prop|
126
132
  @service_query.links(nav_prop)
127
133
  end
128
134
 
129
135
  Then /^the method "([^\"]*)" on the result should be of type "([^\"]*)"$/ do |method, type|
130
- result = @service_result.send(method.to_sym)
136
+ result = @service_result.send(method.to_sym)
131
137
  result.class.to_s.should eq type
132
138
  end
133
139
 
134
140
  Given /^I call "([^\"]*)" on the service with a new "([^\"]*)" object(?: with (.*))?$/ do |method, object, fields|
135
141
  fields_hash = parse_fields_string(fields)
136
-
142
+
137
143
  obj = object.constantize.send(:make, fields_hash)
138
144
  @service.send(method.to_sym, obj)
139
145
  end
@@ -172,6 +178,10 @@ Given /^I call "([^\"]*)" on the service with a new "([^\"]*)" object it should
172
178
  lambda { @service.send(method.to_sym, obj) }.should raise_error(msg)
173
179
  end
174
180
 
181
+ When /^I save changes it should throw an exception with message containing "([^"]*)"$/ do |msg|
182
+ lambda { @service.save_changes }.should raise_error(/#{msg}.*/)
183
+ end
184
+
175
185
  Then /^no "([^\"]*)" should exist$/ do |collection|
176
186
  @service.send(collection)
177
187
  results = @service.execute
@@ -180,19 +190,19 @@ end
180
190
 
181
191
  Then /^the primitive results should be:$/ do |table|
182
192
  # table is a Cucumber::Ast::Table
183
- values = table.hashes
193
+ values = table.hashes
184
194
  result_table = Cucumber::Ast::Table.new(values)
185
195
  table.diff!(result_table)
186
196
  end
187
197
 
188
198
  Then /^the result should be:$/ do |table|
189
199
  # table is a Cucumber::Ast::Table
190
-
200
+
191
201
  fields = table.hashes[0].keys
192
-
202
+
193
203
  # Build an array of hashes so that we can compare tables
194
204
  results = []
195
-
205
+
196
206
  @service_result.each do |result|
197
207
  obj_hash = Hash.new
198
208
  fields.each do |field|
@@ -200,20 +210,20 @@ Then /^the result should be:$/ do |table|
200
210
  end
201
211
  results << obj_hash
202
212
  end
203
-
213
+
204
214
  result_table = Cucumber::Ast::Table.new(results)
205
-
215
+
206
216
  table.diff!(result_table)
207
217
  end
208
218
 
209
219
  Then /^the save result should be:$/ do |table|
210
220
  # table is a Cucumber::Ast::Table
211
-
221
+
212
222
  fields = table.hashes[0].keys
213
-
223
+
214
224
  # Build an array of hashes so that we can compare tables
215
225
  results = []
216
-
226
+
217
227
  @saved_result.each do |result|
218
228
  obj_hash = Hash.new
219
229
  fields.each do |field|
@@ -221,10 +231,10 @@ Then /^the save result should be:$/ do |table|
221
231
  end
222
232
  results << obj_hash
223
233
  end
224
-
234
+
225
235
  result_table = Cucumber::Ast::Table.new(results)
226
-
227
- table.diff!(result_table)
236
+
237
+ table.diff!(result_table)
228
238
  end
229
239
 
230
240
  Then /^a class named "([^\"]*)" should exist$/ do |klass_name|
@@ -299,4 +309,8 @@ Given /^I call the service method "([^"]*)"(?: with (.*))?$/ do |method, args|
299
309
  else
300
310
  @service_result = @service.send(method)
301
311
  end
312
+ end
313
+
314
+ When /^(.*) within a cassette named "([^"]*)"$/ do |the_step, cassette_name|
315
+ VCR.use_cassette(cassette_name) { step the_step }
302
316
  end
@@ -1,6 +1,4 @@
1
1
  lib = File.expand_path(File.join(File.dirname(__FILE__), "../..", "lib"))
2
2
 
3
3
  require lib + '/ruby_odata'
4
- require 'machinist/object'
5
- require 'sham'
6
- require 'faker'
4
+ require "machinist"
@@ -1,4 +1,5 @@
1
1
  Before do
2
- Sham.reset
3
- RestClient.post "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.svc/CleanDatabaseForTesting", {}
2
+ VCR.use_cassette("clean_database_for_testing") do
3
+ RestClient.post "http://#{WEBSERVER}:#{HTTP_PORT_NUMBER}/SampleService/RubyOData.svc/CleanDatabaseForTesting", {}
4
+ end
4
5
  end