castle-rb 7.2.0 → 8.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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/lib/castle/api/authenticate.rb +3 -12
  3. data/lib/castle/api/end_impersonation.rb +1 -3
  4. data/lib/castle/api/filter.rb +2 -10
  5. data/lib/castle/api/log.rb +2 -10
  6. data/lib/castle/api/risk.rb +2 -10
  7. data/lib/castle/api/start_impersonation.rb +1 -3
  8. data/lib/castle/api/track.rb +1 -3
  9. data/lib/castle/client.rb +1 -5
  10. data/lib/castle/commands/log.rb +1 -5
  11. data/lib/castle/commands/risk.rb +1 -5
  12. data/lib/castle/configuration.rb +2 -5
  13. data/lib/castle/core/process_response.rb +4 -3
  14. data/lib/castle/core/send_request.rb +1 -3
  15. data/lib/castle/errors.rb +4 -0
  16. data/lib/castle/headers/extract.rb +1 -3
  17. data/lib/castle/headers/filter.rb +2 -3
  18. data/lib/castle/payload/prepare.rb +1 -2
  19. data/lib/castle/session.rb +1 -1
  20. data/lib/castle/version.rb +1 -1
  21. data/lib/castle.rb +1 -3
  22. data/spec/integration/rails/rails_spec.rb +9 -3
  23. data/spec/integration/rails/support/application.rb +2 -2
  24. data/spec/integration/rails/support/home_controller.rb +4 -30
  25. data/spec/lib/castle/api/approve_device_spec.rb +2 -6
  26. data/spec/lib/castle/api/authenticate_spec.rb +22 -25
  27. data/spec/lib/castle/api/end_impersonation_spec.rb +8 -14
  28. data/spec/lib/castle/api/get_device_spec.rb +1 -3
  29. data/spec/lib/castle/api/get_devices_for_user_spec.rb +1 -3
  30. data/spec/lib/castle/api/report_device_spec.rb +2 -6
  31. data/spec/lib/castle/api/start_impersonation_spec.rb +8 -14
  32. data/spec/lib/castle/api/track_spec.rb +9 -16
  33. data/spec/lib/castle/client_id/extract_spec.rb +2 -9
  34. data/spec/lib/castle/client_spec.rb +32 -78
  35. data/spec/lib/castle/command_spec.rb +3 -3
  36. data/spec/lib/castle/commands/approve_device_spec.rb +2 -2
  37. data/spec/lib/castle/commands/authenticate_spec.rb +17 -24
  38. data/spec/lib/castle/commands/end_impersonation_spec.rb +14 -21
  39. data/spec/lib/castle/commands/filter_spec.rb +15 -15
  40. data/spec/lib/castle/commands/get_device_spec.rb +2 -2
  41. data/spec/lib/castle/commands/get_devices_for_user_spec.rb +2 -2
  42. data/spec/lib/castle/commands/log_spec.rb +15 -15
  43. data/spec/lib/castle/commands/report_device_spec.rb +2 -2
  44. data/spec/lib/castle/commands/risk_spec.rb +15 -15
  45. data/spec/lib/castle/commands/start_impersonation_spec.rb +14 -21
  46. data/spec/lib/castle/commands/track_spec.rb +19 -24
  47. data/spec/lib/castle/configuration_spec.rb +1 -1
  48. data/spec/lib/castle/context/get_default_spec.rb +9 -8
  49. data/spec/lib/castle/context/prepare_spec.rb +3 -4
  50. data/spec/lib/castle/core/process_response_spec.rb +3 -6
  51. data/spec/lib/castle/core/process_webhook_spec.rb +12 -6
  52. data/spec/lib/castle/core/send_request_spec.rb +7 -11
  53. data/spec/lib/castle/failover/strategy_spec.rb +5 -5
  54. data/spec/lib/castle/headers/extract_spec.rb +1 -1
  55. data/spec/lib/castle/headers/filter_spec.rb +6 -3
  56. data/spec/lib/castle/headers/format_spec.rb +5 -5
  57. data/spec/lib/castle/ips/extract_spec.rb +2 -6
  58. data/spec/lib/castle/logger_spec.rb +2 -1
  59. data/spec/lib/castle/payload/prepare_spec.rb +4 -7
  60. data/spec/lib/castle/secure_mode_spec.rb +1 -3
  61. data/spec/lib/castle/session_spec.rb +1 -5
  62. data/spec/lib/castle/singleton_configuration_spec.rb +1 -1
  63. data/spec/lib/castle/utils/clone_spec.rb +1 -1
  64. data/spec/lib/castle/utils/merge_spec.rb +2 -4
  65. data/spec/lib/castle/validators/not_supported_spec.rb +1 -6
  66. data/spec/lib/castle/validators/present_spec.rb +2 -9
  67. data/spec/lib/castle/verdict_spec.rb +3 -3
  68. data/spec/lib/castle/webhooks/verify_spec.rb +12 -6
  69. data/spec/lib/castle_spec.rb +5 -7
  70. data/spec/support/shared_examples/action_request.rb +16 -34
  71. data/spec/support/shared_examples/configuration.rb +14 -16
  72. metadata +48 -48
