workarea-core 3.4.38 → 3.4.43

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: 9ffbb2028cd43e91abbc3601126483073b55997738eba74759b902e353590b67
4
- data.tar.gz: 70acccdddb99146faaf878e862bc8a1e2161f5c2a62a10cd0f3f1f5f97bc4b19
3
+ metadata.gz: 30d5b2273f510412bf81387ac4d229e05ef322219dba42166dffd16c2a30d458
4
+ data.tar.gz: 0163e5cd44474ad11c119debb3dd116a0637be8f514b8d920cab4e093f3f4578
5
5
  SHA512:
6
- metadata.gz: fb66b15c9317d085e8dbd97262ddf4ae85ef31eb5cbb77b1bf6375f69b284a6ce439579c534b6ec05c337644b022e4b186e4f55c51cabf555a29c490f131bc8e
7
- data.tar.gz: db47bf0b35f4f7f12a27b05759d242301e7b0b6779670d41fab803129fd391c9246ecc08f494314e3865c5f8190a636d6f1df521b3b31d545dec53c624c5a6dd
6
+ metadata.gz: 00d52ab3b83bb7057218e4b70d668a98e85b1c953f2607b15826599d75d6970fdd681eea595b1270533889f90e75be3db8a539f4a16016578acd6c285fffb4aa
7
+ data.tar.gz: d73e489b510f361b0a75cbd705c1731ae6bea3693fd25ed3ee76d502ff4802724ba744442bade25b99171d444c0ec0f805591650a852fe74f8f7a5bfef83d5df
@@ -9,6 +9,7 @@ module Workarea
9
9
  @current_referrer ||= TrafficReferrer.new(
10
10
  RefererParser::Parser.new.parse(referrer).slice(:source, :medium, :uri)
11
11
  )
12
+ rescue RefererParser::InvalidUriError
12
13
  end
13
14
  end
14
15
  end
@@ -50,7 +50,8 @@ module Workarea
50
50
  end
51
51
 
52
52
  def current_impersonation
53
- @current_impersonation ||= User.find(cookies.signed[:user_id])
53
+ return @current_impersonation if defined?(@current_impersonation)
54
+ @current_impersonation = User.find(cookies.signed[:user_id]) rescue nil
54
55
  end
55
56
 
56
57
  def touch_impersonation
@@ -123,6 +123,31 @@ module Workarea
123
123
  return nil if orders.zero?
124
124
  revenue / orders.to_f
125
125
  end
126
+
127
+ def merge!(other)
128
+ # To recalculate average_order_value
129
+ self.orders += other.orders
130
+ self.revenue += other.revenue
131
+
132
+ update = {
133
+ '$set' => {
134
+ average_order_value: average_order_value,
135
+ updated_at: Time.current.utc
136
+ },
137
+ '$inc' => {
138
+ orders: other.orders,
139
+ revenue: other.revenue,
140
+ discounts: other.discounts
141
+ }
142
+ }
143
+
144
+ update['$min'] = { first_order_at: other.first_order_at.utc } if other.first_order_at.present?
145
+ update['$max'] = { last_order_at: other.last_order_at.utc } if other.last_order_at.present?
146
+
147
+ self.class.collection.update_one({ _id: id }, update, upsert: true)
148
+ other.delete
149
+ reload
150
+ end
126
151
  end
127
152
  end
128
153
  end
@@ -11,6 +11,10 @@ module Workarea
11
11
  def self.available_sorts
12
12
  AdminSorting.available_sorts
13
13
  end
14
+
15
+ def default_admin_sort
16
+ [{ _score: :desc }, { updated_at: :desc }]
17
+ end
14
18
  end
15
19
  end
16
20
  end
@@ -16,7 +16,7 @@ module Workarea
16
16
  end
17
17
 
18
18
  def default_admin_sort
19
- [{ _score: :desc }, { updated_at: :desc }]
19
+ [{ updated_at: :desc }, { _score: :desc }]
20
20
  end
21
21
 
22
22
  def user_selected_sort
