liveqa 1.4.6 → 1.8.3

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.travis.yml +1 -0
  4. data/README.md +94 -7
  5. data/lib/liveqa/api_operation/delete.rb +38 -0
  6. data/lib/liveqa/api_resource.rb +7 -6
  7. data/lib/liveqa/async_handlers/base.rb +1 -3
  8. data/lib/liveqa/config.rb +35 -11
  9. data/lib/liveqa/event.rb +4 -10
  10. data/lib/liveqa/group.rb +14 -0
  11. data/lib/liveqa/identity.rb +16 -0
  12. data/lib/liveqa/liveqa_object.rb +48 -8
  13. data/lib/liveqa/message.rb +31 -10
  14. data/lib/liveqa/plugins/rack/middleware.rb +50 -36
  15. data/lib/liveqa/plugins/rails/data.rb +19 -0
  16. data/lib/liveqa/plugins/rails/middleware_data.rb +2 -18
  17. data/lib/liveqa/plugins/sidekiq/client_middleware.rb +1 -1
  18. data/lib/liveqa/plugins/sidekiq/server_middleware.rb +2 -2
  19. data/lib/liveqa/plugins.rb +1 -0
  20. data/lib/liveqa/request.rb +2 -0
  21. data/lib/liveqa/store.rb +1 -1
  22. data/lib/liveqa/util.rb +81 -1
  23. data/lib/liveqa/version.rb +1 -1
  24. data/lib/liveqa/watcher.rb +15 -0
  25. data/lib/liveqa.rb +82 -4
  26. data/spec/lib/liveqa/api_resource_spec.rb +109 -0
  27. data/spec/lib/liveqa/async_handlers/base_spec.rb +13 -3
  28. data/spec/lib/liveqa/config_spec.rb +8 -6
  29. data/spec/lib/liveqa/event_spec.rb +2 -23
  30. data/spec/lib/liveqa/group_spec.rb +15 -0
  31. data/spec/lib/liveqa/identity_spec.rb +15 -0
  32. data/spec/lib/liveqa/liveqa_object_spec.rb +53 -2
  33. data/spec/lib/liveqa/message_spec.rb +75 -8
  34. data/spec/lib/liveqa/plugins/rack/middleware_spec.rb +8 -2
  35. data/spec/lib/liveqa/plugins/rails/data_spec.rb +22 -0
  36. data/spec/lib/liveqa/plugins/rails/middleware_data_spec.rb +2 -23
  37. data/spec/lib/liveqa/plugins/sidekiq/server_middleware_spec.rb +6 -12
  38. data/spec/lib/liveqa/util_spec.rb +40 -0
  39. data/spec/lib/liveqa/watcher_spec.rb +25 -0
  40. data/spec/lib/liveqa_spec.rb +88 -5
  41. data/spec/spec_helper.rb +3 -1
  42. metadata +17 -2
@@ -5,12 +5,8 @@ module LiveQA
5
5
 
6
6
  class << self
7
7
 
8
- def store_data(request)
9
- LiveQA::Store.bulk_set(
10
- environement: ::Rails.env
11
- )
12
- store_request_data(request)
13
- store_framework
8
+ def store_data(request = nil)
9
+ store_request_data(request) if request
14
10
  end
15
11
 
16
12
  private
@@ -24,18 +20,6 @@ module LiveQA
24
20
  )
25
21
  end
26
22
 
27
- def store_framework
28
- stack = LiveQA::Store.get(:stack) || []
29
-
30
- LiveQA::Store.set(
31
- :stack,
32
- stack.push(
33
- name: 'rails',
34
- version: ::Rails.version
35
- )
36
- )
37
- end
38
-
39
23
  end
40
24
 
41
25
  end
@@ -9,7 +9,7 @@ module LiveQA
9
9
  class ClientMiddleware
10
10
 
11
11
  def call(_worker_class, job, _queue, _redis_pool)
12
- job['liveqa_store'] = LiveQA::Store.store
12
+ job['liveqa_session_tracker_id'] = LiveQA::Store.store[:session_tracker_id]
13
13
  yield
14
14
  end
15
15
 
@@ -9,7 +9,7 @@ module LiveQA
9
9
  class ServerMiddleware
