apill 3.1.3 → 4.0.0

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/apill/configuration.rb +2 -1
  3. data/lib/apill/errors/{invalid_api_request_error.rb → invalid_api_request.rb} +1 -1
  4. data/lib/apill/errors/{invalid_subdomain_error.rb → invalid_subdomain.rb} +1 -1
  5. data/lib/apill/errors/invalid_token.rb +21 -0
  6. data/lib/apill/matchers/accept_header.rb +13 -0
  7. data/lib/apill/matchers/{generic_matcher.rb → generic.rb} +5 -9
  8. data/lib/apill/matchers/{subdomain_matcher.rb → subdomain.rb} +3 -9
  9. data/lib/apill/matchers/{version_matcher.rb → version.rb} +4 -6
  10. data/lib/apill/middleware/api_request.rb +22 -21
  11. data/lib/apill/parameters/index.rb +1 -1
  12. data/lib/apill/parameters/page.rb +1 -1
  13. data/lib/apill/parameters/sort.rb +1 -1
  14. data/lib/apill/requests/base.rb +86 -10
  15. data/lib/apill/requests/rack.rb +34 -0
  16. data/lib/apill/requests/rails.rb +31 -0
  17. data/lib/apill/resource/model.rb +1 -1
  18. data/lib/apill/resource/processors/filtering.rb +2 -0
  19. data/lib/apill/resource/processors/indexing.rb +2 -0
  20. data/lib/apill/resource/processors/paging.rb +2 -0
  21. data/lib/apill/resource/processors/sorting.rb +2 -0
  22. data/lib/apill/responses/{invalid_subdomain_response.rb → invalid_api_request.rb} +3 -3
  23. data/lib/apill/responses/{invalid_api_request_response.rb → invalid_subdomain.rb} +3 -3
  24. data/lib/apill/responses/invalid_token.rb +17 -0
  25. data/lib/apill/tokens/invalid_request_authorization.rb +21 -0
  26. data/lib/apill/tokens/null_request_authorization.rb +21 -0
  27. data/lib/apill/tokens/request_authorization.rb +62 -0
  28. data/lib/apill/version.rb +1 -1
  29. data/lib/apill.rb +5 -5
  30. data/spec/apill/accept_header_spec.rb +1 -1
  31. data/spec/apill/errors/{invalid_api_request_error_spec.rb → invalid_api_request_spec.rb} +6 -6
  32. data/spec/apill/errors/{invalid_subdomain_error_spec.rb → invalid_subdomain_spec.rb} +6 -6
  33. data/spec/apill/errors/invalid_token_spec.rb +23 -0
  34. data/spec/apill/{invalid_subdomain_response_spec.rb → invalid_subdomain_spec.rb} +7 -7
  35. data/spec/apill/invalid_token_spec.rb +42 -0
  36. data/spec/apill/matchers/{accept_header_matcher_spec.rb → accept_header_spec.rb} +32 -24
  37. data/spec/apill/matchers/subdomain_spec.rb +81 -0
  38. data/spec/apill/matchers/{version_matcher_spec.rb → version_spec.rb} +31 -20
  39. data/spec/apill/middleware/api_request_spec.rb +36 -38
  40. data/spec/apill/parameters_spec.rb +1 -1
  41. data/spec/apill/requests/rack_spec.rb +159 -0
  42. data/spec/apill/requests/rails_spec.rb +151 -0
  43. data/spec/apill/resource/model_spec.rb +1 -1
  44. data/spec/apill/resource/processors/filtering_spec.rb +1 -1
  45. data/spec/apill/resource/processors/indexing_spec.rb +1 -1
  46. data/spec/apill/resource/processors/paging_spec.rb +1 -1
  47. data/spec/apill/resource/processors/sorting_spec.rb +1 -1
  48. data/spec/apill/tokens/request_authorization_spec.rb +49 -0
  49. data/spec/fixtures/test_rsa_key +27 -0
  50. data/spec/fixtures/test_rsa_key.pub +9 -0
  51. data/spec/spec_helper.rb +3 -0
  52. data/spec/support/private_keys.rb +19 -0
  53. metadata +75 -29
  54. data/lib/apill/matchers/accept_header_matcher.rb +0 -15
  55. data/lib/apill/requests/rack_request.rb +0 -37
  56. data/lib/apill/requests/rails_request.rb +0 -29
  57. data/spec/apill/matchers/subdomain_matcher_spec.rb +0 -72
  58. data/spec/apill/requests/rack_request_spec.rb +0 -70
  59. data/spec/apill/requests/rails_request_spec.rb +0 -59
