drillbit 0.0.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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/LICENSE.txt +19 -0
- data/README.md +2 -0
- data/Rakefile +2 -0
- data/lib/drillbit.rb +19 -0
- data/lib/drillbit/accept_header.rb +50 -0
- data/lib/drillbit/authorizable_resource.rb +160 -0
- data/lib/drillbit/authorizers/parameters.rb +24 -0
- data/lib/drillbit/authorizers/parameters/filtering.rb +50 -0
- data/lib/drillbit/authorizers/parameters/resource.rb +11 -0
- data/lib/drillbit/authorizers/query.rb +40 -0
- data/lib/drillbit/authorizers/scope.rb +30 -0
- data/lib/drillbit/configuration.rb +36 -0
- data/lib/drillbit/errors/invalid_api_request.rb +29 -0
- data/lib/drillbit/errors/invalid_subdomain.rb +29 -0
- data/lib/drillbit/errors/invalid_token.rb +22 -0
- data/lib/drillbit/matchers/accept_header.rb +16 -0
- data/lib/drillbit/matchers/generic.rb +30 -0
- data/lib/drillbit/matchers/subdomain.rb +31 -0
- data/lib/drillbit/matchers/version.rb +30 -0
- data/lib/drillbit/middleware/api_request.rb +49 -0
- data/lib/drillbit/parameters.rb +22 -0
- data/lib/drillbit/parameters/filter.rb +57 -0
- data/lib/drillbit/parameters/index.rb +31 -0
- data/lib/drillbit/parameters/page.rb +28 -0
- data/lib/drillbit/parameters/sort.rb +32 -0
- data/lib/drillbit/requests/base.rb +114 -0
- data/lib/drillbit/requests/rack.rb +50 -0
- data/lib/drillbit/requests/rails.rb +44 -0
- data/lib/drillbit/resource.rb +14 -0
- data/lib/drillbit/resource/model.rb +41 -0
- data/lib/drillbit/resource/naming.rb +33 -0
- data/lib/drillbit/resource/processors/filtering.rb +66 -0
- data/lib/drillbit/resource/processors/indexing.rb +40 -0
- data/lib/drillbit/resource/processors/paging.rb +46 -0
- data/lib/drillbit/resource/processors/sorting.rb +42 -0
- data/lib/drillbit/responses/invalid_api_request.rb +18 -0
- data/lib/drillbit/responses/invalid_subdomain.rb +18 -0
- data/lib/drillbit/responses/invalid_token.rb +20 -0
- data/lib/drillbit/serializers/json_api.rb +10 -0
- data/lib/drillbit/tokens/base64.rb +45 -0
- data/lib/drillbit/tokens/base64s/invalid.rb +14 -0
- data/lib/drillbit/tokens/base64s/null.rb +14 -0
- data/lib/drillbit/tokens/invalid.rb +26 -0
- data/lib/drillbit/tokens/json_web_token.rb +112 -0
- data/lib/drillbit/tokens/json_web_tokens/invalid.rb +14 -0
- data/lib/drillbit/tokens/json_web_tokens/null.rb +14 -0
- data/lib/drillbit/tokens/null.rb +26 -0
- data/lib/drillbit/version.rb +4 -0
- data/spec/drillbit/accept_header_spec.rb +112 -0
- data/spec/drillbit/authorizers/parameters/filtering_spec.rb +71 -0
- data/spec/drillbit/authorizers/parameters/resource_spec.rb +12 -0
- data/spec/drillbit/authorizers/parameters_spec.rb +17 -0
- data/spec/drillbit/authorizers/query_spec.rb +21 -0
- data/spec/drillbit/authorizers/scope_spec.rb +20 -0
- data/spec/drillbit/errors/invalid_api_request_spec.rb +31 -0
- data/spec/drillbit/errors/invalid_subdomain_spec.rb +31 -0
- data/spec/drillbit/errors/invalid_token_spec.rb +24 -0
- data/spec/drillbit/invalid_subdomain_spec.rb +46 -0
- data/spec/drillbit/invalid_token_spec.rb +44 -0
- data/spec/drillbit/matchers/accept_header_spec.rb +114 -0
- data/spec/drillbit/matchers/subdomain_spec.rb +78 -0
- data/spec/drillbit/matchers/version_spec.rb +86 -0
- data/spec/drillbit/middleware/api_request_spec.rb +220 -0
- data/spec/drillbit/parameters_spec.rb +49 -0
- data/spec/drillbit/requests/base_spec.rb +37 -0
- data/spec/drillbit/requests/rack_spec.rb +253 -0
- data/spec/drillbit/requests/rails_spec.rb +264 -0
- data/spec/drillbit/resource/model_spec.rb +64 -0
- data/spec/drillbit/resource/processors/filtering_spec.rb +106 -0
- data/spec/drillbit/resource/processors/indexing_spec.rb +46 -0
- data/spec/drillbit/resource/processors/paging_spec.rb +74 -0
- data/spec/drillbit/resource/processors/sorting_spec.rb +66 -0
- data/spec/drillbit/tokens/base64_spec.rb +44 -0
- data/spec/drillbit/tokens/json_web_token_spec.rb +135 -0
- data/spec/fixtures/test_rsa_key +27 -0
- data/spec/fixtures/test_rsa_key.pub +9 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/private_keys.rb +42 -0
- metadata +244 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rspeckled'
|
3
|
+
require 'drillbit/authorizers/parameters'
|
4
|
+
|
5
|
+
module Drillbit
|
6
|
+
module Authorizers
|
7
|
+
RSpec.describe Parameters do
|
8
|
+
it 'defaults to nothing' do
|
9
|
+
parameters = Parameters.new(token: '123',
|
10
|
+
user: 'my_user',
|
11
|
+
params: { foo: 'bar' })
|
12
|
+
|
13
|
+
expect(parameters.call).to eql(foo: 'bar')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rspeckled'
|
3
|
+
require 'drillbit/authorizers/query'
|
4
|
+
|
5
|
+
module Drillbit
|
6
|
+
module Authorizers
|
7
|
+
RSpec.describe Query do
|
8
|
+
it 'does not authorize the resource by default' do
|
9
|
+
authorizer = Query.new(token: '123',
|
10
|
+
user: 'my_user',
|
11
|
+
resource: 'my_resource')
|
12
|
+
|
13
|
+
expect(authorizer).to be_able_to_index
|
14
|
+
expect(authorizer).not_to be_able_to_show
|
15
|
+
expect(authorizer).not_to be_able_to_create
|
16
|
+
expect(authorizer).not_to be_able_to_update
|
17
|
+
expect(authorizer).not_to be_able_to_destroy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rspeckled'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'drillbit/authorizers/scope'
|
5
|
+
|
6
|
+
module Drillbit
|
7
|
+
module Authorizers
|
8
|
+
RSpec.describe Scope do
|
9
|
+
it 'defaults to nothing' do
|
10
|
+
scope = Scope.new(token: '123',
|
11
|
+
user: 'my_user',
|
12
|
+
scoped_user_id: '456',
|
13
|
+
params: {},
|
14
|
+
scope_root: OpenStruct.new(none: []))
|
15
|
+
|
16
|
+
expect(scope.call).to be_empty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/errors/invalid_api_request'
|
4
|
+
|
5
|
+
module Drillbit
|
6
|
+
module Errors
|
7
|
+
RSpec.describe InvalidApiRequest do
|
8
|
+
let(:error) { InvalidApiRequest.new }
|
9
|
+
|
10
|
+
it 'has a status of 400' do
|
11
|
+
expect(error.http_status).to eql 400
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has a code' do
|
15
|
+
expect(error.code).to eql 'errors.invalid_api_request'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can output the detail' do
|
19
|
+
expect(error.detail).to eql 'The accept header that you passed in the ' \
|
20
|
+
'request cannot be parsed, please refer to ' \
|
21
|
+
'the documentation to verify.'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can output the source' do
|
25
|
+
error = InvalidApiRequest.new accept_header: 'foo'
|
26
|
+
|
27
|
+
expect(error.source).to eql(accept_header: 'foo')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/errors/invalid_subdomain'
|
4
|
+
|
5
|
+
module Drillbit
|
6
|
+
module Errors
|
7
|
+
RSpec.describe InvalidSubdomain do
|
8
|
+
let(:error) { InvalidSubdomain.new }
|
9
|
+
|
10
|
+
it 'has a status of 404' do
|
11
|
+
expect(error.http_status).to eql 404
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has a code' do
|
15
|
+
expect(error.code).to eql 'errors.invalid_subdomain'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can output the detail' do
|
19
|
+
expect(error.detail).to eql \
|
20
|
+
'The resource you attempted to access is either not authorized for the ' \
|
21
|
+
'authenticated user or does not exist.'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can output the source' do
|
25
|
+
error = InvalidSubdomain.new http_host: 'foo'
|
26
|
+
|
27
|
+
expect(error.source).to eql(http_host: 'foo')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/errors/invalid_token'
|
4
|
+
|
5
|
+
module Drillbit
|
6
|
+
module Errors
|
7
|
+
RSpec.describe InvalidToken do
|
8
|
+
let(:error) { InvalidToken.new }
|
9
|
+
|
10
|
+
it 'has a status of 401' do
|
11
|
+
expect(error.http_status).to eql 401
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has a code' do
|
15
|
+
expect(error.code).to eql 'errors.invalid_token'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'can output the detail' do
|
19
|
+
expect(error.detail).to eql \
|
20
|
+
'Either the token you passed is invalid or is not allowed to perform this action.'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/responses/invalid_subdomain'
|
4
|
+
|
5
|
+
# rubocop:disable Metrics/LineLength
|
6
|
+
module Drillbit
|
7
|
+
module Responses
|
8
|
+
RSpec.describe InvalidSubdomain, singletons: Erratum::Configuration do
|
9
|
+
it 'returns the proper response' do
|
10
|
+
Erratum.configuration.url_mappings = {
|
11
|
+
'external_documentation_urls' => {
|
12
|
+
'errors.responses.invalid_subdomain' => 'http://example.com/foo',
|
13
|
+
},
|
14
|
+
'developer_documentation_urls' => {
|
15
|
+
'errors.responses.invalid_subdomain' => 'http://example.com/foo',
|
16
|
+
},
|
17
|
+
}
|
18
|
+
|
19
|
+
request = { 'HTTP_HOST' => 'api.example.com' }
|
20
|
+
status, headers, response = InvalidSubdomain.call(request)
|
21
|
+
|
22
|
+
expect(status).to eql 404
|
23
|
+
expect(headers).to eql({})
|
24
|
+
expect(JSON.load(response[0])).to include(
|
25
|
+
'errors' => [
|
26
|
+
include(
|
27
|
+
'id' => match(/[a-f0-9\-]+/),
|
28
|
+
'links' => {
|
29
|
+
'about' => nil,
|
30
|
+
'documentation' => nil,
|
31
|
+
},
|
32
|
+
'status' => 404,
|
33
|
+
'code' => 'errors.invalid_subdomain',
|
34
|
+
'title' => 'Invalid Subdomain',
|
35
|
+
'detail' => 'The resource you attempted to access is either not authorized ' \
|
36
|
+
'for the authenticated user or does not exist.',
|
37
|
+
'source' => {
|
38
|
+
'http_host' => 'api.example.com',
|
39
|
+
},
|
40
|
+
),
|
41
|
+
],
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/responses/invalid_token'
|
4
|
+
|
5
|
+
# rubocop:disable Metrics/LineLength
|
6
|
+
module Drillbit
|
7
|
+
module Responses
|
8
|
+
RSpec.describe InvalidToken, singletons: Erratum::Configuration do
|
9
|
+
it 'returns the proper response' do
|
10
|
+
Erratum.configuration.url_mappings = {
|
11
|
+
'external_documentation_urls' => {
|
12
|
+
'errors.responses.invalid_token' => 'http://example.com/foo',
|
13
|
+
},
|
14
|
+
'developer_documentation_urls' => {
|
15
|
+
'errors.responses.invalid_token' => 'http://example.com/foo',
|
16
|
+
},
|
17
|
+
}
|
18
|
+
|
19
|
+
request = { 'HTTP_HOST' => 'api.example.com' }
|
20
|
+
status, headers, response = InvalidToken.call(request, application_name: 'my_app')
|
21
|
+
|
22
|
+
expect(status).to eql 401
|
23
|
+
expect(headers).to eql('WWW-Authenticate' => 'Token realm="my_app"')
|
24
|
+
expect(JSON.load(response[0])).to include(
|
25
|
+
'errors' => [
|
26
|
+
include(
|
27
|
+
'id' => match(/[a-f0-9\-]+/),
|
28
|
+
'links' => {
|
29
|
+
'about' => nil,
|
30
|
+
'documentation' => nil,
|
31
|
+
},
|
32
|
+
'status' => 401,
|
33
|
+
'code' => 'errors.invalid_token',
|
34
|
+
'title' => 'Invalid or Unauthorized Token',
|
35
|
+
'detail' => 'Either the token you passed is invalid or is not allowed to ' \
|
36
|
+
'perform this action.',
|
37
|
+
'source' => {},
|
38
|
+
),
|
39
|
+
],
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/requests/base'
|
4
|
+
require 'drillbit/matchers/accept_header'
|
5
|
+
|
6
|
+
# rubocop:disable Metrics/LineLength
|
7
|
+
module Drillbit
|
8
|
+
module Matchers
|
9
|
+
RSpec.describe AcceptHeader do
|
10
|
+
it 'matches if the subdomain is API and the accept header is valid' do
|
11
|
+
env = {
|
12
|
+
'HTTP_ACCEPT' => 'application/vnd.westeros+redkeep;version=1.0.0',
|
13
|
+
'HTTP_X_APPLICATION_NAME' => 'westeros',
|
14
|
+
}
|
15
|
+
request = Requests::Base.resolve(env)
|
16
|
+
|
17
|
+
matcher = AcceptHeader.new
|
18
|
+
|
19
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'matches if the subdomain is API and the accept header is passed in as ' \
|
23
|
+
'a parameter' do
|
24
|
+
|
25
|
+
env = {
|
26
|
+
'QUERY_STRING' => 'accept=application/vnd.westeros+redkeep;version=1.0.0',
|
27
|
+
'HTTP_X_APPLICATION_NAME' => 'westeros',
|
28
|
+
}
|
29
|
+
request = Requests::Base.resolve(env)
|
30
|
+
|
31
|
+
matcher = AcceptHeader.new
|
32
|
+
|
33
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'matches if the subdomain is API and the accept header is passed in as a ' \
|
37
|
+
'secondary parameter' do
|
38
|
+
|
39
|
+
env = {
|
40
|
+
'QUERY_STRING' => 'first=my_param&accept=application/vnd.westeros+redkeep;' \
|
41
|
+
'version=1.0.0',
|
42
|
+
'HTTP_X_APPLICATION_NAME' => 'westeros',
|
43
|
+
}
|
44
|
+
request = Requests::Base.resolve(env)
|
45
|
+
|
46
|
+
matcher = AcceptHeader.new
|
47
|
+
|
48
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'matches the header accept header if the subdomain is API and the accept header ' \
|
52
|
+
'is passed both as a valid header and as a parameter' do
|
53
|
+
|
54
|
+
env = {
|
55
|
+
'HTTP_ACCEPT' => 'application/vnd.westeros+redkeep;version=1.0.0',
|
56
|
+
'QUERY_STRING' => 'accept=application/vnd.westeros+redkeep;version=2.0.0',
|
57
|
+
'HTTP_X_APPLICATION_NAME' => 'westeros',
|
58
|
+
}
|
59
|
+
request = Requests::Base.resolve(env)
|
60
|
+
|
61
|
+
matcher = AcceptHeader.new
|
62
|
+
matcher.matches?(request)
|
63
|
+
|
64
|
+
expect(matcher.accept_header.version).to eql '1.0.0'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'matches the accept header parameter if the subdomain is API and the accept ' \
|
68
|
+
'header is passed both as an invalid header as well as as a parameter' do
|
69
|
+
|
70
|
+
env = {
|
71
|
+
'HTTP_ACCEPT' => 'application/vndwesteros+redkeep;version=1.0.0',
|
72
|
+
'QUERY_STRING' => 'accept=application/vnd.westeros+redkeep;version=2.0.0',
|
73
|
+
'HTTP_X_APPLICATION_NAME' => 'westeros',
|
74
|
+
}
|
75
|
+
request = Requests::Base.resolve(env)
|
76
|
+
|
77
|
+
matcher = AcceptHeader.new
|
78
|
+
matcher.matches?(request)
|
79
|
+
|
80
|
+
expect(matcher.accept_header.version).to eql '2.0.0'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'matches the accept header parameter if the subdomain is API and the accept ' \
|
84
|
+
'header is passed both as an invalid header as well as as a parameter' do
|
85
|
+
|
86
|
+
env = {
|
87
|
+
'HTTP_ACCEPT' => 'application/vndwesteros+redkeep;version=1.0.0',
|
88
|
+
'QUERY_STRING' => '',
|
89
|
+
'HTTP_X_APPLICATION_NAME' => 'westeros',
|
90
|
+
}
|
91
|
+
request = Requests::Base.resolve(env)
|
92
|
+
|
93
|
+
matcher = AcceptHeader.new
|
94
|
+
matcher.matches?(request)
|
95
|
+
|
96
|
+
expect(matcher.accept_header.raw_accept_header).to eql \
|
97
|
+
'application/vndwesteros+redkeep;version=1.0.0'
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'does not match if the subdomain is API but the accept header is invalid' do
|
101
|
+
env = {
|
102
|
+
'HTTP_ACCEPT' => 'application/vndwesteros+redkeep;version=1.0.0',
|
103
|
+
'QUERY_STRING' => '',
|
104
|
+
'HTTP_X_APPLICATION_NAME' => 'westeros',
|
105
|
+
}
|
106
|
+
request = Requests::Base.resolve(env)
|
107
|
+
|
108
|
+
matcher = AcceptHeader.new
|
109
|
+
|
110
|
+
expect(matcher.matches?(request)).to be_a FalseClass
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/requests/base'
|
4
|
+
require 'drillbit/matchers/subdomain'
|
5
|
+
require 'drillbit/configuration'
|
6
|
+
|
7
|
+
module Drillbit
|
8
|
+
module Matchers
|
9
|
+
RSpec.describe Subdomain do
|
10
|
+
before(:each) do
|
11
|
+
Drillbit.configuration.allowed_subdomains = %w{api}
|
12
|
+
Drillbit.configuration.allowed_api_subdomains = %w{api}
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'matches if the subdomain is API' do
|
16
|
+
env = { 'HTTP_HOST' => 'api.example.com' }
|
17
|
+
request = Requests::Base.resolve(env)
|
18
|
+
matcher = Subdomain.new
|
19
|
+
|
20
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'matches if the first subdomain is API' do
|
24
|
+
env = { 'HTTP_HOST' => 'api.westeros.example.com' }
|
25
|
+
request = Requests::Base.resolve(env)
|
26
|
+
matcher = Subdomain.new
|
27
|
+
|
28
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'does not match if the first subdomain is not API' do
|
32
|
+
env = { 'HTTP_HOST' => 'westeros.example.com' }
|
33
|
+
request = Requests::Base.resolve(env)
|
34
|
+
matcher = Subdomain.new
|
35
|
+
|
36
|
+
expect(matcher.matches?(request)).to be_a FalseClass
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'allows the matched subdomain to be specified' do
|
40
|
+
env = { 'HTTP_HOST' => 'westeros.example.com' }
|
41
|
+
request = Requests::Base.resolve(env)
|
42
|
+
matcher = Subdomain.new(allowed_subdomains: 'westeros')
|
43
|
+
|
44
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'allows more than one subdomain to be matched' do
|
48
|
+
env = { 'HTTP_HOST' => 'westeros.example.com' }
|
49
|
+
request = Requests::Base.resolve(env)
|
50
|
+
matcher = Subdomain.new(allowed_subdomains: %w{api westeros})
|
51
|
+
|
52
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
53
|
+
|
54
|
+
env = { 'HTTP_HOST' => 'api.example.com' }
|
55
|
+
request = Requests::Base.resolve(env)
|
56
|
+
matcher = Subdomain.new(allowed_subdomains: %w{api westeros})
|
57
|
+
|
58
|
+
expect(matcher.matches?(request)).to be_a TrueClass
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'can match only the api subdomain' do
|
62
|
+
env = { 'HTTP_HOST' => 'westeros.example.com' }
|
63
|
+
request = Requests::Base.resolve(env)
|
64
|
+
matcher = Subdomain.new(allowed_api_subdomains: %w{westeros})
|
65
|
+
|
66
|
+
expect(matcher.matches_api_subdomain?(request)).to be_a TrueClass
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'matches "api" as an api subdomain by default' do
|
70
|
+
env = { 'HTTP_HOST' => 'api.example.com' }
|
71
|
+
request = Requests::Base.resolve(env)
|
72
|
+
matcher = Subdomain.new
|
73
|
+
|
74
|
+
expect(matcher.matches_api_subdomain?(request)).to be_a TrueClass
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|