@@ -0,0 +1,33 @@
1
+ module Workarea
2
+ class UpdateEmail
3
+ include Sidekiq::Worker
4
+ include Sidekiq::CallbacksWorker
5
+
6
+ sidekiq_options(
7
+ enqueue_on: { User => :update, with: -> { [id, changes] } }
8
+ )
9
+
10
+ def perform(id, changes)
11
+ return unless changes['email'].present? && changes['email'].first.present?
12
+
13
+ old_email, new_email = changes['email']
14
+ update_payment_profile(id, old_email, new_email)
15
+ update_metrics(old_email, new_email)
16
+ end
17
+
18
+ def update_payment_profile(id, old_email, new_email)
19
+ user = User.find(id)
20
+ user.email = old_email # set old email so we lookup by old email value
21
+
22
+ Payment::Profile.update_email(PaymentReference.new(user), new_email)
23
+ end
24
+
25
+ def update_metrics(old_email, new_email)
26
+ old_metrics = Metrics::User.find(old_email) rescue nil
27
+ return if old_metrics.blank?
28
+
29
+ new_metrics = Metrics::User.find_or_initialize_by(id: new_email)
30
+ new_metrics.merge!(old_metrics)
31
+ end
32
+ end
33
+ end
@@ -38,7 +38,7 @@ namespace :workarea do
38
38
  author: author
39
39
  }
40
40
 
41
- if subject.start_with?('Revert')
41
+ if subject.start_with?('Revert "')
42
42
  reverts << body.match(/[a-f0-9]{40}/)
43
43
  reverts << sha
44
44
  end
@@ -140,6 +140,7 @@ require 'workarea/ext/mongoid/find_ordered'
140
140
  require 'workarea/ext/sprockets/ruby_processor'
141
141
  require 'workarea/ext/jbuilder/jbuilder_append_partials'
142
142
  require 'workarea/ext/jbuilder/jbuilder_cache'
143
+ require 'workarea/ext/referer_parser/parser.decorator'
143
144
 
144
145
  if Rails.env.development?
145
146
  require 'workarea/ext/freedom_patches/routes_reloader'
@@ -0,0 +1,43 @@
1
+ module RefererParser
2
+ # This code is actually in `master` branch of
3
+ # https://github.com/snowplow-referer-parser/ruby-referer-parser but
4
+ # has not yet been released. It's used to allow through android-app://
5
+ # URLs.
6
+ decorate Parser do
7
+ # Given a string or URI, return a hash of data
8
+ def parse(obj)
9
+ url = obj.is_a?(URI) ? obj : URI.parse(obj.to_s)
10
+
11
+ unless ['android-app', 'http', 'https'].include?(url.scheme)
12
+ raise InvalidUriError, "Only Android-App, HTTP, and HTTPS schemes are supported -- #{url.scheme}"
13
+ end
14
+
15
+ data = { known: false, uri: url.to_s }
16
+
17
+ domain, name_key = domain_and_name_key_for(url)
18
+ if domain && name_key
19
+ referer_data = @name_hash[name_key]
20
+ data[:known] = true
21
+ data[:source] = referer_data[:source]
22
+ data[:medium] = referer_data[:medium]
23
+ data[:domain] = domain
24
+
25
+ # Parse parameters if the referer uses them
26
+ if url.query && referer_data[:parameters]
27
+ query_params = CGI.parse(url.query)
28
+ referer_data[:parameters].each do |param|
29
+ # If there is a matching parameter, get the first non-blank value
30
+ unless (values = query_params[param]).empty?
31
+ data[:term] = values.reject { |v| v.strip == '' }.first
32
+ break if data[:term]
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ data
39
+ rescue URI::InvalidURIError
40
+ raise InvalidUriError.new("Unable to parse URI, not a URI? -- #{obj.inspect}", $ERROR_INFO)
41
+ end
42
+ end
43
+ end
@@ -2,7 +2,7 @@ module Workarea
2
2
  module VERSION
3
3
  MAJOR = 3
4
4
  MINOR = 4
5
- PATCH = 38
5
+ PATCH = 43
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ module RefererParser
4
+ class ParserTest < Workarea::TestCase
5
+ def test_parse_android_app_referrers
6
+ referrers = [
7
+ 'android-app://com.linkedin.android',
8
+ 'android-app://org.telegram.plus',
9
+ 'android-app://com.twitter.android'
10
+ ]
11
+
12
+ referrers.each do |uri|
13
+ referrer = Parser.new.parse(uri)
14
+
15
+ refute(referrer[:known])
16
+ assert_equal(uri, referrer[:uri])
17
+ end
18
+ end
19
+ end
20
+ end
@@ -74,6 +74,57 @@ module Workarea
74
74
  assert_equal(50, two.revenue_percentile)
