workarea-core 3.5.11 → 3.5.16
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/models/workarea/checkout.rb +1 -5
- data/app/models/workarea/inventory/sku.rb +2 -2
- data/app/models/workarea/metrics/user.rb +24 -8
- data/app/models/workarea/order.rb +13 -3
- data/app/models/workarea/payment.rb +1 -6
- data/app/models/workarea/releasable.rb +3 -1
- data/app/models/workarea/release/changeset.rb +1 -0
- data/app/models/workarea/search/admin/pricing_discount.rb +1 -1
- data/app/models/workarea/search/storefront.rb +9 -1
- data/app/models/workarea/search/storefront/category_query.rb +1 -1
- data/app/models/workarea/search/storefront/product.rb +11 -2
- data/app/queries/workarea/product_releases.rb +6 -0
- data/app/services/workarea/direct_upload.rb +17 -13
- data/app/services/workarea/index_release_schedule_previews.rb +37 -0
- data/app/workers/workarea/index_category_changes.rb +16 -3
- data/app/workers/workarea/index_release_schedule_change.rb +32 -0
- data/app/workers/workarea/process_import.rb +3 -3
- data/app/workers/workarea/publish_release.rb +1 -0
- data/lib/tasks/search.rake +10 -4
- data/lib/workarea/configuration.rb +11 -0
- data/lib/workarea/configuration/administrable_options.rb +1 -5
- data/lib/workarea/core.rb +2 -0
- data/lib/workarea/ext/jbuilder/jbuilder_cache.rb +29 -0
- data/lib/workarea/queues_pauser.rb +26 -0
- data/lib/workarea/version.rb +1 -1
- data/lib/workarea/visit.rb +8 -1
- data/test/models/workarea/releasable_test.rb +13 -0
- data/test/models/workarea/search/storefront/category_query_test.rb +11 -0
- data/test/models/workarea/search/storefront/product_releases_test.rb +60 -0
- data/test/models/workarea/search/storefront_test.rb +13 -0
- data/test/queries/workarea/search/category_browse_test.rb +23 -0
- data/test/services/workarea/direct_upload_test.rb +20 -3
- data/test/services/workarea/index_release_schedule_previews_test.rb +28 -0
- data/test/workers/workarea/index_release_schedule_change_test.rb +107 -0
- data/test/workers/workarea/process_import_test.rb +6 -0
- data/test/workers/workarea/publish_release_test.rb +24 -0
- data/workarea-core.gemspec +5 -4
- metadata +31 -11
- data/test/queries/workarea/product_releases_test.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 569f33ae16d992354fca8761ef67ed5473a12755dda710cfff057ebd2d7aa2b4
|
4
|
+
data.tar.gz: 24b32513e4215b2aa1c67a5f1d930ae5f8a81ee098be08234eab95f69a6bc574
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11b65e3f2de7268ec497fecb2019a10133e2a477cc5bf06cd64390976098baa97277a75a295633a4fd6e43b221d31453c6a4da99b1c05012534e19621a6c7d18
|
7
|
+
data.tar.gz: 614ed5b1d7970082ba8eb48b8448434737d194ed1fed7158537774b9e46dce862ab0cae2faafca35f40378a061e3a91c02b9ab4d36875201896ea33ff6b60991
|
@@ -47,11 +47,7 @@ module Workarea
|
|
47
47
|
def inventory
|
48
48
|
@inventory ||= Inventory::Transaction.from_order(
|
49
49
|
order.id,
|
50
|
-
order.
|
51
|
-
memo[item.sku] ||= 0
|
52
|
-
memo[item.sku] += item.quantity
|
53
|
-
memo
|
54
|
-
end
|
50
|
+
order.sku_quantities
|
55
51
|
)
|
56
52
|
end
|
57
53
|
|
@@ -142,11 +142,11 @@ module Workarea
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def policy_class
|
145
|
-
"Workarea::Inventory::Policies::#{policy.
|
145
|
+
"Workarea::Inventory::Policies::#{policy.camelize}".constantize
|
146
146
|
rescue NameError
|
147
147
|
raise(
|
148
148
|
InvalidPolicy,
|
149
|
-
"Workarea::Inventory::Policies::#{policy.
|
149
|
+
"Workarea::Inventory::Policies::#{policy.camelize} must be a policy class"
|
150
150
|
)
|
151
151
|
end
|
152
152
|
|
@@ -110,14 +110,28 @@ module Workarea
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def merge!(other)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
113
|
+
# To recalculate average_order_value
|
114
|
+
self.orders += other.orders
|
115
|
+
self.revenue += other.revenue
|
116
|
+
|
117
|
+
update = {
|
118
|
+
'$set' => {
|
119
|
+
average_order_value: average_order_value,
|
120
|
+
updated_at: Time.current.utc
|
121
|
+
},
|
122
|
+
'$inc' => {
|
123
|
+
orders: other.orders,
|
124
|
+
revenue: other.revenue,
|
125
|
+
discounts: other.discounts,
|
126
|
+
cancellations: other.cancellations,
|
127
|
+
refund: other.refund
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
update['$min'] = { first_order_at: other.first_order_at.utc } if other.first_order_at.present?
|
132
|
+
update['$max'] = { last_order_at: other.last_order_at.utc } if other.last_order_at.present?
|
133
|
+
|
134
|
+
self.class.collection.update_one({ _id: id }, update, upsert: true)
|
121
135
|
|
122
136
|
self.class.save_affinity(
|
123
137
|
id: id,
|
@@ -133,6 +147,8 @@ module Workarea
|
|
133
147
|
category_ids: other.purchased.category_ids,
|
134
148
|
search_ids: other.purchased.search_ids
|
135
149
|
)
|
150
|
+
|
151
|
+
reload
|
136
152
|
end
|
137
153
|
end
|
138
154
|
end
|
@@ -47,13 +47,13 @@ module Workarea
|
|
47
47
|
{
|
48
48
|
placed_at: 1,
|
49
49
|
reminded_at: 1,
|
50
|
+
fraud_suspected_at: 1,
|
50
51
|
checkout_started_at: 1,
|
51
52
|
email: 1,
|
52
|
-
"items[0]._id": 1
|
53
|
-
fraud_suspected_at: 1
|
53
|
+
"items[0]._id": 1
|
54
54
|
},
|
55
55
|
{
|
56
|
-
name: '
|
56
|
+
name: 'abandoned_order_email_with_fraud_index_v2',
|
57
57
|
background: true
|
58
58
|
}
|
59
59
|
)
|
@@ -375,6 +375,16 @@ module Workarea
|
|
375
375
|
)
|
376
376
|
end
|
377
377
|
|
378
|
+
# A hash with the quantity of each SKU in the order
|
379
|
+
#
|
380
|
+
# @return [Hash]
|
381
|
+
#
|
382
|
+
def sku_quantities
|
383
|
+
items.each_with_object(Hash.new(0)) do |item, quantities|
|
384
|
+
quantities[item.sku] += item.quantity
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
378
388
|
private
|
379
389
|
|
380
390
|
def item_count_limit
|
@@ -80,12 +80,7 @@ module Workarea
|
|
80
80
|
build_credit_card unless credit_card
|
81
81
|
credit_card.saved_card_id = nil
|
82
82
|
credit_card.attributes = attrs.slice(
|
83
|
-
|
84
|
-
:year,
|
85
|
-
:saved_card_id,
|
86
|
-
:number,
|
87
|
-
:cvv,
|
88
|
-
:amount
|
83
|
+
*Workarea.config.credit_card_attributes
|
89
84
|
)
|
90
85
|
save
|
91
86
|
end
|
@@ -72,7 +72,9 @@ module Workarea
|
|
72
72
|
release.preview.changesets_for(self).each { |cs| cs.apply_to(result) }
|
73
73
|
result
|
74
74
|
else
|
75
|
-
Release.with_current(release)
|
75
|
+
Release.with_current(release) do
|
76
|
+
Mongoid::QueryCache.uncached { self.class.find(id) }
|
77
|
+
end
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
@@ -18,6 +18,7 @@ module Workarea
|
|
18
18
|
index({ 'document_path.type' => 1, 'document_path.document_id' => 1 })
|
19
19
|
index('changeset.product_ids' => 1)
|
20
20
|
index('original.product_ids' => 1)
|
21
|
+
index('releasable_type' => 1, 'releasable_id' => 1)
|
21
22
|
|
22
23
|
# Finds changeset by whether the passed document is in the document
|
23
24
|
# path of the changeset. Useful for showing embedded changes in the
|
@@ -82,6 +82,14 @@ module Workarea
|
|
82
82
|
@changesets ||= Array.wrap(model.try(:changesets_with_children))
|
83
83
|
end
|
84
84
|
|
85
|
+
def releases
|
86
|
+
changesets
|
87
|
+
.uniq(&:release)
|
88
|
+
.reject { |cs| cs.release.blank? }
|
89
|
+
.flat_map { |cs| [cs.release] + cs.release.scheduled_after }
|
90
|
+
.uniq
|
91
|
+
end
|
92
|
+
|
85
93
|
def as_document
|
86
94
|
Release.with_current(release_id) do
|
87
95
|
{
|
@@ -91,7 +99,7 @@ module Workarea
|
|
91
99
|
active: active,
|
92
100
|
active_segment_ids: active_segment_ids,
|
93
101
|
release_id: release_id,
|
94
|
-
changeset_release_ids:
|
102
|
+
changeset_release_ids: releases.map(&:id),
|
95
103
|
suggestion_content: suggestion_content,
|
96
104
|
created_at: model.created_at,
|
97
105
|
updated_at: model.updated_at,
|
@@ -122,12 +122,21 @@ module Workarea
|
|
122
122
|
ProductPrimaryImageUrl.new(model).path
|
123
123
|
end
|
124
124
|
|
125
|
-
#
|
125
|
+
# All {Releasable}s that could affect the product's Elasticsearch document
|
126
|
+
# should add their changesets to this method.
|
127
|
+
#
|
128
|
+
# @example Add to the changesets affecting a product in a decorator
|
129
|
+
# def changesets
|
130
|
+
# super.merge(SomeReleasable.for_product(product.id).changesets_with_children)
|
131
|
+
# end
|
126
132
|
#
|
127
133
|
# @return [Mongoid::Criteria]
|
128
134
|
#
|
129
135
|
def changesets
|
130
|
-
|
136
|
+
criteria = model.changesets_with_children
|
137
|
+
pricing.each { |ps| criteria.merge!(ps.changesets_with_children) }
|
138
|
+
criteria.merge!(FeaturedProducts.changesets(model.id))
|
139
|
+
criteria.includes(:release)
|
131
140
|
end
|
132
141
|
|
133
142
|
private
|
@@ -6,22 +6,26 @@ module Workarea
|
|
6
6
|
uri = URI.parse(request_url)
|
7
7
|
url = "#{uri.scheme}://#{uri.host}"
|
8
8
|
url += ":#{uri.port}" unless uri.port.in? [80, 443]
|
9
|
+
id = "direct_upload_#{url}"
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
response = begin
|
12
|
+
Workarea.s3.get_bucket_cors(Configuration::S3.bucket)
|
13
|
+
rescue Excon::Error::NotFound
|
14
|
+
Excon::Response.new(body: { 'CORSConfiguration' => [] })
|
15
|
+
end
|
12
16
|
|
13
|
-
response = Workarea.s3.get_bucket_cors(Configuration::S3.bucket)
|
14
17
|
cors = response.data[:body]
|
15
|
-
|
16
|
-
|
17
|
-
'
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
|
19
|
+
unless cors['CORSConfiguration'].pluck('ID').include?(id)
|
20
|
+
cors['CORSConfiguration'] << {
|
21
|
+
'ID' => id,
|
22
|
+
'AllowedMethod' => 'PUT',
|
23
|
+
'AllowedOrigin' => url,
|
24
|
+
'AllowedHeader' => '*'
|
25
|
+
}
|
26
|
+
|
27
|
+
Workarea.s3.put_bucket_cors(Configuration::S3.bucket, cors)
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
attr_reader :type, :filename
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Workarea
|
2
|
+
class IndexReleaseSchedulePreviews
|
3
|
+
attr_reader :release, :starts_at, :ends_at
|
4
|
+
|
5
|
+
def initialize(release: nil, starts_at: nil, ends_at: nil)
|
6
|
+
@release = release
|
7
|
+
@starts_at = starts_at
|
8
|
+
@ends_at = ends_at
|
9
|
+
end
|
10
|
+
|
11
|
+
def affected_releases
|
12
|
+
result = Release
|
13
|
+
.scheduled(after: starts_at, before: ends_at)
|
14
|
+
.includes(:changesets)
|
15
|
+
.to_a
|
16
|
+
|
17
|
+
result << release if release.present?
|
18
|
+
result.uniq
|
19
|
+
end
|
20
|
+
|
21
|
+
def affected_models
|
22
|
+
affected_releases.flat_map(&:changesets).flat_map(&:releasable).compact
|
23
|
+
end
|
24
|
+
|
25
|
+
def perform
|
26
|
+
affected_releases.each do |release|
|
27
|
+
affected_models.each do |releasable|
|
28
|
+
Search::Storefront.new(releasable.in_release(release)).destroy
|
29
|
+
|
30
|
+
# Different models have different indexing workers, running callbacks
|
31
|
+
# ensures the appropriate worker is triggered
|
32
|
+
releasable.run_callbacks(:save_release_changes)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -4,16 +4,29 @@ module Workarea
|
|
4
4
|
include Sidekiq::CallbacksWorker
|
5
5
|
|
6
6
|
sidekiq_options(
|
7
|
-
enqueue_on: {
|
7
|
+
enqueue_on: {
|
8
|
+
Catalog::Category => [:save, :save_release_changes],
|
9
|
+
with: -> { [changes, Release.current.present?] }
|
10
|
+
},
|
8
11
|
ignore_if: -> { changes['product_ids'].blank? },
|
9
12
|
lock: :until_executing,
|
10
13
|
query_cache: true
|
11
14
|
)
|
12
15
|
|
13
|
-
def perform(changes)
|
16
|
+
def perform(changes, for_release = false)
|
14
17
|
return unless changes['product_ids'].present?
|
15
18
|
|
16
|
-
ids =
|
19
|
+
ids = if for_release
|
20
|
+
# This is a shortcut because if you're resorting products within a release,
|
21
|
+
# the `changes` hash doesn't reflect the repositioning within the release,
|
22
|
+
# only the difference between what's live and what's in the release.
|
23
|
+
#
|
24
|
+
# Reindexing all of them is a shortcut to having to manually build a diff
|
25
|
+
# between the changesets in the possible affected releases.
|
26
|
+
changes['product_ids'].flatten.uniq
|
27
|
+
else
|
28
|
+
require_index_ids(*changes['product_ids'])
|
29
|
+
end
|
17
30
|
|
18
31
|
if ids.size > max_count
|
19
32
|
ids.each { |id| IndexProduct.perform_async(id) }
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Workarea
|
2
|
+
class IndexReleaseScheduleChange
|
3
|
+
include Sidekiq::Worker
|
4
|
+
include Sidekiq::CallbacksWorker
|
5
|
+
|
6
|
+
sidekiq_options(
|
7
|
+
enqueue_on: {
|
8
|
+
Release => [:save, :destroy],
|
9
|
+
only_if: -> { publish_at_changed? || destroyed? },
|
10
|
+
with: -> { [id, publish_at_was, publish_at] }
|
11
|
+
},
|
12
|
+
queue: 'releases'
|
13
|
+
)
|
14
|
+
|
15
|
+
def perform(id, previous_publish_at, new_publish_at)
|
16
|
+
# When destroyed, changesets for the release ID will still exist and be used to update the index
|
17
|
+
rescheduled_release = Release.find_or_initialize_by(id: id)
|
18
|
+
|
19
|
+
earlier, later = if rescheduled_release.persisted? && previous_publish_at.present? && new_publish_at.present?
|
20
|
+
[previous_publish_at, new_publish_at].sort
|
21
|
+
elsif previous_publish_at.present?
|
22
|
+
[previous_publish_at, nil]
|
23
|
+
else
|
24
|
+
[new_publish_at, nil]
|
25
|
+
end
|
26
|
+
|
27
|
+
IndexReleaseSchedulePreviews
|
28
|
+
.new(release: rescheduled_release, starts_at: earlier, ends_at: later)
|
29
|
+
.perform
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -17,11 +17,11 @@ module Workarea
|
|
17
17
|
import.process!
|
18
18
|
|
19
19
|
ensure
|
20
|
-
if import
|
20
|
+
if import&.error?
|
21
21
|
Admin::DataFileMailer.import_error(id).deliver_now
|
22
|
-
elsif import
|
22
|
+
elsif import&.failure?
|
23
23
|
Admin::DataFileMailer.import_failure(id).deliver_now
|
24
|
-
|
24
|
+
elsif import.present?
|
25
25
|
Admin::DataFileMailer.import(id).deliver_now
|
26
26
|
end
|
27
27
|
end
|
@@ -8,6 +8,7 @@ module Workarea
|
|
8
8
|
system_user = User.find_system_user!(release.name, 'Release')
|
9
9
|
|
10
10
|
Mongoid::AuditLog.record(system_user) { release.publish! }
|
11
|
+
IndexReleaseSchedulePreviews.new(release: release).perform
|
11
12
|
|
12
13
|
rescue Mongoid::Errors::DocumentNotFound
|
13
14
|
# Doesn't matter, release has been removed
|
data/lib/tasks/search.rake
CHANGED
@@ -16,7 +16,9 @@ namespace :workarea do
|
|
16
16
|
task admin: :environment do
|
17
17
|
setup
|
18
18
|
puts 'Indexing admin...'
|
19
|
-
Workarea::
|
19
|
+
Workarea::QueuesPauser.with_paused_queues do
|
20
|
+
Workarea::Search::Admin.reset_indexes!
|
21
|
+
end
|
20
22
|
|
21
23
|
Mongoid.models.each do |klass|
|
22
24
|
next unless Workarea::Search::Admin.for(klass.first).present?
|
@@ -36,8 +38,10 @@ namespace :workarea do
|
|
36
38
|
setup
|
37
39
|
puts 'Indexing storefront...'
|
38
40
|
|
39
|
-
Workarea::
|
40
|
-
|
41
|
+
Workarea::QueuesPauser.with_paused_queues do
|
42
|
+
Workarea::Search::Storefront.reset_indexes!
|
43
|
+
Workarea::Search::Storefront.ensure_dynamic_mappings
|
44
|
+
end
|
41
45
|
|
42
46
|
# This code finds all unique filters for products so we can index a sample
|
43
47
|
# product for each to ensure the dynamic mappings get created.
|
@@ -83,7 +87,9 @@ namespace :workarea do
|
|
83
87
|
setup
|
84
88
|
puts 'Indexing help...'
|
85
89
|
|
86
|
-
Workarea::
|
90
|
+
Workarea::QueuesPauser.with_paused_queues do
|
91
|
+
Workarea::Search::Help.reset_indexes!
|
92
|
+
end
|
87
93
|
|
88
94
|
Workarea::Help::Article.all.each_by(Workarea.config.bulk_index_batch_size) do |help_article|
|
89
95
|
Workarea::Search::Help.new(help_article).save
|
@@ -1297,6 +1297,17 @@ module Workarea
|
|
1297
1297
|
|
1298
1298
|
# The number of results that will show per-type in the admin jump to
|
1299
1299
|
config.jump_to_results_per_type = 5
|
1300
|
+
|
1301
|
+
# Attributes that will be sliced out of params and persisted on
|
1302
|
+
# the credit card tender during checkout.
|
1303
|
+
config.credit_card_attributes = %i[
|
1304
|
+
month
|
1305
|
+
year
|
1306
|
+
saved_card_id
|
1307
|
+
number
|
1308
|
+
cvv
|
1309
|
+
amount
|
1310
|
+
]
|
1300
1311
|
end
|
1301
1312
|
end
|
1302
1313
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Workarea
|
2
2
|
module Configuration
|
3
3
|
class AdministrableOptions < ActiveSupport::InheritableOptions
|
4
|
-
def
|
4
|
+
def [](name)
|
5
5
|
static_config = super
|
6
6
|
return static_config if static_config.present? || static_config.to_s == 'false'
|
7
7
|
return static_config unless check_fieldsets?(name)
|
@@ -9,10 +9,6 @@ module Workarea
|
|
9
9
|
Configuration::Admin.instance.send(name)
|
10
10
|
end
|
11
11
|
|
12
|
-
def respond_to_missing?(name, include_private)
|
13
|
-
true
|
14
|
-
end
|
15
|
-
|
16
12
|
private
|
17
13
|
|
18
14
|
def check_fieldsets?(name)
|
data/lib/workarea/core.rb
CHANGED
@@ -146,6 +146,7 @@ require 'workarea/ext/mongoid/find_ordered'
|
|
146
146
|
require 'workarea/ext/mongoid/embedded_children'
|
147
147
|
require 'workarea/ext/sprockets/ruby_processor'
|
148
148
|
require 'workarea/ext/jbuilder/jbuilder_append_partials'
|
149
|
+
require 'workarea/ext/jbuilder/jbuilder_cache'
|
149
150
|
|
150
151
|
if Rails.env.development?
|
151
152
|
require 'workarea/ext/freedom_patches/routes_reloader'
|
@@ -221,6 +222,7 @@ require 'workarea/mail_interceptor'
|
|
221
222
|
require 'workarea/visit'
|
222
223
|
require 'workarea/warnings'
|
223
224
|
require 'workarea/latest_version'
|
225
|
+
require 'workarea/queues_pauser'
|
224
226
|
|
225
227
|
#
|
226
228
|
# Engines
|
@@ -0,0 +1,29 @@
|
|
1
|
+
decorate JbuilderTemplate, with: :workarea do
|
2
|
+
def _cache_fragment_for(*)
|
3
|
+
return yield if workarea_admin?
|
4
|
+
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
def _cache_key(*)
|
9
|
+
super.tap do |result|
|
10
|
+
result << workarea_cache_varies if workarea_cache_varies.present?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def workarea_admin?
|
17
|
+
@context&.controller&.current_user&.admin?
|
18
|
+
rescue ::RuntimeError
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def workarea_cache_varies
|
23
|
+
workarea_request_env['workarea.cache_varies']
|
24
|
+
end
|
25
|
+
|
26
|
+
def workarea_request_env
|
27
|
+
@context.controller.request.env || {}
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Workarea
|
2
|
+
module QueuesPauser
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def pause_queues!
|
6
|
+
pauser = Sidekiq::Throttled::QueuesPauser.instance
|
7
|
+
queues.each { |queue| pauser.pause!(queue) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def resume_queues!
|
11
|
+
pauser = Sidekiq::Throttled::QueuesPauser.instance
|
12
|
+
queues.each { |queue| pauser.resume!(queue) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_paused_queues(&block)
|
16
|
+
pause_queues!
|
17
|
+
yield
|
18
|
+
ensure
|
19
|
+
resume_queues!
|
20
|
+
end
|
21
|
+
|
22
|
+
def queues
|
23
|
+
Configuration::Sidekiq.queues
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/workarea/version.rb
CHANGED
data/lib/workarea/visit.rb
CHANGED
@@ -38,7 +38,10 @@ module Workarea
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def current_email
|
41
|
-
|
41
|
+
# For performance, prefer to use the cookie. The fallback to looking it up
|
42
|
+
# by user is a failsafe against a blank email cookie (e.g. from a raised
|
43
|
+
# error or poor application coding).
|
44
|
+
cookies.signed[:email].presence || (email_from_user_id if logged_in?)
|
42
45
|
end
|
43
46
|
|
44
47
|
def metrics
|
@@ -91,5 +94,9 @@ module Workarea
|
|
91
94
|
def blank_metrics
|
92
95
|
@blank_metrics ||= Metrics::User.new
|
93
96
|
end
|
97
|
+
|
98
|
+
def email_from_user_id
|
99
|
+
User.find(session[:user_id]).email rescue nil
|
100
|
+
end
|
94
101
|
end
|
95
102
|
end
|
@@ -375,6 +375,19 @@ module Workarea
|
|
375
375
|
in_release = model.in_release(nil)
|
376
376
|
assert_equal('Foo', in_release.name)
|
377
377
|
refute_equal(in_release.object_id, model.object_id)
|
378
|
+
|
379
|
+
Mongoid::QueryCache.cache do
|
380
|
+
cached = Foo.find(model.id) # a find to ensure it's in the cache table
|
381
|
+
cached.name = 'Bar' # so the cache table's instance has a change
|
382
|
+
|
383
|
+
in_release = model.in_release(nil)
|
384
|
+
assert_equal('Foo', in_release.name)
|
385
|
+
refute_equal(in_release.object_id, model.object_id)
|
386
|
+
refute_equal(cached.object_id, model.object_id)
|
387
|
+
end
|
388
|
+
|
389
|
+
ensure
|
390
|
+
Mongoid::QueryCache.clear_cache
|
378
391
|
end
|
379
392
|
|
380
393
|
def test_skip_changeset
|
@@ -75,6 +75,17 @@ module Workarea
|
|
75
75
|
assert_equal([@category.id.to_s], CategoryQuery.find_by_product(@product))
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
def test_deleted_releases
|
80
|
+
release = create_release
|
81
|
+
release.as_current do
|
82
|
+
@category.product_rules.first.update!(value: 'bar')
|
83
|
+
end
|
84
|
+
|
85
|
+
release.destroy
|
86
|
+
CategoryQuery.new(@category).update
|
87
|
+
assert_equal([@category.id.to_s], CategoryQuery.find_by_product(@product))
|
88
|
+
end
|
78
89
|
end
|
79
90
|
end
|
80
91
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Workarea
|
4
|
+
module Search
|
5
|
+
class Storefront
|
6
|
+
class ProductReleasesTest < TestCase
|
7
|
+
def test_product_changes
|
8
|
+
product = create_product(name: 'Foo')
|
9
|
+
release_one = create_release
|
10
|
+
release_one.as_current { product.update!(name: 'Bar') }
|
11
|
+
|
12
|
+
assert_equal([release_one], Product.new(product).releases)
|
13
|
+
|
14
|
+
release_one.update!(publish_at: 1.day.from_now)
|
15
|
+
release_two = create_release(publish_at: 3.days.from_now)
|
16
|
+
assert_equal([release_one, release_two], Product.new(product).releases)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_featured_product_changes
|
20
|
+
product = create_product
|
21
|
+
category = create_category
|
22
|
+
|
23
|
+
release_one = create_release
|
24
|
+
release_one.as_current { category.update!(product_ids: [product.id]) }
|
25
|
+
assert_equal([release_one], Product.new(product).releases)
|
26
|
+
|
27
|
+
release_one.update!(publish_at: 1.day.from_now)
|
28
|
+
release_two = create_release(publish_at: 3.days.from_now)
|
29
|
+
assert_equal([release_one, release_two], Product.new(product).releases)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_variant_changes
|
33
|
+
product = create_product(variants: [{ sku: 'SKU' }])
|
34
|
+
release = create_release
|
35
|
+
release.as_current { product.variants.first.update!(details: { color: 'Red' }) }
|
36
|
+
assert_equal([release], Product.new(product).releases)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_pricing_changes
|
40
|
+
product = create_product(variants: [{ sku: 'SKU' }])
|
41
|
+
pricing = Pricing::Sku.find('SKU')
|
42
|
+
|
43
|
+
release = create_release
|
44
|
+
release.as_current { pricing.prices.first.update!(regular: 10_000) }
|
45
|
+
assert_equal([release], Product.new(product).releases)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_changesets_with_missing_releases
|
49
|
+
product = create_product(name: 'Foo')
|
50
|
+
release = create_release
|
51
|
+
release.as_current { product.update!(name: 'Bar') }
|
52
|
+
release.delete
|
53
|
+
|
54
|
+
assert_nil(product.reload.changesets.first.release)
|
55
|
+
assert_equal([], Product.new(product).releases)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -25,6 +25,19 @@ module Workarea
|
|
25
25
|
release.as_current { category.product_rules.first.update!(value: 'bar') }
|
26
26
|
assert_equal(2, Storefront.new(category).changesets.size)
|
27
27
|
end
|
28
|
+
|
29
|
+
def test_releases
|
30
|
+
category = create_category(name: 'Foo')
|
31
|
+
assert_empty(Storefront.new(category).as_document[:changeset_release_ids])
|
32
|
+
|
33
|
+
a = create_release(publish_at: 1.week.from_now)
|
34
|
+
a.as_current { category.update!(name: 'Bar') }
|
35
|
+
assert_equal([a.id], Storefront.new(category).as_document[:changeset_release_ids])
|
36
|
+
|
37
|
+
b = create_release(publish_at: 2.weeks.from_now)
|
38
|
+
assert_includes(Storefront.new(category).as_document[:changeset_release_ids], a.id)
|
39
|
+
assert_includes(Storefront.new(category).as_document[:changeset_release_ids], b.id)
|
40
|
+
end
|
28
41
|
end
|
29
42
|
end
|
30
43
|
end
|
@@ -382,6 +382,29 @@ module Workarea
|
|
382
382
|
refute_includes(result_ids, product_five.id)
|
383
383
|
end
|
384
384
|
end
|
385
|
+
|
386
|
+
def test_featured_product_changes_in_a_release
|
387
|
+
one = create_product
|
388
|
+
two = create_product
|
389
|
+
three = create_product(name: 'Foo', active: false)
|
390
|
+
category = create_category(product_ids: [one.id, two.id], product_rules: [])
|
391
|
+
release = create_release(publish_at: 1.week.from_now)
|
392
|
+
|
393
|
+
release.as_current do
|
394
|
+
three.update!(name: 'Bar', active: true, default_category_id: category.id)
|
395
|
+
category.update!(product_ids: [three.id, one.id, two.id])
|
396
|
+
search = CategoryBrowse.new(sort: %w(featured), category_ids: [category.id])
|
397
|
+
sorts = search.results.pluck(:raw).pluck('_source').pluck('sorts').pluck(category.id.to_s)
|
398
|
+
assert_equal([0, 1, 2], sorts)
|
399
|
+
end
|
400
|
+
|
401
|
+
release.as_current do
|
402
|
+
category.update!(product_ids: [one.id, two.id, three.id])
|
403
|
+
search = CategoryBrowse.new(sort: %w(featured), category_ids: [category.id])
|
404
|
+
sorts = search.results.pluck(:raw).pluck('_source').pluck('sorts').pluck(category.id.to_s)
|
405
|
+
assert_equal([0, 1, 2], sorts)
|
406
|
+
end
|
407
|
+
end
|
385
408
|
end
|
386
409
|
end
|
387
410
|
end
|
@@ -108,11 +108,28 @@ module Workarea
|
|
108
108
|
).returns(true)
|
109
109
|
|
110
110
|
assert(DirectUpload.ensure_cors!('http://test.host/admin/content_assets'))
|
111
|
-
assert_equal('true', Workarea.redis.get('cors_http_test_host'))
|
112
111
|
assert(DirectUpload.ensure_cors!('http://localhost:3000/admin/content_assets'))
|
113
|
-
assert_equal('true', Workarea.redis.get('cors_http_localhost_3000'))
|
114
112
|
assert(DirectUpload.ensure_cors!('https://example.com/admin/direct_uploads'))
|
115
|
-
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_ensure_cors_with_no_existing_configuration
|
116
|
+
Workarea.s3.expects(:get_bucket_cors)
|
117
|
+
.raises(Excon::Errors::NotFound.new('CORS configuration does not exist'))
|
118
|
+
|
119
|
+
|
120
|
+
Workarea.s3.expects(:put_bucket_cors).with(
|
121
|
+
Configuration::S3.bucket,
|
122
|
+
'CORSConfiguration' => [
|
123
|
+
{
|
124
|
+
'ID' => "direct_upload_http://test.host",
|
125
|
+
'AllowedMethod' => 'PUT',
|
126
|
+
'AllowedOrigin' => 'http://test.host',
|
127
|
+
'AllowedHeader' => '*'
|
128
|
+
}
|
129
|
+
]
|
130
|
+
).returns(true)
|
131
|
+
|
132
|
+
assert(DirectUpload.ensure_cors!('http://test.host/admin/content_assets'))
|
116
133
|
end
|
117
134
|
|
118
135
|
private
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Workarea
|
4
|
+
class IndexReleaseSchedulePreviewsTest < TestCase
|
5
|
+
def test_affected_releases
|
6
|
+
release = create_release
|
7
|
+
results = IndexReleaseSchedulePreviews.new(release: release).affected_releases
|
8
|
+
assert_equal([release], results)
|
9
|
+
|
10
|
+
a = create_release(publish_at: 1.week.from_now)
|
11
|
+
b = create_release(publish_at: 2.weeks.from_now)
|
12
|
+
c = create_release(publish_at: 4.weeks.from_now)
|
13
|
+
assert_equal([a, b, c], IndexReleaseSchedulePreviews.new.affected_releases)
|
14
|
+
|
15
|
+
results = IndexReleaseSchedulePreviews
|
16
|
+
.new(starts_at: 3.days.from_now, ends_at: 17.days.from_now)
|
17
|
+
.affected_releases
|
18
|
+
|
19
|
+
assert_equal([a, b], results)
|
20
|
+
|
21
|
+
results = IndexReleaseSchedulePreviews
|
22
|
+
.new(release: release, starts_at: 3.days.from_now, ends_at: 10.days.from_now)
|
23
|
+
.affected_releases
|
24
|
+
|
25
|
+
assert_equal([a, release], results)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Workarea
|
4
|
+
class IndexReleaseScheduleChangeTest < TestCase
|
5
|
+
include TestCase::SearchIndexing
|
6
|
+
|
7
|
+
setup :set_product
|
8
|
+
|
9
|
+
def set_product
|
10
|
+
@product = create_product(name: 'Foo')
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_reschedule
|
14
|
+
a = create_release(name: 'A', publish_at: 1.week.from_now)
|
15
|
+
b = create_release(name: 'B', publish_at: 2.weeks.from_now)
|
16
|
+
c = create_release(name: 'C', publish_at: 4.weeks.from_now)
|
17
|
+
|
18
|
+
b.as_current { @product.update!(name: 'Bar') }
|
19
|
+
IndexProduct.perform(@product)
|
20
|
+
|
21
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
22
|
+
b.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
23
|
+
c.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
24
|
+
|
25
|
+
# Changing publish_at via `update` causes the release to publish due to Sidekiq inline
|
26
|
+
previous_publish_at = b.publish_at
|
27
|
+
b.set(publish_at: 5.weeks.from_now)
|
28
|
+
|
29
|
+
Sidekiq::Callbacks.enable(IndexProduct) do
|
30
|
+
IndexReleaseScheduleChange.new.perform(b.id, previous_publish_at, b.publish_at)
|
31
|
+
end
|
32
|
+
|
33
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
34
|
+
b.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
35
|
+
c.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_removing_from_schedule
|
39
|
+
a = create_release(name: 'A', publish_at: 1.week.from_now)
|
40
|
+
b = create_release(name: 'B', publish_at: 2.weeks.from_now)
|
41
|
+
c = create_release(name: 'C', publish_at: 4.weeks.from_now)
|
42
|
+
|
43
|
+
b.as_current { @product.update!(name: 'Bar') }
|
44
|
+
IndexProduct.perform(@product)
|
45
|
+
|
46
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
47
|
+
b.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
48
|
+
c.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
49
|
+
|
50
|
+
# Changing publish_at via `update` causes the release to publish due to Sidekiq inline
|
51
|
+
previous_publish_at = b.publish_at
|
52
|
+
b.set(publish_at: nil)
|
53
|
+
|
54
|
+
Sidekiq::Callbacks.enable(IndexProduct) do
|
55
|
+
IndexReleaseScheduleChange.new.perform(b.id, previous_publish_at, nil)
|
56
|
+
end
|
57
|
+
|
58
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
59
|
+
b.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
60
|
+
c.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_adding_to_schedule
|
64
|
+
a = create_release(name: 'A', publish_at: 1.week.from_now)
|
65
|
+
b = create_release(name: 'B')
|
66
|
+
c = create_release(name: 'C', publish_at: 4.weeks.from_now)
|
67
|
+
|
68
|
+
b.as_current { @product.update!(name: 'Bar') }
|
69
|
+
IndexProduct.perform(@product)
|
70
|
+
|
71
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
72
|
+
b.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
73
|
+
c.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
74
|
+
|
75
|
+
# Changing publish_at via `update` causes the release to publish due to Sidekiq inline
|
76
|
+
b.set(publish_at: 2.weeks.from_now)
|
77
|
+
|
78
|
+
Sidekiq::Callbacks.enable(IndexProduct) do
|
79
|
+
IndexReleaseScheduleChange.new.perform(b.id, nil, b.publish_at)
|
80
|
+
end
|
81
|
+
|
82
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
83
|
+
b.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
84
|
+
c.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_destroyed
|
88
|
+
a = create_release(name: 'A', publish_at: 1.week.from_now)
|
89
|
+
b = create_release(name: 'B', publish_at: 2.weeks.from_now)
|
90
|
+
c = create_release(name: 'C', publish_at: 4.weeks.from_now)
|
91
|
+
|
92
|
+
b.as_current { @product.update!(name: 'Bar') }
|
93
|
+
IndexProduct.perform(@product)
|
94
|
+
|
95
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
96
|
+
b.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
97
|
+
c.as_current { assert_equal([@product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
98
|
+
|
99
|
+
Sidekiq::Callbacks.enable(IndexReleaseScheduleChange, IndexProduct) do
|
100
|
+
b.destroy
|
101
|
+
end
|
102
|
+
|
103
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
104
|
+
c.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -2,6 +2,8 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module Workarea
|
4
4
|
class PublishReleaseTest < TestCase
|
5
|
+
include TestCase::SearchIndexing
|
6
|
+
|
5
7
|
def test_publishes_the_release
|
6
8
|
release = create_release
|
7
9
|
PublishRelease.new.perform(release.id)
|
@@ -16,5 +18,27 @@ module Workarea
|
|
16
18
|
assert_equal(1, Mongoid::AuditLog::Entry.count)
|
17
19
|
assert(Mongoid::AuditLog::Entry.first.modifier.system?)
|
18
20
|
end
|
21
|
+
|
22
|
+
def test_reindexes_release_schedule
|
23
|
+
product = create_product(name: 'Foo')
|
24
|
+
|
25
|
+
a = create_release(publish_at: 1.week.from_now)
|
26
|
+
b = create_release(publish_at: 2.weeks.from_now)
|
27
|
+
c = create_release(publish_at: 4.weeks.from_now)
|
28
|
+
|
29
|
+
b.as_current { product.update!(name: 'Bar') }
|
30
|
+
IndexProduct.perform(product)
|
31
|
+
|
32
|
+
assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model))
|
33
|
+
a.as_current { assert_empty(Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
34
|
+
b.as_current { assert_equal([product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
35
|
+
c.as_current { assert_equal([product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
36
|
+
|
37
|
+
Sidekiq::Callbacks.enable(IndexProduct) { PublishRelease.new.perform(b.id) }
|
38
|
+
|
39
|
+
assert_equal([product], Search::ProductSearch.new(q: 'bar').results.pluck(:model))
|
40
|
+
a.as_current { assert_equal([product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
41
|
+
c.as_current { assert_equal([product], Search::ProductSearch.new(q: 'bar').results.pluck(:model)) }
|
42
|
+
end
|
19
43
|
end
|
20
44
|
end
|
data/workarea-core.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_dependency 'mongoid-sample', '~> 0.1.0'
|
26
26
|
s.add_dependency 'mongoid-encrypted', '~> 1.0.0'
|
27
27
|
s.add_dependency 'elasticsearch', '~> 5.0.1'
|
28
|
-
s.add_dependency 'kaminari', '~>
|
28
|
+
s.add_dependency 'kaminari', '~> 1.2.1'
|
29
29
|
s.add_dependency 'kaminari-mongoid', '~> 0.1.2'
|
30
30
|
s.add_dependency 'activemerchant', '~> 1.52'
|
31
31
|
s.add_dependency 'dragonfly', '~> 1.1.2'
|
@@ -33,7 +33,8 @@ Gem::Specification.new do |s|
|
|
33
33
|
s.add_dependency 'sidekiq-cron', '~> 0.6.3'
|
34
34
|
s.add_dependency 'sidekiq-unique-jobs', '~> 6.0.6'
|
35
35
|
s.add_dependency 'sidekiq-throttled', '~> 0.8.2'
|
36
|
-
s.add_dependency 'geocoder', '~> 1.
|
36
|
+
s.add_dependency 'geocoder', '~> 1.6.3'
|
37
|
+
s.add_dependency 'redis-rails', '~> 5.0.0'
|
37
38
|
s.add_dependency 'redis-rack-cache', '~> 2.2.0'
|
38
39
|
s.add_dependency 'easymon', '~> 1.4.0'
|
39
40
|
s.add_dependency 'image_optim', '~> 0.26.0'
|
@@ -65,7 +66,7 @@ Gem::Specification.new do |s|
|
|
65
66
|
s.add_dependency 'chart-horizontalbar-rails', '~> 1.0.4' # TODO remove v4
|
66
67
|
s.add_dependency 'select2-rails', '~> 4.0.3'
|
67
68
|
s.add_dependency 'wysihtml-rails', '~> 0.6.0.beta2'
|
68
|
-
s.add_dependency 'rack-attack', '~>
|
69
|
+
s.add_dependency 'rack-attack', '~> 6.3.1'
|
69
70
|
s.add_dependency 'jquery-livetype-rails', '~> 0.1.0' # TODO remove v4
|
70
71
|
s.add_dependency 'redcarpet', '~> 3.4.0'
|
71
72
|
s.add_dependency 'jquery-unique-clone-rails', '~> 1.0.0'
|
@@ -93,7 +94,7 @@ Gem::Specification.new do |s|
|
|
93
94
|
s.add_dependency 'chartkick', '~> 3.3.0'
|
94
95
|
s.add_dependency 'browser', '~> 2.6.1'
|
95
96
|
s.add_dependency 'puma', '>= 4.3.1'
|
96
|
-
s.add_dependency 'rack', '>= 2.
|
97
|
+
s.add_dependency 'rack' , '>= 2.1.4'
|
97
98
|
|
98
99
|
# HACK for vendoring active_shipping
|
99
100
|
s.add_dependency 'active_utils', '~> 3.3.1'
|
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.5.
|
4
|
+
version: 3.5.16
|
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-
|
11
|
+
date: 2020-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -170,14 +170,14 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
173
|
+
version: 1.2.1
|
174
174
|
type: :runtime
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
180
|
+
version: 1.2.1
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: kaminari-mongoid
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -282,14 +282,28 @@ dependencies:
|
|
282
282
|
requirements:
|
283
283
|
- - "~>"
|
284
284
|
- !ruby/object:Gem::Version
|
285
|
-
version: 1.
|
285
|
+
version: 1.6.3
|
286
286
|
type: :runtime
|
287
287
|
prerelease: false
|
288
288
|
version_requirements: !ruby/object:Gem::Requirement
|
289
289
|
requirements:
|
290
290
|
- - "~>"
|
291
291
|
- !ruby/object:Gem::Version
|
292
|
-
version: 1.
|
292
|
+
version: 1.6.3
|
293
|
+
- !ruby/object:Gem::Dependency
|
294
|
+
name: redis-rails
|
295
|
+
requirement: !ruby/object:Gem::Requirement
|
296
|
+
requirements:
|
297
|
+
- - "~>"
|
298
|
+
- !ruby/object:Gem::Version
|
299
|
+
version: 5.0.0
|
300
|
+
type: :runtime
|
301
|
+
prerelease: false
|
302
|
+
version_requirements: !ruby/object:Gem::Requirement
|
303
|
+
requirements:
|
304
|
+
- - "~>"
|
305
|
+
- !ruby/object:Gem::Version
|
306
|
+
version: 5.0.0
|
293
307
|
- !ruby/object:Gem::Dependency
|
294
308
|
name: redis-rack-cache
|
295
309
|
requirement: !ruby/object:Gem::Requirement
|
@@ -730,14 +744,14 @@ dependencies:
|
|
730
744
|
requirements:
|
731
745
|
- - "~>"
|
732
746
|
- !ruby/object:Gem::Version
|
733
|
-
version:
|
747
|
+
version: 6.3.1
|
734
748
|
type: :runtime
|
735
749
|
prerelease: false
|
736
750
|
version_requirements: !ruby/object:Gem::Requirement
|
737
751
|
requirements:
|
738
752
|
- - "~>"
|
739
753
|
- !ruby/object:Gem::Version
|
740
|
-
version:
|
754
|
+
version: 6.3.1
|
741
755
|
- !ruby/object:Gem::Dependency
|
742
756
|
name: jquery-livetype-rails
|
743
757
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1128,14 +1142,14 @@ dependencies:
|
|
1128
1142
|
requirements:
|
1129
1143
|
- - ">="
|
1130
1144
|
- !ruby/object:Gem::Version
|
1131
|
-
version: 2.
|
1145
|
+
version: 2.1.4
|
1132
1146
|
type: :runtime
|
1133
1147
|
prerelease: false
|
1134
1148
|
version_requirements: !ruby/object:Gem::Requirement
|
1135
1149
|
requirements:
|
1136
1150
|
- - ">="
|
1137
1151
|
- !ruby/object:Gem::Version
|
1138
|
-
version: 2.
|
1152
|
+
version: 2.1.4
|
1139
1153
|
- !ruby/object:Gem::Dependency
|
1140
1154
|
name: active_utils
|
1141
1155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1720,6 +1734,7 @@ files:
|
|
1720
1734
|
- app/services/workarea/direct_upload/product_image.rb
|
1721
1735
|
- app/services/workarea/export_report.rb
|
1722
1736
|
- app/services/workarea/hash_update.rb
|
1737
|
+
- app/services/workarea/index_release_schedule_previews.rb
|
1723
1738
|
- app/services/workarea/inventory_adjustment.rb
|
1724
1739
|
- app/services/workarea/login.rb
|
1725
1740
|
- app/services/workarea/new_discount.rb
|
@@ -1757,6 +1772,7 @@ files:
|
|
1757
1772
|
- app/workers/workarea/index_product.rb
|
1758
1773
|
- app/workers/workarea/index_product_children.rb
|
1759
1774
|
- app/workers/workarea/index_product_rule.rb
|
1775
|
+
- app/workers/workarea/index_release_schedule_change.rb
|
1760
1776
|
- app/workers/workarea/index_search_customizations.rb
|
1761
1777
|
- app/workers/workarea/index_skus.rb
|
1762
1778
|
- app/workers/workarea/keep_product_index_fresh.rb
|
@@ -1930,6 +1946,7 @@ files:
|
|
1930
1946
|
- lib/workarea/ext/freedom_patches/string.rb
|
1931
1947
|
- lib/workarea/ext/freedom_patches/uri.rb
|
1932
1948
|
- lib/workarea/ext/jbuilder/jbuilder_append_partials.rb
|
1949
|
+
- lib/workarea/ext/jbuilder/jbuilder_cache.rb
|
1933
1950
|
- lib/workarea/ext/mongoid/audit_log_entry.decorator
|
1934
1951
|
- lib/workarea/ext/mongoid/each_by.rb
|
1935
1952
|
- lib/workarea/ext/mongoid/embedded_children.rb
|
@@ -1964,6 +1981,7 @@ files:
|
|
1964
1981
|
- lib/workarea/ping_home_base.rb
|
1965
1982
|
- lib/workarea/plugin.rb
|
1966
1983
|
- lib/workarea/plugin/asset_appends_helper.rb
|
1984
|
+
- lib/workarea/queues_pauser.rb
|
1967
1985
|
- lib/workarea/routes_constraints/redirect.rb
|
1968
1986
|
- lib/workarea/routes_constraints/super_admin.rb
|
1969
1987
|
- lib/workarea/scheduled_jobs.rb
|
@@ -2314,6 +2332,7 @@ files:
|
|
2314
2332
|
- test/models/workarea/search/storefront/product/inventory_test.rb
|
2315
2333
|
- test/models/workarea/search/storefront/product/pricing_test.rb
|
2316
2334
|
- test/models/workarea/search/storefront/product/text_test.rb
|
2335
|
+
- test/models/workarea/search/storefront/product_releases_test.rb
|
2317
2336
|
- test/models/workarea/search/storefront/product_test.rb
|
2318
2337
|
- test/models/workarea/search/storefront_test.rb
|
2319
2338
|
- test/models/workarea/segment/life_cycle_test.rb
|
@@ -2365,7 +2384,6 @@ files:
|
|
2365
2384
|
- test/queries/workarea/pricing_override_params_test.rb
|
2366
2385
|
- test/queries/workarea/product_primary_image_url_test.rb
|
2367
2386
|
- test/queries/workarea/product_primary_navigation_test.rb
|
2368
|
-
- test/queries/workarea/product_releases_test.rb
|
2369
2387
|
- test/queries/workarea/recommendation/order_based_test.rb
|
2370
2388
|
- test/queries/workarea/recommendation/product_based_test.rb
|
2371
2389
|
- test/queries/workarea/recommendation/searches_test.rb
|
@@ -2426,6 +2444,7 @@ files:
|
|
2426
2444
|
- test/services/workarea/direct_upload_test.rb
|
2427
2445
|
- test/services/workarea/export_report_test.rb
|
2428
2446
|
- test/services/workarea/hash_update_test.rb
|
2447
|
+
- test/services/workarea/index_release_schedule_previews_test.rb
|
2429
2448
|
- test/services/workarea/inventory_adjustment_test.rb
|
2430
2449
|
- test/services/workarea/login_test.rb
|
2431
2450
|
- test/services/workarea/order_merge_test.rb
|
@@ -2458,6 +2477,7 @@ files:
|
|
2458
2477
|
- test/workers/workarea/index_payment_transactions_test.rb
|
2459
2478
|
- test/workers/workarea/index_product_rule_test.rb
|
2460
2479
|
- test/workers/workarea/index_product_test.rb
|
2480
|
+
- test/workers/workarea/index_release_schedule_change_test.rb
|
2461
2481
|
- test/workers/workarea/index_skus_test.rb
|
2462
2482
|
- test/workers/workarea/keep_product_index_fresh_test.rb
|
2463
2483
|
- test/workers/workarea/mark_discounts_as_redeemed_test.rb
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module Workarea
|
4
|
-
class ProductReleasesTest < TestCase
|
5
|
-
def test_product_changes
|
6
|
-
product = create_product(name: 'Foo')
|
7
|
-
release_one = create_release
|
8
|
-
release_one.as_current { product.update!(name: 'Bar') }
|
9
|
-
|
10
|
-
assert_equal([release_one], ProductReleases.new(product).releases)
|
11
|
-
|
12
|
-
release_one.update!(publish_at: 1.day.from_now)
|
13
|
-
release_two = create_release(publish_at: 3.days.from_now)
|
14
|
-
assert_equal([release_one, release_two], ProductReleases.new(product).releases)
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_featured_product_changes
|
18
|
-
product = create_product
|
19
|
-
category = create_category
|
20
|
-
|
21
|
-
release_one = create_release
|
22
|
-
release_one.as_current { category.update!(product_ids: [product.id]) }
|
23
|
-
assert_equal([release_one], ProductReleases.new(product).releases)
|
24
|
-
|
25
|
-
release_one.update!(publish_at: 1.day.from_now)
|
26
|
-
release_two = create_release(publish_at: 3.days.from_now)
|
27
|
-
assert_equal([release_one, release_two], ProductReleases.new(product).releases)
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_variant_changes
|
31
|
-
product = create_product(variants: [{ sku: 'SKU' }])
|
32
|
-
release = create_release
|
33
|
-
release.as_current { product.variants.first.update!(details: { color: 'Red' }) }
|
34
|
-
assert_equal([release], ProductReleases.new(product).releases)
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_pricing_changes
|
38
|
-
product = create_product(variants: [{ sku: 'SKU' }])
|
39
|
-
pricing = Pricing::Sku.find('SKU')
|
40
|
-
|
41
|
-
release = create_release
|
42
|
-
release.as_current { pricing.prices.first.update!(regular: 10_000) }
|
43
|
-
assert_equal([release], ProductReleases.new(product).releases)
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_changesets_with_missing_releases
|
47
|
-
product = create_product(name: 'Foo')
|
48
|
-
release = create_release
|
49
|
-
release.as_current { product.update!(name: 'Bar') }
|
50
|
-
release.delete
|
51
|
-
|
52
|
-
assert_nil(product.reload.changesets.first.release)
|
53
|
-
assert_equal([], ProductReleases.new(product).releases)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|