castle-rb 3.6.2 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +57 -5
- data/lib/castle.rb +5 -3
- data/lib/castle/api.rb +12 -6
- data/lib/castle/api/request.rb +15 -10
- data/lib/castle/api/session.rb +39 -0
- data/lib/castle/client.rb +23 -18
- data/lib/castle/configuration.rb +49 -6
- data/lib/castle/context/default.rb +36 -18
- data/lib/castle/context/sanitizer.rb +1 -0
- data/lib/castle/events.rb +49 -0
- data/lib/castle/extractors/client_id.rb +7 -3
- data/lib/castle/extractors/headers.rb +24 -30
- data/lib/castle/extractors/ip.rb +69 -5
- data/lib/castle/headers_filter.rb +35 -0
- data/lib/castle/headers_formatter.rb +22 -0
- data/lib/castle/validators/not_supported.rb +1 -0
- data/lib/castle/validators/present.rb +1 -0
- data/lib/castle/version.rb +1 -1
- data/spec/integration/rails/rails_spec.rb +61 -0
- data/spec/integration/rails/support/all.rb +6 -0
- data/spec/integration/rails/support/application.rb +15 -0
- data/spec/integration/rails/support/home_controller.rb +21 -0
- data/spec/lib/castle/api/request_spec.rb +43 -30
- data/spec/lib/castle/api/session_spec.rb +47 -0
- data/spec/lib/castle/api_spec.rb +4 -4
- data/spec/lib/castle/client_spec.rb +5 -3
- data/spec/lib/castle/commands/authenticate_spec.rb +1 -0
- data/spec/lib/castle/commands/identify_spec.rb +1 -0
- data/spec/lib/castle/commands/impersonate_spec.rb +1 -0
- data/spec/lib/castle/commands/track_spec.rb +1 -0
- data/spec/lib/castle/configuration_spec.rb +21 -4
- data/spec/lib/castle/context/default_spec.rb +13 -13
- data/spec/lib/castle/events_spec.rb +5 -0
- data/spec/lib/castle/extractors/client_id_spec.rb +2 -1
- data/spec/lib/castle/extractors/headers_spec.rb +67 -51
- data/spec/lib/castle/extractors/ip_spec.rb +89 -12
- data/spec/lib/castle/headers_filter_spec.rb +38 -0
- data/spec/lib/castle/{header_formatter_spec.rb → headers_formatter_spec.rb} +3 -3
- data/spec/lib/castle/utils/cloner_spec.rb +1 -0
- data/spec/lib/castle/utils/timestamp_spec.rb +3 -4
- data/spec/lib/castle/utils_spec.rb +1 -1
- data/spec/lib/castle/validators/not_supported_spec.rb +1 -3
- data/spec/spec_helper.rb +1 -2
- metadata +38 -10
- data/lib/castle/api/request/build.rb +0 -27
- data/lib/castle/header_formatter.rb +0 -9
- data/spec/lib/castle/api/request/build_spec.rb +0 -44
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'action_controller/railtie'
|
4
|
+
|
5
|
+
class TestApp < Rails::Application
|
6
|
+
secrets.secret_token = 'secret_token'
|
7
|
+
secrets.secret_key_base = 'secret_key_base'
|
8
|
+
|
9
|
+
config.logger = Logger.new($stdout)
|
10
|
+
Rails.logger = config.logger
|
11
|
+
|
12
|
+
routes.draw do
|
13
|
+
get '/' => 'home#index'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class HomeController < ActionController::Base
|
4
|
+
def index
|
5
|
+
request_context = ::Castle::Client.to_context(request)
|
6
|
+
track_options = ::Castle::Client.to_options(
|
7
|
+
event: '$login.succeeded',
|
8
|
+
user_id: '123',
|
9
|
+
properties: {
|
10
|
+
key: 'value'
|
11
|
+
},
|
12
|
+
user_traits: {
|
13
|
+
key: 'value'
|
14
|
+
}
|
15
|
+
)
|
16
|
+
client = ::Castle::Client.new(request_context)
|
17
|
+
client.track(track_options)
|
18
|
+
|
19
|
+
render inline: 'hello'
|
20
|
+
end
|
21
|
+
end
|
@@ -4,56 +4,69 @@ describe Castle::API::Request do
|
|
4
4
|
describe '#call' do
|
5
5
|
subject(:call) { described_class.call(command, api_secret, headers) }
|
6
6
|
|
7
|
+
let(:session) { instance_double('Castle::API::Session') }
|
7
8
|
let(:http) { instance_double('Net::HTTP') }
|
8
|
-
let(:request_build) { instance_double('Castle::API::Request::Build') }
|
9
9
|
let(:command) { Castle::Commands::Track.new({}).build(event: '$login.succeeded') }
|
10
10
|
let(:headers) { {} }
|
11
11
|
let(:api_secret) { 'secret' }
|
12
|
+
let(:request_build) { {} }
|
12
13
|
let(:expected_headers) { { 'Content-Type' => 'application/json' } }
|
13
14
|
|
14
15
|
before do
|
15
|
-
allow(
|
16
|
-
allow(
|
17
|
-
allow(
|
18
|
-
|
19
|
-
.and_return(request_build)
|
16
|
+
allow(Castle::API::Session).to receive(:instance).and_return(session)
|
17
|
+
allow(session).to receive(:http).and_return(http)
|
18
|
+
allow(http).to receive(:request)
|
19
|
+
allow(described_class).to receive(:build).and_return(request_build)
|
20
20
|
call
|
21
21
|
end
|
22
22
|
|
23
23
|
it do
|
24
|
-
expect(
|
25
|
-
.with(command, expected_headers, api_secret)
|
24
|
+
expect(described_class).to have_received(:build).with(command, expected_headers, api_secret)
|
26
25
|
end
|
26
|
+
|
27
27
|
it { expect(http).to have_received(:request).with(request_build) }
|
28
28
|
end
|
29
29
|
|
30
|
-
describe '#
|
31
|
-
subject(:
|
30
|
+
describe '#build' do
|
31
|
+
subject(:build) { described_class.build(command, headers, api_secret) }
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
Castle.config.host = 'localhost'
|
36
|
-
Castle.config.port = 3002
|
37
|
-
end
|
33
|
+
let(:headers) { { 'SAMPLE-HEADER' => '1' } }
|
34
|
+
let(:api_secret) { 'secret' }
|
38
35
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
36
|
+
context 'when get' do
|
37
|
+
let(:command) { Castle::Commands::Review.build(review_id) }
|
38
|
+
let(:review_id) { SecureRandom.uuid }
|
43
39
|
|
44
|
-
it { expect(
|
45
|
-
it { expect(
|
46
|
-
it { expect(
|
47
|
-
it { expect(
|
48
|
-
it { expect(
|
40
|
+
it { expect(build.body).to be_nil }
|
41
|
+
it { expect(build.method).to eql('GET') }
|
42
|
+
it { expect(build.path).to eql("/v1/#{command.path}") }
|
43
|
+
it { expect(build.to_hash).to have_key('authorization') }
|
44
|
+
it { expect(build.to_hash).to have_key('sample-header') }
|
45
|
+
it { expect(build.to_hash['sample-header']).to eql(['1']) }
|
49
46
|
end
|
50
47
|
|
51
|
-
context 'when
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
48
|
+
context 'when post' do
|
49
|
+
let(:time) { Time.now.utc.iso8601(3) }
|
50
|
+
let(:command) do
|
51
|
+
Castle::Commands::Track.new({}).build(event: '$login.succeeded', name: "\xC4")
|
52
|
+
end
|
53
|
+
let(:expected_body) do
|
54
|
+
{
|
55
|
+
event: '$login.succeeded',
|
56
|
+
name: '�',
|
57
|
+
context: {},
|
58
|
+
sent_at: time
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
before { allow(Castle::Utils::Timestamp).to receive(:call).and_return(time) }
|
63
|
+
|
64
|
+
it { expect(build.body).to be_eql(expected_body.to_json) }
|
65
|
+
it { expect(build.method).to eql('POST') }
|
66
|
+
it { expect(build.path).to eql("/v1/#{command.path}") }
|
67
|
+
it { expect(build.to_hash).to have_key('authorization') }
|
68
|
+
it { expect(build.to_hash).to have_key('sample-header') }
|
69
|
+
it { expect(build.to_hash['sample-header']).to eql(['1']) }
|
57
70
|
end
|
58
71
|
end
|
59
72
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Castle::API::Session do
|
4
|
+
describe '#get' do
|
5
|
+
it { expect(described_class.get).to eql(described_class.get) }
|
6
|
+
it { expect(described_class.get).to eql(described_class.instance.http) }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
subject(:session) { described_class.get }
|
11
|
+
|
12
|
+
after do
|
13
|
+
described_class.instance.reset
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when ssl false' do
|
17
|
+
before do
|
18
|
+
Castle.config.host = 'localhost'
|
19
|
+
Castle.config.port = 3002
|
20
|
+
described_class.instance.reset
|
21
|
+
end
|
22
|
+
|
23
|
+
after do
|
24
|
+
Castle.config.host = Castle::Configuration::HOST
|
25
|
+
Castle.config.port = Castle::Configuration::PORT
|
26
|
+
end
|
27
|
+
|
28
|
+
it { expect(session).to be_instance_of(Net::HTTP) }
|
29
|
+
it { expect(session.address).to eq('localhost') }
|
30
|
+
it { expect(session.port).to eq(3002) }
|
31
|
+
it { expect(session.use_ssl?).to be false }
|
32
|
+
it { expect(session.verify_mode).to be_nil }
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when ssl true' do
|
36
|
+
before do
|
37
|
+
described_class.instance.reset
|
38
|
+
end
|
39
|
+
|
40
|
+
it { expect(session).to be_instance_of(Net::HTTP) }
|
41
|
+
it { expect(session.address).to eq(Castle.config.host) }
|
42
|
+
it { expect(session.port).to eq(Castle.config.port) }
|
43
|
+
it { expect(session.use_ssl?).to be true }
|
44
|
+
it { expect(session.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/spec/lib/castle/api_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe Castle::API do
|
4
|
-
subject(:
|
4
|
+
subject(:call) { described_class.call(command) }
|
5
5
|
|
6
6
|
let(:command) { Castle::Commands::Track.new({}).build(event: '$login.succeeded') }
|
7
7
|
|
@@ -10,7 +10,7 @@ describe Castle::API do
|
|
10
10
|
|
11
11
|
it do
|
12
12
|
expect do
|
13
|
-
|
13
|
+
call
|
14
14
|
end.to raise_error(Castle::RequestError)
|
15
15
|
end
|
16
16
|
end
|
@@ -20,7 +20,7 @@ describe Castle::API do
|
|
20
20
|
|
21
21
|
it do
|
22
22
|
expect do
|
23
|
-
|
23
|
+
call
|
24
24
|
end.to raise_error(Castle::BadRequestError)
|
25
25
|
end
|
26
26
|
end
|
@@ -30,7 +30,7 @@ describe Castle::API do
|
|
30
30
|
|
31
31
|
it do
|
32
32
|
expect do
|
33
|
-
|
33
|
+
call
|
34
34
|
end.to raise_error(Castle::ConfigurationError)
|
35
35
|
end
|
36
36
|
end
|
@@ -244,11 +244,13 @@ describe Castle::Client do
|
|
244
244
|
it { expect(request_response[:action]).to be_eql('allow') }
|
245
245
|
it { expect(request_response[:user_id]).to be_eql('1234') }
|
246
246
|
it { expect(request_response[:failover]).to be true }
|
247
|
-
it { expect(request_response[:failover_reason]).to be_eql('Castle set to do not track.') }
|
247
|
+
it { expect(request_response[:failover_reason]).to be_eql('Castle is set to do not track.') }
|
248
248
|
end
|
249
249
|
|
250
250
|
context 'when request with fail' do
|
251
|
-
before
|
251
|
+
before do
|
252
|
+
allow(Castle::API).to receive(:request).and_raise(Castle::RequestError.new(Timeout::Error))
|
253
|
+
end
|
252
254
|
|
253
255
|
context 'with request error and throw strategy' do
|
254
256
|
before { allow(Castle.config).to receive(:failover_strategy).and_return(:throw) }
|
@@ -274,7 +276,7 @@ describe Castle::Client do
|
|
274
276
|
it { expect { request_response }.to raise_error(Castle::InternalServerError) }
|
275
277
|
end
|
276
278
|
|
277
|
-
|
279
|
+
describe 'not throw on eg deny strategy' do
|
278
280
|
it { assert_not_requested :post, 'https://:secret@api.castle.io/v1/authenticate' }
|
279
281
|
it { expect(request_response[:action]).to be_eql('allow') }
|
280
282
|
it { expect(request_response[:user_id]).to be_eql('1234') }
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
describe Castle::Configuration do
|
4
4
|
subject(:config) do
|
5
|
-
described_class.
|
5
|
+
described_class.instance
|
6
6
|
end
|
7
7
|
|
8
8
|
describe 'host' do
|
@@ -31,14 +31,26 @@ describe Castle::Configuration do
|
|
31
31
|
|
32
32
|
describe 'api_secret' do
|
33
33
|
context 'with env' do
|
34
|
+
let(:secret_key_env) { 'secret_key_env' }
|
35
|
+
let(:secret_key) { 'secret_key' }
|
36
|
+
|
34
37
|
before do
|
35
38
|
allow(ENV).to receive(:fetch).with(
|
36
39
|
'CASTLE_API_SECRET', ''
|
37
|
-
).and_return(
|
40
|
+
).and_return(secret_key_env)
|
41
|
+
config.reset
|
38
42
|
end
|
39
43
|
|
40
44
|
it do
|
41
|
-
expect(config.api_secret).to be_eql(
|
45
|
+
expect(config.api_secret).to be_eql(secret_key_env)
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when key is overwritten' do
|
49
|
+
before { config.api_secret = secret_key }
|
50
|
+
|
51
|
+
it do
|
52
|
+
expect(config.api_secret).to be_eql(secret_key)
|
53
|
+
end
|
42
54
|
end
|
43
55
|
end
|
44
56
|
|
@@ -48,13 +60,14 @@ describe Castle::Configuration do
|
|
48
60
|
before do
|
49
61
|
config.api_secret = value
|
50
62
|
end
|
63
|
+
|
51
64
|
it do
|
52
65
|
expect(config.api_secret).to be_eql(value)
|
53
66
|
end
|
54
67
|
end
|
55
68
|
|
56
69
|
it do
|
57
|
-
expect(config.api_secret).to be_eql('')
|
70
|
+
expect(config.api_secret).to be_eql('secret')
|
58
71
|
end
|
59
72
|
end
|
60
73
|
|
@@ -69,6 +82,7 @@ describe Castle::Configuration do
|
|
69
82
|
before do
|
70
83
|
config.request_timeout = value
|
71
84
|
end
|
85
|
+
|
72
86
|
it do
|
73
87
|
expect(config.request_timeout).to be_eql(value)
|
74
88
|
end
|
@@ -84,6 +98,7 @@ describe Castle::Configuration do
|
|
84
98
|
before do
|
85
99
|
config.whitelisted = ['header']
|
86
100
|
end
|
101
|
+
|
87
102
|
it do
|
88
103
|
expect(config.whitelisted).to be_eql(['Header'])
|
89
104
|
end
|
@@ -99,6 +114,7 @@ describe Castle::Configuration do
|
|
99
114
|
before do
|
100
115
|
config.blacklisted = ['header']
|
101
116
|
end
|
117
|
+
|
102
118
|
it do
|
103
119
|
expect(config.blacklisted).to be_eql(['Header'])
|
104
120
|
end
|
@@ -114,6 +130,7 @@ describe Castle::Configuration do
|
|
114
130
|
before do
|
115
131
|
config.failover_strategy = :deny
|
116
132
|
end
|
133
|
+
|
117
134
|
it do
|
118
135
|
expect(config.failover_strategy).to be_eql(:deny)
|
119
136
|
end
|
@@ -4,37 +4,37 @@ describe Castle::Context::Default do
|
|
4
4
|
subject { described_class.new(request, nil) }
|
5
5
|
|
6
6
|
let(:ip) { '1.2.3.4' }
|
7
|
-
let(:
|
7
|
+
let(:client_id) { 'abcd' }
|
8
8
|
|
9
9
|
let(:env) do
|
10
10
|
Rack::MockRequest.env_for('/',
|
11
11
|
'HTTP_X_FORWARDED_FOR' => ip,
|
12
12
|
'HTTP_ACCEPT_LANGUAGE' => 'en',
|
13
13
|
'HTTP_USER_AGENT' => 'test',
|
14
|
-
'HTTP_COOKIE' => "__cid=#{
|
14
|
+
'HTTP_COOKIE' => "__cid=#{client_id};other=efgh")
|
15
15
|
end
|
16
16
|
let(:request) { Rack::Request.new(env) }
|
17
17
|
let(:default_context) { subject.call }
|
18
18
|
let(:version) { '2.2.0' }
|
19
|
-
|
20
|
-
|
21
|
-
stub_const('Castle::VERSION', version)
|
22
|
-
end
|
23
|
-
|
24
|
-
it { expect(default_context[:active]).to be_eql(true) }
|
25
|
-
it { expect(default_context[:origin]).to be_eql('web') }
|
26
|
-
|
27
|
-
it do
|
28
|
-
expect(default_context[:headers]).to be_eql(
|
19
|
+
let(:result_headers) do
|
20
|
+
{
|
29
21
|
'X-Forwarded-For' => '1.2.3.4',
|
30
22
|
'Accept-Language' => 'en',
|
31
23
|
'User-Agent' => 'test',
|
32
24
|
'Content-Length' => '0',
|
33
25
|
'Cookie' => true
|
34
|
-
|
26
|
+
}
|
35
27
|
end
|
36
28
|
|
29
|
+
before do
|
30
|
+
stub_const('Castle::VERSION', version)
|
31
|
+
end
|
32
|
+
|
33
|
+
it { expect(default_context[:active]).to be_eql(true) }
|
34
|
+
it { expect(default_context[:origin]).to be_eql('web') }
|
35
|
+
it { expect(default_context[:headers]).to be_eql(result_headers) }
|
37
36
|
it { expect(default_context[:ip]).to be_eql(ip) }
|
37
|
+
it { expect(default_context[:client_id]).to be_eql(client_id) }
|
38
38
|
it { expect(default_context[:library][:name]).to be_eql('castle-rb') }
|
39
39
|
it { expect(default_context[:library][:version]).to be_eql(version) }
|
40
40
|
it { expect(default_context[:user_agent]).to be_eql('test') }
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe Castle::Extractors::ClientId do
|
4
|
-
subject(:extractor) { described_class.new(
|
4
|
+
subject(:extractor) { described_class.new(formatted_headers, cookies) }
|
5
5
|
|
6
|
+
let(:formatted_headers) { Castle::HeadersFilter.new(request).call }
|
6
7
|
let(:client_id_cookie) { 'abcd' }
|
7
8
|
let(:client_id_header) { 'abcde' }
|
8
9
|
let(:cookies) { request.cookies }
|
@@ -1,78 +1,94 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe Castle::Extractors::Headers do
|
4
|
-
subject(:headers) { described_class.new(
|
5
|
-
|
6
|
-
let(:
|
7
|
-
|
8
|
-
|
9
|
-
'
|
10
|
-
'
|
11
|
-
'
|
12
|
-
'
|
13
|
-
'
|
14
|
-
'
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
4
|
+
subject(:headers) { described_class.new(formatted_headers).call }
|
5
|
+
|
6
|
+
let(:formatted_headers) do
|
7
|
+
{
|
8
|
+
'Content-Length' => '0',
|
9
|
+
'Authorization' => 'Basic 123456',
|
10
|
+
'Cookie' => '__cid=abcd;other=efgh',
|
11
|
+
'Ok' => 'OK',
|
12
|
+
'Accept' => 'application/json',
|
13
|
+
'X-Forwarded-For' => '1.2.3.4',
|
14
|
+
'User-Agent' => 'Mozilla 1234'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
Castle.config.whitelisted = %w[]
|
20
|
+
Castle.config.blacklisted = %w[]
|
20
21
|
end
|
21
|
-
let(:request) { Rack::Request.new(env) }
|
22
22
|
|
23
23
|
context 'when whitelist is not set in the configuration' do
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
let(:result) do
|
25
|
+
{
|
26
|
+
'Accept' => 'application/json',
|
27
|
+
'Authorization' => true,
|
28
|
+
'Cookie' => true,
|
29
|
+
'Content-Length' => '0',
|
30
|
+
'Ok' => 'OK',
|
31
|
+
'User-Agent' => 'Mozilla 1234',
|
32
|
+
'X-Forwarded-For' => '1.2.3.4'
|
33
|
+
}
|
32
34
|
end
|
35
|
+
|
36
|
+
it { expect(headers).to eq(result) }
|
33
37
|
end
|
34
38
|
|
35
39
|
context 'when whitelist is set in the configuration' do
|
36
40
|
before { Castle.config.whitelisted = %w[Accept OK] }
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
let(:result) do
|
43
|
+
{
|
44
|
+
'Accept' => 'application/json',
|
45
|
+
'Authorization' => true,
|
46
|
+
'Cookie' => true,
|
47
|
+
'Content-Length' => true,
|
48
|
+
'Ok' => 'OK',
|
49
|
+
'User-Agent' => 'Mozilla 1234',
|
50
|
+
'X-Forwarded-For' => true
|
51
|
+
}
|
46
52
|
end
|
53
|
+
|
54
|
+
it { expect(headers).to eq(result) }
|
47
55
|
end
|
48
56
|
|
49
57
|
context 'when blacklist is set in the configuration' do
|
50
58
|
context 'with a User-Agent' do
|
59
|
+
let(:result) do
|
60
|
+
{
|
61
|
+
'Accept' => 'application/json',
|
62
|
+
'Authorization' => true,
|
63
|
+
'Cookie' => true,
|
64
|
+
'Content-Length' => '0',
|
65
|
+
'Ok' => 'OK',
|
66
|
+
'User-Agent' => 'Mozilla 1234',
|
67
|
+
'X-Forwarded-For' => '1.2.3.4'
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
51
71
|
before { Castle.config.blacklisted = %w[User-Agent] }
|
52
72
|
|
53
|
-
it
|
54
|
-
is_expected.to eq('Accept' => 'application/json',
|
55
|
-
'Authorization' => true,
|
56
|
-
'Cookie' => true,
|
57
|
-
'Content-Length' => '0',
|
58
|
-
'Ok' => 'OK',
|
59
|
-
'User-Agent' => 'Mozilla 1234',
|
60
|
-
'X-Forwarded-For' => '1.2.3.4')
|
61
|
-
end
|
73
|
+
it { expect(headers).to eq(result) }
|
62
74
|
end
|
63
75
|
|
64
76
|
context 'with a different header' do
|
77
|
+
let(:result) do
|
78
|
+
{
|
79
|
+
'Accept' => true,
|
80
|
+
'Authorization' => true,
|
81
|
+
'Cookie' => true,
|
82
|
+
'Content-Length' => '0',
|
83
|
+
'Ok' => 'OK',
|
84
|
+
'User-Agent' => 'Mozilla 1234',
|
85
|
+
'X-Forwarded-For' => '1.2.3.4'
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
65
89
|
before { Castle.config.blacklisted = %w[Accept] }
|
66
90
|
|
67
|
-
it
|
68
|
-
is_expected.to eq('Accept' => true,
|
69
|
-
'Authorization' => true,
|
70
|
-
'Cookie' => true,
|
71
|
-
'Content-Length' => '0',
|
72
|
-
'Ok' => 'OK',
|
73
|
-
'User-Agent' => 'Mozilla 1234',
|
74
|
-
'X-Forwarded-For' => '1.2.3.4')
|
75
|
-
end
|
91
|
+
it { expect(headers).to eq(result) }
|
76
92
|
end
|
77
93
|
end
|
78
94
|
|