75
75
  assert_equal(50, two.average_order_value_percentile)
76
76
  end
77
+
78
+ def test_merging_metrics
79
+ freeze_time
80
+
81
+ first = User.create!(
82
+ first_order_at: 2.weeks.ago,
83
+ last_order_at: 1.day.ago,
84
+ orders: 2,
85
+ revenue: 100,
86
+ discounts: -10,
87
+ average_order_value: 50,
88
+ )
89
+
90
+ first.merge!(User.new)
91
+ first.reload
92
+ assert_equal(1, Metrics::User.count)
93
+ assert_equal(2.weeks.ago, first.first_order_at)
94
+ assert_equal(1.day.ago, first.last_order_at)
95
+ assert_equal(2, first.orders)
96
+ assert_equal(100, first.revenue)
97
+ assert_equal(-10, first.discounts)
98
+ assert_equal(50, first.average_order_value)
99
+
100
+ second = User.create!(id: 'foo').tap { |u| u.merge!(first) }
101
+ second.reload
102
+ assert_equal(1, Metrics::User.count)
103
+ assert_equal(2.weeks.ago, second.first_order_at)
104
+ assert_equal(1.day.ago, second.last_order_at)
105
+ assert_equal(2, second.orders)
106
+ assert_equal(100, second.revenue)
107
+ assert_equal(-10, second.discounts)
108
+ assert_equal(50, second.average_order_value)
109
+
110
+ third = User.create!(
111
+ first_order_at: 3.weeks.ago,
112
+ last_order_at: 3.weeks.ago,
113
+ orders: 2,
114
+ revenue: 120,
115
+ average_order_value: 60,
116
+ )
117
+
118
+ third.merge!(second)
119
+ third.reload
120
+ assert_equal(1, Metrics::User.count)
121
+ assert_equal(3.weeks.ago, third.first_order_at)
122
+ assert_equal(1.day.ago, third.last_order_at)
123
+ assert_equal(4, third.orders)
124
+ assert_equal(220, third.revenue)
125
+ assert_equal(-10, third.discounts)
126
+ assert_equal(55, third.average_order_value)
127
+ end
77
128
  end
78
129
  end
79
130
  end
@@ -81,6 +81,16 @@ module Workarea
81
81
  assert_equal(results.reverse, search.results)
82
82
  end
83
83
 
84
+ def test_default_sort_by_score
85
+ # Unlike other admin searches (primarily indexes), we want searching to
86
+ # default sort by score. Testing scores directly is unreliable so just
87
+ # do a simple check here.
88
+ assert_equal(
89
+ [{ _score: :desc }, { updated_at: :desc }],
90
+ AdminSearch.new.default_admin_sort
91
+ )
92
+ end
93
+
84
94
  def test_selected_sorting