@@ -29,45 +29,45 @@ describe Castle::Commands::Risk do
29
29
  let(:payload) { default_payload.merge(properties: { test: '1' }) }
30
30
  let(:command_data) { default_payload.merge(properties: { test: '1' }, context: context) }
31
31
 
32
- it { expect(command.method).to be_eql(:post) }
33
- it { expect(command.path).to be_eql('risk') }
34
- it { expect(command.data).to be_eql(command_data) }
32
+ it { expect(command.method).to be(:post) }
33
+ it { expect(command.path).to eql('risk') }
34
+ it { expect(command.data).to eql(command_data) }
35
35
  end
36
36
 
37
37
  context 'with user_traits' do
38
38
  let(:payload) { default_payload.merge(user_traits: { test: '1' }) }
39
39
  let(:command_data) { default_payload.merge(user_traits: { test: '1' }, context: context) }
40
40
 
41
- it { expect(command.method).to be_eql(:post) }
42
- it { expect(command.path).to be_eql('risk') }
43
- it { expect(command.data).to be_eql(command_data) }
41
+ it { expect(command.method).to be(:post) }
42
+ it { expect(command.path).to eql('risk') }
43
+ it { expect(command.data).to eql(command_data) }
44
44
  end
45
45
 
46
46
  context 'when active true' do
47
47
  let(:payload) { default_payload.merge(context: context.merge(active: true)) }
48
48
  let(:command_data) { default_payload.merge(context: context.merge(active: true)) }
49
49
 
50
- it { expect(command.method).to be_eql(:post) }
51
- it { expect(command.path).to be_eql('risk') }
52
- it { expect(command.data).to be_eql(command_data) }
50
+ it { expect(command.method).to be(:post) }
51
+ it { expect(command.path).to eql('risk') }
52
+ it { expect(command.data).to eql(command_data) }
53
53
  end
54
54
 
55
55
  context 'when active false' do
56
56
  let(:payload) { default_payload.merge(context: context.merge(active: false)) }
57
57
  let(:command_data) { default_payload.merge(context: context.merge(active: false)) }
58
58
 
59
- it { expect(command.method).to be_eql(:post) }
60
- it { expect(command.path).to be_eql('risk') }
61
- it { expect(command.data).to be_eql(command_data) }
59
+ it { expect(command.method).to be(:post) }
60
+ it { expect(command.path).to eql('risk') }
61
+ it { expect(command.data).to eql(command_data) }
62
62
  end
63
63
 
64
64
  context 'when active string' do
65
65
  let(:payload) { default_payload.merge(context: context.merge(active: 'string')) }
66
66
  let(:command_data) { default_payload.merge(context: context) }
67
67
 
68
- it { expect(command.method).to be_eql(:post) }
69
- it { expect(command.path).to be_eql('risk') }
70
- it { expect(command.data).to be_eql(command_data) }
68
+ it { expect(command.method).to be(:post) }
69
+ it { expect(command.path).to eql('risk') }
70
+ it { expect(command.data).to eql(command_data) }
71
71
  end
72
72
  end
73
73
  end
@@ -19,40 +19,38 @@ describe Castle::Commands::StartImpersonation do
19
19
 
20
20
  context 'with impersonator' do
21
21
  let(:payload) { default_payload.merge(properties: { impersonator: impersonator }) }
22
- let(:command_data) do
23
- default_payload.merge(properties: { impersonator: impersonator }, context: context)
24
- end
22
+ let(:command_data) { default_payload.merge(properties: { impersonator: impersonator }, context: context) }
25
23
 
26
- it { expect(command.method).to be_eql(:post) }
27
- it { expect(command.path).to be_eql('impersonate') }
28
- it { expect(command.data).to be_eql(command_data) }
24
+ it { expect(command.method).to be(:post) }
25
+ it { expect(command.path).to eql('impersonate') }
26
+ it { expect(command.data).to eql(command_data) }
29
27
  end
30
28
 
31
29
  context 'when active true' do
32
30
  let(:payload) { default_payload.merge(context: context.merge(active: true)) }
