castle-rb 7.2.0 → 8.1.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.
- checksums.yaml +4 -4
- data/lib/castle/api/authenticate.rb +3 -12
- data/lib/castle/api/end_impersonation.rb +1 -3
- data/lib/castle/api/filter.rb +2 -10
- data/lib/castle/api/list_items/archive.rb +23 -0
- data/lib/castle/api/list_items/count.rb +22 -0
- data/lib/castle/api/list_items/create.rb +22 -0
- data/lib/castle/api/list_items/get.rb +22 -0
- data/lib/castle/api/list_items/query.rb +22 -0
- data/lib/castle/api/list_items/unarchive.rb +22 -0
- data/lib/castle/api/list_items/update.rb +22 -0
- data/lib/castle/api/lists/create.rb +23 -0
- data/lib/castle/api/lists/delete.rb +22 -0
- data/lib/castle/api/lists/get.rb +22 -0
- data/lib/castle/api/lists/get_all.rb +22 -0
- data/lib/castle/api/lists/query.rb +22 -0
- data/lib/castle/api/lists/update.rb +22 -0
- data/lib/castle/api/log.rb +2 -10
- data/lib/castle/api/risk.rb +2 -10
- data/lib/castle/api/start_impersonation.rb +1 -3
- data/lib/castle/api/track.rb +1 -3
- data/lib/castle/client.rb +4 -5
- data/lib/castle/client_actions/list_items.rb +44 -0
- data/lib/castle/client_actions/lists.rb +39 -0
- data/lib/castle/commands/list_items/archive.rb +24 -0
- data/lib/castle/commands/list_items/count.rb +23 -0
- data/lib/castle/commands/list_items/create.rb +22 -0
- data/lib/castle/commands/list_items/get.rb +23 -0
- data/lib/castle/commands/list_items/query.rb +24 -0
- data/lib/castle/commands/list_items/unarchive.rb +23 -0
- data/lib/castle/commands/list_items/update.rb +22 -0
- data/lib/castle/commands/lists/create.rb +21 -0
- data/lib/castle/commands/lists/delete.rb +20 -0
- data/lib/castle/commands/lists/get.rb +20 -0
- data/lib/castle/commands/lists/get_all.rb +17 -0
- data/lib/castle/commands/lists/query.rb +21 -0
- data/lib/castle/commands/lists/update.rb +22 -0
- data/lib/castle/commands/log.rb +1 -5
- data/lib/castle/commands/risk.rb +1 -5
- data/lib/castle/configuration.rb +2 -5
- data/lib/castle/core/process_response.rb +4 -3
- data/lib/castle/core/send_request.rb +1 -3
- data/lib/castle/errors.rb +4 -0
- data/lib/castle/headers/extract.rb +1 -3
- data/lib/castle/headers/filter.rb +2 -3
- data/lib/castle/payload/prepare.rb +1 -2
- data/lib/castle/session.rb +1 -1
- data/lib/castle/version.rb +1 -1
- data/lib/castle.rb +29 -3
- data/spec/integration/rails/rails_spec.rb +9 -3
- data/spec/integration/rails/support/application.rb +2 -2
- data/spec/integration/rails/support/home_controller.rb +4 -30
- data/spec/lib/castle/api/approve_device_spec.rb +3 -7
- data/spec/lib/castle/api/authenticate_spec.rb +23 -26
- data/spec/lib/castle/api/end_impersonation_spec.rb +9 -15
- data/spec/lib/castle/api/filter_spec.rb +1 -1
- data/spec/lib/castle/api/get_device_spec.rb +2 -4
- data/spec/lib/castle/api/get_devices_for_user_spec.rb +2 -4
- data/spec/lib/castle/api/list_items/archive_spec.rb +18 -0
- data/spec/lib/castle/api/list_items/count_spec.rb +21 -0
- data/spec/lib/castle/api/list_items/create_spec.rb +22 -0
- data/spec/lib/castle/api/list_items/get_spec.rb +18 -0
- data/spec/lib/castle/api/list_items/query_spec.rb +21 -0
- data/spec/lib/castle/api/list_items/unarchive_spec.rb +18 -0
- data/spec/lib/castle/api/list_items/update_spec.rb +22 -0
- data/spec/lib/castle/api/lists/create_spec.rb +21 -0
- data/spec/lib/castle/api/lists/delete_spec.rb +17 -0
- data/spec/lib/castle/api/lists/get_all_spec.rb +17 -0
- data/spec/lib/castle/api/lists/get_spec.rb +17 -0
- data/spec/lib/castle/api/lists/query_spec.rb +21 -0
- data/spec/lib/castle/api/lists/update_spec.rb +21 -0
- data/spec/lib/castle/api/log_spec.rb +1 -1
- data/spec/lib/castle/api/report_device_spec.rb +3 -7
- data/spec/lib/castle/api/risk_spec.rb +1 -1
- data/spec/lib/castle/api/start_impersonation_spec.rb +9 -15
- data/spec/lib/castle/api/track_spec.rb +10 -17
- data/spec/lib/castle/api_spec.rb +1 -1
- data/spec/lib/castle/client_id/extract_spec.rb +3 -10
- data/spec/lib/castle/client_spec.rb +38 -79
- data/spec/lib/castle/command_spec.rb +4 -4
- data/spec/lib/castle/commands/approve_device_spec.rb +3 -3
- data/spec/lib/castle/commands/authenticate_spec.rb +18 -25
- data/spec/lib/castle/commands/end_impersonation_spec.rb +15 -22
- data/spec/lib/castle/commands/filter_spec.rb +16 -16
- data/spec/lib/castle/commands/get_device_spec.rb +3 -3
- data/spec/lib/castle/commands/get_devices_for_user_spec.rb +3 -3
- data/spec/lib/castle/commands/list_items/archive_spec.rb +21 -0
- data/spec/lib/castle/commands/list_items/count_spec.rb +21 -0
- data/spec/lib/castle/commands/list_items/create_spec.rb +22 -0
- data/spec/lib/castle/commands/list_items/get_spec.rb +21 -0
- data/spec/lib/castle/commands/list_items/query_spec.rb +27 -0
- data/spec/lib/castle/commands/list_items/unarchive_spec.rb +21 -0
- data/spec/lib/castle/commands/list_items/update_spec.rb +21 -0
- data/spec/lib/castle/commands/lists/create_spec.rb +33 -0
- data/spec/lib/castle/commands/lists/delete_spec.rb +21 -0
- data/spec/lib/castle/commands/lists/get_all_spec.rb +11 -0
- data/spec/lib/castle/commands/lists/get_spec.rb +21 -0
- data/spec/lib/castle/commands/lists/query_spec.rb +27 -0
- data/spec/lib/castle/commands/lists/update_spec.rb +29 -0
- data/spec/lib/castle/commands/log_spec.rb +16 -16
- data/spec/lib/castle/commands/report_device_spec.rb +3 -3
- data/spec/lib/castle/commands/risk_spec.rb +16 -16
- data/spec/lib/castle/commands/start_impersonation_spec.rb +15 -22
- data/spec/lib/castle/commands/track_spec.rb +20 -25
- data/spec/lib/castle/configuration_spec.rb +2 -2
- data/spec/lib/castle/context/get_default_spec.rb +10 -9
- data/spec/lib/castle/context/merge_spec.rb +1 -1
- data/spec/lib/castle/context/prepare_spec.rb +4 -5
- data/spec/lib/castle/context/sanitize_spec.rb +1 -1
- data/spec/lib/castle/core/get_connection_spec.rb +1 -1
- data/spec/lib/castle/core/process_response_spec.rb +4 -7
- data/spec/lib/castle/core/process_webhook_spec.rb +13 -7
- data/spec/lib/castle/core/send_request_spec.rb +8 -12
- data/spec/lib/castle/failover/strategy_spec.rb +6 -6
- data/spec/lib/castle/headers/extract_spec.rb +2 -2
- data/spec/lib/castle/headers/filter_spec.rb +7 -4
- data/spec/lib/castle/headers/format_spec.rb +6 -6
- data/spec/lib/castle/ips/extract_spec.rb +3 -7
- data/spec/lib/castle/logger_spec.rb +3 -2
- data/spec/lib/castle/payload/prepare_spec.rb +5 -8
- data/spec/lib/castle/secure_mode_spec.rb +2 -4
- data/spec/lib/castle/session_spec.rb +2 -6
- data/spec/lib/castle/singleton_configuration_spec.rb +2 -2
- data/spec/lib/castle/utils/clean_invalid_chars_spec.rb +1 -1
- data/spec/lib/castle/utils/clone_spec.rb +2 -2
- data/spec/lib/castle/utils/deep_symbolize_keys_spec.rb +1 -1
- data/spec/lib/castle/utils/get_timestamp_spec.rb +1 -1
- data/spec/lib/castle/utils/merge_spec.rb +3 -5
- data/spec/lib/castle/validators/not_supported_spec.rb +2 -7
- data/spec/lib/castle/validators/present_spec.rb +3 -10
- data/spec/lib/castle/verdict_spec.rb +4 -4
- data/spec/lib/castle/version_spec.rb +1 -1
- data/spec/lib/castle/webhooks/verify_spec.rb +13 -7
- data/spec/lib/castle_spec.rb +6 -8
- data/spec/spec_helper.rb +2 -0
- data/spec/support/shared_examples/action_request.rb +16 -34
- data/spec/support/shared_examples/configuration.rb +14 -16
- data/spec/support/shared_examples/list_items.rb +52 -0
- data/spec/support/shared_examples/lists.rb +45 -0
- metadata +132 -48
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Core::ProcessResponse do
|
3
|
+
RSpec.describe Castle::Core::ProcessResponse do
|
4
4
|
describe '#call' do
|
5
5
|
subject(:call) { described_class.call(response) }
|
6
6
|
|
@@ -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)
|
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)
|
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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Core::ProcessWebhook do
|
3
|
+
RSpec.describe Castle::Core::ProcessWebhook do
|
4
4
|
describe '#call' do
|
5
5
|
subject(:call) { described_class.call(webhook) }
|
6
6
|
|
@@ -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
|
-
|
20
|
-
|
18
|
+
context: {
|
19
|
+
},
|
20
|
+
location: {
|
21
|
+
},
|
22
|
+
user_agent: {
|
23
|
+
}
|
21
24
|
},
|
22
|
-
user_traits: {
|
23
|
-
|
24
|
-
|
25
|
+
user_traits: {
|
26
|
+
},
|
27
|
+
properties: {
|
28
|
+
},
|
29
|
+
policy: {
|
30
|
+
}
|
25
31
|
}.to_json
|
26
32
|
end
|
27
33
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Core::SendRequest do
|
3
|
+
RSpec.describe Castle::Core::SendRequest do
|
4
4
|
let(:config) { Castle.config }
|
5
5
|
|
6
6
|
describe '#call' do
|
@@ -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(
|
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(
|
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
|
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
|
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
|
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
|
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
|
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
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Failover::Strategy do
|
3
|
+
RSpec.describe Castle::Failover::Strategy do
|
4
4
|
subject(:strategy) { described_class }
|
5
5
|
|
6
|
-
it { expect(strategy::ALLOW).to
|
7
|
-
it { expect(strategy::DENY).to
|
8
|
-
it { expect(strategy::CHALLENGE).to
|
9
|
-
it { expect(strategy::THROW).to
|
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
|
11
|
+
it { expect(Castle::Failover::STRATEGIES).to eql(%i[allow deny challenge throw]) }
|
12
12
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Headers::Extract do
|
3
|
+
RSpec.describe Castle::Headers::Extract do
|
4
4
|
subject(:extract_call) { described_class.new(formatted_headers).call }
|
5
5
|
|
6
6
|
let(:formatted_headers) do
|
@@ -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
|
101
|
+
it { expect(extract_call['Accept']).to be(true) }
|
102
102
|
end
|
103
103
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Headers::Filter do
|
3
|
+
RSpec.describe Castle::Headers::Filter do
|
4
4
|
subject(:filter_call) { described_class.new(request).call }
|
5
5
|
|
6
6
|
let(:env) do
|
@@ -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
|
40
|
+
it { expect(filter_call).to match(filtered) }
|
38
41
|
end
|
39
42
|
end
|
@@ -1,25 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Headers::Format do
|
3
|
+
RSpec.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
|
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
|
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
|
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
|
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
|
23
|
+
expect(format.call(:clearance)).to eql('Clearance')
|
24
24
|
end
|
25
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::IPs::Extract do
|
3
|
+
RSpec.describe Castle::IPs::Extract do
|
4
4
|
subject(:extractor) { described_class.new(headers) }
|
5
5
|
|
6
6
|
describe 'ip' do
|
@@ -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)
|
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)
|
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,10 +3,11 @@
|
|
3
3
|
# tmp logger for testing
|
4
4
|
class TmpLogger
|
5
5
|
# @param _message [String]
|
6
|
-
def info(_message)
|
6
|
+
def info(_message)
|
7
|
+
end
|
7
8
|
end
|
8
9
|
|
9
|
-
describe Castle::Logger do
|
10
|
+
RSpec.describe Castle::Logger do
|
10
11
|
subject(:log) { described_class.call(message, data) }
|
11
12
|
|
12
13
|
let(:message) { 'https://localhost/test:' }
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Payload::Prepare do
|
3
|
+
RSpec.describe Castle::Payload::Prepare do
|
4
4
|
let(:ip) { '1.2.3.4' }
|
5
5
|
let(:cookie_id) { 'abcd' }
|
6
6
|
let(:ua) { 'Chrome' }
|
@@ -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)
|
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)
|
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)
|
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::SecureMode do
|
3
|
+
RSpec.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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Session do
|
3
|
+
RSpec.describe Castle::Session do
|
4
4
|
describe '.call' do
|
5
5
|
context 'when ssl false' do
|
6
6
|
let(:localhost) { 'localhost' }
|
@@ -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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::SingletonConfiguration do
|
3
|
+
RSpec.describe Castle::SingletonConfiguration do
|
4
4
|
subject(:config) { described_class.instance }
|
5
5
|
|
6
6
|
it_behaves_like 'configuration_host'
|
@@ -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
|
13
|
+
it { expect(config.api_secret).to eql('secret') }
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Utils::Clone do
|
3
|
+
RSpec.describe Castle::Utils::Clone do
|
4
4
|
subject(:clone) { described_class }
|
5
5
|
|
6
6
|
describe 'call' do
|
@@ -13,7 +13,7 @@ describe Castle::Utils::Clone do
|
|
13
13
|
|
14
14
|
it do
|
15
15
|
nested[:test] = 'sample'
|
16
|
-
expect(cloned).to
|
16
|
+
expect(cloned).to eql(result)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Utils::DeepSymbolizeKeys do
|
3
|
+
RSpec.describe Castle::Utils::DeepSymbolizeKeys do
|
4
4
|
let(:nested_strings) { { 'a' => { 'b' => { 'c' => 3 } } } }
|
5
5
|
let(:nested_symbols) { { a: { b: { c: 3 } } } }
|
6
6
|
let(:nested_mixed) { { 'a' => { b: { 'c' => 3 } } } }
|
@@ -1,15 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Utils::Merge do
|
3
|
+
RSpec.describe Castle::Utils::Merge do
|
4
4
|
subject(:merge) { described_class }
|
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)
|
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
|
11
|
+
it { expect(merge.call(first, second)).to eql(result) }
|
14
12
|
end
|
15
13
|
end
|
@@ -1,18 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Validators::NotSupported do
|
3
|
+
RSpec.describe Castle::Validators::NotSupported do
|
4
4
|
describe '#call' do
|
5
5
|
subject(:call) { described_class.call({ first: 1 }, keys) }
|
6
6
|
|
7
7
|
context 'when keys is present' do
|
8
8
|
let(:keys) { %i[first second] }
|
9
9
|
|
10
|
-
it
|
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
|
@@ -1,26 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Validators::Present do
|
3
|
+
RSpec.describe Castle::Validators::Present do
|
4
4
|
describe '#call' do
|
5
5
|
subject(:call) { described_class.call({ first: 1, second: '2', invalid: '' }, keys) }
|
6
6
|
|
7
7
|
context 'when keys is not present' do
|
8
8
|
let(:keys) { %i[second third] }
|
9
9
|
|
10
|
-
it
|
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
|
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
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Verdict do
|
3
|
+
RSpec.describe Castle::Verdict do
|
4
4
|
subject(:verdict) { described_class }
|
5
5
|
|
6
|
-
it { expect(verdict::ALLOW).to
|
7
|
-
it { expect(verdict::DENY).to
|
8
|
-
it { expect(verdict::CHALLENGE).to
|
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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle::Webhooks::Verify do
|
3
|
+
RSpec.describe Castle::Webhooks::Verify do
|
4
4
|
describe '#call' do
|
5
5
|
subject(:call) { described_class.call(webhook) }
|
6
6
|
|
@@ -19,13 +19,19 @@ describe Castle::Webhooks::Verify do
|
|
19
19
|
device_token: 'token',
|
20
20
|
user_id: user_id,
|
21
21
|
trigger: '$login.succeeded',
|
22
|
-
context: {
|
23
|
-
|
24
|
-
|
22
|
+
context: {
|
23
|
+
},
|
24
|
+
location: {
|
25
|
+
},
|
26
|
+
user_agent: {
|
27
|
+
}
|
25
28
|
},
|
26
|
-
user_traits: {
|
27
|
-
|
28
|
-
|
29
|
+
user_traits: {
|
30
|
+
},
|
31
|
+
properties: {
|
32
|
+
},
|
33
|
+
policy: {
|
34
|
+
}
|
29
35
|
}.to_json
|
30
36
|
end
|
31
37
|
|
data/spec/lib/castle_spec.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe Castle do
|
3
|
+
RSpec.describe Castle do
|
4
4
|
subject(:castle) { described_class }
|
5
5
|
|
6
6
|
describe 'config' do
|
7
|
-
it { expect(castle.config).to
|
7
|
+
it { expect(castle.config).to be_a(Castle::Configuration) }
|
8
8
|
end
|
9
9
|
|
10
10
|
describe 'api_secret setter' do
|
@@ -12,7 +12,7 @@ describe Castle do
|
|
12
12
|
|
13
13
|
before { castle.api_secret = value }
|
14
14
|
|
15
|
-
it { expect(castle.config.api_secret).to
|
15
|
+
it { expect(castle.config.api_secret).to eql(value) }
|
16
16
|
end
|
17
17
|
|
18
18
|
describe 'configure' do
|
@@ -20,8 +20,8 @@ describe Castle do
|
|
20
20
|
let(:timeout) { 60 }
|
21
21
|
|
22
22
|
shared_examples 'config_setup' do
|
23
|
-
it { expect(castle.config.api_secret).to
|
24
|
-
it { expect(castle.config.request_timeout).to
|
23
|
+
it { expect(castle.config.api_secret).to eql(value) }
|
24
|
+
it { expect(castle.config.request_timeout).to eql(timeout) }
|
25
25
|
end
|
26
26
|
|
27
27
|
context 'with block' do
|
@@ -52,9 +52,7 @@ describe Castle do
|
|
52
52
|
let(:value) { 'new_secret' }
|
53
53
|
|
54
54
|
it do
|
55
|
-
expect { castle.configure { |config| config.wrong_config = value } }.to raise_error(
|
56
|
-
Castle::ConfigurationError
|
57
|
-
)
|
55
|
+
expect { castle.configure { |config| config.wrong_config = value } }.to raise_error(Castle::ConfigurationError)
|
58
56
|
end
|
59
57
|
end
|
60
58
|
end
|