10
10
 
11
11
  def call(_worker, job, _queue)
12
- LiveQA::Store.load_from_hash(job['liveqa_store'])
12
+ LiveQA::Store.set(:session_tracker_id, job['liveqa_session_tracker_id'] || SecureRandom.uuid)
13
13
  store_worker_data(job)
14
14
  yield
15
15
  ensure
@@ -36,7 +36,7 @@ module LiveQA
36
36
  end
37
37
 
38
38
  def convert_to_iso8601(int_time)
39
- Time.at(int_time).utc.iso8601
39
+ Time.at(int_time).utc.iso8601(3)
40
40
  rescue
41
41
  nil
42
42
  end
@@ -7,6 +7,7 @@ if defined?(Rack)
7
7
  if defined?(Rails)
8
8
  require 'liveqa/plugins/rails/railtie'
9
9
  require 'liveqa/plugins/rails/middleware_data'
10
+ require 'liveqa/plugins/rails/data'
10
11
  end
11
12
  end
12
13
 
@@ -60,6 +60,7 @@ module LiveQA
60
60
  def put
61
61
  @request = Net::HTTP::Put.new(uri.path)
62
62
 
63
+ set_header
63
64
  request.body = params[:payload]
64
65
 
65
66
  handle_request
@@ -76,6 +77,7 @@ module LiveQA
76
77
  def delete
77
78
  @request = Net::HTTP::Delete.new(uri.path)
78
79
 
80
+ set_header
79
81
  request.body = params[:payload]
80
82
 
81
83
  handle_request
data/lib/liveqa/store.rb CHANGED
@@ -2,7 +2,7 @@ module LiveQA
2
2
  ##
3
3
  # == LiveQA \Store
4
4
  #
5
- # Store environement data
5
+ # Store environment data
6
6
  #
7
7
  class Store
8
8
  class << self
data/lib/liveqa/util.rb CHANGED
@@ -3,7 +3,30 @@ module LiveQA
3
3
  class << self
4
4
 
5
5
  DATE_FORMAT = '%Y/%m/%d'.freeze
6
- OBFUSCATED = '[HIDDEN]'.freeze
6
+ OBFUSCATED = '[HIDDEN]'.freeze
7
+ DEFAULT_OBJECT_DEF = %w[id name].freeze
8
+
9
+ ##
10
+ # Remove keys from a Hash
11
+ #
12
+ # @param [Hash] to be excepted
13
+ # @param [List[String]] to be excepted
14
+ #
15
+ # @return [Hash]
16
+ def except_keys(hash, *keys)
17
+ hash.dup.delete_if { |(key, _value)| keys.include?(key) }
18
+ end
19
+
20
+ ##
21
+ # Convert string to camelize
22
+ #
23
+ # @param [String]
24
+ #
25
+ # @example
26
+ # camelize('my_model') => 'MyModel'
27
+ def camelize(string)
28
+ string.split('_').map(&:capitalize).join
29
+ end
7
30
 
8
31
  ##
9
32
  # Remove nil value from hash
@@ -128,6 +151,38 @@ module LiveQA
128
151
  end
129
152
  end
130
153
 
154
+ ##
155
+ # Convert object into Hash
156
+ #
157
+ # @params [Objects]
158
+ #
159
+ # @return [Hash]
160
+ def properties(*args)
161
+ params = extract_params!(args)
162
+
163
+ attributes = params.each_with_object({}) do |(key, value), hash|
164
+ hash[key] = extract_object(value)
165
+ end
166
+
167
+ attributes.merge(
168
+ args.each_with_object({}) do |object, hash|
169
+ key = object.class.name.downcase
170
+ next if key.nil?
171
+
172
+ hash[key] = extract_object(object)
173
+ end
174
+ )
175
+ end
176
+
177
+ ##
178
+ # Parse JSON without raise
179
+ #
180
+ def safe_json_parse(data)
181
+ JSON.parse(data.to_s)
182
+ rescue JSON::ParserError
183
+ {}
184
+ end
185
+
131
186
  private
132
187
 
133
188
  def deep_transform_keys_in_object(object, &block)
@@ -143,6 +198,31 @@ module LiveQA
143
198
  end