33
31
  let(:command_data) { default_payload.merge(context: context.merge(active: true)) }
34
32
 
35
- it { expect(command.method).to be_eql(:post) }
36
- it { expect(command.path).to be_eql('impersonate') }
37
- it { expect(command.data).to be_eql(command_data) }
33
+ it { expect(command.method).to be(:post) }
34
+ it { expect(command.path).to eql('impersonate') }
35
+ it { expect(command.data).to eql(command_data) }
38
36
  end
39
37
 
40
38
  context 'when active false' do
41
39
  let(:payload) { default_payload.merge(context: context.merge(active: false)) }
42
40
  let(:command_data) { default_payload.merge(context: context.merge(active: false)) }
43
41
 
44
- it { expect(command.method).to be_eql(:post) }
45
- it { expect(command.path).to be_eql('impersonate') }
46
- it { expect(command.data).to be_eql(command_data) }
42
+ it { expect(command.method).to be(:post) }
43
+ it { expect(command.path).to eql('impersonate') }
44
+ it { expect(command.data).to eql(command_data) }
47
45
  end
48
46
 
49
47
  context 'when active string' do
50
48
  let(:payload) { default_payload.merge(context: context.merge(active: 'string')) }
51
49
  let(:command_data) { default_payload.merge(context: context) }
52
50
 
53
- it { expect(command.method).to be_eql(:post) }
54
- it { expect(command.path).to be_eql('impersonate') }
55
- it { expect(command.data).to be_eql(command_data) }
51
+ it { expect(command.method).to be(:post) }
52
+ it { expect(command.path).to eql('impersonate') }
53
+ it { expect(command.data).to eql(command_data) }
56
54
  end
57
55
  end
58
56
 
@@ -62,12 +60,7 @@ describe Castle::Commands::StartImpersonation do
62
60
  context 'when user_id not present' do
63
61
  let(:payload) { {} }
64
62
 
65
- it do
66
- expect { validate! }.to raise_error(
67
- Castle::InvalidParametersError,
68
- 'user_id is missing or empty'
69
- )
70
- end
63
+ it { expect { validate! }.to raise_error(Castle::InvalidParametersError, 'user_id is missing or empty') }
71
64
  end
72
65
 
73
66
  context 'when user_id present' do
@@ -20,54 +20,54 @@ describe Castle::Commands::Track do
20
20
  let(:payload) { default_payload.merge(user_id: '1234') }
21
21
  let(:command_data) { default_payload.merge(user_id: '1234', context: context) }
22
22
 
23
- it { expect(command.method).to be_eql(:post) }
24
- it { expect(command.path).to be_eql('track') }
25
- it { expect(command.data).to be_eql(command_data) }
23
+ it { expect(command.method).to be(:post) }
24
+ it { expect(command.path).to eql('track') }
25
+ it { expect(command.data).to eql(command_data) }
26
26
  end
27
27
 
28
28
  context 'with properties' do
29
29
  let(:payload) { default_payload.merge(properties: { test: '1' }) }
30
30
  let(:command_data) { default_payload.merge(properties: { test: '1' }, context: context) }
31
31
 
32
- it { expect(command.method).to be_eql(:post) }
33
- it { expect(command.path).to be_eql('track') }
34
- it { expect(command.data).to be_eql(command_data) }
32
+ it { expect(command.method).to be(:post) }
33
+ it { expect(command.path).to eql('track') }
34
+ it { expect(command.data).to eql(command_data) }
35
35
  end
36
36
 
37
37
  context 'with user_traits' do
38
38
  let(:payload) { default_payload.merge(user_traits: { test: '1' }) }
39
39
  let(:command_data) { default_payload.merge(user_traits: { test: '1' }, context: context) }
40
40
 
41
- it { expect(command.method).to be_eql(:post) }
42
- it { expect(command.path).to be_eql('track') }
43
- it { expect(command.data).to be_eql(command_data) }
41
+ it { expect(command.method).to be(:post) }
42
+ it { expect(command.path).to eql('track') }
43
+ it { expect(command.data).to eql(command_data) }
44
44
  end
45
45
 
46
46
  context 'when active true' do
47
47
  let(:payload) { default_payload.merge(context: context.merge(active: true)) }
48
48
  let(:command_data) { default_payload.merge(context: context.merge(active: true)) }
49
49
 
50
- it { expect(command.method).to be_eql(:post) }
51
- it { expect(command.path).to be_eql('track') }
52
- it { expect(command.data).to be_eql(command_data) }
50
+ it { expect(command.method).to be(:post) }
51
+ it { expect(command.path).to eql('track') }
52
+ it { expect(command.data).to eql(command_data) }
53
53
  end
