workarea-core 3.5.8 → 3.5.13
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/application_controller.rb +0 -5
- data/app/controllers/workarea/authentication.rb +6 -0
- data/app/helpers/workarea/i18n_helper.rb +1 -1
- data/app/middleware/workarea/application_middleware.rb +18 -0
- data/app/models/workarea/bulk_action/product_edit.rb +6 -6
- data/app/models/workarea/order.rb +3 -3
- 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 +2 -2
- data/app/models/workarea/search/storefront/product.rb +11 -2
- data/app/models/workarea/user/password_reset.rb +3 -1
- data/app/queries/workarea/product_releases.rb +6 -0
- data/app/queries/workarea/search/pagination.rb +4 -1
- data/app/queries/workarea/search/product_entries.rb +7 -5
- data/app/queries/workarea/search/storefront_search.rb +1 -1
- data/app/services/workarea/direct_upload.rb +17 -13
- data/app/services/workarea/hash_update.rb +15 -1
- data/app/workers/workarea/bulk_index_admin.rb +1 -1
- data/app/workers/workarea/bulk_index_products.rb +3 -2
- data/app/workers/workarea/bulk_index_searches.rb +4 -4
- data/app/workers/workarea/index_category_changes.rb +16 -3
- data/app/workers/workarea/process_import.rb +3 -3
- data/app/workers/workarea/reindex_release.rb +42 -0
- data/app/workers/workarea/synchronize_user_metrics.rb +12 -2
- data/lib/tasks/search.rake +10 -4
- data/lib/workarea/cache.rb +1 -1
- data/lib/workarea/changelog.rake +1 -1
- data/lib/workarea/core.rb +3 -0
- data/lib/workarea/elasticsearch/document.rb +15 -8
- data/lib/workarea/ext/freedom_patches/i18n_js.rb +27 -0
- data/lib/workarea/ext/freedom_patches/mongoid_localized_defaults.rb +25 -0
- data/lib/workarea/geolocation.rb +1 -9
- data/lib/workarea/queues_pauser.rb +26 -0
- data/lib/workarea/version.rb +1 -1
- data/lib/workarea/visit.rb +8 -1
- data/lib/workarea/warnings.rb +3 -4
- data/test/helpers/workarea/i18n_helper_test.rb +2 -0
- data/test/integration/workarea/authentication_test.rb +10 -0
- data/test/integration/workarea/cache_varies_integration_test.rb +31 -0
- data/test/lib/workarea/elasticsearch/document_test.rb +20 -0
- data/test/lib/workarea/ext/freedom_patches/mongoid_localized_defaults_test.rb +25 -0
- data/test/lib/workarea/geolocation_test.rb +3 -3
- data/test/models/workarea/releasable_test.rb +13 -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/models/workarea/segment/rules/geolocation_test.rb +9 -7
- data/test/models/workarea/user/password_reset_test.rb +12 -4
- data/test/queries/workarea/search/category_browse_test.rb +23 -0
- data/test/queries/workarea/search/pagination_test.rb +9 -0
- data/test/queries/workarea/search/product_entries_test.rb +11 -0
- data/test/queries/workarea/search/product_search_test.rb +16 -0
- data/test/services/workarea/direct_upload_test.rb +20 -3
- data/test/services/workarea/hash_update_test.rb +12 -12
- data/test/workers/workarea/process_import_test.rb +6 -0
- data/test/workers/workarea/reindex_release_test.rb +81 -0
- data/workarea-core.gemspec +4 -3
- metadata +29 -9
- data/test/queries/workarea/product_releases_test.rb +0 -56
@@ -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
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Workarea
|
2
|
+
class ReindexRelease
|
3
|
+
include Sidekiq::Worker
|
4
|
+
include Sidekiq::CallbacksWorker
|
5
|
+
|
6
|
+
sidekiq_options(
|
7
|
+
enqueue_on: {
|
8
|
+
Release => :save,
|
9
|
+
only_if: -> { publish_at_changed? },
|
10
|
+
with: -> { [id, publish_at_was, publish_at] }
|
11
|
+
},
|
12
|
+
queue: 'high'
|
13
|
+
)
|
14
|
+
|
15
|
+
def perform(id, previous_publish_at, new_publish_at)
|
16
|
+
rescheduled_release = Release.find(id)
|
17
|
+
earlier, later = if previous_publish_at.present? && new_publish_at.present?
|
18
|
+
[previous_publish_at, new_publish_at].sort
|
19
|
+
elsif previous_publish_at.present?
|
20
|
+
[previous_publish_at, nil]
|
21
|
+
else
|
22
|
+
[new_publish_at, nil]
|
23
|
+
end
|
24
|
+
|
25
|
+
affected_releases = Release.scheduled(after: earlier, before: later).includes(:changesets).to_a
|
26
|
+
affected_releases += [rescheduled_release]
|
27
|
+
affected_releases.uniq!
|
28
|
+
|
29
|
+
affected_models = affected_releases.flat_map(&:changesets).flat_map(&:releasable)
|
30
|
+
|
31
|
+
affected_releases.each do |release|
|
32
|
+
affected_models.each do |releasable|
|
33
|
+
Search::Storefront.new(releasable.in_release(release)).destroy
|
34
|
+
|
35
|
+
# Different models have different indexing workers, running callbacks
|
36
|
+
# ensures the appropriate worker is triggered
|
37
|
+
releasable.run_callbacks(:save_release_changes)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -19,8 +19,18 @@ module Workarea
|
|
19
19
|
|
20
20
|
def perform(id)
|
21
21
|
user = User.find(id)
|
22
|
-
|
23
|
-
|
22
|
+
|
23
|
+
Metrics::User.collection.update_one(
|
24
|
+
{ _id: user.email },
|
25
|
+
{
|
26
|
+
'$set' => {
|
27
|
+
admin: user.admin?,
|
28
|
+
tags: user.tags,
|
29
|
+
updated_at: Time.current.utc
|
30
|
+
}
|
31
|
+
},
|
32
|
+
upsert: true
|
33
|
+
)
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
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
|
data/lib/workarea/cache.rb
CHANGED
data/lib/workarea/changelog.rake
CHANGED
data/lib/workarea/core.rb
CHANGED
@@ -131,6 +131,8 @@ require 'workarea/ext/freedom_patches/dragonfly_callable_url_host'
|
|
131
131
|
require 'workarea/ext/freedom_patches/active_support_duration'
|
132
132
|
require 'workarea/ext/freedom_patches/premailer'
|
133
133
|
require 'workarea/ext/freedom_patches/referer_parser'
|
134
|
+
require 'workarea/ext/freedom_patches/mongoid_localized_defaults'
|
135
|
+
require 'workarea/ext/freedom_patches/i18n_js'
|
134
136
|
require 'workarea/ext/mongoid/list_field'
|
135
137
|
require 'workarea/ext/mongoid/each_by'
|
136
138
|
require 'workarea/ext/mongoid/except'
|
@@ -219,6 +221,7 @@ require 'workarea/mail_interceptor'
|
|
219
221
|
require 'workarea/visit'
|
220
222
|
require 'workarea/warnings'
|
221
223
|
require 'workarea/latest_version'
|
224
|
+
require 'workarea/queues_pauser'
|
222
225
|
|
223
226
|
#
|
224
227
|
# Engines
|
@@ -44,22 +44,27 @@ module Workarea
|
|
44
44
|
|
45
45
|
def save(document, options = {})
|
46
46
|
options = options.merge(type: type)
|
47
|
-
|
47
|
+
current_index.save(document, options)
|
48
48
|
end
|
49
49
|
|
50
|
-
def bulk(documents, options = {})
|
50
|
+
def bulk(documents = [], options = {})
|
51
51
|
options = options.merge(type: type)
|
52
|
-
|
52
|
+
|
53
|
+
if block_given?
|
54
|
+
I18n.for_each_locale { current_index.bulk(Array.wrap(yield), options) }
|
55
|
+
else
|
56
|
+
current_index.bulk(documents, options)
|
57
|
+
end
|
53
58
|
end
|
54
59
|
|
55
60
|
def update(document, options = {})
|
56
61
|
options = options.merge(type: type)
|
57
|
-
|
62
|
+
current_index.update(document, options)
|
58
63
|
end
|
59
64
|
|
60
65
|
def delete(id, options = {})
|
61
66
|
options = options.merge(type: type)
|
62
|
-
|
67
|
+
current_index.delete(id, options)
|
63
68
|
end
|
64
69
|
|
65
70
|
def count(query = nil, options = {})
|
@@ -97,12 +102,14 @@ module Workarea
|
|
97
102
|
end
|
98
103
|
|
99
104
|
def save(options = {})
|
100
|
-
|
101
|
-
|
105
|
+
I18n.for_each_locale do
|
106
|
+
document = as_document.merge(Serializer.serialize(model))
|
107
|
+
self.class.save(document, options)
|
108
|
+
end
|
102
109
|
end
|
103
110
|
|
104
111
|
def destroy(options = {})
|
105
|
-
self.class.delete(id, options)
|
112
|
+
I18n.for_each_locale { self.class.delete(id, options) }
|
106
113
|
end
|
107
114
|
end
|
108
115
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module I18n
|
2
|
+
module JS
|
3
|
+
class FallbackLocales
|
4
|
+
# i18n-js uses just the second part of this check out-of-the-box. This
|
5
|
+
# causes the I18n fallbacks to get autoloaded without the developer
|
6
|
+
# knowing.
|
7
|
+
#
|
8
|
+
# This surfaces in tests. System or integration tests will do this check
|
9
|
+
# for compiling assets, then I18n fallbacks get autoloaded. So this shows
|
10
|
+
# as some tests not having fallbacks if they run before one of those tests
|
11
|
+
# or magically having fallbacks if they run after one of those types of
|
12
|
+
# tests.
|
13
|
+
#
|
14
|
+
# Adding the `respond_to?` check doesn't cause autoload, but will return
|
15
|
+
# `true` if fallbacks are enabled. Retain the original check because we
|
16
|
+
# want the current I18n::JS backend to be checked, once fallbacks are
|
17
|
+
# `require`d `I18n.respond_to?(:fallbacks)` will always return `true`.
|
18
|
+
#
|
19
|
+
# See also: https://github.com/fnando/i18n-js/blob/master/lib/i18n/js/fallback_locales.rb#L49-L58
|
20
|
+
#
|
21
|
+
def using_i18n_fallbacks_module?
|
22
|
+
I18n.respond_to?(:fallbacks) &&
|
23
|
+
I18n::JS.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Fields
|
3
|
+
module LocalizedDefaults
|
4
|
+
def create_accessors(name, meth, options = {})
|
5
|
+
super
|
6
|
+
|
7
|
+
if options[:localize]
|
8
|
+
field = fields[name]
|
9
|
+
|
10
|
+
define_method meth do |*args|
|
11
|
+
result = super(*args)
|
12
|
+
return result unless result.nil?
|
13
|
+
|
14
|
+
default_name = field.send(:default_name)
|
15
|
+
return send(default_name) if respond_to?(default_name)
|
16
|
+
|
17
|
+
field.default_val
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
ClassMethods.prepend(LocalizedDefaults)
|
24
|
+
end
|
25
|
+
end
|
data/lib/workarea/geolocation.rb
CHANGED
@@ -57,15 +57,7 @@ module Workarea
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def names
|
60
|
-
@names ||= [
|
61
|
-
postal_code,
|
62
|
-
city,
|
63
|
-
region,
|
64
|
-
subdivision&.name,
|
65
|
-
country&.alpha2,
|
66
|
-
country&.alpha3,
|
67
|
-
country&.name
|
68
|
-
].reject(&:blank?)
|
60
|
+
@names ||= [postal_code, city, subdivision&.name, country&.name].reject(&:blank?)
|
69
61
|
end
|
70
62
|
|
71
63
|
private
|
@@ -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
|
data/lib/workarea/warnings.rb
CHANGED
@@ -51,13 +51,12 @@ db.getSiblingDB("admin").runCommand( { setParameter: 1, notablescan: 0 } )
|
|
51
51
|
**************************************************
|
52
52
|
⛔️ WARNING: Dragonfly is configured to use the filesystem.
|
53
53
|
|
54
|
-
This means all
|
54
|
+
This means all Dragonfly assets (assets, product images, etc.) will be stored
|
55
55
|
locally and not accessible to all servers within your environment.
|
56
56
|
|
57
57
|
We recommend using S3 when running in a live environment by setting
|
58
|
-
WORKAREA_S3_REGION and WORKAREA_S3_BUCKET_NAME in your environment variables
|
59
|
-
|
60
|
-
are present.
|
58
|
+
WORKAREA_S3_REGION and WORKAREA_S3_BUCKET_NAME in your environment variables,
|
59
|
+
and setting `Workarea.config.asset_store = :s3` in an initializer.
|
61
60
|
**************************************************
|
62
61
|
eos
|
63
62
|
end
|
@@ -7,12 +7,14 @@ module Workarea
|
|
7
7
|
params[:controller] = 'controller'
|
8
8
|
params[:action] = 'action'
|
9
9
|
params[:foo] = 'bar'
|
10
|
+
params[:locale] = 'es'
|
10
11
|
|
11
12
|
assert_includes(switch_locale_fields, 'foo')
|
12
13
|
assert_includes(switch_locale_fields, 'bar')
|
13
14
|
refute_includes(switch_locale_fields, 'utf8')
|
14
15
|
refute_includes(switch_locale_fields, 'controller')
|
15
16
|
refute_includes(switch_locale_fields, 'action')
|
17
|
+
refute_includes(switch_locale_fields, 'locale')
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -185,5 +185,15 @@ module Workarea
|
|
185
185
|
get '/test_logout'
|
186
186
|
refute(cookies[:email].present?)
|
187
187
|
end
|
188
|
+
|
189
|
+
def test_ensures_locale_passthrough_for_return_to
|
190
|
+
set_locales(available: [:en, :es], default: :en, current: :en)
|
191
|
+
|
192
|
+
get '/login_required', params: { locale: 'es', return_to: '/blah?foo=bar' }
|
193
|
+
get '/test_login', params: { user_id: @user.id }
|
194
|
+
assert(response.redirect?)
|
195
|
+
assert_match('locale=es', response.location)
|
196
|
+
assert_match('foo=bar', response.location)
|
197
|
+
end
|
188
198
|
end
|
189
199
|
end
|
@@ -25,6 +25,10 @@ module Workarea
|
|
25
25
|
render plain: session[:foo].presence || 'nil'
|
26
26
|
end
|
27
27
|
|
28
|
+
def varies
|
29
|
+
render plain: request.env['workarea.cache_varies']
|
30
|
+
end
|
31
|
+
|
28
32
|
def current_user
|
29
33
|
nil
|
30
34
|
end
|
@@ -34,6 +38,11 @@ module Workarea
|
|
34
38
|
Rails.application.routes.prepend do
|
35
39
|
post 'cache_varies_test_set_session', to: 'workarea/cache_varies_integration_test/caching#set_session'
|
36
40
|
get 'cache_varies_test_foo', to: 'workarea/cache_varies_integration_test/caching#foo'
|
41
|
+
|
42
|
+
scope '(:locale)', constraints: Workarea::I18n.routes_constraint do
|
43
|
+
get 'cache_varies_test_varies', to: 'workarea/cache_varies_integration_test/caching#varies'
|
44
|
+
patch 'cache_varies_test_varies', to: 'workarea/cache_varies_integration_test/caching#varies'
|
45
|
+
end
|
37
46
|
end
|
38
47
|
|
39
48
|
Rails.application.reload_routes!
|
@@ -74,5 +83,27 @@ module Workarea
|
|
74
83
|
assert_equal('baz', response.body)
|
75
84
|
assert_equal('fresh', response.headers['X-Rack-Cache'])
|
76
85
|
end
|
86
|
+
|
87
|
+
def test_varies_includes_locale
|
88
|
+
set_locales(available: [:en, :es], default: :en, current: :en)
|
89
|
+
|
90
|
+
get '/cache_varies_test_varies'
|
91
|
+
assert_includes(response.body, 'en')
|
92
|
+
|
93
|
+
get '/cache_varies_test_varies', params: { locale: 'es' }
|
94
|
+
assert_includes(response.body, 'es')
|
95
|
+
|
96
|
+
get '/es/cache_varies_test_varies'
|
97
|
+
assert_includes(response.body, 'es')
|
98
|
+
|
99
|
+
patch '/cache_varies_test_varies'
|
100
|
+
assert_includes(response.body, 'en')
|
101
|
+
|
102
|
+
patch '/cache_varies_test_varies', params: { locale: 'es' }
|
103
|
+
assert_includes(response.body, 'es')
|
104
|
+
|
105
|
+
patch '/es/cache_varies_test_varies'
|
106
|
+
assert_includes(response.body, 'es')
|
107
|
+
end
|
77
108
|
end
|
78
109
|
end
|
@@ -67,6 +67,26 @@ module Workarea
|
|
67
67
|
assert_equal({ 'id' => '1' }, results.first['_source'])
|
68
68
|
end
|
69
69
|
|
70
|
+
def test_bulk_with_block
|
71
|
+
set_locales(available: [:en, :es], default: :en, current: :en)
|
72
|
+
Foo.bulk { { id: I18n.locale.to_s, bulk_action: 'index' } }
|
73
|
+
|
74
|
+
find_results = -> do
|
75
|
+
Foo
|
76
|
+
.current_index
|
77
|
+
.search({ query: { match_all: {} } }, type: 'foo')
|
78
|
+
.dig('hits', 'hits')
|
79
|
+
end
|
80
|
+
|
81
|
+
I18n.locale = :en
|
82
|
+
assert(1, Foo.count)
|
83
|
+
assert_equal({ 'id' => 'en' }, find_results.call.first['_source'])
|
84
|
+
|
85
|
+
I18n.locale = :es
|
86
|
+
assert(1, Foo.count)
|
87
|
+
assert_equal({ 'id' => 'es' }, find_results.call.first['_source'])
|
88
|
+
end
|
89
|
+
|
70
90
|
def test_update
|
71
91
|
Foo.save(id: '1')
|
72
92
|
Foo.update(id: '1', foo: 'bar')
|