144
199
  end
145
200
 
201
+ def extract_object(object, custom_object_properties = LiveQA.configurations.custom_object_properties)
202
+ return unless object
203
+
204
+ object_name = object.class.name.downcase
205
+
206
+ columns =
207
+ custom_object_properties[object_name.to_sym] ||
208
+ custom_object_properties[object_name.to_s] ||
209
+ DEFAULT_OBJECT_DEF
210
+
211
+ params = columns.each_with_object({}) do |column, attributes|
212
+ attributes[column.to_s] = object.send(column) if object.respond_to?(column)
213
+ end
214
+
215
+ params.empty? ? object : params
216
+ end
217
+
218
+ def extract_params!(args)
219
+ if args.last.is_a?(Hash) && args.last.instance_of?(Hash)
220
+ args.pop
221
+ else
222
+ {}
223
+ end
224
+ end
225
+
146
226
  end
147
227
  end
148
228
  end
@@ -1,3 +1,3 @@
1
1
  module LiveQA # :nodoc:
2
- VERSION = '1.4.6'.freeze
2
+ VERSION = '1.8.3'.freeze
3
3
  end
@@ -0,0 +1,15 @@
1
+ module LiveQA
2
+ ##
3
+ # == LiveQA \Watcher
4
+ #
5
+ # Create and update groups
6
+ #
7
+ # @example: Usage
8
+ #
9
+ # request = LiveQA::Watcher.create(template_flow: 'My Flow', expected_times: 42) #=> #<LiveQA::Response...>
10
+ #
11
+ class Watcher < APIResource
12
+ include LiveQA::APIOperation::Save
13
+ include LiveQA::APIOperation::Delete
14
+ end
15
+ end
data/lib/liveqa.rb CHANGED
@@ -3,6 +3,8 @@ require 'securerandom'
3
3
  require 'net/http'
4
4
  require 'ostruct'
5
5
  require 'json'
6
+ require 'time'
7
+ require 'cgi'
6
8
 
7
9
  # Async
8
10
  require 'liveqa/async_handlers/base'
@@ -21,9 +23,13 @@ require 'liveqa/message'
21
23
 
22
24
  # Operations
23
25
  require 'liveqa/api_operation/save'
26
+ require 'liveqa/api_operation/delete'
24
27
 
25
28
  # Resources
26
29
  require 'liveqa/event'
30
+ require 'liveqa/group'
31
+ require 'liveqa/identity'
32
+ require 'liveqa/watcher'
27
33
 
28
34
  # Plugins
29
35
  require 'liveqa/plugins'
@@ -42,7 +48,9 @@ module LiveQA
42
48
  #
43
49
  # @example Default configuration
44
50
  # LiveQA.configure do |config|
45
- # config.api_key = 'your-api-key'
51
+ # config.account_token = 'acc_xx'
52
+ # config.space_name = 'LiveQA'
53
+ # config.environment_name = 'production'
46
54
  # end
47
55
  def configure
48
56
  yield @configurations = LiveQA::Config.new
@@ -54,7 +62,6 @@ module LiveQA
54
62
  # Send a track event to the server
55
63
  #
56
64
  # @param [String] event name
57
- # @param [String] user id from your database
58
65
  # @param [Hash] payload to be send
59
66
  # @param [Hash] options for the request
60
67
  #
@@ -64,8 +71,9 @@ module LiveQA
64
71
 
65
72
  payload[:type] = 'track'
66
73
  payload[:name] = name
74
+ LiveQA::Plugins::Rails::Data.store_data if defined?(LiveQA::Plugins::Rails::Data)
67
75
 
68
- payload = Event.build_payload(payload)
76
+ payload = Message.extended.merge(payload)
69
77
 
70
78
  if configurations.async_handler
71
79
  return configurations.async_handler.enqueue('LiveQA::Event', 'create', payload, request_options)
@@ -89,8 +97,9 @@ module LiveQA
89
97
 
90
98
  payload[:type] = 'identify'
91
99
  payload[:user_id] = user_id
100
+ LiveQA::Plugins::Rails::Data.store_data if defined?(LiveQA::Plugins::Rails::Data)
92
101
 