data/lib/apill.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  require 'apill/version'
2
2
 
3
3
  require 'apill/configuration'
4
- require 'apill/matchers/accept_header_matcher'
5
- require 'apill/matchers/subdomain_matcher'
6
- require 'apill/matchers/version_matcher'
4
+ require 'apill/matchers/accept_header'
5
+ require 'apill/matchers/subdomain'
6
+ require 'apill/matchers/version'
7
7
  require 'apill/resource'
8
8
  require 'apill/serializers/json_api'
9
9
 
10
10
  require 'apill/middleware/api_request'
11
11
 
12
- require 'apill/responses/invalid_api_request_response'
13
- require 'apill/responses/invalid_subdomain_response'
12
+ require 'apill/responses/invalid_api_request'
13
+ require 'apill/responses/invalid_subdomain'
@@ -1,4 +1,4 @@
1
- require 'rspectacular'
1
+ require 'spec_helper'
2
2
  require 'apill/accept_header'
3
3
 
4
4
  module Apill
@@ -1,17 +1,17 @@
1
- require 'rspectacular'
2
- require 'apill/errors/invalid_api_request_error'
1
+ require 'spec_helper'
2
+ require 'apill/errors/invalid_api_request'
3
3
 
4
4
  module Apill
5
5
  module Errors
6
- describe InvalidApiRequestError do
7
- let(:error) { InvalidApiRequestError.new }
6
+ describe InvalidApiRequest do
7
+ let(:error) { InvalidApiRequest.new }
8
8
 
9
9
  it 'has a status of 400' do
10
10
  expect(error.http_status).to eql 400
11
11
  end
12
12
 
13
13
  it 'has a code' do
14
- expect(error.code).to eql 'errors.invalid_api_request_error'
14
+ expect(error.code).to eql 'errors.invalid_api_request'
15
15
  end
16
16
 
17
17
  it 'can output the detail' do
@@ -21,7 +21,7 @@ describe InvalidApiRequestError do
21
21
  end
22
22
 
23
23
  it 'can output the source' do
24
- error = InvalidApiRequestError.new accept_header: 'foo'
24
+ error = InvalidApiRequest.new accept_header: 'foo'
25
25
 
26
26
  expect(error.source).to eql(accept_header: 'foo')
27
27
  end
@@ -1,17 +1,17 @@
1
- require 'rspectacular'
2
- require 'apill/errors/invalid_subdomain_error'
1
+ require 'spec_helper'
2
+ require 'apill/errors/invalid_subdomain'
3
3
 
4
4
  module Apill
5
5
  module Errors
6
- describe InvalidSubdomainError do
7
- let(:error) { InvalidSubdomainError.new }
6
+ describe InvalidSubdomain do
7
+ let(:error) { InvalidSubdomain.new }
8
8
 
9
9
  it 'has a status of 404' do
10
10
  expect(error.http_status).to eql 404
11
11
  end
12
12
 
13
13
  it 'has a code' do
14
- expect(error.code).to eql 'errors.invalid_subdomain_error'
14
+ expect(error.code).to eql 'errors.invalid_subdomain'
15
15
  end
16
16
 
17
17
  it 'can output the detail' do
@@ -21,7 +21,7 @@ describe InvalidSubdomainError do
21
21
  end
22
22
 
23
23
  it 'can output the source' do
