castle-rb 3.4.0 → 3.4.1
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/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 }
|