93
- payload = Event.build_payload(payload)
102
+ payload = Message.extended.merge(payload)
94
103
 
95
104
  if configurations.async_handler
96
105
  return configurations.async_handler.enqueue('LiveQA::Event', 'create', payload, request_options)
@@ -101,5 +110,74 @@ module LiveQA
101
110
  event.successful?
102
111
  end
103
112
 
113
+ ##
114
+ # Send a create/update for a group
115
+ #
116
+ # @param [String] group id from your database
117
+ # @param [Hash] payload to be send
118
+ # @param [Hash] options for the request
119
+ #
120
+ # @return [LiveQA::Object] response from the server
121
+ def set_group(group_id, payload = {}, request_options = {})
122
+ return true unless configurations.enabled
123
+
124
+ payload = Message.base.merge(payload)
125
+
126
+ if configurations.async_handler
127
+ return configurations.async_handler.enqueue('LiveQA::Group', 'update', group_id, payload, request_options)
128
+ end
129
+
130
+ group = Group.update(group_id, payload, request_options)
131
+
132
+ group.successful?
133
+ end
134
+
135
+ ##
136
+ # Send a create/update for an identity
137
+ #
138
+ # @param [String] user id from your database
139
+ # @param [Hash] payload to be send
140
+ # @param [Hash] options for the request
141
+ #
142
+ # @return [LiveQA::Object] response from the server
143
+ def set_identity(user_id, payload = {}, request_options = {})
144
+ return true unless configurations.enabled
145
+
146
+ payload = Message.base.merge(payload)
147
+
148
+ if configurations.async_handler
149
+ return configurations.async_handler.enqueue('LiveQA::Identity', 'update', user_id, payload, request_options)
150
+ end
151
+
152
+ identity = Identity.update(user_id, payload, request_options)
153
+
154
+ identity.successful?
155
+ end
156
+
157
+ ##
158
+ # Send a create a watcher
159
+ #
160
+ # @param [String|Integer] template flow name or id
161
+ # @param [Hash] payload to be send
162
+ # @param [Hash] options for the request
163
+ #
164
+ # @return [LiveQA::Object] response from the server
165
+ def watch(id_or_name, payload = {}, request_options = {})
166
+ return true unless configurations.enabled
167
+
168
+ payload[:template_flow] = id_or_name
169
+ payload = Message.base.merge(payload)
170
+
171
+ payload.delete(:session_tracker_id) if payload.delete(:without_session)
172
+
173
+ if configurations.async_handler
174
+ return configurations.async_handler.enqueue('LiveQA::Watcher', 'create', payload, request_options)
175
+ end
176
+
177
+ watcher = Watcher.create(payload, request_options)
178
+
179
+ watcher.successful?
180
+ end
181
+
104
182
  end
105
183
  end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::APIResource do
