hyperdrive 0.0.5 → 0.0.6
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.
- checksums.yaml +4 -4
- data/.travis.yml +12 -4
- data/Gemfile +2 -0
- data/hyperdrive.gemspec +6 -2
- data/lib/hyperdrive/docs.rb +10 -11
- data/lib/hyperdrive/dsl/resource.rb +10 -15
- data/lib/hyperdrive/dsl.rb +49 -3
- data/lib/hyperdrive/endpoint.rb +65 -0
- data/lib/hyperdrive/errors/missing_required_param.rb +19 -0
- data/lib/hyperdrive/errors/not_acceptable.rb +18 -0
- data/lib/hyperdrive/errors.rb +13 -8
- data/lib/hyperdrive/filter.rb +20 -0
- data/lib/hyperdrive/hateoas.rb +45 -0
- data/lib/hyperdrive/middleware/accept.rb +16 -0
- data/lib/hyperdrive/middleware/content_negotiation.rb +19 -0
- data/lib/hyperdrive/middleware/cors.rb +36 -0
- data/lib/hyperdrive/middleware/error.rb +35 -0
- data/lib/hyperdrive/middleware/request_method.rb +31 -0
- data/lib/hyperdrive/middleware/required_params.rb +35 -0
- data/lib/hyperdrive/middleware/resource.rb +18 -0
- data/lib/hyperdrive/middleware/sanitize_params.rb +25 -0
- data/lib/hyperdrive/middleware.rb +10 -0
- data/lib/hyperdrive/param.rb +44 -0
- data/lib/hyperdrive/resource.rb +74 -30
- data/lib/hyperdrive/server.rb +16 -17
- data/lib/hyperdrive/utils.rb +27 -0
- data/lib/hyperdrive/values.rb +37 -3
- data/lib/hyperdrive/version.rb +1 -1
- data/lib/hyperdrive.rb +21 -7
- data/spec/hyperdrive/docs_spec.rb +14 -8
- data/spec/hyperdrive/dsl/resource_spec.rb +27 -37
- data/spec/hyperdrive/dsl_spec.rb +52 -0
- data/spec/hyperdrive/endpoint_spec.rb +22 -0
- data/spec/hyperdrive/filter_spec.rb +34 -0
- data/spec/hyperdrive/hateoas_spec.rb +42 -0
- data/spec/hyperdrive/middleware/accept_spec.rb +15 -0
- data/spec/hyperdrive/middleware/content_negotiation_spec.rb +29 -0
- data/spec/hyperdrive/middleware/cors_spec.rb +47 -0
- data/spec/hyperdrive/middleware/error_spec.rb +25 -0
- data/spec/hyperdrive/middleware/request_method_spec.rb +28 -0
- data/spec/hyperdrive/middleware/required_params_spec.rb +43 -0
- data/spec/hyperdrive/middleware/resource_spec.rb +15 -0
- data/spec/hyperdrive/middleware/sanitize_params_spec.rb +24 -0
- data/spec/hyperdrive/param_spec.rb +34 -0
- data/spec/hyperdrive/resource_spec.rb +87 -25
- data/spec/hyperdrive/server_spec.rb +48 -7
- data/spec/hyperdrive/utils_spec.rb +38 -0
- data/spec/hyperdrive/values_spec.rb +37 -0
- data/spec/spec_helper.rb +71 -12
- metadata +106 -11
- data/.coveralls.yml +0 -1
- data/lib/hyperdrive/dsl/main.rb +0 -19
- data/lib/hyperdrive/response.rb +0 -42
- data/spec/hyperdrive/dsl/main_spec.rb +0 -16
- data/spec/hyperdrive/response_spec.rb +0 -23
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Middleware::ContentNegotiation do
|
6
|
+
def app
|
7
|
+
Rack::Builder.new do
|
8
|
+
use Hyperdrive::Middleware::ContentNegotiation
|
9
|
+
map '/' do
|
10
|
+
run ->(env) { [200, {}, ["#{env['hyperdrive.media_type']}"]] }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
@resource = default_resource
|
17
|
+
@env = default_rack_env(@resource)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns the best supported media type" do
|
21
|
+
get '/', {}, @env
|
22
|
+
last_response.body.must_equal 'application/vnd.hyperdrive.things+hal+json'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "throws an error if the media type requested is not supported" do
|
26
|
+
bad_env = @env.merge('hyperdrive.accept' => Rack::Accept::MediaType.new('application/xml'), 'HTTP_ACCEPT' => 'application/xml')
|
27
|
+
-> { get '/', {}, bad_env }.must_raise Hyperdrive::Errors::NotAcceptable
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Middleware::CORS do
|
6
|
+
def app
|
7
|
+
cors_options = {
|
8
|
+
origins: '*',
|
9
|
+
allow_headers: '*, Content-Type, Accept, AUTHORIZATION, Cache-Control',
|
10
|
+
credentials: true,
|
11
|
+
expose_headers: 'Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma',
|
12
|
+
max_age: 86400
|
13
|
+
}
|
14
|
+
inner_app = ->(env) { [200, {}, ['']] }
|
15
|
+
Hyperdrive::Middleware::CORS.new(inner_app, cors_options)
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
env = default_rack_env(default_resource)
|
20
|
+
get '/', {}, env
|
21
|
+
@headers = last_response.headers
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allows origins" do
|
25
|
+
@headers['Access-Control-Allow-Origin'].must_equal '*'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "allows methods" do
|
29
|
+
@headers['Access-Control-Allow-Methods'].must_equal 'OPTIONS, GET, HEAD'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "allows headers" do
|
33
|
+
@headers['Access-Control-Allow-Headers'].must_equal '*, Content-Type, Accept, AUTHORIZATION, Cache-Control'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "allows credentials" do
|
37
|
+
@headers['Access-Control-Allow-Credentials'].must_equal "true"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "has a max age" do
|
41
|
+
@headers['Access-Control-Max-Age'].must_equal "86400"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "exposes headers" do
|
45
|
+
@headers['Access-Control-Expose-Headers'].must_equal 'Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma'
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Middleware::Error do
|
6
|
+
def app
|
7
|
+
Rack::Builder.new do
|
8
|
+
use Hyperdrive::Middleware::Error
|
9
|
+
run ->(env) { raise Hyperdrive::Errors::HTTPError }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
@response = %Q({"_links":{"root":{"href":"/","title":"API Root"}},"error":{"type":"HTTPError","message":"Hyperdrive::Errors::HTTPError"}})
|
15
|
+
get '/'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "traps errors" do
|
19
|
+
last_response.status.must_equal 500
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns a formatted error message" do
|
23
|
+
last_response.body.must_equal @response
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Middleware::RequestMethod do
|
6
|
+
def app
|
7
|
+
inner_app = ->(env) { [200, {}, ['']] }
|
8
|
+
Hyperdrive::Middleware::RequestMethod.new(inner_app)
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
@resource = default_resource
|
13
|
+
@env = default_rack_env(@resource)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "is successful if the request method is supported" do
|
17
|
+
get '/', {}, @env
|
18
|
+
last_response.successful?.must_equal true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "throws an error if hyperdrive doesn't support the request method" do
|
22
|
+
->{ request('/', @env.merge('REQUEST_METHOD' => 'TRACE')) }.must_raise Hyperdrive::Errors::NotImplemented
|
23
|
+
end
|
24
|
+
|
25
|
+
it "throws an error if the resource doesn't support the request method" do
|
26
|
+
->{ post('/', {}, @env.merge('REQUEST_METHOD' => 'POST')) }.must_raise Hyperdrive::Errors::MethodNotAllowed
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Middleware::RequiredParams do
|
6
|
+
def app
|
7
|
+
inner_app = ->(env) { [200, {}, [env['hyperdrive.params'][:id]]] }
|
8
|
+
Hyperdrive::Middleware::RequiredParams.new(inner_app)
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
@resource = default_resource
|
13
|
+
@env = default_rack_env(@resource).merge('hyperdrive.params' => {})
|
14
|
+
@filters = { parent_id: '1000' }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "Filters" do
|
18
|
+
it "responds successfully if required filter is present" do
|
19
|
+
get '/', @filters, @env.merge('hyperdrive.params' => @filters)
|
20
|
+
last_response.successful?.must_equal true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "raises an error if required filter is missing" do
|
24
|
+
->{ get '/', {}, @env }.must_raise Hyperdrive::Errors::MissingRequiredParam
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "Params" do
|
29
|
+
before do
|
30
|
+
@env.merge!('REQUEST_METHOD' => 'PUT')
|
31
|
+
@params = { id: '1001', name: 'yoda' }
|
32
|
+
end
|
33
|
+
|
34
|
+
it "responds successfully if required params are present" do
|
35
|
+
put '/', @params, @env.merge('hyperdrive.params' => @params)
|
36
|
+
last_response.successful?.must_equal true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "raises an error if required param is missing" do
|
40
|
+
->{ put '/', {}, @env }.must_raise Hyperdrive::Errors::MissingRequiredParam
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Middleware::Resource do
|
6
|
+
def app
|
7
|
+
inner_app = ->(env) { [200, {}, [env['hyperdrive.resource'].namespace]] }
|
8
|
+
Hyperdrive::Middleware::Resource.new(inner_app, default_resource)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "adds the requested resource to rack's env" do
|
12
|
+
get '/'
|
13
|
+
last_response.body.must_equal "things"
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Middleware::SanitizeParams do
|
6
|
+
before do
|
7
|
+
@env = default_rack_env(default_resource)
|
8
|
+
end
|
9
|
+
|
10
|
+
def app
|
11
|
+
inner_app = ->(env) { [200, {}, [env['hyperdrive.params']]] }
|
12
|
+
Hyperdrive::Middleware::SanitizeParams.new(inner_app)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "will sanitize filters" do
|
16
|
+
get '/', { 'id' => '1001', 'removed' => 'me' }, @env
|
17
|
+
last_response.body.must_equal "{:id=>\"1001\"}"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "will sanitize params" do
|
21
|
+
post '/', { 'id' => '1001', 'removed' => 'me' }, @env
|
22
|
+
last_response.body.must_equal "{:id=>\"1001\"}"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Param do
|
6
|
+
before do
|
7
|
+
@param = default_param
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has a name" do
|
11
|
+
@param.name.must_equal 'id'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a description" do
|
15
|
+
@param.description.must_equal 'Identifier'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns an array of HTTP methods it's required for" do
|
19
|
+
@param.required.must_equal %w(PUT PATCH DELETE)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns true if the param is required for the given HTTP method" do
|
23
|
+
@param.required?('PUT').must_equal true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns false if the param is not required for the given HTTP method" do
|
27
|
+
@param.required?('POST').must_equal false
|
28
|
+
end
|
29
|
+
|
30
|
+
it "converts itself as a hash" do
|
31
|
+
constraints = { name: 'id', description: 'Identifier', type: 'String', constraints: 'Required for: PUT, PATCH, DELETE. Must be a valid BSON Object ID.' }
|
32
|
+
@param.to_hash.must_equal constraints
|
33
|
+
end
|
34
|
+
end
|
@@ -2,7 +2,27 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Hyperdrive::Resource do
|
4
4
|
before do
|
5
|
-
@resource = Hyperdrive::Resource.new(:thing)
|
5
|
+
@resource = Hyperdrive::Resource.new(:thing, { vendor: 'hyperdrive', media_types: ['json'] })
|
6
|
+
@resource.register_param(:name, 'Thing Name')
|
7
|
+
@resource.register_filter(:parent_id, 'Parent ID', required: true)
|
8
|
+
@resource.register_request_handler(:get, Proc.new { |env| 'v1' })
|
9
|
+
@resource.register_request_handler(:get, Proc.new { |env| 'v2' }, 'v2')
|
10
|
+
@media_types = ["application/vnd.hyperdrive.things.v2+json",
|
11
|
+
"application/vnd.hyperdrive.things.v1+json",
|
12
|
+
"application/vnd.hyperdrive.things+json",
|
13
|
+
"application/vnd.hyperdrive+json"]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has an ID" do
|
17
|
+
@resource.id.must_equal "hyperdrive:things"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has a namespace" do
|
21
|
+
@resource.namespace.must_equal 'things'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has an endpoint" do
|
25
|
+
@resource.endpoint.must_equal '/things'
|
6
26
|
end
|
7
27
|
|
8
28
|
it "has a name" do
|
@@ -11,57 +31,99 @@ describe Hyperdrive::Resource do
|
|
11
31
|
end
|
12
32
|
|
13
33
|
it "has a description" do
|
14
|
-
@resource.
|
15
|
-
@resource.
|
34
|
+
@resource.description = 'Thing Description'
|
35
|
+
@resource.description.must_equal 'Thing Description'
|
16
36
|
end
|
17
37
|
|
18
|
-
it "
|
19
|
-
@resource.
|
38
|
+
it "auto-registers the :id param" do
|
39
|
+
@resource.params[:id].description.must_equal 'Identifier'
|
20
40
|
end
|
21
41
|
|
22
|
-
it "
|
23
|
-
@resource.
|
24
|
-
@resource.allowed_params[:id][:required].must_equal %w(PUT PATCH DELETE)
|
42
|
+
it "registers a param" do
|
43
|
+
@resource.params[:name].description.must_equal 'Thing Name'
|
25
44
|
end
|
26
45
|
|
27
|
-
it "
|
28
|
-
@resource.
|
29
|
-
|
30
|
-
|
46
|
+
it "returns true if the param is required for the given HTTP Method" do
|
47
|
+
@resource.required_param?(:name, 'POST').must_equal true
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns false if the param is not required for the given HTTP Method" do
|
51
|
+
@resource.required_param?(:name, 'DELETE').must_equal false
|
31
52
|
end
|
32
53
|
|
33
54
|
it "auto-registers the :id filter" do
|
34
|
-
@resource.filters[:id]
|
35
|
-
@resource.filters[:id][:required].must_equal false
|
55
|
+
@resource.filters[:id].description.must_equal 'Resource Identifier'
|
36
56
|
end
|
37
57
|
|
38
58
|
it "registers a filter" do
|
39
|
-
@resource.
|
40
|
-
|
41
|
-
|
59
|
+
@resource.filters[:parent_id].description.must_equal 'Parent ID'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns true if the filter is required for the given HTTP Method" do
|
63
|
+
@resource.required_filter?(:parent_id, 'GET').must_equal true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns false if the filter is not required for the given HTTP Method" do
|
67
|
+
@resource.required_filter?(:parent_id, 'OPTIONS').must_equal false
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns true if the param (or filter) is required" do
|
71
|
+
@resource.required?(:name, 'POST').must_equal true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns true if the filter (or param) is required" do
|
75
|
+
@resource.required?(:parent_id, 'GET').must_equal true
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns false if the param (or filter) is not required" do
|
79
|
+
@resource.required?(:name, 'GET').must_equal false
|
42
80
|
end
|
43
81
|
|
44
|
-
it "
|
45
|
-
@resource.
|
46
|
-
|
82
|
+
it "returns false if the filter (or param) is not required" do
|
83
|
+
@resource.required?(:parent_id, 'DELETE').must_equal false
|
84
|
+
end
|
85
|
+
|
86
|
+
it "registers a request handler" do
|
87
|
+
@resource.request_handlers[:get]['v1'].must_be :===, Proc
|
88
|
+
end
|
89
|
+
|
90
|
+
it "auto-registers HEAD request handler when GET handler is registered" do
|
91
|
+
@resource.request_handlers[:head]['v1'].must_be :===, Proc
|
47
92
|
end
|
48
93
|
|
49
94
|
it "returns the specified request handler" do
|
50
|
-
@resource.
|
51
|
-
@resource.request_handler('GET').call.must_equal 'ok'
|
95
|
+
@resource.request_handler('GET').must_be :===, Proc
|
52
96
|
end
|
53
97
|
|
54
98
|
it "returns true if the request can be handled" do
|
55
|
-
@resource.define_request_handler(:get, Proc.new { return 'ok' })
|
56
99
|
@resource.request_method_allowed?('GET').must_equal true
|
57
100
|
end
|
58
101
|
|
59
102
|
it "returns false if the request can not be handled" do
|
60
|
-
@resource.request_method_allowed?('
|
103
|
+
@resource.request_method_allowed?('POST').must_equal false
|
61
104
|
end
|
62
105
|
|
63
106
|
it "returns the request methods that can handled" do
|
64
|
-
@resource.define_request_handler(:get, Proc.new { return 'ok' })
|
65
107
|
@resource.allowed_methods.must_equal ['OPTIONS','GET','HEAD']
|
66
108
|
end
|
109
|
+
|
110
|
+
it "returns the request handler for the specified version" do
|
111
|
+
@resource.request_handler('GET', 'v2').must_be :===, Proc
|
112
|
+
end
|
113
|
+
|
114
|
+
it "returns the acceptable content types" do
|
115
|
+
@resource.acceptable_content_types('GET').must_equal @media_types
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns the available versions for this resource" do
|
119
|
+
@resource.available_versions('GET').must_equal ['v2','v1']
|
120
|
+
end
|
121
|
+
|
122
|
+
it "returns the latest available version for this resource" do
|
123
|
+
@resource.latest_version('GET').must_equal 'v2'
|
124
|
+
end
|
125
|
+
|
126
|
+
it "returns a hash representation of the resource" do
|
127
|
+
@resource.to_hash.must_be_kind_of Hash
|
128
|
+
end
|
67
129
|
end
|
@@ -1,11 +1,52 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require 'spec_helper'
|
4
|
+
|
3
5
|
describe Hyperdrive::Server do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
def app
|
7
|
+
Hyperdrive::Server
|
8
|
+
end
|
9
|
+
|
10
|
+
before do
|
11
|
+
sample_api
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
hyperdrive.send(:reset!)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "responds to GET requests successfully" do
|
19
|
+
get '/things', { parent_id: 42 }
|
20
|
+
last_response.successful?.must_equal true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "responds to HEAD requests successfully" do
|
24
|
+
head '/things', { parent_id: 42 }
|
25
|
+
last_response.successful?.must_equal true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "responds to OPTIONS requests successfully" do
|
29
|
+
options '/things'
|
30
|
+
last_response.successful?.must_equal true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "responds to POST requests successfully" do
|
34
|
+
post '/things', { name: 'bender' }
|
35
|
+
last_response.successful?.must_equal true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "responds to PUT requests successfully" do
|
39
|
+
put '/things', { id: 1, name: 'bender' }
|
40
|
+
last_response.successful?.must_equal true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "responds to PATCH requests successfully" do
|
44
|
+
patch '/things', { id: 1, name: 'bender' }
|
45
|
+
last_response.successful?.must_equal true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "responds to DELETE requests successfully" do
|
49
|
+
delete '/things', { id: 1 }
|
50
|
+
last_response.successful?.must_equal true
|
51
|
+
end
|
11
52
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Utils do
|
6
|
+
context '.sanitize_keys' do
|
7
|
+
before do
|
8
|
+
@subject = Hyperdrive::Utils.sanitize_keys([:keep], { keep: 'this', remove: 'that' })
|
9
|
+
end
|
10
|
+
|
11
|
+
it "removes keys that were specified from the given hash" do
|
12
|
+
@subject.key?(:remove).must_equal false
|
13
|
+
end
|
14
|
+
|
15
|
+
it "keeps keys that were not specified from the given hash" do
|
16
|
+
@subject.key?(:keep).must_equal true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context '.symbolize_keys' do
|
21
|
+
before do
|
22
|
+
@hash = { 'string' => 'cheese', 'collection' => [{'skylanders' => 155}], 'map' => { 'oceans' => 'blue' } }
|
23
|
+
@subject = Hyperdrive::Utils.symbolize_keys(@hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can symbolize the keys of a hash" do
|
27
|
+
@subject[:string].must_equal 'cheese'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can symbolize the keys of nested hashes" do
|
31
|
+
@subject[:map][:oceans].must_equal 'blue'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can symbolize the keys of arrays of hashes" do
|
35
|
+
@subject[:collection].first[:skylanders].must_equal 155
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hyperdrive::Values do
|
6
|
+
before do
|
7
|
+
@values = Hyperdrive::Values
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns a list of request methods that are definable" do
|
11
|
+
@values.definable_request_methods.must_be_kind_of Array
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns a list of request_methods that are supported" do
|
15
|
+
@values.supported_request_methods.must_be_kind_of Array
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns a map of request methods to http request methods" do
|
19
|
+
@values.request_methods.must_be_kind_of Hash
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns a map of http request methods to request methods" do
|
23
|
+
@values.http_request_methods.must_be_kind_of Hash
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns a map of default cors options" do
|
27
|
+
@values.default_cors_options.must_be_kind_of Hash
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns a map of default config options" do
|
31
|
+
@values.default_cors_options.must_be_kind_of Hash
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns a map of default headers" do
|
35
|
+
@values.default_cors_options.must_be_kind_of Hash
|
36
|
+
end
|
37
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require 'rubinius/coverage' if RUBY_ENGINE == 'rubinius'
|
4
|
+
require "codeclimate-test-reporter"
|
5
|
+
CodeClimate::TestReporter.start
|
6
|
+
|
3
7
|
# bootstrap the environment
|
4
8
|
ENV['RACK_ENV'] = 'test'
|
5
9
|
lib_path = File.expand_path('../lib', __FILE__)
|
@@ -13,27 +17,82 @@ Bundler.setup(:default, ENV['RACK_ENV'])
|
|
13
17
|
require 'hyperdrive'
|
14
18
|
|
15
19
|
# Fire up the BDD Stack
|
20
|
+
require 'rack/test'
|
16
21
|
require 'minitest/autorun'
|
17
22
|
require "minitest-spec-context"
|
18
23
|
require 'minitest/reporters'
|
19
24
|
|
20
25
|
# all systems go
|
21
26
|
MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new
|
22
|
-
|
27
|
+
include Rack::Test::Methods
|
28
|
+
|
29
|
+
module Hyperdrive
|
30
|
+
module TestData
|
31
|
+
def default_rack_env(resource = nil)
|
32
|
+
default_env = {
|
33
|
+
"rack.version" => Rack::VERSION,
|
34
|
+
"rack.input" => StringIO.new,
|
35
|
+
"rack.errors" => StringIO.new,
|
36
|
+
"rack.multithread" => true,
|
37
|
+
"rack.multiprocess" => true,
|
38
|
+
"rack.run_once" => false,
|
39
|
+
'HTTP_ACCEPT_CHARSET' => 'UTF-8',
|
40
|
+
'HTTP_ACCEPT' => 'application/vnd.hyperdrive.things+hal+json;q=0.8, application/json;q=1',
|
41
|
+
'HTTP_ACCEPT_LANGUAGE' => 'en',
|
42
|
+
'REQUEST_METHOD' => 'GET',
|
43
|
+
'QUERY_STRING' => 'id=1001'
|
44
|
+
}
|
45
|
+
default_env.merge!('hyperdrive.accept' => Rack::Accept::MediaType.new(default_env['HTTP_ACCEPT']))
|
46
|
+
default_env.merge!('hyperdrive.resource' => resource) if resource
|
47
|
+
default_env
|
48
|
+
end
|
49
|
+
|
50
|
+
def default_resource
|
51
|
+
resource = Hyperdrive::Resource.new(:thing, { vendor: 'hyperdrive', media_types: ['hal+json', 'json'] })
|
52
|
+
resource.register_request_handler(:get, Proc.new { |env| }, 'v1')
|
53
|
+
resource.register_filter(:parent_id, '', required: true)
|
54
|
+
resource
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_filter
|
58
|
+
Hyperdrive::Filter.new(:parent_id, 'Parent Identifier', required: true, constraints: 'Must be a valid BSON Object ID.')
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_param
|
62
|
+
Hyperdrive::Param.new(:id, 'Identifier', required: %w(PUT PATCH DELETE), constraints: 'Must be a valid BSON Object ID.')
|
63
|
+
end
|
64
|
+
|
65
|
+
def sample_api
|
66
|
+
hyperdrive do
|
67
|
+
resource(:thing) do
|
68
|
+
name 'Thing Resource'
|
69
|
+
description 'Description of Thing Resource'
|
70
|
+
|
71
|
+
param :name, '50 Chars or less', required: true
|
72
|
+
filter :parent_id, 'Parent ID of Thing', required: true
|
73
|
+
|
74
|
+
request(:get) do
|
75
|
+
'ok'
|
76
|
+
end
|
77
|
+
|
78
|
+
request(:post) do
|
79
|
+
'ok'
|
80
|
+
end
|
23
81
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
name 'Thing Resource'
|
28
|
-
desc 'Description of Thing Resource'
|
82
|
+
request(:put) do
|
83
|
+
'ok'
|
84
|
+
end
|
29
85
|
|
30
|
-
|
31
|
-
|
32
|
-
|
86
|
+
request(:patch) do
|
87
|
+
'ok'
|
88
|
+
end
|
33
89
|
|
34
|
-
|
35
|
-
|
36
|
-
|
90
|
+
request(:delete) do
|
91
|
+
''
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
37
95
|
end
|
38
96
|
end
|
39
97
|
end
|
98
|
+
include Hyperdrive::TestData
|