liveqa 1.8.3 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/liveqa.rb CHANGED
@@ -5,12 +5,11 @@ require 'ostruct'
5
5
  require 'json'
6
6
  require 'time'
7
7
  require 'cgi'
8
-
9
- # Async
10
- require 'liveqa/async_handlers/base'
8
+ require 'logger'
11
9
 
12
10
  # Base
13
11
  require 'liveqa/version'
12
+ require 'liveqa/formated_logger'
14
13
  require 'liveqa/library_name'
15
14
  require 'liveqa/util'
16
15
  require 'liveqa/config'
@@ -21,6 +20,11 @@ require 'liveqa/api_resource'
21
20
  require 'liveqa/store'
22
21
  require 'liveqa/message'
23
22
 
23
+ # Processor
24
+ require 'liveqa/processor/async'
25
+ require 'liveqa/processor/worker'
26
+ require 'liveqa/processor/batch'
27
+
24
28
  # Operations
25
29
  require 'liveqa/api_operation/save'
26
30
  require 'liveqa/api_operation/delete'
@@ -30,6 +34,7 @@ require 'liveqa/event'
30
34
  require 'liveqa/group'
31
35
  require 'liveqa/identity'
32
36
  require 'liveqa/watcher'
37
+ require 'liveqa/batch'
33
38
 
34
39
  # Plugins
35
40
  require 'liveqa/plugins'
@@ -39,6 +44,11 @@ require 'liveqa/plugins'
39
44
  module LiveQA
40
45
  class << self
41
46
 
47
+ EVENTS_CREATE_ACTION = 'events:create'.freeze
48
+ GROUPS_UPDATE_ACTION = 'groups:update'.freeze
49
+ IDENTITIES_UPDATE_ACTION = 'identities:update'.freeze
50
+ WATCHERS_CREATE_ACTION = 'watchers:create'.freeze
51
+
42
52
  ##
43
53
  # @return [LiveQA::Config] configurations
44
54
  attr_reader :configurations
@@ -65,8 +75,8 @@ module LiveQA
65
75
  # @param [Hash] payload to be send
66
76
  # @param [Hash] options for the request
67
77
  #
68
- # @return [LiveQA::Object] response from the server
69
- def track(name, payload = {}, request_options = {})
78
+ # @return [Boolean] status of the request
79
+ def track(name, payload = {}, options = {})
70
80
  return true unless configurations.enabled
71
81
 
72
82
  payload[:type] = 'track'
@@ -75,12 +85,15 @@ module LiveQA
75
85
 
76
86
  payload = Message.extended.merge(payload)
77
87
 
78
- if configurations.async_handler
79
- return configurations.async_handler.enqueue('LiveQA::Event', 'create', payload, request_options)
88
+ if configurations.async
89
+ return processor.enqueue(
90
+ action: EVENTS_CREATE_ACTION,
91
+ payload: payload,
92
+ options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
93
+ )
80
94
  end
81
95
 
82
- event = Event.create(payload, request_options)
83
-
96
+ event = Event.create(payload, options)
84
97
  event.successful?
85
98
  end
86
99
 
@@ -91,8 +104,8 @@ module LiveQA
91
104
  # @param [Hash] payload to be send
92
105
  # @param [Hash] options for the request
93
106
  #
94
- # @return [LiveQA::Object] response from the server
95
- def identify(user_id, payload = {}, request_options = {})
107
+ # @return [Boolean] status of the request
108
+ def identify(user_id, payload = {}, options = {})
96
109
  return true unless configurations.enabled
97
110
 
98
111
  payload[:type] = 'identify'
@@ -101,12 +114,15 @@ module LiveQA
101
114
 
102
115
  payload = Message.extended.merge(payload)
103
116
 
104
- if configurations.async_handler
105
- return configurations.async_handler.enqueue('LiveQA::Event', 'create', payload, request_options)
117
+ if configurations.async
118
+ return processor.enqueue(
119
+ action: EVENTS_CREATE_ACTION,
120
+ payload: payload,
121
+ options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
122
+ )
106
123
  end
107
124
 
108
- event = Event.create(payload, request_options)
109
-
125
+ event = Event.create(payload, options)
110
126
  event.successful?
111
127
  end
112
128
 
@@ -117,18 +133,22 @@ module LiveQA
117
133
  # @param [Hash] payload to be send
118
134
  # @param [Hash] options for the request
119
135
  #
120
- # @return [LiveQA::Object] response from the server
121
- def set_group(group_id, payload = {}, request_options = {})
136
+ # @return [Boolean] status of the request
137
+ def set_group(group_id, payload = {}, options = {})
122
138
  return true unless configurations.enabled
