action_tracker_client 0.0.1 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6552efeec467f77ebcdd5e12f42ea71f604549501d28197693931c7952ab1f5
4
- data.tar.gz: 9d59e3d822664351982c2edf20745577cf37442907ce3d0a213815c128f1ce53
3
+ metadata.gz: faa74a2a231928f025207b06a3f36b057588909ef546807506488f454b3f3865
4
+ data.tar.gz: 6e5a9554b441d87a7e746eded4d6028fdedf7e370dcc4cda4b675e3de675896e
5
5
  SHA512:
6
- metadata.gz: 76f7c8f9293b8fe68d012f1a02314f7f3db256f2f8f36b16a48566a8928f6c27df1ec1531dbfc0e34319b3885859ebaa8466d6034590a315fc028c2f58d2de76
7
- data.tar.gz: 9aaa18d8ef6fba934d1a3926ca3ccf9556db103430124015fd1e35ff1495e2430f364a9caf4d57a7299643a272677ef24daa496bc0df00231a11845389ae518e
6
+ metadata.gz: 4330a2055a63d1df6225510ec32105db12ef290144299272a41a34a0c390ec420ee206eacafdbe01598d54a770685478991bf58ac84650038d03ef4901dee2a3
7
+ data.tar.gz: 8244c43631586b63a06ccea9c469e372ff43c23fd1e6e30fc25f3279284436a857ba5ae693cd1696f0cbb28a496b850efe4e868c01e90791906c6f6ac05d9dfa
data/Gemfile.lock CHANGED
@@ -1,12 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- action_tracker_client (0.0.1)
4
+ action_tracker_client (0.1.0)
5
5
  activemodel (>= 4.0)
6
6
  activesupport (>= 4.0)
7
7
  api_signature (~> 0.1.5)
8
8
  httparty (~> 0.17.0)
9
- model_auditor (~> 0.0.1)
9
+ model_auditor (~> 0.0.2)
10
10
  virtus (~> 1.0, >= 1.0.5)
11
11
 
12
12
  GEM
@@ -72,7 +72,7 @@ GEM
72
72
  mime-types-data (~> 3.2015)
73
73
  mime-types-data (3.2019.0331)
74
74
  minitest (5.11.3)
75
- model_auditor (0.0.1)
75
+ model_auditor (0.0.2)
76
76
  multi_xml (0.6.0)
77
77
  nenv (0.3.0)
78
78
  notiffany (0.1.1)
data/README.md CHANGED
@@ -2,8 +2,7 @@
2
2
 