4
+
5
+ describe '#request' do
6
+ subject(:resource) { LiveQA::APIResource.request(:post, '/test') }
7
+
8
+ context 'valid request' do
9
+ let(:response) { double('response', code: '200', code_type: Net::HTTPOK, body: {}.to_json) }
10
+
11
+ context 'default payload' do
12
+ let(:expected_payload) {{
13
+ method: :post,
14
+ url: 'http://localhost:4003/test',
15
+ payload: '{}',
16
+ use_ssl: false,
17
+ headers: {
18
+ accept: 'application/json',
19
+ content_type: 'application/json',
20
+ x_account_token: 'acc_xx',
21
+ x_space_name: 'LiveQA',
22
+ x_environment_name: 'test'
23
+ }
24
+ }}
25
+
26
+ after { resource }
27
+
28
+ it { expect(LiveQA::Request).to receive(:execute).with(expected_payload).and_return(response) }
29
+ end
30
+
31
+ context 'with body and post' do
32
+ let(:expected_payload) {{
33
+ method: :post,
34
+ url: 'http://localhost:4003/test',
35
+ payload: "{\"test\":true}",
36
+ use_ssl: false,
37
+ headers: {
38
+ accept: 'application/json',
39
+ content_type: 'application/json',
40
+ x_account_token: 'acc_xx',
41
+ x_space_name: 'LiveQA',
42
+ x_environment_name: 'test'
43
+ }
44
+ }}
45
+
46
+ after { LiveQA::APIResource.request(:post, '/test', { test: true }) }
47
+
48
+ it { expect(LiveQA::Request).to receive(:execute).with(expected_payload).and_return(response) }
49
+ end
50
+
51
+ context 'with body and get' do
52
+ let(:expected_payload) {{
53
+ method: :get,
54
+ url: 'http://localhost:4003/test?test=true',
55
+ payload: "{\"test\":true}",
56
+ use_ssl: false,
57
+ headers: {
58
+ accept: 'application/json',
59
+ content_type: 'application/json',
60
+ x_account_token: 'acc_xx',
61
+ x_space_name: 'LiveQA',
62
+ x_environment_name: 'test'
63
+ }
64
+ }}
65
+
66
+ after { LiveQA::APIResource.request(:get, '/test', { test: true }) }
67
+
68
+ it { expect(LiveQA::Request).to receive(:execute).with(expected_payload).and_return(response) }
69
+ end
70
+
71
+ context 'with overwrite headers tokens' do
72
+ let(:expected_payload) {{
73
+ method: :post,
74
+ url: 'http://localhost:4003/test',
75
+ payload: '{}',
76
+ use_ssl: false,
77
+ headers: {
78
+ accept: 'application/json',
79
+ content_type: 'application/json',
80
+ x_account_token: 'acc_42',
81
+ x_space_name: 'MySpace',
82
+ x_environment_name: 'staging'
83
+ }
84
+ }}
85
+
86
+ after { LiveQA::APIResource.request(:post, '/test', {}, account_token: 'acc_42', space_name: 'MySpace', environment_name: 'staging') }
87
+
88
+ it { expect(LiveQA::Request).to receive(:execute).with(expected_payload).and_return(response) }
89
+ end
90
+ end
91
+
92
+ context 'with errors' do
93
+ before { allow(LiveQA::Request).to receive(:execute).and_raise(LiveQA::RequestError.new(response)) }
94
+
95
+ context 'with Net::HTTPUnprocessableEntity' do
96
+ let(:response) { double('response', code: '422', code_type: Net::HTTPUnprocessableEntity, body: {}.to_json, message: 'failed') }
97
+
98
+ it { expect { resource }.to_not raise_error }
99
+ end
100
+
101
+ context 'with Net::HTTPBadRequest' do
102
+ let(:response) { double('response', code: '400', code_type: Net::HTTPBadRequest, body: {}.to_json, message: 'failed') }
103
+
104
+ it { expect { resource }.to_not raise_error }
105
+ end
106
+ end
107
+ end
108
+
109
+ end
@@ -10,10 +10,20 @@ describe LiveQA::AsyncHandlers::Base do
10
10
  end
11
11
 
12
12
  describe 'execute' do
13
- let(:params) { ['LiveQA::Event', 'create', { test: true }] }
13
+ context 'default params' do
14
+ let(:params) { ['LiveQA::Event', 'create', { test: true }] }
14
15
 
15
- after { base.execute(params) }
16
+ after { base.execute(params) }
16
17
 
17
- it { expect(LiveQA::Event).to receive(:create).with({ test: true }, nil) }
18
+ it { expect(LiveQA::Event).to receive(:create).with({ test: true }) }
19
+ end
20
+
21
+ context 'more params params' do
22
+ let(:params) { ['LiveQA::Group', 'update', 42, { test: true }, { no_ssl: true }] }
23
+
24
+ after { base.execute(params) }
25
+
26
+ it { expect(LiveQA::Group).to receive(:update).with(42, { test: true }, { no_ssl: true }) }
27
+ end
18
28
  end
19
29
  end
@@ -4,30 +4,32 @@ describe LiveQA::Config do
4
4
  subject(:config) { LiveQA::Config.new(params) }
5
5
 
6
6
  describe '#initialize' do
7
- let(:params) {{ api_key: SecureRandom.hex }}
7
+ let(:params) {{ account_token: 'acc_xx', space_name: 'LiveQA', environment_name: 'test' }}
8
8
 
9
9
  it { expect(config.valid!).to be_truthy }
10
10
 
