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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +57 -5
  3. data/lib/castle.rb +5 -3
  4. data/lib/castle/api.rb +12 -6
  5. data/lib/castle/api/request.rb +15 -10
  6. data/lib/castle/api/session.rb +39 -0
  7. data/lib/castle/client.rb +23 -18
  8. data/lib/castle/configuration.rb +49 -6
  9. data/lib/castle/context/default.rb +36 -18
  10. data/lib/castle/context/sanitizer.rb +1 -0
  11. data/lib/castle/events.rb +49 -0
  12. data/lib/castle/extractors/client_id.rb +7 -3
  13. data/lib/castle/extractors/headers.rb +24 -30
  14. data/lib/castle/extractors/ip.rb +69 -5
  15. data/lib/castle/headers_filter.rb +35 -0
  16. data/lib/castle/headers_formatter.rb +22 -0
  17. data/lib/castle/validators/not_supported.rb +1 -0
  18. data/lib/castle/validators/present.rb +1 -0
  19. data/lib/castle/version.rb +1 -1
  20. data/spec/integration/rails/rails_spec.rb +61 -0
  21. data/spec/integration/rails/support/all.rb +6 -0
  22. data/spec/integration/rails/support/application.rb +15 -0
  23. data/spec/integration/rails/support/home_controller.rb +21 -0
  24. data/spec/lib/castle/api/request_spec.rb +43 -30
  25. data/spec/lib/castle/api/session_spec.rb +47 -0
  26. data/spec/lib/castle/api_spec.rb +4 -4
  27. data/spec/lib/castle/client_spec.rb +5 -3
  28. data/spec/lib/castle/commands/authenticate_spec.rb +1 -0
  29. data/spec/lib/castle/commands/identify_spec.rb +1 -0
  30. data/spec/lib/castle/commands/impersonate_spec.rb +1 -0
  31. data/spec/lib/castle/commands/track_spec.rb +1 -0
  32. data/spec/lib/castle/configuration_spec.rb +21 -4
  33. data/spec/lib/castle/context/default_spec.rb +13 -13
  34. data/spec/lib/castle/events_spec.rb +5 -0
  35. data/spec/lib/castle/extractors/client_id_spec.rb +2 -1
  36. data/spec/lib/castle/extractors/headers_spec.rb +67 -51
  37. data/spec/lib/castle/extractors/ip_spec.rb +89 -12
  38. data/spec/lib/castle/headers_filter_spec.rb +38 -0
  39. data/spec/lib/castle/{header_formatter_spec.rb → headers_formatter_spec.rb} +3 -3
  40. data/spec/lib/castle/utils/cloner_spec.rb +1 -0
  41. data/spec/lib/castle/utils/timestamp_spec.rb +3 -4
  42. data/spec/lib/castle/utils_spec.rb +1 -1
  43. data/spec/lib/castle/validators/not_supported_spec.rb +1 -3
  44. data/spec/spec_helper.rb +1 -2
  45. metadata +38 -10
  46. data/lib/castle/api/request/build.rb +0 -27
  47. data/lib/castle/header_formatter.rb +0 -9
  48. data/spec/lib/castle/api/request/build_spec.rb +0 -44
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV['RAILS_ENV'] = 'test'
4
+ require_relative 'application'
5
+ require_relative 'home_controller'
6
+ require 'rspec/rails'
@@ -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(described_class).to receive(:http).and_return(http)
16
- allow(http).to receive(:request).with(request_build)
17
- allow(Castle::API::Request::Build).to receive(:call)
18
- .with(command, expected_headers, api_secret)
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(Castle::API::Request::Build).to have_received(:call)
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 '#http' do
31
- subject(:http) { described_class.http }
30
+ describe '#build' do
31
+ subject(:build) { described_class.build(command, headers, api_secret) }
32
32
 