54
54
 
55
55
  context 'when active false' do
56
56
  let(:payload) { default_payload.merge(context: context.merge(active: false)) }
57
57
  let(:command_data) { default_payload.merge(context: context.merge(active: false)) }
58
58
 
59
- it { expect(command.method).to be_eql(:post) }
60
- it { expect(command.path).to be_eql('track') }
61
- it { expect(command.data).to be_eql(command_data) }
59
+ it { expect(command.method).to be(:post) }
60
+ it { expect(command.path).to eql('track') }
61
+ it { expect(command.data).to eql(command_data) }
62
62
  end
63
63
 
64
64
  context 'when active string' do
65
65
  let(:payload) { default_payload.merge(context: context.merge(active: 'string')) }
66
66
  let(:command_data) { default_payload.merge(context: context) }
67
67
 
68
- it { expect(command.method).to be_eql(:post) }
69
- it { expect(command.path).to be_eql('track') }
70
- it { expect(command.data).to be_eql(command_data) }
68
+ it { expect(command.method).to be(:post) }
69
+ it { expect(command.path).to eql('track') }
70
+ it { expect(command.data).to eql(command_data) }
71
71
  end
72
72
  end
73
73
 
@@ -77,12 +77,7 @@ describe Castle::Commands::Track do
77
77
  context 'when event not present' do
78
78
  let(:payload) { {} }
79
79
 
80
- it do
81
- expect { validate! }.to raise_error(
82
- Castle::InvalidParametersError,
83
- 'event is missing or empty'
84
- )
85
- end
80
+ it { expect { validate! }.to raise_error(Castle::InvalidParametersError, 'event is missing or empty') }
86
81
  end
87
82
 
88
83
  context 'when event present' do
@@ -10,5 +10,5 @@ describe Castle::Configuration do
10
10
  it_behaves_like 'configuration_failover_strategy'
11
11
  it_behaves_like 'configuration_api_secret'
12
12
 
13
- it { expect(config.api_secret).to be_eql('') }
13
+ it { expect(config.api_secret).to eql('') }
14
14
  end
@@ -12,7 +12,8 @@ describe Castle::Context::GetDefault do
12
12
  'HTTP_X_FORWARDED_FOR' => ip,
13
13
  'HTTP_ACCEPT_LANGUAGE' => 'en',
14
14
  'HTTP_USER_AGENT' => 'test',
15
- 'HTTP_COOKIE' => "__cid=#{client_id};other=efgh"
15
+ 'HTTP_COOKIE' => "__cid=#{client_id};other=efgh",
16
+ 'HTTP_CONTENT_LENGTH' => '0'
16
17
  )
17
18
  end
18
19
  let(:request) { Rack::Request.new(env) }
@@ -30,11 +31,11 @@ describe Castle::Context::GetDefault do
30
31
 
31
32
  before { stub_const('Castle::VERSION', version) }
32
33
 
33
- it { expect(default_context[:active]).to be_eql(true) }
34
- it { expect(default_context[:headers]).to be_eql(result_headers) }
35
- it { expect(default_context[:ip]).to be_eql(ip) }
36
- it { expect(default_context[:client_id]).to be_eql(client_id) }
37
- it { expect(default_context[:library][:name]).to be_eql('castle-rb') }
38
- it { expect(default_context[:library][:version]).to be_eql(version) }
39
- it { expect(default_context[:user_agent]).to be_eql('test') }
34
+ it { expect(default_context[:active]).to be(true) }
35
+ it { expect(default_context[:headers]).to eql(result_headers) }
36
+ it { expect(default_context[:ip]).to eql(ip) }
37
+ it { expect(default_context[:client_id]).to eql(client_id) }
38
+ it { expect(default_context[:library][:name]).to eql('castle-rb') }
39
+ it { expect(default_context[:library][:version]).to eql(version) }
40
+ it { expect(default_context[:user_agent]).to eql('test') }
40
41
  end
@@ -9,7 +9,8 @@ describe Castle::Context::Prepare do
9
9
  '/',
10
10
  'HTTP_USER_AGENT' => ua,
11
11
  'HTTP_X_FORWARDED_FOR' => ip,
12
- 'HTTP_COOKIE' => "__cid=#{cookie_id};other=efgh"
12
+ 'HTTP_COOKIE' => "__cid=#{cookie_id};other=efgh",
13
+ 'HTTP_CONTENT_LENGTH' => '0'
13
14
  )
14
15
  end
15
16
  let(:request) { Rack::Request.new(env) }
