workarea-core 3.5.0.beta.1 → 3.5.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 +4 -4
- data/app/controllers/workarea/current_tracking.rb +4 -0
- data/app/models/workarea/checkout/collect_payment.rb +5 -5
- data/app/models/workarea/data_file/operation.rb +4 -0
- data/app/models/workarea/fulfillment/policies/base.rb +0 -4
- data/app/models/workarea/fulfillment/policies/{ignore.rb → shipping.rb} +2 -2
- data/app/models/workarea/fulfillment/sku.rb +0 -2
- data/app/models/workarea/insights/trending_searches.rb +8 -1
- data/app/models/workarea/metrics/search_by_day.rb +2 -0
- data/app/models/workarea/order.rb +12 -2
- data/app/models/workarea/order/item.rb +28 -2
- data/app/models/workarea/pricing/calculators/tax_calculator.rb +2 -2
- data/app/models/workarea/pricing/discount.rb +3 -2
- data/app/models/workarea/releasable.rb +3 -5
- data/app/models/workarea/reports/custom_event.rb +22 -0
- data/app/models/workarea/search/admin/releasable.rb +18 -6
- data/app/models/workarea/segment/life_cycle.rb +5 -5
- data/app/models/workarea/segment/rules/last_order.rb +9 -2
- data/app/models/workarea/segment/rules/traffic_referrer.rb +16 -5
- data/app/models/workarea/segmentable.rb +13 -0
- data/app/models/workarea/traffic_referrer.rb +3 -0
- data/app/queries/workarea/alerts.rb +21 -0
- data/app/queries/workarea/order_item_details.rb +16 -16
- data/app/queries/workarea/search/admin_index_search.rb +2 -1
- data/app/queries/workarea/search/product_display_rules.rb +0 -2
- data/app/services/workarea/direct_upload.rb +5 -0
- data/app/services/workarea/packaging.rb +1 -1
- data/app/workers/workarea/deactivate_stale_discounts.rb +1 -1
- data/app/workers/workarea/synchronize_user_metrics.rb +9 -0
- data/config/locales/en.yml +22 -0
- data/lib/tasks/migrate.rake +9 -12
- data/lib/workarea/configuration.rb +6 -6
- data/lib/workarea/configuration/redis.rb +21 -3
- data/lib/workarea/core.rb +3 -0
- data/lib/workarea/ext/freedom_patches/referer_parser.rb +7 -0
- data/lib/workarea/ext/mongoid/embedded_children.rb +20 -0
- data/lib/workarea/latest_version.rb +24 -0
- data/lib/workarea/ping_home_base.rb +0 -1
- data/lib/workarea/version.rb +1 -1
- data/lib/workarea/visit.rb +5 -2
- data/lib/workarea/warnings.rb +6 -6
- data/test/lib/workarea/ext/mongoid/embedded_children_test.rb +32 -0
- data/test/lib/workarea/latest_version_test.rb +11 -0
- data/test/models/workarea/checkout/collect_payment_test.rb +6 -6
- data/test/models/workarea/data_file/csv_test.rb +15 -0
- data/test/models/workarea/fulfillment/sku_test.rb +5 -5
- data/test/models/workarea/insights/cold_searches_test.rb +13 -11
- data/test/models/workarea/insights/hot_searches_test.rb +13 -11
- data/test/models/workarea/insights/searches_to_improve_test.rb +9 -6
- data/test/models/workarea/insights/star_searches_test.rb +5 -4
- data/test/models/workarea/insights/trending_searches_test.rb +12 -9
- data/test/models/workarea/pricing/calculators/tax_calculator_test.rb +1 -1
- data/test/models/workarea/search/admin/releasable_test.rb +5 -7
- data/test/models/workarea/segment/life_cycle_test.rb +5 -0
- data/test/models/workarea/segment/rules/last_order_test.rb +15 -3
- data/test/models/workarea/segment/rules/traffic_referrer_test.rb +10 -8
- data/test/models/workarea/segmentable_test.rb +18 -0
- data/test/queries/workarea/alerts_test.rb +11 -0
- data/test/queries/workarea/order_item_details_test.rb +4 -12
- data/test/services/workarea/direct_upload_test.rb +3 -0
- data/test/vcr_cassettes/get_latest_version.yml +90 -0
- data/test/workers/workarea/deactivate_stale_discounts_test.rb +2 -2
- data/workarea-core.gemspec +2 -3
- metadata +16 -25
- data/app/controllers/workarea/current_referrer.rb +0 -14
- data/app/models/workarea/fulfillment/policies/ship.rb +0 -15
@@ -45,24 +45,24 @@ module Workarea
|
|
45
45
|
@fulfillment ||= Fulfillment::Sku.find_or_initialize_by(id: sku)
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
def to_h
|
49
|
+
Rails.cache.fetch(cache_key, expires_in: cache_expiration) do
|
50
|
+
{
|
51
|
+
product_id: product.id,
|
52
|
+
product_attributes: product.as_document,
|
53
|
+
category_ids: category_ids,
|
54
|
+
discountable: pricing.discountable?,
|
55
|
+
fulfillment: fulfillment.policy
|
56
|
+
}
|
57
|
+
end
|
56
58
|
end
|
57
59
|
|
58
|
-
def
|
59
|
-
{
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
requires_shipping: requires_shipping?
|
65
|
-
}
|
60
|
+
def cache_key
|
61
|
+
"order_item_details/#{product.cache_key}/#{sku}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def cache_expiration
|
65
|
+
Workarea.config.cache_expirations.order_item_details
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -119,7 +119,8 @@ module Workarea
|
|
119
119
|
TermsFacet.new(self, 'type'),
|
120
120
|
TermsFacet.new(self, 'status'),
|
121
121
|
TermsFacet.new(self, 'tags'),
|
122
|
-
TermsFacet.new(self, 'upcoming_changes')
|
122
|
+
TermsFacet.new(self, 'upcoming_changes'),
|
123
|
+
TermsFacet.new(self, 'active_by_segment')
|
123
124
|
]
|
124
125
|
end
|
125
126
|
end
|
@@ -7,6 +7,9 @@ module Workarea
|
|
7
7
|
url = "#{uri.scheme}://#{uri.host}"
|
8
8
|
url += ":#{uri.port}" unless uri.port.in? [80, 443]
|
9
9
|
|
10
|
+
redis_key = "cors_#{url.optionize}"
|
11
|
+
return if Workarea.redis.get(redis_key) == 'true'
|
12
|
+
|
10
13
|
Workarea.s3.put_bucket_cors(
|
11
14
|
Configuration::S3.bucket,
|
12
15
|
'CORSConfiguration' => [
|
@@ -18,6 +21,8 @@ module Workarea
|
|
18
21
|
}
|
19
22
|
]
|
20
23
|
)
|
24
|
+
|
25
|
+
Workarea.redis.set(redis_key, 'true')
|
21
26
|
end
|
22
27
|
|
23
28
|
attr_reader :type, :filename
|
@@ -29,7 +29,7 @@ module Workarea
|
|
29
29
|
|
30
30
|
def all_active_discount_ids
|
31
31
|
Pricing::Discount
|
32
|
-
.where(:
|
32
|
+
.where(:updated_at.lt => Workarea.config.discount_staleness_ttl.ago)
|
33
33
|
.select(&:active?)
|
34
34
|
.map(&:id)
|
35
35
|
.map(&:to_s)
|
@@ -8,6 +8,15 @@ module Workarea
|
|
8
8
|
queue: 'low'
|
9
9
|
)
|
10
10
|
|
11
|
+
# It's essential for the {Metrics::User#admin} field always be in sync, so
|
12
|
+
# we always want this worker enabled.
|
13
|
+
#
|
14
|
+
# @return [Boolean]
|
15
|
+
#
|
16
|
+
def self.enabled?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
11
20
|
def perform(id)
|
12
21
|
user = User.find(id)
|
13
22
|
metrics = Metrics::User.find_or_create_by(id: user.email)
|
data/config/locales/en.yml
CHANGED
@@ -50,6 +50,28 @@ en:
|
|
50
50
|
unit: instance
|
51
51
|
csv:
|
52
52
|
unit: row
|
53
|
+
duration:
|
54
|
+
years:
|
55
|
+
one: '%{count} year'
|
56
|
+
other: '%{count} years'
|
57
|
+
months:
|
58
|
+
one: '%{count} month'
|
59
|
+
other: '%{count} months'
|
60
|
+
weeks:
|
61
|
+
one: '%{count} week'
|
62
|
+
other: '%{count} weeks'
|
63
|
+
days:
|
64
|
+
one: '%{count} day'
|
65
|
+
other: '%{count} days'
|
66
|
+
hours:
|
67
|
+
one: '%{count} hour'
|
68
|
+
other: '%{count} hours'
|
69
|
+
minutes:
|
70
|
+
one: '%{count} minute'
|
71
|
+
other: '%{count} minutes'
|
72
|
+
seconds:
|
73
|
+
one: '%{count} second'
|
74
|
+
other: '%{count} seconds'
|
53
75
|
errors:
|
54
76
|
messages:
|
55
77
|
contains_type: cannot contain 'type'
|
data/lib/tasks/migrate.rake
CHANGED
@@ -35,18 +35,6 @@ namespace :workarea do
|
|
35
35
|
|
36
36
|
puts "✅ #{count} tax categories updated."
|
37
37
|
|
38
|
-
Workarea::Catalog::Product.each_by(500) do |product|
|
39
|
-
next unless product.digital?
|
40
|
-
|
41
|
-
product.skus.each do |sku|
|
42
|
-
fulfillment = Workarea::Fulfillment::Sku.find_or_initialize_by(id: sku)
|
43
|
-
fulfillment.policy = 'ignore'
|
44
|
-
fulfillment.save!
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
puts "✅ #{count} fulfillment skus for digital product have been created."
|
49
|
-
|
50
38
|
count = 0
|
51
39
|
failed_ids = []
|
52
40
|
backup = Mongo::Collection.new(Mongoid::Clients.default.database, 'workarea_legacy_segments')
|
@@ -100,6 +88,15 @@ namespace :workarea do
|
|
100
88
|
puts "The segments that failed are #{failed_ids.to_sentence}."
|
101
89
|
end
|
102
90
|
|
91
|
+
Workarea::Segment::LifeCycle.create!
|
92
|
+
puts "✅ Life cycle segments have been created."
|
93
|
+
|
94
|
+
admin_ids = Workarea::User.admins.pluck(:id)
|
95
|
+
admin_ids.each do |id|
|
96
|
+
Workarea::SynchronizeUserMetrics.new.perform(id)
|
97
|
+
end
|
98
|
+
puts "✅ #{admin_ids.count} admins have had their metrics synchronized." if admin_ids.count > 0
|
99
|
+
|
103
100
|
puts "\nMigration complete!"
|
104
101
|
end
|
105
102
|
end
|
@@ -821,8 +821,7 @@ module Workarea
|
|
821
821
|
# recommended as the default policy.
|
822
822
|
config.fulfillment_policies = SwappableList.new(
|
823
823
|
%w(
|
824
|
-
Workarea::Fulfillment::Policies::
|
825
|
-
Workarea::Fulfillment::Policies::Ignore
|
824
|
+
Workarea::Fulfillment::Policies::Shipping
|
826
825
|
Workarea::Fulfillment::Policies::Download
|
827
826
|
)
|
828
827
|
)
|
@@ -877,6 +876,7 @@ module Workarea
|
|
877
876
|
config.cache_expirations.sitemap_fragment_cache = 1.day
|
878
877
|
config.cache_expirations.free_gift_attributes = 1.hour
|
879
878
|
config.cache_expirations.reports = 1.hour
|
879
|
+
config.cache_expirations.order_item_details = 15.minutes
|
880
880
|
|
881
881
|
# Send transactional emails. Allows default transaction emails to be
|
882
882
|
# disabled when using third-party email services.
|
@@ -1257,14 +1257,14 @@ module Workarea
|
|
1257
1257
|
# setting to configure the `:encoding` options for `CSV.foreach`
|
1258
1258
|
# if your CSV files are failing to import with a UTF-8 encoding
|
1259
1259
|
# error.
|
1260
|
-
config.csv_import_options = {}
|
1260
|
+
config.csv_import_options = { encoding: 'bom|utf-8' }
|
1261
1261
|
|
1262
1262
|
# Determines what payment action happens when "place order" is submitted.
|
1263
1263
|
# These correspond to methods on the {Checkout}'s instance of {Payment}
|
1264
1264
|
config.checkout_payment_action = {
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1265
|
+
shipping: 'authorize!',
|
1266
|
+
partial_shipping: 'purchase!',
|
1267
|
+
no_shipping: 'purchase!'
|
1268
1268
|
}
|
1269
1269
|
|
1270
1270
|
# Class used to determine if an order is fraudlent
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Workarea
|
2
2
|
module Configuration
|
3
3
|
class Redis
|
4
|
-
DEFAULT = { host: 'localhost', port: 6379, db: 0 }.freeze
|
4
|
+
DEFAULT = { host: 'localhost', port: 6379, db: 0, scheme: 'redis' }.freeze
|
5
5
|
|
6
6
|
class << self
|
7
7
|
# Used for Sidekiq and Predictor
|
@@ -39,11 +39,15 @@ module Workarea
|
|
39
39
|
return from_config if from_config.present?
|
40
40
|
|
41
41
|
env_slug = name.to_s.underscore.upcase
|
42
|
+
scheme = ENV["WORKAREA_#{env_slug}_SCHEME"].presence || DEFAULT[:scheme]
|
42
43
|
|
43
44
|
{
|
45
|
+
scheme: scheme,
|
44
46
|
host: ENV["WORKAREA_#{env_slug}_HOST"].presence || DEFAULT[:host],
|
45
47
|
port: ENV["WORKAREA_#{env_slug}_PORT"].presence || DEFAULT[:port],
|
46
|
-
db: ENV["WORKAREA_#{env_slug}_DB"].presence || DEFAULT[:db]
|
48
|
+
db: ENV["WORKAREA_#{env_slug}_DB"].presence || DEFAULT[:db],
|
49
|
+
password: ENV["WORKAREA_#{env_slug}_PASSWORD"].presence,
|
50
|
+
ssl: scheme == 'rediss' ? true : false
|
47
51
|
}
|
48
52
|
end
|
49
53
|
end
|
@@ -55,10 +59,22 @@ module Workarea
|
|
55
59
|
@config = config.to_h.deep_symbolize_keys
|
56
60
|
end
|
57
61
|
|
62
|
+
def scheme
|
63
|
+
@config[:scheme]
|
64
|
+
end
|
65
|
+
|
66
|
+
def ssl
|
67
|
+
@config[:ssl]
|
68
|
+
end
|
69
|
+
|
58
70
|
def host
|
59
71
|
@config[:host]
|
60
72
|
end
|
61
73
|
|
74
|
+
def password
|
75
|
+
@config[:password]
|
76
|
+
end
|
77
|
+
|
62
78
|
def port
|
63
79
|
@config[:port]
|
64
80
|
end
|
@@ -68,7 +84,9 @@ module Workarea
|
|
68
84
|
end
|
69
85
|
|
70
86
|
def to_url
|
71
|
-
base = "
|
87
|
+
base = "#{scheme}://"
|
88
|
+
base << "admin:#{password}@" if password.present?
|
89
|
+
base << "#{host}"
|
72
90
|
base << ":#{port}" if port.present?
|
73
91
|
base << "/#{db}" if db.present?
|
74
92
|
base
|
data/lib/workarea/core.rb
CHANGED
@@ -131,6 +131,7 @@ require 'workarea/ext/freedom_patches/dragonfly_job_fetch_url'
|
|
131
131
|
require 'workarea/ext/freedom_patches/dragonfly_callable_url_host'
|
132
132
|
require 'workarea/ext/freedom_patches/active_support_duration'
|
133
133
|
require 'workarea/ext/freedom_patches/premailer'
|
134
|
+
require 'workarea/ext/freedom_patches/referer_parser'
|
134
135
|
require 'workarea/ext/mongoid/list_field'
|
135
136
|
require 'workarea/ext/mongoid/each_by'
|
136
137
|
require 'workarea/ext/mongoid/except'
|
@@ -141,6 +142,7 @@ require 'workarea/ext/mongoid/lookup_hash'
|
|
141
142
|
require 'workarea/ext/active_shipping/workarea'
|
142
143
|
require 'workarea/ext/mongoid/audit_log_entry.decorator'
|
143
144
|
require 'workarea/ext/mongoid/find_ordered'
|
145
|
+
require 'workarea/ext/mongoid/embedded_children'
|
144
146
|
require 'workarea/ext/sprockets/ruby_processor'
|
145
147
|
require 'workarea/ext/jbuilder/jbuilder_append_partials'
|
146
148
|
|
@@ -218,6 +220,7 @@ require 'workarea/string_id'
|
|
218
220
|
require 'workarea/mail_interceptor'
|
219
221
|
require 'workarea/visit'
|
220
222
|
require 'workarea/warnings'
|
223
|
+
require 'workarea/latest_version'
|
221
224
|
|
222
225
|
#
|
223
226
|
# Core
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Document
|
3
|
+
# Returns all the embedded children in this document by recursion.
|
4
|
+
#
|
5
|
+
# @return [Array<Mongoid::Document>]
|
6
|
+
#
|
7
|
+
def embedded_children
|
8
|
+
result = []
|
9
|
+
|
10
|
+
embedded_relations.each do |name, metadata|
|
11
|
+
Array.wrap(send(name)).each do |child|
|
12
|
+
result << child
|
13
|
+
result += child.embedded_children
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
result
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Workarea
|
2
|
+
module LatestVersion
|
3
|
+
def self.get
|
4
|
+
Rails.cache.fetch('workarea/version/latest', expires_in: 3.days) do
|
5
|
+
request = Net::HTTP::Get.new('/api/v1/gems/workarea.json')
|
6
|
+
request.content_type = 'application/json'
|
7
|
+
|
8
|
+
uri = URI('https://rubygems.org')
|
9
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
10
|
+
http.use_ssl = true
|
11
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
12
|
+
response = http.start { |h| h.request(request) }
|
13
|
+
|
14
|
+
JSON.parse(response.body)['version']
|
15
|
+
end
|
16
|
+
rescue Exception => e
|
17
|
+
Rails.logger.error '-------------------------------------'
|
18
|
+
Rails.logger.error "There was an error contacting rubygems.org!"
|
19
|
+
Rails.logger.error e.class
|
20
|
+
Rails.logger.error e.message
|
21
|
+
Rails.logger.error '-------------------------------------'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/workarea/version.rb
CHANGED
data/lib/workarea/visit.rb
CHANGED
@@ -64,8 +64,11 @@ module Workarea
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def referrer
|
67
|
-
|
68
|
-
|
67
|
+
@referrer ||= begin
|
68
|
+
value = cookies['workarea_referrer'].presence || request.referrer
|
69
|
+
attributes = Workarea.referrer_parser.parse(value) rescue {}
|
70
|
+
TrafficReferrer.new(attributes)
|
71
|
+
end
|
69
72
|
end
|
70
73
|
|
71
74
|
def browser
|
data/lib/workarea/warnings.rb
CHANGED
@@ -75,16 +75,16 @@ of items in the order.
|
|
75
75
|
You should set Workarea.config.checkout_payment_action instead. You can set it
|
76
76
|
for each type of order, here are the defaults:
|
77
77
|
{
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
shipping: 'authorize!',
|
79
|
+
partial_shipping: 'authorize!',
|
80
|
+
no_shipping: 'purchase!'
|
81
81
|
}
|
82
82
|
|
83
83
|
To achieve the same functionality as Workarea.config.auto_capture, you'd set:
|
84
84
|
{
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
shipping: 'purchase!',
|
86
|
+
partial_shipping: 'purchase!',
|
87
|
+
no_shipping: 'purchase!'
|
88
88
|
}
|
89
89
|
|
90
90
|
**************************************************
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
class EmbeddedChildrenTest < Workarea::TestCase
|
5
|
+
class Parent
|
6
|
+
include Mongoid::Document
|
7
|
+
embeds_one :child, class_name: 'Mongoid::EmbeddedChildrenTest::Child'
|
8
|
+
embeds_many :children, class_name: 'Mongoid::EmbeddedChildrenTest::Child'
|
9
|
+
end
|
10
|
+
|
11
|
+
class Child
|
12
|
+
include Mongoid::Document
|
13
|
+
field :name, type: String
|
14
|
+
embeds_one :grandchild, class_name: 'Mongoid::EmbeddedChildrenTest::Grandchild'
|
15
|
+
embeds_many :grandchildren, class_name: 'Mongoid::EmbeddedChildrenTest::Grandchild'
|
16
|
+
end
|
17
|
+
|
18
|
+
class Grandchild
|
19
|
+
include Mongoid::Document
|
20
|
+
field :name, type: String
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_embedded_children
|
24
|
+
model = Parent.create!(
|
25
|
+
child: { name: '1', grandchild: { name: '2' } },
|
26
|
+
children: [{ name: '3' }, { name: '4', grandchildren: [{ name: '5' }] }]
|
27
|
+
)
|
28
|
+
|
29
|
+
assert_equal(%w(1 2 3 4 5), model.embedded_children.map(&:name))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|