123
139
 
124
140
  payload = Message.base.merge(payload)
125
141
 
126
- if configurations.async_handler
127
- return configurations.async_handler.enqueue('LiveQA::Group', 'update', group_id, payload, request_options)
142
+ if configurations.async
143
+ return processor.enqueue(
144
+ action: GROUPS_UPDATE_ACTION,
145
+ id: group_id,
146
+ payload: payload,
147
+ options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
148
+ )
128
149
  end
129
150
 
130
- group = Group.update(group_id, payload, request_options)
131
-
151
+ group = Group.update(group_id, payload, options)
132
152
  group.successful?
133
153
  end
134
154
 
@@ -139,18 +159,22 @@ module LiveQA
139
159
  # @param [Hash] payload to be send
140
160
  # @param [Hash] options for the request
141
161
  #
142
- # @return [LiveQA::Object] response from the server
143
- def set_identity(user_id, payload = {}, request_options = {})
162
+ # @return [Boolean] status of the request
163
+ def set_identity(user_id, payload = {}, options = {})
144
164
  return true unless configurations.enabled
145
165
 
146
166
  payload = Message.base.merge(payload)
147
167
 
148
- if configurations.async_handler
149
- return configurations.async_handler.enqueue('LiveQA::Identity', 'update', user_id, payload, request_options)
168
+ if configurations.async
169
+ return processor.enqueue(
170
+ action: IDENTITIES_UPDATE_ACTION,
171
+ id: user_id,
172
+ payload: payload,
173
+ options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
174
+ )
150
175
  end
151
176
 
152
- identity = Identity.update(user_id, payload, request_options)
153
-
177
+ identity = Identity.update(user_id, payload, options)
154
178
  identity.successful?
155
179
  end
156
180
 
@@ -161,8 +185,8 @@ module LiveQA
161
185
  # @param [Hash] payload to be send
162
186
  # @param [Hash] options for the request
163
187
  #
164
- # @return [LiveQA::Object] response from the server
165
- def watch(id_or_name, payload = {}, request_options = {})
188
+ # @return [Boolean] status of the request
189
+ def watch(id_or_name, payload = {}, options = {})
166
190
  return true unless configurations.enabled
167
191
 
168
192
  payload[:template_flow] = id_or_name
@@ -170,14 +194,23 @@ module LiveQA
170
194
 
171
195
  payload.delete(:session_tracker_id) if payload.delete(:without_session)
172
196
 
173
- if configurations.async_handler
174
- return configurations.async_handler.enqueue('LiveQA::Watcher', 'create', payload, request_options)
197
+ if configurations.async
198
+ return processor.enqueue(
199
+ action: WATCHERS_CREATE_ACTION,
200
+ payload: payload,
201
+ options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
202
+ )
175
203
  end
176
204
 
177
- watcher = Watcher.create(payload, request_options)
178
-
205
+ watcher = Watcher.create(payload, options)
179
206
  watcher.successful?
180
207
  end
181
208
 
209
+ private
210
+
211
+ def processor
212
+ @processor ||= Processor::Async.new
213
+ end
214
+
182
215
  end
183
216
  end
data/liveqa.gemspec CHANGED
@@ -1,4 +1,4 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'liveqa/version'
4
4
  require 'liveqa/library_name'
@@ -19,8 +19,8 @@ Gem::Specification.new do |s|
19
19
  s.test_files = `git ls-files -- spec/*`.split("\n")
20
20
 
21
21
  s.add_development_dependency 'faker', '~> 1.8.4'
22
- s.add_development_dependency 'rake', '>= 0.9.0'
23
22
  s.add_development_dependency 'pry'
23
+ s.add_development_dependency 'rake', '>= 0.9.0'
24
24
  s.add_development_dependency 'rspec', '~> 3.5'
25
- s.add_development_dependency 'rubocop', '= 0.49.1'
25
+ s.add_development_dependency 'rubocop', '= 0.58.2'
26
26
  end
@@ -12,7 +12,7 @@ describe LiveQA::APIResource do
12
12
  let(:expected_payload) {{
13
13
  method: :post,
14
14
  url: 'http://localhost:4003/test',
15
- payload: '{}',
15
+ payload: match(''),
16
16
  use_ssl: false,
17
17
  headers: {
18
18
  accept: 'application/json',
@@ -20,7 +20,7 @@ describe LiveQA::APIResource do
20
20
  x_account_token: 'acc_xx',
21
21
  x_space_name: 'LiveQA',
22
22
  x_environment_name: 'test'
23
- }
23
+ },
24
24
  }}
25
25
 
26
26
  after { resource }