85
95
  results = [
86
96
  create_product(name: 'A', variants: []),
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ class UpdateEmailTest < TestCase
5
+ def test_updating_payment_profile
6
+ user = create_user(email: 'user@workarea.com')
7
+ profile = Payment::Profile.lookup(PaymentReference.new(user))
8
+
9
+ UpdateEmail.new.perform(user.id.to_s, 'email' => [nil, 'user@workarea.com'])
10
+ assert_equal(profile.reload.email, 'user@workarea.com')
11
+
12
+ UpdateEmail.new.perform(
13
+ user.id.to_s,
14
+ 'email' => ['user@workarea.com', 'test@workarea.com']
15
+ )
16
+ assert_equal(profile.reload.email, 'test@workarea.com')
17
+ end
18
+
19
+ def test_updating_metrics
20
+ user = create_user(email: 'user@workarea.com')
21
+ old_metrics = Metrics::User.find_or_initialize_by(id: 'user@workarea.com')
22
+ old_metrics.update!(orders: 3)
23
+
24
+ UpdateEmail.new.perform(user.id.to_s, 'email' => [nil, 'user@workarea.com'])
25
+ assert_equal(1, Metrics::User.count)
26
+ assert_equal(3, old_metrics.reload.orders)
27
+
28
+ new_metrics = Metrics::User.create!(id: 'test@workarea.com', orders: 1)
29
+
30
+ UpdateEmail.new.perform(
31
+ user.id.to_s,
32
+ 'email' => ['user@workarea.com', 'test@workarea.com']
33
+ )
34
+ assert_equal(1, Metrics::User.count)
35
+ assert_raises(Mongoid::Errors::DocumentNotFound) { old_metrics.reload }
36
+ assert_equal(4, new_metrics.reload.orders)
37
+ end
38
+ end
39
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workarea-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.38
4
+ version: 3.4.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Crouse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-19 00:00:00.000000000 Z
11
+ date: 2020-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -1711,7 +1711,7 @@ files:
1711
1711
  - app/workers/workarea/status_reporter.rb
1712
1712
  - app/workers/workarea/undo_release.rb
1713
1713
  - app/workers/workarea/update_elasticsearch_settings.rb
1714
- - app/workers/workarea/update_payment_profile_email.rb
1714
+ - app/workers/workarea/update_email.rb
1715
1715
  - app/workers/workarea/verify_scheduled_releases.rb
1716
1716
  - bin/rails
1717
1717
  - config/i18n-js.yml
@@ -1873,6 +1873,7 @@ files:
1873
1873
  - lib/workarea/ext/mongoid/list_field.rb
1874
1874
  - lib/workarea/ext/mongoid/moped_bson.rb
1875
1875
  - lib/workarea/ext/mongoid/timestamps_timeless.rb
1876
+ - lib/workarea/ext/referer_parser/parser.decorator
1876
1877
  - lib/workarea/ext/sprockets/ruby_processor.rb
1877
1878
  - lib/workarea/ext/sprockets/task.rb
1878
1879
  - lib/workarea/geolocation.rb
@@ -2017,6 +2018,7 @@ files:
2017
2018
  - test/lib/workarea/ext/mongoid/except_test.rb
2018
2019
  - test/lib/workarea/ext/mongoid/find_ordered_test.rb
2019
2020
  - test/lib/workarea/ext/mongoid/list_field_test.rb
2021
+ - test/lib/workarea/ext/referer_parser/parser_test.rb
2020
2022
  - test/lib/workarea/geolocation_test.rb
2021
2023
  - test/lib/workarea/lint/inconsistent_details_test.rb
2022
2024
  - test/lib/workarea/lint/products_missing_images_test.rb
@@ -2366,7 +2368,7 @@ files:
2366
2368
  - test/workers/workarea/send_refund_email_test.rb
2367
2369
  - test/workers/workarea/status_reporter_test.rb
2368
2370
  - test/workers/workarea/undo_release_test.rb
2369
- - test/workers/workarea/update_payment_profile_email_test.rb
2371
+ - test/workers/workarea/update_email_test.rb
2370
2372
  - test/workers/workarea/verify_scheduled_releases_test.rb
2371
2373
  - vendor/active_shipping/.gitignore
2372
2374
  - vendor/active_shipping/.travis.yml
@@ -1,22 +0,0 @@
1
- module Workarea
2
- class UpdatePaymentProfileEmail
3
- include Sidekiq::Worker
4
- include Sidekiq::CallbacksWorker
5
-
6
- sidekiq_options(
7
- enqueue_on: { User => :update, with: -> { [id, changes] } }
8
- )
9
-
10
- def perform(id, changes)
11
- if changes['email'].present? && changes['email'].first.present?
12
- old_email = changes['email'].first
13
- new_email = changes['email'].last
14
-
15
- user = User.find(id)
16
- user.email = old_email # set old email so we lookup by old email value
17
-
18
- Payment::Profile.update_email(PaymentReference.new(user), new_email)
19
- end
20
- end
21
- end
22
- end
@@ -1,27 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Workarea
4
- class UpdatePaymentProfileEmailTest < Workarea::TestCase
5
- setup do
6
- @user = create_user(email: 'user@workarea.com')
7
- @profile = Payment::Profile.lookup(PaymentReference.new(@user))
8
- @worker = UpdatePaymentProfileEmail.new
9
- end
10
-
11
- def test_updating_payment_profile_email_address
12
- @worker.perform(
13
- @user.id.to_s,
14
- 'email' => ['user@workarea.com', 'test@workarea.com']
15
- )
16
-
17
- @profile.reload
18
- assert_equal(@profile.email, 'test@workarea.com')
19
- end
20
-
21
- def test_skipping_update_if_email_change_is_nil
22
- @worker.perform(@user.id.to_s, 'email' => [nil, 'user@workarea.com'])
23
- @profile.reload
24
- assert_equal(@profile.email, 'user@workarea.com')
25
- end
26
- end
27
- end