3
3
  [![Build Status](https://semaphoreci.com/api/v1/ipm/action_tracker/branches/master/badge.svg)](https://semaphoreci.com/ipm/action_tracker)
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/cfdcabfc3610c6eac895/maintainability)](https://codeclimate.com/github/psyipm/action_tracker/maintainability)
5
- [![Gem Version](https://badge.fury.io/rb/action_tracker.svg)](https://badge.fury.io/rb/action_tracker)
6
-
5
+ [![Gem Version](https://badge.fury.io/rb/action_tracker_client.svg)](https://badge.fury.io/rb/action_tracker_client)
7
6
 
8
7
  ## Installation
9
8
 
@@ -34,6 +33,15 @@ ActionTracker.configure do |config|
34
33
  config.api_url = ENV['ACTION_TRACKING_API_URL']
35
34
  config.api_key = ENV['ACTION_TRACKING_API_KEY']
36
35
  config.api_secret = ENV['ACTION_TRACKING_API_SECRET']
36
+
37
+ # Avalilable options:
38
+ #
39
+ # :inline (default) -> performs request to external API
40
+ # :test -> stores request parameters, can be accessed via ActionTracker.records
41
+ # :custom -> calls custom labda
42
+ #
43
+ config.tracking_method = :custom
44
+ config.custom_worker_proc = ->(form) { MyCustomActionTrackingJob.perform_later(form.attributes) }
37
45
  end
38
46
  ```
39
47
 
@@ -144,6 +152,46 @@ ActionTracker::Recorder.new(:state_change).call(target)
144
152
  ActionTracker::Recorder.new('Orders::SomeCustomEvent').call(target)
145
153
  ```
146
154
 
155
+ ## Testing
156
+
157
+ Set tracking method to `:test` in application environment config and clear records after each spec
158
+
159
+ ```ruby
160
+ # config/environments/test.rb
161
+
162
+ config.after_initialize do
163
+ ActionTracker.config.tracking_method = :test
164
+ end
165
+
166
+ # spec/rails_helper.rb
167
+
168
+ config.after(:each) do
169
+ ActionTracker.clear_records
170
+ end
171
+ ```
172
+
173
+ ```ruby
174
+ ActionTracker.records
175
+
176
+ => [{:target_id=>76, :target_type=>"Order", :payload=>{:event=>"Created payment #89", :content=>"amount 100.0", :user=>{:id=>0, :name=>"Anonymous", :type=>"System"}}, :reference_id=>89, :reference_type=>"PaymentTransaction"}]
177
+
178
+ ActionTracker.last_event
179
+
180
+ => "Created payment #89"
181
+
182
+ ActionTracker.records.select_by('payload.user.name', 'Anonymous')
183
+
184
+ => [{:target_id=>76, :target_type=>"Order".....
185
+
186
+ ActionTracker.records.last_content
187
+
188
+ => "amount 100.0"
189
+
190
+ ActionTracker.records.select_by('payload.user.name', 'SomeUser')
191
+
192
+ => []
193
+ ```
194
+
147
195
  ## Development
148
196
 
149
197
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency 'activesupport', '>= 4.0'
33
33
  spec.add_dependency 'api_signature', '~> 0.1.5'
34
34
  spec.add_dependency 'httparty', '~> 0.17.0'
35
- spec.add_dependency 'model_auditor', '~> 0.0.1'
35
+ spec.add_dependency 'model_auditor', '~> 0.0.2'
36
36
 
37
37
  spec.add_dependency 'virtus', '~> 1.0', '>= 1.0.5'
38
38
  end
@@ -2,9 +2,14 @@
2
2
 
3
3
  module ActionTracker
4
4
  class ClientNotConfiguredError < StandardError; end
5
+ class InvalidTrackingMethodError < StandardError; end
5
6
 
6
7
  class Config
7
- attr_writer :api_url, :api_key, :api_secret
8
+ VALID_TRACKING_METHODS = [
9
+ :inline, :custom, :test
10
+ ].freeze
11
+
12
+ attr_writer :api_url, :api_key, :api_secret, :custom_worker_proc
8
13
 
9
14
  def api_url
10
15
  @api_url || raise(ActionTracker::ClientNotConfiguredError, missing_value: :api_url)
@@ -17,5 +22,19 @@ module ActionTracker
17
22
  def api_secret
18
23
  @api_secret || raise(ActionTracker::ClientNotConfiguredError, missing_value: :api_secret)
19
24
  end
25
+
26
+ def tracking_method
27
+ @tracking_method ||= :inline
28
+ end
29
+
30
+ def tracking_method=(value)
31
+ raise(InvalidTrackingMethodError, value) unless VALID_TRACKING_METHODS.include?(value)
32
+
33
+ @tracking_method = value
34
+ end
35
+
36
+ def custom_worker_proc
37
+ @custom_worker_proc ||= ->(form) { ActionTracker::Workers::Inline.new(form).perform }
38
+ end
20
39
  end
21
40
  end
@@ -37,6 +37,10 @@ module ActionTracker
37
37
  def to_key
38
38
  [id]
39
39
  end
40
+
41
+ def present_attributes
42
+ attributes.reject { |_key, value| value.blank? }
43
+ end
40
44
  end
41
45
  end
42
46
  end
@@ -21,6 +21,10 @@ module ActionTracker
21
21
  self
22
22
  end
23
23
 
24
+ def user
25
+ super || ActionTracker::Models::User.default_user
26
+ end
27
+
24
28
  def for_event(event)
25
29
  self[:event] = event.to_s.humanize
26
30
  self
@@ -30,6 +34,10 @@ module ActionTracker
30
34
  self[:content] = content.to_s.truncate(MAX_CONTENT_LENGTH)
31
35
  self
32
36
  end
37
+
38
+ def attributes
39
+ super.merge(user: user.attributes)
40
+ end
33
41
  end
34
42
  end
35
43
  end
@@ -9,18 +9,27 @@ module ActionTracker
9
9
  attribute :target_type, String
10
10
  attribute :created_at, DateTime
11
11
  attribute :payload, ActionTracker::Models::Payload
12
+ attribute :reference_id, Integer
13
+ attribute :reference_type, String
12
14
 
13
15
  delegate :event, :content, :user, to: :payload
14
16
 
15
17
  validate :check_payload
16
18
 
17
19
  def with_target(target)
18
- self.target_id = target.id
19
- self.target_type = target.class.name
20
+ self.target_id = target.try(:id)
21
+ self.target_type = target.try(:type) || target.class.name
20
22
 
21
23
  self
22
24
  end
23
25
 
26
+ def reference=(item)
27
+ return unless item
28
+
29
+ self[:reference_id] = item.try(:id)
30
+ self[:reference_type] = item.try(:type) || item.class.name
31
+ end
32
+
24
33
  def index(params = {})
25
34
  path = [collection_path, params.to_query].reject(&:blank?).compact.join('?')
26
35
  @response ||= Connection.new.get(path)
@@ -2,6 +2,7 @@
2
2
 
3
3
  module ActionTracker
4
4
  class UndefinedTemplateError < StandardError; end
5
+ class EmptyTargetError < StandardError; end
5
6
 
6
7
  # Usage:
7
8
  # ActionTracker::Recorder.new(:create).call(order)
@@ -21,8 +22,9 @@ module ActionTracker
21
22
  def call(target)
22
23
  form = template_klass.new(target, options).form
23
24
  return unless form.valid?
25
+ raise EmptyTargetError, inspect unless target
24
26
 
25
- @response = connection.post form.collection_path, body: form.attributes
27
+ @response = ActionTracker::Workers::Factory.new(form).instance.perform
26
28
  @response.to_h
27
29
  end
28
30
 
@@ -38,9 +40,5 @@ module ActionTracker
38
40
 
39
41
  klass
40
42
  end
41
-
42
- def connection
43
- @connection ||= ActionTracker::Connection.new
44
- end
45
43
  end
46
44
  end
@@ -11,7 +11,10 @@ module ActionTracker
11
11
  end
12
12
 
13
13
  def form
14
- @form ||= ActionTracker::Models::TransitionRecord.new(payload: payload).with_target(target)
14
+ @form ||= ActionTracker::Models::TransitionRecord.new(
15
+ payload: payload,
16
+ reference: reference
17
+ ).with_target(target)
15
18
  end
16
19
 
17
20
  protected
@@ -22,7 +25,11 @@ module ActionTracker
22
25
 
23
26
  def build_payload
24
27
  payload_instance = ActionTracker::Models::Payload.new
25
- payload_instance.with_user(user).with_content(content).for_event(event_title)
28
+
29
+ payload_instance
30
+ .with_user(user)
31
+ .with_content(content)
32
+ .for_event(event_title)
26
33
  end
27
34
 
28
35
  def user
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionTracker
4
+ class RecordsCollection < Array
5
+ def select_by(path, value)
6
+ keys = path.to_s.split('.').map(&:to_sym)
7
+
8
+ items = select do |item|
9
+ item.dig(*keys) == value
10
+ end
11
+
12
+ self.class.new items
13
+ end
14
+
15
+ def last_event
16
+ last.dig(:payload, :event)
17
+ end
18
+
19
+ def last_content
20
+ last.dig(:payload, :content)
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module ActionTracker
2
- VERSION = '0.0.1'.freeze
2
+ VERSION = '0.1.0'.freeze
3
3
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionTracker
4
+ module Workers
5
+ class Custom
6
+ attr_reader :form
7
+
8
+ def initialize(form)
9
+ @form = form
10
+ end
11
+
12
+ def perform
13
+ custom_worker_proc.call(form)
14
+ end
15
+
16
+ private
17
+
18
+ def custom_worker_proc
19
+ ActionTracker.config.custom_worker_proc
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionTracker
4
+ module Workers
5
+ class UndefinedWorkerError < StandardError; end
6
+
7
+ class Factory
8
+ attr_reader :form
9
+
10
+ def initialize(form)
11
+ @form = form
12
+ end
13
+
14
+ def instance
15
+ raise UndefinedWorkerError, tracking_method unless worker_klass
16
+
17
+ worker_klass.new(form)
18
+ end
19
+
20
+ private
21
+
22
+ def worker_klass
23
+ @worker_klass ||= "ActionTracker::Workers::#{tracking_method.classify}".safe_constantize
24
+ end
25
+
26
+ def tracking_method
27
+ ActionTracker.config.tracking_method.to_s
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionTracker
4
+ module Workers
5
+ class Inline
6
+ attr_reader :form
7
+
8
+ def initialize(form)
9
+ @form = form
10
+ end
11
+
12
+ def perform
13
+ connection.post form.collection_path, body: form.present_attributes
14
+ end
15
+
16
+ private
17
+
18
+ def connection
19
+ @connection ||= ActionTracker::Connection.new
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionTracker
4
+ module Workers
5
+ class Test
6
+ attr_reader :form
7
+
8
+ def initialize(form)
9
+ @form = form
10
+ end
11
+
12
+ def perform
13
+ ActionTracker.records.append(params)
14
+
15
+ params
16
+ end
17
+
18
+ private
19
+
20
+ def params
21
+ form.present_attributes
22
+ end
23
+ end
24
+ end
25
+ end
@@ -8,11 +8,12 @@ require 'active_support/core_ext/object'
8
8
 
9
9
  module ActionTracker
10
10
  autoload :Config, 'action_tracker/config'
11
- autoload :SignedRequest, 'action_tracker/signed_request'
12
- autoload :Connection, 'action_tracker/connection'
13
11
 
14
- autoload :Pagination, 'action_tracker/pagination'
15
- autoload :CollectionProxy, 'action_tracker/collection_proxy'
12
+ autoload :CollectionProxy, 'action_tracker/utils/collection_proxy'
13
+ autoload :Connection, 'action_tracker/utils/connection'
14
+ autoload :Pagination, 'action_tracker/utils/pagination'
15
+ autoload :RecordsCollection, 'action_tracker/utils/records_collection'
16
+ autoload :SignedRequest, 'action_tracker/utils/signed_request'
16
17
 
17
18
  autoload :Recorder, 'action_tracker/recorder'
18
19
 
@@ -30,6 +31,13 @@ module ActionTracker
30
31
  autoload :Destroy, 'action_tracker/templates/destroy'
31
32
  end
32
33
 
34
+ module Workers
35
+ autoload :Factory, 'action_tracker/workers/factory'
36
+ autoload :Inline, 'action_tracker/workers/inline'
37
+ autoload :Custom, 'action_tracker/workers/custom'
38
+ autoload :Test, 'action_tracker/workers/test'
39
+ end
40
+
33
41
  def self.config
34
42
  @config ||= Config.new
35
43
  end
@@ -37,4 +45,16 @@ module ActionTracker
37
45
  def self.configure
38
46
  yield(config)
39
47
  end
48
+
49
+ def self.last_event
50
+ records.last_event
51
+ end
52
+
53
+ def self.records
54
+ @records || clear_records
55
+ end
56
+
57
+ def self.clear_records
58
+ @records = ActionTracker::RecordsCollection.new
59
+ end
40
60
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_tracker_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Malinovskiy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-22 00:00:00.000000000 Z
11
+ date: 2019-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -168,14 +168,14 @@ dependencies:
168
168
  requirements:
169
169
  - - "~>"
170
170
  - !ruby/object:Gem::Version
171
- version: 0.0.1
171
+ version: 0.0.2
172
172
  type: :runtime
173
173
  prerelease: false
174
174
  version_requirements: !ruby/object:Gem::Requirement
175
175
  requirements:
176
176
  - - "~>"
177
177
  - !ruby/object:Gem::Version
178
- version: 0.0.1
178
+ version: 0.0.2
179
179
  - !ruby/object:Gem::Dependency
180
180
  name: virtus
181
181
  requirement: !ruby/object:Gem::Requirement
@@ -218,21 +218,26 @@ files:
218
218
  - bin/console
219
219
  - bin/setup
220
220
  - lib/action_tracker.rb
221
- - lib/action_tracker/collection_proxy.rb
222
221
  - lib/action_tracker/config.rb
223
- - lib/action_tracker/connection.rb
224
222
  - lib/action_tracker/models/application_record.rb
225
223
  - lib/action_tracker/models/payload.rb
226
224
  - lib/action_tracker/models/transition_record.rb
227
225
  - lib/action_tracker/models/user.rb
228
- - lib/action_tracker/pagination.rb
229
226
  - lib/action_tracker/recorder.rb
230
- - lib/action_tracker/signed_request.rb
231
227
  - lib/action_tracker/templates/base_template.rb
232
228
  - lib/action_tracker/templates/create.rb
233
229
  - lib/action_tracker/templates/destroy.rb
234
230
  - lib/action_tracker/templates/update.rb
231
+ - lib/action_tracker/utils/collection_proxy.rb
232
+ - lib/action_tracker/utils/connection.rb
233
+ - lib/action_tracker/utils/pagination.rb
234
+ - lib/action_tracker/utils/records_collection.rb
235
+ - lib/action_tracker/utils/signed_request.rb
235
236
  - lib/action_tracker/version.rb
237
+ - lib/action_tracker/workers/custom.rb
238
+ - lib/action_tracker/workers/factory.rb
239
+ - lib/action_tracker/workers/inline.rb
240
+ - lib/action_tracker/workers/test.rb
236
241
  homepage: https://github.com/psyipm/action_tracker
237
242
  licenses:
238
243
  - MIT