@@ -32,7 +32,7 @@ describe LiveQA::APIResource do
32
32
  let(:expected_payload) {{
33
33
  method: :post,
34
34
  url: 'http://localhost:4003/test',
35
- payload: "{\"test\":true}",
35
+ payload: match("\"test\":true"),
36
36
  use_ssl: false,
37
37
  headers: {
38
38
  accept: 'application/json',
@@ -51,8 +51,8 @@ describe LiveQA::APIResource do
51
51
  context 'with body and get' do
52
52
  let(:expected_payload) {{
53
53
  method: :get,
54
- url: 'http://localhost:4003/test?test=true',
55
- payload: "{\"test\":true}",
54
+ url: match("http://localhost:4003/test\\?test=true"),
55
+ payload: match("\"test\":true"),
56
56
  use_ssl: false,
57
57
  headers: {
58
58
  accept: 'application/json',
@@ -71,8 +71,8 @@ describe LiveQA::APIResource do
71
71
  context 'with overwrite headers tokens' do
72
72
  let(:expected_payload) {{
73
73
  method: :post,
74
- url: 'http://localhost:4003/test',
75
- payload: '{}',
74
+ url: match('http://localhost:4003/test'),
75
+ payload: match(''),
76
76
  use_ssl: false,
77
77
  headers: {
78
78
  accept: 'application/json',
@@ -101,7 +101,7 @@ describe LiveQA::APIResource do
101
101
  context 'with Net::HTTPBadRequest' do
102
102
  let(:response) { double('response', code: '400', code_type: Net::HTTPBadRequest, body: {}.to_json, message: 'failed') }
103
103
 
104
- it { expect { resource }.to_not raise_error }
104
+ it { expect { resource }.to raise_error(LiveQA::RequestError) }
105
105
  end
106
106
  end
107
107
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::Batch do
4
+
5
+ describe '.create' do
6
+ let(:response) { double('LiveQA::Request', body: "{\"object\":\"event\",\"id\":41}") }
7
+ before { allow(LiveQA::Request).to receive(:execute).and_return(response) }
8
+
9
+ subject(:create) { LiveQA::Batch.create(data: []) }
10
+
11
+ it { is_expected.to be_successful }
12
+ end
13
+
14
+ end
@@ -10,7 +10,15 @@ describe LiveQA::Config do
10
10
 
11
11
  %i[account_token environment_name api_host api_version].each do |field|
12
12
  context "validate #{field}" do
13
- let(:params) {{ account_token: 'acc_xx', space_name: 'LiveQA', environment_name: 'test', api_host: 'host', api_version: 'v1' }.merge(field => '')}
13
+ let(:params) {
14
+ {
15
+ account_token: 'acc_xx',
16
+ space_name: 'LiveQA',
17
+ environment_name: 'test',
18
+ api_host: 'host',
19
+ api_version: 'v1',
20
+ }.merge(field => '')
21
+ }
14
22
 
15
23
  it { expect { config.valid! }.to raise_error(LiveQA::ConfigurationError, "#{field} can't be blank") }
16
24
  end
@@ -24,19 +32,5 @@ describe LiveQA::Config do
24
32
  it { expect(config.obfuscated_fields).to match_array(%w[another_password password_confirmation password access_token api_key authenticity_token ccv credit_card_number cvv secret secret_token token]) }
25
33
  end
26
34
 
27
- context 'async_handler' do
28
- context 'sidekiq' do
29
- let(:params) {{
30
- account_token: 'acc_xx',
31
- space_name: 'LiveQA',
32
- environment_name: 'test',
33
- async_handler: :sidekiq
34
- }}
35
- before { config.valid! }
36
-
37
- it { expect(config.async_handler).to be_a(LiveQA::AsyncHandlers::Sidekiq) }
38
- end
39
- end
40
-
41
35
  end
42
36
  end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::FormatedLogger do
4
+ let(:default_logger) { Logger.new(STDOUT) }
5
+ let(:logger) { LiveQA::FormatedLogger.build(default_logger) }
6
+
7
+ describe 'debug' do
8
+
9
+ context 'active' do
10
+ before do
11
+ allow(default_logger).to receive(:debug)
12
+ logger.debug('test')
13
+ end
14
+
15
+ it { expect(default_logger).to have_received(:debug).with('[LiveQA] test') }
16
+ end
17
+
18
+ context 'inactive' do
19
+ before do
20
+ LiveQA.configurations.log = false
21
+ allow(default_logger).to receive(:debug)
22
+ logger.debug('test')
23
+ end
24
+
25
+ it { expect(default_logger).to_not have_received(:debug) }
26
+ end
27
+
28
+ end
29
+
30
+ describe 'info' do
31
+
32
+ context 'active' do
33
+ before do
34
+ allow(default_logger).to receive(:info)
35
+ logger.info('test')
36
+ end
37
+
38
+ it { expect(default_logger).to have_received(:info).with('[LiveQA] test') }
39
+ end
40
+
41
+ context 'inactive' do
42
+ before do
43
+ LiveQA.configurations.log = false
44
+ allow(default_logger).to receive(:info)
45
+ logger.info('test')
46
+ end
47
+
48
+ it { expect(default_logger).to_not have_received(:info) }
49
+ end
50
+
51
+ end
52
+
53
+ describe 'info' do
54
+
55
+ context 'active' do
56
+ before do
57
+ allow(default_logger).to receive(:info)
58
+ logger.info('test')
59
+ end
60
+
61
+ it { expect(default_logger).to have_received(:info).with('[LiveQA] test') }
62
+ end
63
+
64
+ context 'inactive' do
65
+ before do
66
+ LiveQA.configurations.log = false
67
+ allow(default_logger).to receive(:info)
68
+ logger.info('test')
69
+ end
70
+
71
+ it { expect(default_logger).to_not have_received(:info) }
72
+ end
73
+
74
+ end
75
+
76
+ describe 'error' do
77
+
78
+ context 'active' do
79
+ before do
80
+ allow(default_logger).to receive(:error)
81
+ logger.error('test')
82
+ end
83
+
84
+ it { expect(default_logger).to have_received(:error).with('[LiveQA] test') }
85
+ end
86
+
87
+ context 'inactive' do
88
+ before do
89
+ LiveQA.configurations.log = false
90
+ allow(default_logger).to receive(:error)
91
+ logger.error('test')
92
+ end
93
+
94
+ it { expect(default_logger).to_not have_received(:error) }
95
+ end
96
+
97
+ end
98
+
99
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::Processor::Async do
4
+
5
+ let(:processor) { LiveQA::Processor::Async.new }
6
+
7
+ context 'enqueue a message' do
8
+
9
+ before do
10
+ allow(processor).to receive(:ensure_worker_running)
11
+ processor.enqueue({ test: 'hello' })
12
+ end
13
+
14
+ it { expect(processor).to have_received(:ensure_worker_running) }
15
+ it { expect(processor.instance_variable_get(:@queue).length).to eq(1) }
16
+ end
17
+
18
+
19
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::Processor::Batch do
4
+ let(:batch) { LiveQA::Processor::Batch.new }
5
+
6
+ context 'set defaults' do
7
+ it { expect(batch.messages).to eq([]) }
8
+ it { expect(batch.can_run?).to be_truthy }
9
+ it { expect(batch.can_retry?).to be_truthy }
10
+ it { expect(batch.full?).to be_falsey }
11
+ end
12
+
13
+ context 'add message' do
14
+ before { batch << { test: 'hello' }}
15
+
16
+ it { expect(batch.messages).to eq([{ test: 'hello' }]) }
17
+ it { expect(batch.full?).to be_falsey }
18
+ end
19
+
20
+ context 'with extended task' do
21
+ before { batch.update_retry }
22
+
23
+ it { expect(batch.can_run?).to be_falsey }
24
+ it { expect(batch.can_retry?).to be_truthy }
25
+ end
26
+
27
+ context 'with extended task' do
28
+ before do
29
+ 11.times { batch.update_retry }
30
+ end
31
+
32
+ it { expect(batch.can_run?).to be_falsey }
33
+ it { expect(batch.can_retry?).to be_falsey }
34
+ end
35
+
36
+ context 'with max number of messages reached' do
37
+ before { 100.times { batch << { test: 'hello' }}}
38
+
39
+ it { expect(batch.full?).to be_truthy }
40
+ end
41
+
42
+ context 'with max size reached' do
43
+ before { 20.times { batch << 1000.times.map {{ test: 'hello' }}}}
44
+
45
+ it { expect(batch.full?).to be_truthy }
46
+ end
47
+
48
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::Processor::Worker do
4
+ let(:queue) { Queue.new }
5
+ let(:worker) { LiveQA::Processor::Worker.new(queue) }
6
+
7
+ context 'do nothing' do
8
+ before do
9
+ allow(worker).to receive(:send_batches)
10
+ worker.run
11
+ end
12
+
13
+ it { expect(worker).not_to have_received(:send_batches) }
14
+ end
15
+
16
+ context 'with something in the queue' do
17
+ before do
18
+ queue << { test: true }
19
+ allow(LiveQA::Batch).to receive(:create)
20
+ worker.run
21
+ end
22
+
23
+ it { expect(LiveQA::Batch).to have_received(:create) }
24
+ end
25
+ end