11
- %i[api_key api_host api_version].each do |field|
11
+ %i[account_token environment_name api_host api_version].each do |field|
12
12
  context "validate #{field}" do
13
- let(:params) {{ api_key: 'api-key', api_host: 'host', api_version: 'v1' }.merge(field => '')}
13
+ let(:params) {{ account_token: 'acc_xx', space_name: 'LiveQA', environment_name: 'test', api_host: 'host', api_version: 'v1' }.merge(field => '')}
14
14
 
15
15
  it { expect { config.valid! }.to raise_error(LiveQA::ConfigurationError, "#{field} can't be blank") }
16
16
  end
17
17
  end
18
18
 
19
19
  context 'format obfuscated_fields' do
20
- let(:params) {{ api_key: SecureRandom.hex, obfuscated_fields: %i[another_password password_confirmation] }}
20
+ let(:params) {{ account_token: 'acc_xx', space_name: 'LiveQA', environment_name: 'test', obfuscated_fields: %i[another_password password_confirmation] }}
21
21
 
22
22
  before { config.valid! }
23
23
 
24
- it { expect(config.obfuscated_fields).to match_array(%w[another_password password_confirmation password access_token api_key ccv credit_card_number cvv secret secret_token token]) }
24
+ 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
25
  end
26
26
 
27
27
  context 'async_handler' do
28
28
  context 'sidekiq' do
29
29
  let(:params) {{
30
- api_key: SecureRandom.hex,
30
+ account_token: 'acc_xx',
31
+ space_name: 'LiveQA',
32
+ environment_name: 'test',
31
33
  async_handler: :sidekiq
32
34
  }}
33
35
  before { config.valid! }
@@ -2,35 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  describe LiveQA::Event do
4
4
 
5
- describe '.build_payload' do
6
- before { LiveQA::Store.set(:tracker_id, '41') }
7
-
8
- let(:expected) {{
9
- library: {
10
- name: "liveqa",
11
- language: "ruby",
12
- version: kind_of(String)
13
- },
14
- server: {
15
- host: kind_of(String),
16
- pid: kind_of(Numeric)
17
- },
18
- message_id: kind_of(String),
19
- timestamp: kind_of(String),
20
- tracker_id: '42',
21
- session_tracker_id: kind_of(String)
22
- }}
23
-
24
- it { expect(LiveQA::Event.build_payload(tracker_id: '42')).to match(expected) }
25
- end
26
-
27
5
  describe '.create' do
28
- let(:response) { double('LiveQA::Request', body: '') }
6
+ let(:response) { double('LiveQA::Request', body: "{\"object\":\"event\",\"id\":41}") }
29
7
  before { expect(LiveQA::Request).to receive(:execute).and_return(response) }
30
8
 
31
9
  subject(:create) { LiveQA::Event.create(user_id: 42) }
32
10
 
33
11
  it { is_expected.to be_successful }
12
+ it { expect(create.id).to eq(41) }
34
13
  end
35
14
 
36
15
  end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::Group do
