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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -24
  3. data/lib/castle.rb +5 -3
  4. data/lib/castle/client.rb +21 -18
  5. data/lib/castle/commands/authenticate.rb +8 -16
  6. data/lib/castle/commands/identify.rb +9 -21
  7. data/lib/castle/commands/impersonate.rb +9 -23
  8. data/lib/castle/commands/review.rb +5 -4
  9. data/lib/castle/commands/track.rb +8 -16
  10. data/lib/castle/configuration.rb +1 -2
  11. data/lib/castle/context/default.rb +40 -0
  12. data/lib/castle/context/merger.rb +14 -0
  13. data/lib/castle/context/sanitizer.rb +23 -0
  14. data/lib/castle/review.rb +1 -1
  15. data/lib/castle/utils/merger.rb +9 -9
  16. data/lib/castle/validators/not_supported.rb +16 -0
  17. data/lib/castle/validators/present.rb +16 -0
  18. data/lib/castle/version.rb +1 -1
  19. data/spec/lib/castle/client_spec.rb +3 -2
  20. data/spec/lib/castle/commands/authenticate_spec.rb +21 -21
  21. data/spec/lib/castle/commands/identify_spec.rb +17 -17
  22. data/spec/lib/castle/commands/impersonate_spec.rb +1 -1
  23. data/spec/lib/castle/commands/review_spec.rb +1 -1
  24. data/spec/lib/castle/commands/track_spec.rb +23 -23
  25. data/spec/lib/castle/configuration_spec.rb +13 -13
  26. data/spec/lib/castle/{default_context_spec.rb → context/default_spec.rb} +1 -1
  27. data/spec/lib/castle/{context_merger_spec.rb → context/merger_spec.rb} +4 -4
  28. data/spec/lib/castle/{context_sanitizer_spec.rb → context/sanitizer_spec.rb} +1 -1
  29. data/spec/lib/castle/extractors/client_id_spec.rb +1 -1
  30. data/spec/lib/castle/request_spec.rb +2 -2
  31. data/spec/lib/castle/response_spec.rb +4 -4
  32. data/spec/lib/castle/review_spec.rb +1 -1
  33. data/spec/lib/castle/utils_spec.rb +14 -14
  34. data/spec/lib/castle/validators/not_supported_spec.rb +26 -0
  35. data/spec/lib/castle/validators/present_spec.rb +33 -0
  36. data/spec/lib/castle_spec.rb +3 -3
  37. metadata +19 -13
  38. data/lib/castle/context_merger.rb +0 -12
  39. data/lib/castle/context_sanitizer.rb +0 -20
  40. 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
@@ -3,7 +3,7 @@
3
3
  module Castle
4
4
  class Review
5
5
  def self.retrieve(review_id)
6
- command = Castle::Commands::Review.new.build(review_id)
6
+ command = Castle::Commands::Review.build(review_id)
7
7
 
8
8
  API.new.request(command)
9
9
  end
@@ -3,20 +3,20 @@
3
3
  module Castle
4
4
  module Utils
5
5
  class Merger
6
- def self.call(first, second)
7
- first_s = Castle::Utils.deep_symbolize_keys(first)
8
- second_s = Castle::Utils.deep_symbolize_keys(second)
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
- second_s.each do |name, value|
10
+ extra_s.each do |name, value|
11
11
  if value.nil?
12
- first_s.delete(name)
13
- elsif value.is_a?(Hash) && first_s[name].is_a?(Hash)
14
- first_s[name] = call(first_s[name], value)
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
- first_s[name] = value
16
+ base_s[name] = value
17
17
  end
18
18
  end
19
- first_s
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Castle
4
- VERSION = '3.4.0'
4
+ VERSION = '3.4.1'
5
5
  end
@@ -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', impersonator: impersonator, context: context }
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
- context 'throw strategy' do
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({ context: { test: { test2: '1' } } }) }
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({ context: { test: { test1: '1', test2: '1' } } })
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({ properties: { test: '1' } }) }
29
+ context 'with properties' do
30
+ let(:payload) { default_payload.merge(properties: { test: '1' }) }
31
31
  let(:command_data) do
32
- default_payload.merge({ properties: { test: '1' }, context: context })
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({ traits: { test: '1' } }) }
40
+ context 'with traits' do
41
+ let(:payload) { default_payload.merge(traits: { test: '1' }) }
42
42
  let(:command_data) do
43
- default_payload.merge({ traits: { test: '1' }, context: context })
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({ context: { active: true } }) }
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({ context: context.merge(active: true) })
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({ context: { active: false } }) }
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({ context: context.merge(active: false) })
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({ context: { active: 'string' } }) }
75
- let(:command_data) { default_payload.merge({ context: context }) }
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({ context: { test: { test2: '1' } } }) }
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({ context: { test: { test1: '1', test2: '1' } } })
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({ traits: { test: '1' } }) }
29
+ context 'with traits' do
30
+ let(:payload) { default_payload.merge(traits: { test: '1' }) }
31
31
  let(:command_data) do
32
- default_payload.merge({ traits: { test: '1' }, context: context })
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({ context: { active: true } }) }
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({ context: context.merge(active: true) })
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({ context: { active: false } }) }
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({ context: context.merge(active: false) })
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({ context: { active: 'string' } }) }
64
- let(:command_data) { default_payload.merge({ context: context }) }
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) }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Castle::Commands::Review do
4
- subject(:instance) { described_class.new }
4
+ subject(:instance) { described_class }
5
5
 
6
6
  let(:context) { {} }
7
7
  let(:review_id) { '1234' }
@@ -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({ context: { test: { test2: '1' } } }) }
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({ context: { test: { test1: '1', test2: '1' } } })
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({ user_id: '1234' }) }
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({ user_id: '1234', context: context })
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({ properties: { test: '1' } }) }
40
+ context 'with properties' do
41
+ let(:payload) { default_payload.merge(properties: { test: '1' }) }
42
42
  let(:command_data) do
43
- default_payload.merge({ properties: { test: '1' }, context: context })
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({ traits: { test: '1' } }) }
51
+ context 'with traits' do
52
+ let(:payload) { default_payload.merge(traits: { test: '1' }) }
53
53
  let(:command_data) do
54
- default_payload.merge({ traits: { test: '1' }, context: context })
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({ context: { active: true } }) }
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({ context: context.merge(active: true) })
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({ context: { active: false } }) }
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({ context: context.merge(active: false) })
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({ context: { active: 'string' } }) }
86
- let(:command_data) { default_payload.merge({ context: context }) }
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 }