33
- context 'when ssl false' do
34
- before do
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
- after do
40
- Castle.config.host = Castle::Configuration::HOST
41
- Castle.config.port = Castle::Configuration::PORT
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(http).to be_instance_of(Net::HTTP) }
45
- it { expect(http.address).to eq(Castle.config.host) }
46
- it { expect(http.port).to eq(Castle.config.port) }
47
- it { expect(http.use_ssl?).to be false }
48
- it { expect(http.verify_mode).to be_nil }
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 ssl true' do
52
- it { expect(http).to be_instance_of(Net::HTTP) }
53
- it { expect(http.address).to eq(Castle.config.host) }
54
- it { expect(http.port).to eq(Castle.config.port) }
55
- it { expect(http.use_ssl?).to be true }
56
- it { expect(http.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER) }
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Castle::API do
4
- subject(:request) { described_class.request(command) }
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
- request
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
- request
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
- request
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 { allow(Castle::API).to receive(:request).and_raise(Castle::RequestError.new(Timeout::Error)) }
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
- context 'not throw on eg deny strategy' do
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') }
@@ -10,6 +10,7 @@ describe Castle::Commands::Authenticate do
10
10
  let(:time_auto) { time_now.utc.iso8601(3) }
11
11
 
12
12
  before { Timecop.freeze(time_now) }
13
+
13
14
  after { Timecop.return }
14
15
 
15
16
  describe '.build' do
@@ -10,6 +10,7 @@ describe Castle::Commands::Identify do
10
10
  let(:time_auto) { time_now.utc.iso8601(3) }
11
11
 
12
12
  before { Timecop.freeze(time_now) }
13
+
13
14
  after { Timecop.return }
14
15
 
15
16
  describe '.build' do
@@ -11,6 +11,7 @@ describe Castle::Commands::Impersonate do
11
11
  let(:time_auto) { time_now.utc.iso8601(3) }
12
12
 
13
13
  before { Timecop.freeze(time_now) }
14
+
14
15
  after { Timecop.return }
15
16
 
16
17
  describe '.build' do
@@ -10,6 +10,7 @@ describe Castle::Commands::Track do
10
10
  let(:time_auto) { time_now.utc.iso8601(3) }
11
11
 
12
12
  before { Timecop.freeze(time_now) }
13
+
13
14
  after { Timecop.return }
14
15
 
15
16
  describe '#build' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  describe Castle::Configuration do
4
4
  subject(:config) do
5
- described_class.new
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('secret_key')
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('secret_key')
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(:cookie_id) { 'abcd' }
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=#{cookie_id};other=efgh")
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
- before do
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') }
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Castle::Events do
4
+ it { expect(described_class::LOGIN_SUCCEEDED).to eq('$login.succeeded') }
5
+ end
@@ -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(request, cookies) }
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(request).call }
5
-
6
- let(:client_id) { 'abcd' }
7
- let(:env) do
8
- result = Rack::MockRequest.env_for(
9
- '/',
10
- 'Action-Dispatch.request.content-Type' => 'application/json',
11
- 'HTTP_AUTHORIZATION' => 'Basic 123456',
12
- 'HTTP_COOKIE' => "__cid=#{client_id};other=efgh",
13
- 'HTTP_ACCEPT' => 'application/json',
14
- 'HTTP_X_FORWARDED_FOR' => '1.2.3.4',
15
- 'HTTP_USER_AGENT' => 'Mozilla 1234',
16
- 'TEST' => '1'
17
- )
18
- result[:HTTP_OK] = 'OK'
19
- result
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
- it do
25
- is_expected.to eq('Accept' => 'application/json',
26
- 'Authorization' => true,
27
- 'Cookie' => true,
28
- 'Content-Length' => '0',
29
- 'Ok' => 'OK',
30
- 'User-Agent' => 'Mozilla 1234',
31
- 'X-Forwarded-For' => '1.2.3.4')
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
- it do
39
- is_expected.to eq('Accept' => 'application/json',
40
- 'Authorization' => true,
41
- 'Cookie' => true,
42
- 'Content-Length' => true,
43
- 'Ok' => 'OK',
44
- 'User-Agent' => 'Mozilla 1234',
45
- 'X-Forwarded-For' => true)
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 do
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 do
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