24
- error = InvalidSubdomainError.new http_host: 'foo'
24
+ error = InvalidSubdomain.new http_host: 'foo'
25
25
 
26
26
  expect(error.source).to eql(http_host: 'foo')
27
27
  end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'apill/errors/invalid_token'
3
+
4
+ module Apill
5
+ module Errors
6
+ describe InvalidToken do
7
+ let(:error) { InvalidToken.new }
8
+
9
+ it 'has a status of 401' do
10
+ expect(error.http_status).to eql 401
11
+ end
12
+
13
+ it 'has a code' do
14
+ expect(error.code).to eql 'errors.invalid_token'
15
+ end
16
+
17
+ it 'can output the detail' do
18
+ expect(error.detail).to eql \
19
+ 'Either the token you passed is invalid or is not allowed to perform this action.'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,21 +1,21 @@
1
- require 'rspectacular'
2
- require 'apill/responses/invalid_subdomain_response'
1
+ require 'spec_helper'
2
+ require 'apill/responses/invalid_subdomain'
3
3
 
4
4
  module Apill
5
5
  module Responses
6
- describe InvalidSubdomainResponse, singletons: HumanError::Configuration do
6
+ describe InvalidSubdomain, singletons: HumanError::Configuration do
7
7
  it 'returns the proper response' do
8
8
  HumanError.configuration.url_mappings = {
9
9
  'external_documentation_urls' => {
10
- 'errors.invalid_subdomain_response' => 'http://example.com/foo',
10
+ 'errors.responses.invalid_subdomain' => 'http://example.com/foo',
11
11
  },
12
12
  'developer_documentation_urls' => {
13
- 'errors.invalid_subdomain_response' => 'http://example.com/foo',
13
+ 'errors.responses.invalid_subdomain' => 'http://example.com/foo',
14
14
  },
15
15
  }
16
16
 
17
17
  request = { 'HTTP_HOST' => 'api.example.com' }
18
- status, headers, response = InvalidSubdomainResponse.call(request)
18
+ status, headers, response = InvalidSubdomain.call(request)
19
19
 
20
20
  expect(status).to eql 404
21
21
  expect(headers).to eql({})
@@ -28,7 +28,7 @@ describe InvalidSubdomainResponse, singletons: HumanError::Configuration do
28
28
  'documentation' => nil,
29
29
  },
30
30
  'status' => 404,
31
- 'code' => 'errors.invalid_subdomain_error',
31
+ 'code' => 'errors.invalid_subdomain',
32
32
  'title' => 'Invalid Subdomain',
33
33
  'detail' => 'The resource you attempted to access is either not authorized ' \
