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.
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 }