castle-rb 3.4.0 → 3.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +36 -24
- data/lib/castle.rb +5 -3
- data/lib/castle/client.rb +21 -18
- data/lib/castle/commands/authenticate.rb +8 -16
- data/lib/castle/commands/identify.rb +9 -21
- data/lib/castle/commands/impersonate.rb +9 -23
- data/lib/castle/commands/review.rb +5 -4
- data/lib/castle/commands/track.rb +8 -16
- data/lib/castle/configuration.rb +1 -2
- data/lib/castle/context/default.rb +40 -0
- data/lib/castle/context/merger.rb +14 -0
- data/lib/castle/context/sanitizer.rb +23 -0
- data/lib/castle/review.rb +1 -1
- data/lib/castle/utils/merger.rb +9 -9
- data/lib/castle/validators/not_supported.rb +16 -0
- data/lib/castle/validators/present.rb +16 -0
- data/lib/castle/version.rb +1 -1
- data/spec/lib/castle/client_spec.rb +3 -2
- data/spec/lib/castle/commands/authenticate_spec.rb +21 -21
- data/spec/lib/castle/commands/identify_spec.rb +17 -17
- data/spec/lib/castle/commands/impersonate_spec.rb +1 -1
- data/spec/lib/castle/commands/review_spec.rb +1 -1
- data/spec/lib/castle/commands/track_spec.rb +23 -23
- data/spec/lib/castle/configuration_spec.rb +13 -13
- data/spec/lib/castle/{default_context_spec.rb → context/default_spec.rb} +1 -1
- data/spec/lib/castle/{context_merger_spec.rb → context/merger_spec.rb} +4 -4
- data/spec/lib/castle/{context_sanitizer_spec.rb → context/sanitizer_spec.rb} +1 -1
- data/spec/lib/castle/extractors/client_id_spec.rb +1 -1
- data/spec/lib/castle/request_spec.rb +2 -2
- data/spec/lib/castle/response_spec.rb +4 -4
- data/spec/lib/castle/review_spec.rb +1 -1
- data/spec/lib/castle/utils_spec.rb +14 -14
- data/spec/lib/castle/validators/not_supported_spec.rb +26 -0
- data/spec/lib/castle/validators/present_spec.rb +33 -0
- data/spec/lib/castle_spec.rb +3 -3
- metadata +19 -13
- data/lib/castle/context_merger.rb +0 -12
- data/lib/castle/context_sanitizer.rb +0 -20
- data/lib/castle/default_context.rb +0 -28
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Context
|
5
|
+
# removes not proper active flag values
|
6
|
+
class Sanitizer
|
7
|
+
class << self
|
8
|
+
def call(context)
|
9
|
+
sanitized_active_mode(context) || {}
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def sanitized_active_mode(context)
|
15
|
+
return unless context
|
16
|
+
return context unless context.key?(:active)
|
17
|
+
return context if [true, false].include?(context[:active])
|
18
|
+
context.reject { |key| key == :active }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/castle/review.rb
CHANGED
data/lib/castle/utils/merger.rb
CHANGED
@@ -3,20 +3,20 @@
|
|
3
3
|
module Castle
|
4
4
|
module Utils
|
5
5
|
class Merger
|
6
|
-
def self.call(
|
7
|
-
|
8
|
-
|
6
|
+
def self.call(base, extra)
|
7
|
+
base_s = Castle::Utils.deep_symbolize_keys(base)
|
8
|
+
extra_s = Castle::Utils.deep_symbolize_keys(extra)
|
9
9
|
|
10
|
-
|
10
|
+
extra_s.each do |name, value|
|
11
11
|
if value.nil?
|
12
|
-
|
13
|
-
elsif value.is_a?(Hash) &&
|
14
|
-
|
12
|
+
base_s.delete(name)
|
13
|
+
elsif value.is_a?(Hash) && base_s[name].is_a?(Hash)
|
14
|
+
base_s[name] = call(base_s[name], value)
|
15
15
|
else
|
16
|
-
|
16
|
+
base_s[name] = value
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
base_s
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Validators
|
5
|
+
class NotSupported
|
6
|
+
class << self
|
7
|
+
def call(options, keys)
|
8
|
+
keys.each do |key|
|
9
|
+
next unless options.key?(key)
|
10
|
+
raise Castle::InvalidParametersError, "#{key} is/are not supported"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Validators
|
5
|
+
class Present
|
6
|
+
class << self
|
7
|
+
def call(options, keys)
|
8
|
+
keys.each do |key|
|
9
|
+
next unless options[key].to_s.empty?
|
10
|
+
raise Castle::InvalidParametersError, "#{key} is missing or empty"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/castle/version.rb
CHANGED
@@ -76,7 +76,8 @@ describe Castle::Client do
|
|
76
76
|
describe 'impersonate' do
|
77
77
|
let(:impersonator) { 'test@castle.io' }
|
78
78
|
let(:request_body) do
|
79
|
-
{ user_id: '1234',
|
79
|
+
{ user_id: '1234', timestamp: time_auto, sent_at: time_auto,
|
80
|
+
impersonator: impersonator, context: context }
|
80
81
|
end
|
81
82
|
let(:options) { { user_id: '1234', impersonator: impersonator } }
|
82
83
|
|
@@ -255,7 +256,7 @@ describe Castle::Client do
|
|
255
256
|
context 'when request is internal server error' do
|
256
257
|
before { allow(client.api).to receive(:request).and_raise(Castle::InternalServerError) }
|
257
258
|
|
258
|
-
|
259
|
+
describe 'throw strategy' do
|
259
260
|
before { allow(Castle.config).to receive(:failover_strategy).and_return(:throw) }
|
260
261
|
|
261
262
|
it { expect { request_response }.to raise_error(Castle::InternalServerError) }
|
@@ -15,10 +15,10 @@ describe Castle::Commands::Authenticate do
|
|
15
15
|
describe '.build' do
|
16
16
|
subject(:command) { instance.build(payload) }
|
17
17
|
|
18
|
-
context 'simple merger' do
|
19
|
-
let(:payload) { default_payload.merge(
|
18
|
+
context 'with simple merger' do
|
19
|
+
let(:payload) { default_payload.merge(context: { test: { test2: '1' } }) }
|
20
20
|
let(:command_data) do
|
21
|
-
default_payload.merge(
|
21
|
+
default_payload.merge(context: { test: { test1: '1', test2: '1' } })
|
22
22
|
end
|
23
23
|
|
24
24
|
it { expect(command.method).to be_eql(:post) }
|
@@ -26,10 +26,10 @@ describe Castle::Commands::Authenticate do
|
|
26
26
|
it { expect(command.data).to be_eql(command_data) }
|
27
27
|
end
|
28
28
|
|
29
|
-
context 'properties' do
|
30
|
-
let(:payload) { default_payload.merge(
|
29
|
+
context 'with properties' do
|
30
|
+
let(:payload) { default_payload.merge(properties: { test: '1' }) }
|
31
31
|
let(:command_data) do
|
32
|
-
default_payload.merge(
|
32
|
+
default_payload.merge(properties: { test: '1' }, context: context)
|
33
33
|
end
|
34
34
|
|
35
35
|
it { expect(command.method).to be_eql(:post) }
|
@@ -37,10 +37,10 @@ describe Castle::Commands::Authenticate do
|
|
37
37
|
it { expect(command.data).to be_eql(command_data) }
|
38
38
|
end
|
39
39
|
|
40
|
-
context 'traits' do
|
41
|
-
let(:payload) { default_payload.merge(
|
40
|
+
context 'with traits' do
|
41
|
+
let(:payload) { default_payload.merge(traits: { test: '1' }) }
|
42
42
|
let(:command_data) do
|
43
|
-
default_payload.merge(
|
43
|
+
default_payload.merge(traits: { test: '1' }, context: context)
|
44
44
|
end
|
45
45
|
|
46
46
|
it { expect(command.method).to be_eql(:post) }
|
@@ -48,10 +48,10 @@ describe Castle::Commands::Authenticate do
|
|
48
48
|
it { expect(command.data).to be_eql(command_data) }
|
49
49
|
end
|
50
50
|
|
51
|
-
context 'active true' do
|
52
|
-
let(:payload) { default_payload.merge(
|
51
|
+
context 'when active true' do
|
52
|
+
let(:payload) { default_payload.merge(context: { active: true }) }
|
53
53
|
let(:command_data) do
|
54
|
-
default_payload.merge(
|
54
|
+
default_payload.merge(context: context.merge(active: true))
|
55
55
|
end
|
56
56
|
|
57
57
|
it { expect(command.method).to be_eql(:post) }
|
@@ -59,10 +59,10 @@ describe Castle::Commands::Authenticate do
|
|
59
59
|
it { expect(command.data).to be_eql(command_data) }
|
60
60
|
end
|
61
61
|
|
62
|
-
context 'active false' do
|
63
|
-
let(:payload) { default_payload.merge(
|
62
|
+
context 'when active false' do
|
63
|
+
let(:payload) { default_payload.merge(context: { active: false }) }
|
64
64
|
let(:command_data) do
|
65
|
-
default_payload.merge(
|
65
|
+
default_payload.merge(context: context.merge(active: false))
|
66
66
|
end
|
67
67
|
|
68
68
|
it { expect(command.method).to be_eql(:post) }
|
@@ -70,9 +70,9 @@ describe Castle::Commands::Authenticate do
|
|
70
70
|
it { expect(command.data).to be_eql(command_data) }
|
71
71
|
end
|
72
72
|
|
73
|
-
context 'active string' do
|
74
|
-
let(:payload) { default_payload.merge(
|
75
|
-
let(:command_data) { default_payload.merge(
|
73
|
+
context 'when active string' do
|
74
|
+
let(:payload) { default_payload.merge(context: { active: 'string' }) }
|
75
|
+
let(:command_data) { default_payload.merge(context: context) }
|
76
76
|
|
77
77
|
it { expect(command.method).to be_eql(:post) }
|
78
78
|
it { expect(command.path).to be_eql('authenticate') }
|
@@ -83,7 +83,7 @@ describe Castle::Commands::Authenticate do
|
|
83
83
|
describe '#validate!' do
|
84
84
|
subject(:validate!) { instance.build(payload) }
|
85
85
|
|
86
|
-
context 'event not present' do
|
86
|
+
context 'with event not present' do
|
87
87
|
let(:payload) { {} }
|
88
88
|
|
89
89
|
it do
|
@@ -93,7 +93,7 @@ describe Castle::Commands::Authenticate do
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
context 'user_id not present' do
|
96
|
+
context 'with user_id not present' do
|
97
97
|
let(:payload) { { event: '$login.track' } }
|
98
98
|
|
99
99
|
it do
|
@@ -103,7 +103,7 @@ describe Castle::Commands::Authenticate do
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
context 'event and user_id present' do
|
106
|
+
context 'with event and user_id present' do
|
107
107
|
let(:payload) { { event: '$login.track', user_id: '1234' } }
|
108
108
|
|
109
109
|
it { expect { validate! }.not_to raise_error }
|
@@ -15,10 +15,10 @@ describe Castle::Commands::Identify do
|
|
15
15
|
describe '.build' do
|
16
16
|
subject(:command) { instance.build(payload) }
|
17
17
|
|
18
|
-
context 'simple merger' do
|
19
|
-
let(:payload) { default_payload.merge(
|
18
|
+
context 'with simple merger' do
|
19
|
+
let(:payload) { default_payload.merge(context: { test: { test2: '1' } }) }
|
20
20
|
let(:command_data) do
|
21
|
-
default_payload.merge(
|
21
|
+
default_payload.merge(context: { test: { test1: '1', test2: '1' } })
|
22
22
|
end
|
23
23
|
|
24
24
|
it { expect(command.method).to be_eql(:post) }
|
@@ -26,10 +26,10 @@ describe Castle::Commands::Identify do
|
|
26
26
|
it { expect(command.data).to be_eql(command_data) }
|
27
27
|
end
|
28
28
|
|
29
|
-
context 'traits' do
|
30
|
-
let(:payload) { default_payload.merge(
|
29
|
+
context 'with traits' do
|
30
|
+
let(:payload) { default_payload.merge(traits: { test: '1' }) }
|
31
31
|
let(:command_data) do
|
32
|
-
default_payload.merge(
|
32
|
+
default_payload.merge(traits: { test: '1' }, context: context)
|
33
33
|
end
|
34
34
|
|
35
35
|
it { expect(command.method).to be_eql(:post) }
|
@@ -37,10 +37,10 @@ describe Castle::Commands::Identify do
|
|
37
37
|
it { expect(command.data).to be_eql(command_data) }
|
38
38
|
end
|
39
39
|
|
40
|
-
context 'active true' do
|
41
|
-
let(:payload) { default_payload.merge(
|
40
|
+
context 'when active true' do
|
41
|
+
let(:payload) { default_payload.merge(context: { active: true }) }
|
42
42
|
let(:command_data) do
|
43
|
-
default_payload.merge(
|
43
|
+
default_payload.merge(context: context.merge(active: true))
|
44
44
|
end
|
45
45
|
|
46
46
|
it { expect(command.method).to be_eql(:post) }
|
@@ -48,10 +48,10 @@ describe Castle::Commands::Identify do
|
|
48
48
|
it { expect(command.data).to be_eql(command_data) }
|
49
49
|
end
|
50
50
|
|
51
|
-
context 'active false' do
|
52
|
-
let(:payload) { default_payload.merge(
|
51
|
+
context 'when active false' do
|
52
|
+
let(:payload) { default_payload.merge(context: { active: false }) }
|
53
53
|
let(:command_data) do
|
54
|
-
default_payload.merge(
|
54
|
+
default_payload.merge(context: context.merge(active: false))
|
55
55
|
end
|
56
56
|
|
57
57
|
it { expect(command.method).to be_eql(:post) }
|
@@ -59,9 +59,9 @@ describe Castle::Commands::Identify do
|
|
59
59
|
it { expect(command.data).to be_eql(command_data) }
|
60
60
|
end
|
61
61
|
|
62
|
-
context 'active string' do
|
63
|
-
let(:payload) { default_payload.merge(
|
64
|
-
let(:command_data) { default_payload.merge(
|
62
|
+
context 'when active string' do
|
63
|
+
let(:payload) { default_payload.merge(context: { active: 'string' }) }
|
64
|
+
let(:command_data) { default_payload.merge(context: context) }
|
65
65
|
|
66
66
|
it { expect(command.method).to be_eql(:post) }
|
67
67
|
it { expect(command.path).to be_eql('identify') }
|
@@ -72,7 +72,7 @@ describe Castle::Commands::Identify do
|
|
72
72
|
describe '#validate!' do
|
73
73
|
subject(:validate!) { instance.build(payload) }
|
74
74
|
|
75
|
-
context 'user_id not present' do
|
75
|
+
context 'with user_id not present' do
|
76
76
|
let(:payload) { {} }
|
77
77
|
|
78
78
|
it do
|
@@ -82,7 +82,7 @@ describe Castle::Commands::Identify do
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
context 'user_id present' do
|
85
|
+
context 'with user_id present' do
|
86
86
|
let(:payload) { { user_id: '1234' } }
|
87
87
|
|
88
88
|
it { expect { validate! }.not_to raise_error }
|
@@ -5,7 +5,7 @@ describe Castle::Commands::Impersonate do
|
|
5
5
|
|
6
6
|
let(:context) { { user_agent: 'test', ip: '127.0.0.1', client_id: 'test' } }
|
7
7
|
let(:impersonator) { 'test@castle.io' }
|
8
|
-
let(:default_payload) { { user_id: '1234' } }
|
8
|
+
let(:default_payload) { { user_id: '1234', sent_at: time_auto } }
|
9
9
|
|
10
10
|
let(:time_now) { Time.now }
|
11
11
|
let(:time_auto) { time_now.utc.iso8601(3) }
|
@@ -15,10 +15,10 @@ describe Castle::Commands::Track do
|
|
15
15
|
describe '#build' do
|
16
16
|
subject(:command) { instance.build(payload) }
|
17
17
|
|
18
|
-
context 'simple merger' do
|
19
|
-
let(:payload) { default_payload.merge(
|
18
|
+
context 'with simple merger' do
|
19
|
+
let(:payload) { default_payload.merge(context: { test: { test2: '1' } }) }
|
20
20
|
let(:command_data) do
|
21
|
-
default_payload.merge(
|
21
|
+
default_payload.merge(context: { test: { test1: '1', test2: '1' } })
|
22
22
|
end
|
23
23
|
|
24
24
|
it { expect(command.method).to be_eql(:post) }
|
@@ -26,10 +26,10 @@ describe Castle::Commands::Track do
|
|
26
26
|
it { expect(command.data).to be_eql(command_data) }
|
27
27
|
end
|
28
28
|
|
29
|
-
context 'user_id' do
|
30
|
-
let(:payload) { default_payload.merge(
|
29
|
+
context 'with user_id' do
|
30
|
+
let(:payload) { default_payload.merge(user_id: '1234') }
|
31
31
|
let(:command_data) do
|
32
|
-
default_payload.merge(
|
32
|
+
default_payload.merge(user_id: '1234', context: context)
|
33
33
|
end
|
34
34
|
|
35
35
|
it { expect(command.method).to be_eql(:post) }
|
@@ -37,10 +37,10 @@ describe Castle::Commands::Track do
|
|
37
37
|
it { expect(command.data).to be_eql(command_data) }
|
38
38
|
end
|
39
39
|
|
40
|
-
context 'properties' do
|
41
|
-
let(:payload) { default_payload.merge(
|
40
|
+
context 'with properties' do
|
41
|
+
let(:payload) { default_payload.merge(properties: { test: '1' }) }
|
42
42
|
let(:command_data) do
|
43
|
-
default_payload.merge(
|
43
|
+
default_payload.merge(properties: { test: '1' }, context: context)
|
44
44
|
end
|
45
45
|
|
46
46
|
it { expect(command.method).to be_eql(:post) }
|
@@ -48,10 +48,10 @@ describe Castle::Commands::Track do
|
|
48
48
|
it { expect(command.data).to be_eql(command_data) }
|
49
49
|
end
|
50
50
|
|
51
|
-
context 'traits' do
|
52
|
-
let(:payload) { default_payload.merge(
|
51
|
+
context 'with traits' do
|
52
|
+
let(:payload) { default_payload.merge(traits: { test: '1' }) }
|
53
53
|
let(:command_data) do
|
54
|
-
default_payload.merge(
|
54
|
+
default_payload.merge(traits: { test: '1' }, context: context)
|
55
55
|
end
|
56
56
|
|
57
57
|
it { expect(command.method).to be_eql(:post) }
|
@@ -59,10 +59,10 @@ describe Castle::Commands::Track do
|
|
59
59
|
it { expect(command.data).to be_eql(command_data) }
|
60
60
|
end
|
61
61
|
|
62
|
-
context 'active true' do
|
63
|
-
let(:payload) { default_payload.merge(
|
62
|
+
context 'when active true' do
|
63
|
+
let(:payload) { default_payload.merge(context: { active: true }) }
|
64
64
|
let(:command_data) do
|
65
|
-
default_payload.merge(
|
65
|
+
default_payload.merge(context: context.merge(active: true))
|
66
66
|
end
|
67
67
|
|
68
68
|
it { expect(command.method).to be_eql(:post) }
|
@@ -70,10 +70,10 @@ describe Castle::Commands::Track do
|
|
70
70
|
it { expect(command.data).to be_eql(command_data) }
|
71
71
|
end
|
72
72
|
|
73
|
-
context 'active false' do
|
74
|
-
let(:payload) { default_payload.merge(
|
73
|
+
context 'when active false' do
|
74
|
+
let(:payload) { default_payload.merge(context: { active: false }) }
|
75
75
|
let(:command_data) do
|
76
|
-
default_payload.merge(
|
76
|
+
default_payload.merge(context: context.merge(active: false))
|
77
77
|
end
|
78
78
|
|
79
79
|
it { expect(command.method).to be_eql(:post) }
|
@@ -81,9 +81,9 @@ describe Castle::Commands::Track do
|
|
81
81
|
it { expect(command.data).to be_eql(command_data) }
|
82
82
|
end
|
83
83
|
|
84
|
-
context 'active string' do
|
85
|
-
let(:payload) { default_payload.merge(
|
86
|
-
let(:command_data) { default_payload.merge(
|
84
|
+
context 'when active string' do
|
85
|
+
let(:payload) { default_payload.merge(context: { active: 'string' }) }
|
86
|
+
let(:command_data) { default_payload.merge(context: context) }
|
87
87
|
|
88
88
|
it { expect(command.method).to be_eql(:post) }
|
89
89
|
it { expect(command.path).to be_eql('track') }
|
@@ -94,7 +94,7 @@ describe Castle::Commands::Track do
|
|
94
94
|
describe '#validate!' do
|
95
95
|
subject(:validate!) { instance.build(payload) }
|
96
96
|
|
97
|
-
context 'event not present' do
|
97
|
+
context 'when event not present' do
|
98
98
|
let(:payload) { {} }
|
99
99
|
|
100
100
|
it do
|
@@ -104,7 +104,7 @@ describe Castle::Commands::Track do
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
context 'event present' do
|
107
|
+
context 'when event present' do
|
108
108
|
let(:payload) { { event: '$login.track' } }
|
109
109
|
|
110
110
|
it { expect { validate! }.not_to raise_error }
|