34
34
  'for the authenticated user or does not exist.',
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'apill/responses/invalid_token'
3
+
4
+ module Apill
5
+ module Responses
6
+ describe InvalidToken, singletons: HumanError::Configuration do
7
+ it 'returns the proper response' do
8
+ HumanError.configuration.url_mappings = {
9
+ 'external_documentation_urls' => {
10
+ 'errors.responses.invalid_token' => 'http://example.com/foo',
11
+ },
12
+ 'developer_documentation_urls' => {
13
+ 'errors.responses.invalid_token' => 'http://example.com/foo',
14
+ },
15
+ }
16
+
17
+ request = { 'HTTP_HOST' => 'api.example.com' }
18
+ status, headers, response = InvalidToken.call(request)
19
+
20
+ expect(status).to eql 401
21
+ expect(headers).to eql({})
22
+ expect(JSON.load(response[0])).to include(
23
+ 'errors' => [
24
+ include(
25
+ 'id' => match(/[a-f0-9\-]+/),
26
+ 'links' => {
27
+ 'about' => nil,
28
+ 'documentation' => nil,
29
+ },
30
+ 'status' => 401,
31
+ 'code' => 'errors.invalid_token',
32
+ 'title' => 'Invalid or Unauthorized Token',
33
+ 'detail' => 'Either the token you passed is invalid or is not allowed to ' \
34
+ 'perform this action.',
35
+ 'source' => {},
36
+ ),
37
+ ],
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,58 +1,63 @@
1
- require 'rspectacular'
2
- require 'apill/matchers/accept_header_matcher'
1
+ require 'spec_helper'
2
+ require 'apill/requests/base'
3
+ require 'apill/matchers/accept_header'
3
4
 
4
5
  module Apill
5
6
  module Matchers
6
- describe AcceptHeaderMatcher do
7
+ describe AcceptHeader do
7
8
  it 'matches if the subdomain is API and the accept header is valid' do
8
- request = {
9
+ env = {
9
10
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
10
11
  'HTTP_X_APPLICATION_NAME' => 'matrix',
11
12
  }
13
+ request = Requests::Base.resolve(env)
12
14
 
13
- matcher = AcceptHeaderMatcher.new
15
+ matcher = AcceptHeader.new(request: request)
14
16
 
15
- expect(matcher.matches?(request)).to be_a TrueClass
17
+ expect(matcher).to be_matches
16
18
  end
17
19
 
18
20
  it 'matches if the subdomain is API and the accept header is passed in as ' \
19
21
  'a parameter' do
20
22
 
21
- request = {
23
+ env = {
22
24
  'QUERY_STRING' => 'accept=application/vnd.matrix+zion;version=1.0.0',
23
25
  'HTTP_X_APPLICATION_NAME' => 'matrix',
24
26
  }
27
+ request = Requests::Base.resolve(env)
25
28
 
26
- matcher = AcceptHeaderMatcher.new
29
+ matcher = AcceptHeader.new(request: request)
27
30
 
28
- expect(matcher.matches?(request)).to be_a TrueClass
31
+ expect(matcher).to be_matches
29
32
  end
30
33
 
31
34
  it 'matches if the subdomain is API and the accept header is passed in as a ' \
32
35
  'secondary parameter' do
33
36
 
34
- request = {
37
+ env = {
35
38
  'QUERY_STRING' => 'first=my_param&accept=application/vnd.matrix+zion;' \
36
39
  'version=1.0.0',
37
40
  'HTTP_X_APPLICATION_NAME' => 'matrix',
38
41
  }
42
+ request = Requests::Base.resolve(env)
39
43
 
40
- matcher = AcceptHeaderMatcher.new
44
+ matcher = AcceptHeader.new(request: request)
41
45
 
42
- expect(matcher.matches?(request)).to be_a TrueClass
46
+ expect(matcher).to be_matches
43
47
  end
44
48
 
45
49
  it 'matches the header accept header if the subdomain is API and the accept header ' \
46
50
  'is passed both as a valid header and as a parameter' do
47
51
 
48
- request = {
52
+ env = {
49
53
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
50
54
  'QUERY_STRING' => 'accept=application/vnd.matrix+zion;version=2.0.0',
51
55
  'HTTP_X_APPLICATION_NAME' => 'matrix',
52
56
  }
57
+ request = Requests::Base.resolve(env)
53
58
 
54
- matcher = AcceptHeaderMatcher.new
55
- matcher.matches?(request)
59
+ matcher = AcceptHeader.new(request: request)
60
+ matcher.matches?
56
61
 
57
62
  expect(matcher.accept_header.version).to eql '1.0.0'
58
63
  end
@@ -60,14 +65,15 @@ describe AcceptHeaderMatcher do
60
65
  it 'matches the accept header parameter if the subdomain is API and the accept ' \
61
66
  'header is passed both as an invalid header as well as as a parameter' do
62
67
 
63
- request = {
68
+ env = {
64
69
  'HTTP_ACCEPT' => 'application/vndmatrix+zion;version=1.0.0',
65
70
  'QUERY_STRING' => 'accept=application/vnd.matrix+zion;version=2.0.0',
66
71
  'HTTP_X_APPLICATION_NAME' => 'matrix',
67
72
  }
73
+ request = Requests::Base.resolve(env)
68
74
 
69
- matcher = AcceptHeaderMatcher.new
70
- matcher.matches?(request)
75
+ matcher = AcceptHeader.new(request: request)
76
+ matcher.matches?
71
77
 
72
78
  expect(matcher.accept_header.version).to eql '2.0.0'
73
79
  end
@@ -75,29 +81,31 @@ describe AcceptHeaderMatcher do
75
81
  it 'matches the accept header parameter if the subdomain is API and the accept ' \
76
82
  'header is passed both as an invalid header as well as as a parameter' do
77
83
 
78
- request = {
84
+ env = {
79
85
  'HTTP_ACCEPT' => 'application/vndmatrix+zion;version=1.0.0',
80
86
  'QUERY_STRING' => '',
81
87
  'HTTP_X_APPLICATION_NAME' => 'matrix',
82
88
  }
89
+ request = Requests::Base.resolve(env)
83
90
 
84
- matcher = AcceptHeaderMatcher.new
85
- matcher.matches?(request)
91
+ matcher = AcceptHeader.new(request: request)
92
+ matcher.matches?
86
93
 
87
94
  expect(matcher.accept_header.raw_accept_header).to eql \
88
95
  'application/vndmatrix+zion;version=1.0.0'
89
96
  end
90
97
 
91
98
  it 'does not match if the subdomain is API but the accept header is invalid' do
92
- request = {
99
+ env = {
93
100
  'HTTP_ACCEPT' => 'application/vndmatrix+zion;version=1.0.0',
94
101
  'QUERY_STRING' => '',
95
102
  'HTTP_X_APPLICATION_NAME' => 'matrix',
96
103
  }
104
+ request = Requests::Base.resolve(env)
97
105
 
98
- matcher = AcceptHeaderMatcher.new
106
+ matcher = AcceptHeader.new(request: request)
99
107
 
100
- expect(matcher.matches?(request)).to be_a FalseClass
108
+ expect(matcher).not_to be_matches
101
109
  end
102
110
  end
103
111
  end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'apill/requests/base'
3
+ require 'apill/matchers/subdomain'
4
+ require 'apill/configuration'
5
+
6
+ module Apill
7
+ module Matchers
8
+ describe Subdomain do
9
+ before(:each) do
10
+ Apill.configuration.allowed_subdomains = %w{api}
11
+ Apill.configuration.allowed_api_subdomains = %w{api}
12
+ end
13
+
14
+ it 'matches if the subdomain is API' do
15
+ env = { 'HTTP_HOST' => 'api.example.com' }
16
+ request = Requests::Base.resolve(env)
17
+ matcher = Subdomain.new(request: request)
18
+
19
+ expect(matcher.matches?).to be_a TrueClass
20
+ end
21
+
22
+ it 'matches if the first subdomain is API' do
23
+ env = { 'HTTP_HOST' => 'api.matrix.example.com' }
24
+ request = Requests::Base.resolve(env)
25
+ matcher = Subdomain.new(request: request)
26
+
27
+ expect(matcher.matches?).to be_a TrueClass
28
+ end
29
+
30
+ it 'does not match if the first subdomain is not API' do
31
+ env = { 'HTTP_HOST' => 'matrix.example.com' }
32
+ request = Requests::Base.resolve(env)
33
+ matcher = Subdomain.new(request: request)
34
+
35
+ expect(matcher.matches?).to be_a FalseClass
36
+ end
37
+
38
+ it 'allows the matched subdomain to be specified' do
39
+ env = { 'HTTP_HOST' => 'matrix.example.com' }
40
+ request = Requests::Base.resolve(env)
41
+ matcher = Subdomain.new(allowed_subdomains: 'matrix',
42
+ request: request)
43
+
44
+ expect(matcher.matches?).to be_a TrueClass
45
+ end
46
+
47
+ it 'allows more than one subdomain to be matched' do
48
+ env = { 'HTTP_HOST' => 'matrix.example.com' }
49
+ request = Requests::Base.resolve(env)
50
+ matcher = Subdomain.new(allowed_subdomains: %w{api matrix},
51
+ request: request)
52
+
53
+ expect(matcher.matches?).to be_a TrueClass
54
+
55
+ env = { 'HTTP_HOST' => 'api.example.com' }
56
+ request = Requests::Base.resolve(env)
57
+ matcher = Subdomain.new(allowed_subdomains: %w{api matrix},
58
+ request: request)
59
+
60
+ expect(matcher.matches?).to be_a TrueClass
61
+ end
62
+
63
+ it 'can match only the api subdomain' do
64
+ env = { 'HTTP_HOST' => 'matrix.example.com' }
65
+ request = Requests::Base.resolve(env)
66
+ matcher = Subdomain.new(allowed_api_subdomains: %w{matrix},
67
+ request: request)
68
+
69
+ expect(matcher.matches_api_subdomain?).to be_a TrueClass
70
+ end
71
+
72
+ it 'matches "api" as an api subdomain by default' do
73
+ env = { 'HTTP_HOST' => 'api.example.com' }
74
+ request = Requests::Base.resolve(env)
75
+ matcher = Subdomain.new(request: request)
76
+
77
+ expect(matcher.matches_api_subdomain?).to be_a TrueClass
78
+ end
79
+ end
80
+ end
81
+ end
@@ -1,34 +1,39 @@
1
- require 'rspectacular'
2
- require 'apill/matchers/version_matcher'
1
+ require 'spec_helper'
2
+ require 'apill/requests/base'
3
+ require 'apill/matchers/version'
3
4
 
4
5
  module Apill
5
6
  module Matchers
6
- describe VersionMatcher do
7
+ describe Version do
7
8
  context 'when the version is passed in the accept header' do
8
9
  it 'does not match if the subdomain is API but the requested version does not ' \
9
10
  'equal the version constraint' do
10
11
 
11
- request = {
12
+ env = {
12
13
  'HTTP_X_APPLICATION_NAME' => 'matrix',
13
14
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=10.0',
14
15
  }
16
+ request = Requests::Base.resolve(env)
15
17
 
16
- matcher = VersionMatcher.new(version_constraint: '10.1')
18
+ matcher = Version.new(request: request,
19
+ version_constraint: '10.1')
17
20
 
18
- expect(matcher.matches?(request)).to be_a FalseClass
21
+ expect(matcher).not_to be_matches
19
22
  end
20
23
 
21
24
  it 'does match if the subdomain is API and the requested version equals the ' \
22
25
  'version constraint' do
23
26
 
24
- request = {
27
+ env = {
25
28
  'HTTP_X_APPLICATION_NAME' => 'matrix',
26
29
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=10.0',
27
30
  }
31
+ request = Requests::Base.resolve(env)
28
32
 
29
- matcher = VersionMatcher.new(version_constraint: '10.0')
33
+ matcher = Version.new(request: request,
34
+ version_constraint: '10.0')
30
35
 
31
- expect(matcher.matches?(request)).to be_a TrueClass
36
+ expect(matcher).to be_matches
32
37
  end
33
38
  end
34
39
 
@@ -36,43 +41,49 @@ describe VersionMatcher do
36
41
  it 'does not match if the subdomain is API but the requested version does not ' \
37
42
  'equal the version constraint' do
38
43
 
39
- request = {
44
+ env = {
40
45
  'HTTP_X_APPLICATION_NAME' => 'matrix',
41
46
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion',
42
47
  }
48
+ request = Requests::Base.resolve(env)
43
49
 
44
- matcher = VersionMatcher.new(version_constraint: '10.1',
45
- default_version: '10.0')
50
+ matcher = Version.new(request: request,
51
+ version_constraint: '10.1',
52
+ default_version: '10.0')
46
53
 
47
- expect(matcher.matches?(request)).to be_a FalseClass
54
+ expect(matcher).not_to be_matches
48
55
  end
49
56
 
50
57
  it 'does match if the subdomain is API and the requested version equals the ' \
51
58
  'version constraint' do
52
59
 
53
- request = {
60
+ env = {
54
61
  'HTTP_X_APPLICATION_NAME' => 'matrix',
55
62
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion',
56
63
  }
64
+ request = Requests::Base.resolve(env)
57
65
 
58
- matcher = VersionMatcher.new(version_constraint: '10.0',
59
- default_version: '10.0')
66
+ matcher = Version.new(request: request,
67
+ version_constraint: '10.0',
68
+ default_version: '10.0')
60
69
 
61
- expect(matcher.matches?(request)).to be_a TrueClass
70
+ expect(matcher).to be_matches
62
71
  end
63
72
  end
64
73
 
65
74
  it 'matches the default version in the configuration if none is passed in' do
66
75
  Apill.configuration.default_api_version = '100.0'
67
76
 
68
- request = {
77
+ env = {
69
78
  'HTTP_X_APPLICATION_NAME' => 'matrix',
70
79
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion',
71
80
  }
81
+ request = Requests::Base.resolve(env)
72
82
 
73
- matcher = VersionMatcher.new(version_constraint: '100.0')
83
+ matcher = Version.new(request: request,
84
+ version_constraint: '100.0')
74
85
 
75
- expect(matcher.matches?(request)).to be_a TrueClass
86
+ expect(matcher).to be_matches
76
87
  end
77
88
  end
78
89
  end
@@ -1,4 +1,4 @@
1
- require 'rspectacular'
1
+ require 'spec_helper'
2
2
  require 'apill/middleware/api_request'
3
3
 
4
4
  module Apill
@@ -9,10 +9,10 @@ describe ApiRequest, singletons: HumanError::Configuration do
9
9
  before(:each) do
10
10
  HumanError.configuration.url_mappings = {
11
11
  'external_documentation_urls' => {
12
- 'errors.invalid_subdomain_response' => 'http://example.com/foo',
12
+ 'errors.responses.invalid_subdomain' => 'http://example.com/foo',
13
13
  },
14
14
  'developer_documentation_urls' => {
15
- 'errors.invalid_subdomain_response' => 'http://example.com/foo',
15
+ 'errors.responses.invalid_subdomain' => 'http://example.com/foo',
16
16
  },
17
17
  }
18
18
 
@@ -61,7 +61,7 @@ describe ApiRequest, singletons: HumanError::Configuration do
61
61
  'documentation' => nil,
62
62
  },
63
63
  'status' => 404,
64
- 'code' => 'errors.invalid_subdomain_error',
64
+ 'code' => 'errors.invalid_subdomain',
65
65
  'title' => 'Invalid Subdomain',
66
66
  'detail' => 'The resource you attempted to access is either not authorized ' \
67
67
  'for the authenticated user or does not exist.',
@@ -97,7 +97,7 @@ describe ApiRequest, singletons: HumanError::Configuration do
97
97
  'documentation' => nil,
98
98
  },
99
99
  'status' => 400,
100
- 'code' => 'errors.invalid_api_request_error',
100
+ 'code' => 'errors.invalid_api_request',
101
101
  'title' => 'Invalid API Request',
102
102
  'detail' => 'The accept header that you passed in the request cannot be ' \
103
103
  'parsed, please refer to the documentation to verify.',
@@ -125,59 +125,57 @@ describe ApiRequest, singletons: HumanError::Configuration do
125
125
  expect(response).to eql 'response'
126
126
  end
127
127
 
128
- it 'converts JSON API compliant dasherized query params to underscored' do
129
- app = ->(env) { [200, env, 'response'] }
130
- api_request_middleware = ApiRequest.new(app)
128
+ it 'does allow requests if the subdomain, the accept header and the token are valid' do
129
+ Apill.configuration.token_private_key = test_private_key
130
+ api_request_middleware = ApiRequest.new(app)
131
131
 
132
132
  request = {
133
- 'HTTP_HOST' => 'api.example.com',
134
- 'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
135
- 'QUERY_STRING' => 'hello-there=bob-jones&' \
136
- 'nice-to-meet=you-bob&' \
137
- 'hows-the-weather=today-bob',
133
+ 'HTTP_HOST' => 'api.example.com',
134
+ 'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
135
+ 'HTTP_AUTHORIZATION' => "Token #{valid_token}",
136
+ 'QUERY_STRING' => 'accept=application/vnd.matrix+zion;version=1.0.0',
138
137
  }
139
138
 
140
- _status, headers, _response = api_request_middleware.call(request)
139
+ status, headers, response = api_request_middleware.call(request)
141
140
 
142
- expect(headers['QUERY_STRING']).to eql 'hello_there=bob-jones&' \
143
- 'nice_to_meet=you-bob&' \
144
- 'hows_the_weather=today-bob'
141
+ expect(status).to eql 200
142
+ expect(headers).to eql({})
143
+ expect(response).to eql 'response'
145
144
  end
146
145
 
147
- it 'properly converts the content type for Rails when it is the only one' do
148
- api_request_middleware = ApiRequest.new(app)
146
+ it 'returns the proper response if the token is invalid' do
147
+ Apill.configuration.token_private_key = test_private_key
148
+ api_request_middleware = ApiRequest.new(app)
149
149
 
150
150
  request = {
151
- 'CONTENT_TYPE' => 'application/vnd.api+json',
152
- 'HTTP_HOST' => 'matrix.example.com',
153
- 'HTTP_ACCEPT' => '',
154
- 'QUERY_STRING' => '',
151
+ 'HTTP_HOST' => 'api.example.com',
152
+ 'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
153
+ 'HTTP_AUTHORIZATION' => "Token #{invalid_token}",
154
+ 'QUERY_STRING' => 'accept=application/vnd.matrix+zion;version=1.0.0',
155
155
  }
156
156
 
157
- allow(app).to receive(:call)
158
-
159
- _response = api_request_middleware.call(request)
157
+ _status, _headers, response = api_request_middleware.call(request)
160
158
 
161
- expect(app).to have_received(:call).
162
- with(a_hash_including('CONTENT_TYPE' => 'application/json'))
159
+ expect(response.first).to include 'errors.invalid_token'
163
160
  end
164
161
 
165
- it 'properly converts the content type for Rails when it is not the only one' do
162
+ it 'converts JSON API compliant dasherized query params to underscored' do
163
+ app = ->(env) { [200, env, 'response'] }
166
164
  api_request_middleware = ApiRequest.new(app)
167
165
 
168
166
  request = {
169
- 'CONTENT_TYPE' => 'application/vnd.api+json;other',
170
- 'HTTP_HOST' => 'matrix.example.com',
171
- 'HTTP_ACCEPT' => '',
172
- 'QUERY_STRING' => '',
167
+ 'HTTP_HOST' => 'api.example.com',
168
+ 'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
169
+ 'QUERY_STRING' => 'hello-there=bob-jones&' \
170
+ 'nice-to-meet=you-bob&' \
171
+ 'hows-the-weather=today-bob',
173
172
  }
174
173
 
175
- allow(app).to receive(:call)
176
-
177
- _response = api_request_middleware.call(request)
174
+ _status, headers, _response = api_request_middleware.call(request)
178
175
 
179
- expect(app).to have_received(:call).
180
- with(a_hash_including('CONTENT_TYPE' => 'application/json;other'))
176
+ expect(headers['QUERY_STRING']).to eql 'hello_there=bob-jones&' \
177
+ 'nice_to_meet=you-bob&' \
178
+ 'hows_the_weather=today-bob'
181
179
  end
182
180
  end
183
181
  end
@@ -1,4 +1,4 @@
1
- require 'rspectacular'
1
+ require 'spec_helper'
2
2
  require 'apill/parameters'
3
3
 
4
4
  module Apill