@@ -27,9 +28,7 @@ describe Castle::Context::Prepare do
27
28
  }
28
29
  end
29
30
 
30
- let(:headers) do
31
- { 'Content-Length': '0', 'User-Agent': ua, 'X-Forwarded-For': ip.to_s, 'Cookie': true }
32
- end
31
+ let(:headers) { { 'Content-Length': '0', 'User-Agent': ua, 'X-Forwarded-For': ip.to_s, Cookie: true } }
33
32
 
34
33
  before { stub_const('Castle::VERSION', '6.0.0') }
35
34
 
@@ -18,17 +18,13 @@ describe Castle::Core::ProcessResponse do
18
18
  end
19
19
 
20
20
  context 'when allow with additional props' do
21
- let(:response) do
22
- OpenStruct.new(body: '{"action":"allow","user_id":"12345","internal":{}}', code: 200)
23
- end
21
+ let(:response) { OpenStruct.new(body: '{"action":"allow","user_id":"12345","internal":{}}', code: 200) }
24
22
 
25
23
  it { expect(call).to eql({ action: 'allow', user_id: '12345', internal: {} }) }
26
24
  end
27
25
 
28
26
  context 'when deny without risk policy' do
29
- let(:response) do
30
- OpenStruct.new(body: '{"action":"deny","user_id":"1","device_token":"abc"}', code: 200)
31
- end
27
+ let(:response) { OpenStruct.new(body: '{"action":"deny","user_id":"1","device_token":"abc"}', code: 200) }
32
28
 
33
29
  it { expect(call).to eql({ action: 'deny', user_id: '1', device_token: 'abc' }) }
34
30
  end
@@ -100,6 +96,7 @@ describe Castle::Core::ProcessResponse do
100
96
  it_behaves_like 'response_failed', '404', Castle::NotFoundError
101
97
  it_behaves_like 'response_failed', '419', Castle::UserUnauthorizedError
102
98
  it_behaves_like 'response_failed', '422', Castle::InvalidParametersError
99
+ it_behaves_like 'response_failed', '429', Castle::RateLimitError
103
100
  it_behaves_like 'response_failed', '499', Castle::ApiError
104
101
  it_behaves_like 'response_failed', '500', Castle::InternalServerError
105
102
  end
@@ -15,13 +15,19 @@ describe Castle::Core::ProcessWebhook do
15
15
  device_token: 'token',
16
16
  user_id: '',
17
17
  trigger: '$login.succeeded',
18
- context: {},
19
- location: {},
20
- user_agent: {}
18
+ context: {
19
+ },
20
+ location: {
21
+ },
22
+ user_agent: {
23
+ }
21
24
  },
22
- user_traits: {},
23
- properties: {},
24
- policy: {}
25
+ user_traits: {
26
+ },
27
+ properties: {
28
+ },
29
+ policy: {
30
+ }
25
31
  }.to_json
26
32
  end
27
33
 
@@ -8,12 +8,12 @@ describe Castle::Core::SendRequest do
8
8
  let(:headers) { {} }
9
9
  let(:request_build) { {} }
10
10
  let(:expected_headers) { { 'Content-Type' => 'application/json' } }
11
- let(:http) { instance_double('Net::HTTP') }
11
+ let(:http) { instance_double(Net::HTTP) }
12
12
 
13
13
  context 'without http arg provided' do
14
14
  subject(:call) { described_class.call(command, headers, nil, config) }
15
15
 
16
- let(:http) { instance_double('Net::HTTP') }
16
+ let(:http) { instance_double(Net::HTTP) }
17
17
  let(:command) { Castle::Commands::Track.build(event: '$login.succeeded') }
18
18
  let(:headers) { {} }
19
19
  let(:request_build) { {} }
@@ -26,9 +26,7 @@ describe Castle::Core::SendRequest do
26
26
  call
27
27
  end
28
28
 
29
- it do
30
- expect(described_class).to have_received(:build).with(command, expected_headers, config)
31
- end
29
+ it { expect(described_class).to have_received(:build).with(command, expected_headers, config) }
32
30
 
33
31
  it { expect(http).to have_received(:request).with(request_build) }
34
32
  end
@@ -45,9 +43,7 @@ describe Castle::Core::SendRequest do
45
43
 
46
44
  it { expect(Castle::Core::GetConnection).not_to have_received(:call) }
47
45
 
48
- it do
49
- expect(described_class).to have_received(:build).with(command, expected_headers, config)
50
- end
46
+ it { expect(described_class).to have_received(:build).with(command, expected_headers, config) }
51
47
 
