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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -4
  3. data/Gemfile +2 -0
  4. data/hyperdrive.gemspec +6 -2
  5. data/lib/hyperdrive/docs.rb +10 -11
  6. data/lib/hyperdrive/dsl/resource.rb +10 -15
  7. data/lib/hyperdrive/dsl.rb +49 -3
  8. data/lib/hyperdrive/endpoint.rb +65 -0
  9. data/lib/hyperdrive/errors/missing_required_param.rb +19 -0
  10. data/lib/hyperdrive/errors/not_acceptable.rb +18 -0
  11. data/lib/hyperdrive/errors.rb +13 -8
  12. data/lib/hyperdrive/filter.rb +20 -0
  13. data/lib/hyperdrive/hateoas.rb +45 -0
  14. data/lib/hyperdrive/middleware/accept.rb +16 -0
  15. data/lib/hyperdrive/middleware/content_negotiation.rb +19 -0
  16. data/lib/hyperdrive/middleware/cors.rb +36 -0
  17. data/lib/hyperdrive/middleware/error.rb +35 -0
  18. data/lib/hyperdrive/middleware/request_method.rb +31 -0
  19. data/lib/hyperdrive/middleware/required_params.rb +35 -0
  20. data/lib/hyperdrive/middleware/resource.rb +18 -0
  21. data/lib/hyperdrive/middleware/sanitize_params.rb +25 -0
  22. data/lib/hyperdrive/middleware.rb +10 -0
  23. data/lib/hyperdrive/param.rb +44 -0
  24. data/lib/hyperdrive/resource.rb +74 -30
  25. data/lib/hyperdrive/server.rb +16 -17
  26. data/lib/hyperdrive/utils.rb +27 -0
  27. data/lib/hyperdrive/values.rb +37 -3
  28. data/lib/hyperdrive/version.rb +1 -1
  29. data/lib/hyperdrive.rb +21 -7
  30. data/spec/hyperdrive/docs_spec.rb +14 -8
  31. data/spec/hyperdrive/dsl/resource_spec.rb +27 -37
  32. data/spec/hyperdrive/dsl_spec.rb +52 -0
  33. data/spec/hyperdrive/endpoint_spec.rb +22 -0
  34. data/spec/hyperdrive/filter_spec.rb +34 -0
  35. data/spec/hyperdrive/hateoas_spec.rb +42 -0
  36. data/spec/hyperdrive/middleware/accept_spec.rb +15 -0
  37. data/spec/hyperdrive/middleware/content_negotiation_spec.rb +29 -0
  38. data/spec/hyperdrive/middleware/cors_spec.rb +47 -0
  39. data/spec/hyperdrive/middleware/error_spec.rb +25 -0
  40. data/spec/hyperdrive/middleware/request_method_spec.rb +28 -0
  41. data/spec/hyperdrive/middleware/required_params_spec.rb +43 -0
  42. data/spec/hyperdrive/middleware/resource_spec.rb +15 -0
  43. data/spec/hyperdrive/middleware/sanitize_params_spec.rb +24 -0
  44. data/spec/hyperdrive/param_spec.rb +34 -0
  45. data/spec/hyperdrive/resource_spec.rb +87 -25
  46. data/spec/hyperdrive/server_spec.rb +48 -7
  47. data/spec/hyperdrive/utils_spec.rb +38 -0
  48. data/spec/hyperdrive/values_spec.rb +37 -0
  49. data/spec/spec_helper.rb +71 -12
  50. metadata +106 -11
  51. data/.coveralls.yml +0 -1
  52. data/lib/hyperdrive/dsl/main.rb +0 -19
  53. data/lib/hyperdrive/response.rb +0 -42
  54. data/spec/hyperdrive/dsl/main_spec.rb +0 -16
  55. 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.desc = 'Description of Thing Resource'
15
- @resource.desc.must_equal 'Description of Thing Resource'
34
+ @resource.description = 'Thing Description'
35
+ @resource.description.must_equal 'Thing Description'
16
36
  end
17
37
 
18
- it "has an endpoint" do
19
- @resource.endpoint.must_equal '/things'
38
+ it "auto-registers the :id param" do
39
+ @resource.params[:id].description.must_equal 'Identifier'
20
40
  end
21
41
 
22
- it "auto-registers the :id param" do
23
- @resource.allowed_params[:id][:desc].must_equal 'Resource Identifier'
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 "registers an allowed param" do
28
- @resource.register_param(:name, "Thing's Name")
29
- @resource.allowed_params[:name][:desc].must_equal "Thing's Name"
30
- @resource.allowed_params[:name][:required].must_equal true
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][:desc].must_equal 'Resource Identifier'
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.register_filter(:parent_id, 'Parent ID of Thing', required: true)
40
- @resource.filters[:parent_id][:desc].must_equal 'Parent ID of Thing'
41
- @resource.filters[:parent_id][:required].must_equal true
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 "defines a request handler" do
45
- @resource.define_request_handler(:get, Proc.new { return 'ok' })
46
- @resource.request_handlers[:get].call.must_equal 'ok'
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.define_request_handler(:get, Proc.new { return 'ok' })
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?('GET').must_equal false
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
- it "handles GET requests successfully"
5
- it "handles HEAD requests successfully"
6
- it "handles OPTIONS requests successfully"
7
- it "handles POST requests successfully"
8
- it "handles PUT requests successfully"
9
- it "handles PATCH requests successfully"
10
- it "handles DELETE requests successfully"
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
- #include Rack::Test::Methods
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
- def sample_api
25
- hyperdrive do
26
- resource(:thing) do
27
- name 'Thing Resource'
28
- desc 'Description of Thing Resource'
82
+ request(:put) do
83
+ 'ok'
84
+ end
29
85
 
30
- param :name, '50 Chars or less'
31
- param :start_date, 'Format: YYYY-MM-DD', required: false
32
- param :end_date, 'Format: YYYY-MM-DD', required: false
86
+ request(:patch) do
87
+ 'ok'
88
+ end
33
89
 
34
- filter :start_date, 'Format: YYYY-MM-DD'
35
- filter :end_date, 'Format: YYYY-MM-DD'
36
- filter :parent_id, 'Parent ID of Thing', required: true
90
+ request(:delete) do
91
+ ''
92
+ end
93
+ end
94
+ end
37
95
  end
38
96
  end
39
97
  end
98
+ include Hyperdrive::TestData