4
+
5
+ describe '#update' do
6
+ let(:response) { double('LiveQA::Request', body: "{\"object\":\"group\",\"id\":3,\"externalId\":\"41df8a48a68cb7c94e119ef7f1380537\",\"rawData\":{\"name\":\"Lubowitz, Cartwright and Davis\",\"email\":\"kenya_parker@batz.info\",\"plan\":\"premium\",\"address\":{\"street\":\"19222 Keyshawn Mountain\",\"city\":\"Rogahnmouth\",\"state\":\"Hawaii\",\"postal_code\":\"98441-4908\",\"country\":\"Singapore\"}}}") }
7
+ before { expect(LiveQA::Request).to receive(:execute).and_return(response) }
8
+
9
+ subject(:update) { LiveQA::Group.update('41df8a48a68cb7c94e119ef7f1380537', properties: { name: 'Lubowitz, Cartwright and Davis' }) }
10
+
11
+ it { is_expected.to be_successful }
12
+ it { expect(update.external_id).to eq('41df8a48a68cb7c94e119ef7f1380537') }
13
+ end
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe LiveQA::Identity do
4
+
5
+ describe '#update' do
6
+ let(:response) { double('LiveQA::Request', body: "{\"object\":\"identity\",\"id\":1,\"externalId\":\"8b5439f2bc0bc5bc2b80817f29477f0d\",\"trackerIds\":[],\"rawData\":{\"name\":\"Runte, Macejkovic and Reinger\",\"email\":\"hardy@abernathy.com\",\"plan\":\"premium\",\"address\":{\"street\":\"680 Collins Branch\",\"city\":\"Holdenview\",\"state\":\"Alabama\",\"postal_code\":\"51094-2637\",\"country\":\"America\"}},\"devices\":{\"object\":\"list\",\"data\":[{\"object\":\"device\",\"bot\":false,\"botName\":null,\"brand\":null,\"browserName\":\"chrome\",\"fullVersion\":\"62.0.3202.94\",\"known\":true,\"name\":null,\"osFullVersion\":\"10.12.5\",\"osName\":\"mac\",\"osVersion\":\"10\",\"type\":\"desktop\",\"version\":\"62\",\"usedLastAt\":null}]}}") }
7
+ before { expect(LiveQA::Request).to receive(:execute).and_return(response) }
8
+
9
+ subject(:update) { LiveQA::Identity.update('8b5439f2bc0bc5bc2b80817f29477f0d', properties: { name: 'Runte, Macejkovic and Reinger' }) }
10
+
11
+ it { is_expected.to be_successful }
12
+ it { expect(update.external_id).to eq('8b5439f2bc0bc5bc2b80817f29477f0d') }
13
+ end
14
+
15
+ end
@@ -5,7 +5,24 @@ describe LiveQA::LiveQAObject do
5
5
  let(:klass) { Class.new(LiveQA::LiveQAObject) }
6
6
  subject(:instance) { klass.new(id: 42, name: 'test', test: true) }
7
7
 
8
- let(:api_response) { '' }
8
+ let(:api_response) {{
9
+ object: 'event',
10
+ id: 42,
11
+ other: 'other test'
12
+ }}
13
+
14
+ let(:api_responses) {{
15
+ object: 'list',
16
+ currentPage: 10,
17
+ data: [{
18
+ object: 'group',
19
+ id: 42,
20
+ other: 'other test'
21
+ }],
22
+ links: {
23
+ self: 'http://www.liveqa.io/test'
24
+ }
25
+ }}
9
26
 
10
27
  describe 'add attribute accessors' do
11
28
  it { expect(instance.id).to eq(42) }
@@ -62,10 +79,44 @@ describe LiveQA::LiveQAObject do
62
79
 
63
80
  describe '.initialize_from' do
64
81
  context 'with single object' do
65
- subject(:instance) { klass.initialize_from(api_response) }
82
+ subject(:instance) { klass.initialize_from(api_response.to_json) }
66
83
 
67
84
  it { is_expected.to be_successful }
85
+ it { expect(instance.id).to eq(42) }
86
+ it { expect(instance.other).to eq('other test') }
87
+ it { expect { instance.name }.to raise_error(NameError) }
68
88
  end
89
+
90
+ context 'with array' do
91
+ subject(:instance) { klass.initialize_from(api_responses.to_json) }
92
+
93
+ it { is_expected.to be_successful }
94
+ it { expect(instance.data.size).to eq(1) }
95
+ it { expect(instance.data.first).to be_a(LiveQA::Group) }
96
+ it { expect(instance.current_page).to eq(10) }
97
+ it { expect(instance.links[:self]).to eq('http://www.liveqa.io/test') }
98
+ end
99
+
100
+ context 'with empty string' do
101
+ subject(:instance) { klass.initialize_from('') }
102
+
103
+ it { is_expected.to be_successful }
104
+ end
105
+
106
+ context 'with nil' do
107
+ subject(:instance) { klass.initialize_from(nil) }
108
+
109
+ it { is_expected.to be_successful }
110
+ end
111
+ end
112
+
113
+ describe '#update_from' do
114
+ before { instance.update_from(api_response) }
115
+
116
+ it { is_expected.to be_successful }
117
+ it { expect(instance.id).to eq(42) }
118
+ it { expect(instance.other).to eq('other test') }
119
+ it { expect { instance.name }.to raise_error(NameError) }
69
120
  end
70
121
 
71
122