52
48
  it { expect(http).to have_received(:request).with(request_build) }
53
49
  end
@@ -66,7 +62,7 @@ describe Castle::Core::SendRequest do
66
62
 
67
63
  before { allow(Castle::Utils::GetTimestamp).to receive(:call).and_return(time) }
68
64
 
69
- it { expect(build.body).to be_eql(expected_body.to_json) }
65
+ it { expect(build.body).to eql(expected_body.to_json) }
70
66
  it { expect(build.method).to eql('POST') }
71
67
  it { expect(build.path).to eql("/v1/#{command.path}") }
72
68
  it { expect(build.to_hash).to have_key('authorization') }
@@ -81,7 +77,7 @@ describe Castle::Core::SendRequest do
81
77
 
82
78
  before { allow(Castle::Utils::GetTimestamp).to receive(:call).and_return(time) }
83
79
 
84
- it { expect(build.body).to be_eql(expected_body.to_json) }
80
+ it { expect(build.body).to eql(expected_body.to_json) }
85
81
  it { expect(build.method).to eql('GET') }
86
82
  it { expect(build.path).to eql("/v1/#{command.path}") }
87
83
  end
@@ -93,7 +89,7 @@ describe Castle::Core::SendRequest do
93
89
 
94
90
  before { allow(Castle::Utils::GetTimestamp).to receive(:call).and_return(time) }
95
91
 
96
- it { expect(build.body).to be_eql(expected_body.to_json) }
92
+ it { expect(build.body).to eql(expected_body.to_json) }
97
93
  it { expect(build.method).to eql('PUT') }
98
94
  it { expect(build.path).to eql("/v1/#{command.path}") }
99
95
  end
@@ -3,10 +3,10 @@
3
3
  describe Castle::Failover::Strategy do
4
4
  subject(:strategy) { described_class }
5
5
 
6
- it { expect(strategy::ALLOW).to be_eql(:allow) }
7
- it { expect(strategy::DENY).to be_eql(:deny) }
8
- it { expect(strategy::CHALLENGE).to be_eql(:challenge) }
9
- it { expect(strategy::THROW).to be_eql(:throw) }
6
+ it { expect(strategy::ALLOW).to be(:allow) }
7
+ it { expect(strategy::DENY).to be(:deny) }
8
+ it { expect(strategy::CHALLENGE).to be(:challenge) }
9
+ it { expect(strategy::THROW).to be(:throw) }
10
10
 
11
- it { expect(Castle::Failover::STRATEGIES).to be_eql(%i[allow deny challenge throw]) }
11
+ it { expect(Castle::Failover::STRATEGIES).to eql(%i[allow deny challenge throw]) }
12
12
  end
@@ -98,6 +98,6 @@ describe Castle::Headers::Extract do
98
98
  Castle.config.denylisted = %w[Accept]
99
99
  end
100
100
 
101
- it { expect(extract_call['Accept']).to eq(true) }
101
+ it { expect(extract_call['Accept']).to be(true) }
102
102
  end
103
103
  end
@@ -14,7 +14,9 @@ describe Castle::Headers::Filter do
14
14
  'HTTP_X_FORWARDED_FOR' => '1.2.3.4',
15
15
  'HTTP_USER_AGENT' => 'Mozilla 1234',
16
16
  'TEST' => '1',
17
- 'REMOTE_ADDR' => '1.2.3.4'
17
+ 'REMOTE_ADDR' => '1.2.3.4',
18
+ 'HTTP_CONTENT_LENGTH' => '0',
19
+ 'http_accept_language.parser' => -> { 'noop' }
18
20
  )
19
21
  result[:HTTP_OK] = 'OK'
20
22
  result
@@ -28,12 +30,13 @@ describe Castle::Headers::Filter do
28
30
  'Ok' => 'OK',
29
31
  'User-Agent' => 'Mozilla 1234',
30
32
  'Remote-Addr' => '1.2.3.4',
31
- 'X-Forwarded-For' => '1.2.3.4'
33
+ 'X-Forwarded-For' => '1.2.3.4',
34
+ 'Accept-Language.parser' => start_with('#<Proc')
32
35
  }
33
36
  end
34
37
  let(:request) { Rack::Request.new(env) }
35
38
 
36
39
  context 'with list of header' do
37
- it { expect(filter_call).to eq(filtered) }
40
+ it { expect(filter_call).to match(filtered) }
38
41
  end
39
42
  end
@@ -4,22 +4,22 @@ describe Castle::Headers::Format do
4
4
  subject(:format) { described_class }
5
5
 
6
6
  it 'removes HTTP_' do
7
- expect(format.call('HTTP_X_TEST')).to be_eql('X-Test')
7
+ expect(format.call('HTTP_X_TEST')).to eql('X-Test')
8
8
  end
9
9
 
10
10
  it 'capitalizes header' do
11
- expect(format.call('X_TEST')).to be_eql('X-Test')
11
+ expect(format.call('X_TEST')).to eql('X-Test')
12
12
  end
13
13
 
14
14
  it 'ignores letter case and -_ divider' do
15
- expect(format.call('http-X_teST')).to be_eql('X-Test')
15
+ expect(format.call('http-X_teST')).to eql('X-Test')
16
16
  end
17
17
 
18
18
  it 'does not remove http if there is no _- char' do
19
- expect(format.call('httpX_teST')).to be_eql('Httpx-Test')
19
+ expect(format.call('httpX_teST')).to eql('Httpx-Test')
20
20
  end
21
21
 
22
22
  it 'capitalizes' do
23
- expect(format.call(:clearance)).to be_eql('Clearance')
23
+ expect(format.call(:clearance)).to eql('Clearance')
24
24
  end
25
25
  end
@@ -16,9 +16,7 @@ describe Castle::IPs::Extract do
16
16
  end
17
17
 
18
18
  context 'when we need to use other ip header' do
19
- let(:headers) do
20
- { 'Cf-Connecting-Ip' => '1.2.3.4', 'X-Forwarded-For' => '1.1.1.1, 1.2.2.2, 1.2.3.5' }
21
- end
19
+ let(:headers) { { 'Cf-Connecting-Ip' => '1.2.3.4', 'X-Forwarded-For' => '1.1.1.1, 1.2.2.2, 1.2.3.5' } }
22
20
 
23
21
  context 'with uppercase format' do
24
22
  before { Castle.config.ip_headers = %w[CF_CONNECTING_IP X-Forwarded-For] }
@@ -77,9 +75,7 @@ describe Castle::IPs::Extract do
77
75
  end
78
76
 
79
77
  context 'when list of not trusted ips provided in X_FORWARDED_FOR' do
80
- let(:headers) do
81
- { 'X-Forwarded-For' => '6.6.6.6, 2.2.2.3, 192.168.0.7', 'Client-Ip' => '6.6.6.6' }
82
- end
78
+ let(:headers) { { 'X-Forwarded-For' => '6.6.6.6, 2.2.2.3, 192.168.0.7', 'Client-Ip' => '6.6.6.6' } }
83
79
 
84
80
  it 'does not allow to spoof ip' do
85
81
  expect(extractor.call).to eql('2.2.2.3')
@@ -3,7 +3,8 @@
3
3
  # tmp logger for testing
4
4
  class TmpLogger
5
5
  # @param _message [String]
6
- def info(_message); end
6
+ def info(_message)
7
+ end
7
8
  end
8
9
 
9
10
  describe Castle::Logger do
@@ -9,14 +9,13 @@ describe Castle::Payload::Prepare do
9
9
  '/',
10
10
  'HTTP_USER_AGENT' => ua,
11
11
  'HTTP_X_FORWARDED_FOR' => ip,
12
- 'HTTP_COOKIE' => "__cid=#{cookie_id};other=efgh"
12
+ 'HTTP_COOKIE' => "__cid=#{cookie_id};other=efgh",
13
+ 'HTTP_CONTENT_LENGTH' => '0'
13
14
  )
14
15
  end
15
16
  let(:request) { Rack::Request.new(env) }
16
17
 
17
- let(:headers) do
18
- { 'Content-Length': '0', 'User-Agent': ua, 'X-Forwarded-For': ip.to_s, 'Cookie': true }
19
- end
18
+ let(:headers) { { 'Content-Length': '0', 'User-Agent': ua, 'X-Forwarded-For': ip.to_s, Cookie: true } }
20
19
  let(:context) do
21
20
  {
22
21
  client_id: 'abcd',
@@ -34,9 +33,7 @@ describe Castle::Payload::Prepare do
34
33
  let(:time_now) { Time.now }
35
34
  let(:time_formatted) { time_now.utc.iso8601(3) }
36
35
  let(:payload_options) { { user_id: '1234', user_traits: { name: 'Jo' } } }
37
- let(:result) do
38
- { user_id: '1234', user_traits: { name: 'Jo' }, timestamp: time_formatted, context: context }
39
- end
36
+ let(:result) { { user_id: '1234', user_traits: { name: 'Jo' }, timestamp: time_formatted, context: context } }
40
37
 
41
38
  before do
42
39
  Timecop.freeze(time_now)
@@ -2,8 +2,6 @@
2
2
 
3
3
  describe Castle::SecureMode do
4
4
  it 'has signature' do
5
- expect(described_class.signature('test')).to eql(
6
- '0329a06b62cd16b33eb6792be8c60b158d89a2ee3a876fce9a881ebb488c0914'
7
- )
5
+ expect(described_class.signature('test')).to eql('0329a06b62cd16b33eb6792be8c60b158d89a2ee3a876fce9a881ebb488c0914')
8
6
  end
9
7
  end
@@ -39,11 +39,7 @@ describe Castle::Session do
39
39
 
40
40
  before do
41
41
  Castle.config.base_url = 'https://localhost'
42
- stub_request(:get, 'https://localhost/test').to_return(
43
- status: 200,
44
- body: '{}',
45
- headers: {}
46
- )
42
+ stub_request(:get, 'https://localhost/test').to_return(status: 200, body: '{}', headers: {})
47
43
  end
48
44
 
49
45
  context 'with block' do
@@ -10,5 +10,5 @@ describe Castle::SingletonConfiguration do
10
10
  it_behaves_like 'configuration_failover_strategy'
11
11
  it_behaves_like 'configuration_api_secret'
12
12
 
13
- it { expect(config.api_secret).to be_eql('secret') }
13
+ it { expect(config.api_secret).to eql('secret') }
14
14
  end
@@ -13,7 +13,7 @@ describe Castle::Utils::Clone do
13
13
 
14
14
  it do
15
15
  nested[:test] = 'sample'
16
- expect(cloned).to be_eql(result)
16
+ expect(cloned).to eql(result)
17
17
  end
18
18
  end
19
19
  end
@@ -5,11 +5,9 @@ describe Castle::Utils::Merge do
5
5
 
6
6
  describe 'call' do
7
7
  let(:first) { { test: { test1: { c: '4' }, test2: { c: '3' }, a: '1', b: '2' } } }
8
- let(:second) do
9
- { test2: '2', test: { 'test1' => { d: '5' }, :test2 => '6', :a => nil, :b => '3' } }
10
- end
8
+ let(:second) { { test2: '2', test: { 'test1' => { d: '5' }, :test2 => '6', :a => nil, :b => '3' } } }
11
9
  let(:result) { { test2: '2', test: { test1: { c: '4', d: '5' }, test2: '6', b: '3' } } }
12
10
 
13
- it { expect(merge.call(first, second)).to be_eql(result) }
11
+ it { expect(merge.call(first, second)).to eql(result) }
14
12
  end
15
13
  end
@@ -7,12 +7,7 @@ describe Castle::Validators::NotSupported do
7
7
  context 'when keys is present' do
8
8
  let(:keys) { %i[first second] }
9
9
 
10
- it do
11
- expect { call }.to raise_error(
12
- Castle::InvalidParametersError,
13
- 'first is/are not supported'
14
- )
15
- end
10
+ it { expect { call }.to raise_error(Castle::InvalidParametersError, 'first is/are not supported') }
16
11
  end
17
12
 
18
13
  context 'when key is not present' do
@@ -7,20 +7,13 @@ describe Castle::Validators::Present do
7
7
  context 'when keys is not present' do
8
8
  let(:keys) { %i[second third] }
9
9
 
10
- it do
11
- expect { call }.to raise_error(Castle::InvalidParametersError, 'third is missing or empty')
12
- end
10
+ it { expect { call }.to raise_error(Castle::InvalidParametersError, 'third is missing or empty') }
13
11
  end
14
12
 
15
13
  context 'when keys is empty' do
16
14
  let(:keys) { %i[second invalid] }
17
15
 
18
- it do
19
- expect { call }.to raise_error(
20
- Castle::InvalidParametersError,
21
- 'invalid is missing or empty'
22
- )
23
- end
16
+ it { expect { call }.to raise_error(Castle::InvalidParametersError, 'invalid is missing or empty') }
24
17
  end
25
18
 
26
19
  context 'when key is present' do
@@ -3,7 +3,7 @@
3
3
  describe Castle::Verdict do
4
4
  subject(:verdict) { described_class }
5
5
 
6
- it { expect(verdict::ALLOW).to be_eql('allow') }
7
- it { expect(verdict::DENY).to be_eql('deny') }
8
- it { expect(verdict::CHALLENGE).to be_eql('challenge') }
6
+ it { expect(verdict::ALLOW).to eql('allow') }
7
+ it { expect(verdict::DENY).to eql('deny') }
8
+ it { expect(verdict::CHALLENGE).to eql('challenge') }
9
9
  end