workarea-core 3.5.9 → 3.5.14

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/workarea/bulk_action/product_edit.rb +6 -6
  3. data/app/models/workarea/order.rb +3 -3
  4. data/app/models/workarea/releasable.rb +3 -1
  5. data/app/models/workarea/release/changeset.rb +1 -0
  6. data/app/models/workarea/search/admin/pricing_discount.rb +1 -1
  7. data/app/models/workarea/search/storefront.rb +9 -1
  8. data/app/models/workarea/search/storefront/category_query.rb +1 -1
  9. data/app/models/workarea/search/storefront/product.rb +11 -2
  10. data/app/queries/workarea/product_releases.rb +6 -0
  11. data/app/queries/workarea/search/pagination.rb +4 -1
  12. data/app/queries/workarea/search/storefront_search.rb +1 -1
  13. data/app/services/workarea/direct_upload.rb +17 -13
  14. data/app/services/workarea/hash_update.rb +15 -1
  15. data/app/services/workarea/index_release_schedule_previews.rb +37 -0
  16. data/app/workers/workarea/index_category_changes.rb +16 -3
  17. data/app/workers/workarea/index_release_schedule_change.rb +32 -0
  18. data/app/workers/workarea/process_import.rb +3 -3
  19. data/app/workers/workarea/publish_release.rb +1 -0
  20. data/lib/tasks/search.rake +10 -4
  21. data/lib/workarea/changelog.rake +1 -1
  22. data/lib/workarea/core.rb +2 -0
  23. data/lib/workarea/ext/freedom_patches/i18n_js.rb +27 -0
  24. data/lib/workarea/queues_pauser.rb +26 -0
  25. data/lib/workarea/version.rb +1 -1
  26. data/lib/workarea/visit.rb +8 -1
  27. data/lib/workarea/warnings.rb +3 -4
  28. data/test/models/workarea/releasable_test.rb +13 -0
  29. data/test/models/workarea/search/storefront/category_query_test.rb +11 -0
  30. data/test/models/workarea/search/storefront/product_releases_test.rb +60 -0
  31. data/test/models/workarea/search/storefront_test.rb +13 -0
  32. data/test/queries/workarea/search/category_browse_test.rb +23 -0
  33. data/test/queries/workarea/search/pagination_test.rb +9 -0
  34. data/test/queries/workarea/search/product_search_test.rb +3 -0
  35. data/test/services/workarea/direct_upload_test.rb +20 -3
  36. data/test/services/workarea/hash_update_test.rb +12 -12
  37. data/test/services/workarea/index_release_schedule_previews_test.rb +28 -0
  38. data/test/workers/workarea/index_release_schedule_change_test.rb +107 -0
  39. data/test/workers/workarea/process_import_test.rb +6 -0
  40. data/test/workers/workarea/publish_release_test.rb +24 -0
  41. data/workarea-core.gemspec +4 -3
  42. metadata +29 -9
  43. 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: 277c3f21e9ad08940c1f72830fd89f066987b104d019cb45b670774dc31b91e2
4
- data.tar.gz: a256669db5f584453ad3103365446f5cb885bfa55bae6b68240b07782775b8aa
3
+ metadata.gz: 32f457800d2f9e59fb315b3bdedde57f90d04ea6befdd4cf04dc5b4c78838eaf
4
+ data.tar.gz: 564f64759f19ea4d0db9b1ea4b7a2c12cdebf629ea2f52b5916519a3c958d611
5
5
  SHA512:
6
- metadata.gz: 97608d2f8240e4e21862d986599f8a6cbe4f5e461dc0bbb027203fff9d36b2d74f6477f27a9a652a893690146cfcaac3347bd0e263084f85af6438649d4a9c52
7
- data.tar.gz: 2affa2d8c642e5f47f690d29ccf01629efaaa41f2963d1b16b9a02a3e690ceb57a22447f0e9ebbf7552973de4b817f6d6f80154a76cca01bc8065e6bfa5620ed
6
+ metadata.gz: 6ae82b803bfe0daffc1e54953aa54f0c3a045cbe83fbb7b2e0c3d68961746950f442f7d87bee7c6b31c4fb697f685b0db3aa5277b0e6b430e6adabfbab4d9837
7
+ data.tar.gz: '094e9624ee3213c17dc554e263dc79538c5c09d2db4868d0f1aaa827db8559e60e46728c171364db364d2ff323f6100e0b2edaeea5746a4f59a73cbc51b16832'
@@ -36,15 +36,15 @@ module Workarea
36
36
  end
37
37
 
38
38
  def apply_details!(product)
39
- HashUpdate
40
- .new(adds: add_details, removes: remove_details)
41
- .apply(product.details)
39
+ product.details = HashUpdate
40
+ .new(original: product.details, adds: add_details, removes: remove_details)
41
+ .result
42
42
  end
43
43
 
44
44
  def apply_filters!(product)
45
- HashUpdate
46
- .new(adds: add_filters, removes: remove_filters)
47
- .apply(product.filters)
45
+ product.filters = HashUpdate
46
+ .new(original: product.filters, adds: add_filters, removes: remove_filters)
47
+ .result
48
48
  end
49
49
 
50
50
  def apply_pricing!(product)
@@ -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: 'abandoned_order_email_index',
56
+ name: 'abandoned_order_email_with_fraud_index_v2',
57
57
  background: true
58
58
  }
59
59
  )
@@ -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) { self.class.find(id) }
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
@@ -21,7 +21,7 @@ module Workarea
21
21
  end
22
22
 
23
23
  def keywords
24
- super + model.promo_codes
24
+ super + Array.wrap(model.try(:promo_codes))
25
25
  end
26
26
 
27
27
  def facets
@@ -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: changesets.map(&:release_id),
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,
@@ -144,7 +144,7 @@ module Workarea
144
144
  .where(releasable_type: ProductRule.name)
145
145
  .any_in(releasable_id: category.product_rules.map(&:id))
146
146
  .includes(:release)
147
- .to_a
147
+ .select(&:release)
148
148
  end
149
149
  end
150
150
  end
@@ -122,12 +122,21 @@ module Workarea
122
122
  ProductPrimaryImageUrl.new(model).path
123
123
  end
124
124
 
125
- # Override to include release changesets for pricing, featured products, etc.
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
- @product_changesets ||= ProductReleases.new(model).changesets
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
@@ -1,4 +1,10 @@
1
1
  module Workarea
2
+ #
3
+ # TODO remove in v3.6
4
+ #
5
+ # This is no longer used, this logic was moved into the search models to allow
6
+ # it to be used for any model (not just products).
7
+ #
2
8
  class ProductReleases
3
9
  attr_reader :product
4
10
 
@@ -7,7 +7,10 @@ module Workarea
7
7
  end
8
8
 
9
9
  def per_page
10
- params[:per_page].presence || Workarea.config.per_page
10
+ return Workarea.config.per_page if params[:per_page].blank?
11
+
12
+ tmp = params[:per_page].to_i
13
+ tmp > 0 ? tmp : Workarea.config.per_page
11
14
  end
12
15
 
13
16
  def size
@@ -4,7 +4,7 @@ module Workarea
4
4
  attr_reader :params
5
5
 
6
6
  def initialize(params)
7
- @params = params
7
+ @params = params.with_indifferent_access.except(:per_page)
8
8
  @used_middleware = []
9
9
  end
10
10
 
@@ -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
- redis_key = "cors_#{url.optionize}"
11
- return if Workarea.redis.get(redis_key) == 'true'
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
- cors['CORSConfiguration'] << {
16
- 'ID' => "direct_upload_#{url}",
17
- 'AllowedMethod' => 'PUT',
18
- 'AllowedOrigin' => url,
19
- 'AllowedHeader' => '*'
20
- }
21
- cors['CORSConfiguration'].uniq!
22
-
23
- Workarea.s3.put_bucket_cors(Configuration::S3.bucket, cors)
24
- Workarea.redis.set(redis_key, 'true')
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
@@ -5,13 +5,27 @@ module Workarea
5
5
  parsed.map(&:to_s).map(&:strip).reject(&:blank?) if parsed.present?
6
6
  end
7
7
 
8
- def initialize(adds: [], updates: [], removes: [])
8
+ def initialize(original: {}, adds: [], updates: [], removes: [])
9
+ @original = original
9
10
  @adds = Array(adds).flatten.each_slice(2).to_a
10
11
  @updates = Array(updates).flatten.each_slice(2).to_a
11
12
  @removes = Array(removes).flatten
12
13
  end
13
14
 
15
+ def result
16
+ apply_to(@original.deep_dup)
17
+ end
18
+
19
+ # TODO v3.6 remove this method, doesn't work when the field is localized
20
+ # @deprecated
14
21
  def apply(hash)
22
+ Workarea.deprecation.deprecate_methods(self.class, apply: :result)
23
+ apply_to(hash)
24
+ end
25
+
26
+ private
27
+
28
+ def apply_to(hash)
15
29
  @adds.each do |tuple|
16
30
  key, value = *tuple
17
31
  hash[key] = self.class.parse_values(value)
@@ -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: { Catalog::Category => [:save, :save_release_changes], with: -> { [changes] } },
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 = require_index_ids(*changes['product_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.error?
20
+ if import&.error?
21
21
  Admin::DataFileMailer.import_error(id).deliver_now
22
- elsif import.failure?
22
+ elsif import&.failure?
23
23
  Admin::DataFileMailer.import_failure(id).deliver_now
24
- else
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
@@ -16,7 +16,9 @@ namespace :workarea do
16
16
  task admin: :environment do
17
17
  setup
18
18
  puts 'Indexing admin...'
19
- Workarea::Search::Admin.reset_indexes!
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::Search::Storefront.reset_indexes!
40
- Workarea::Search::Storefront.ensure_dynamic_mappings
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::Search::Help.reset_indexes!
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
@@ -67,7 +67,7 @@ namespace :workarea do
67
67
  message << " #{line.strip}"
68
68
  end
69
69
  end
70
- message << " #{entry[:author]}\n"
70
+ message << "\n #{entry[:author]}\n"
71
71
  end
72
72
 
73
73
  # ensure and append to changelog
@@ -132,6 +132,7 @@ 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
134
  require 'workarea/ext/freedom_patches/mongoid_localized_defaults'
135
+ require 'workarea/ext/freedom_patches/i18n_js'
135
136
  require 'workarea/ext/mongoid/list_field'
136
137
  require 'workarea/ext/mongoid/each_by'
137
138
  require 'workarea/ext/mongoid/except'
@@ -220,6 +221,7 @@ require 'workarea/mail_interceptor'
220
221
  require 'workarea/visit'
221
222
  require 'workarea/warnings'
222
223
  require 'workarea/latest_version'
224
+ require 'workarea/queues_pauser'
223
225
 
224
226
  #
225
227
  # Engines
@@ -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,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
@@ -2,7 +2,7 @@ module Workarea
2
2
  module VERSION
3
3
  MAJOR = 3
4
4
  MINOR = 5
5
- PATCH = 9
5
+ PATCH = 14
6
6
  PRE = nil
7
7
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
8
8
 
@@ -38,7 +38,10 @@ module Workarea
38
38
  end
39
39
 
40
40
  def current_email
41
- cookies.signed[:email]
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
@@ -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 dragonfly assets (assets, product images, etc.) will be stored
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
- Workarea will automatically configure Dragonfly to use S3 if those values
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
@@ -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
@@ -19,6 +19,15 @@ module Workarea
19
19
  assert_equal(1, Paginate.new(page: 'asdf').page)
20
20
  end
21
21
 
22
+ def test_per_page
23
+ assert_equal(Workarea.config.per_page, Paginate.new.per_page)
24
+ assert_equal(2, Paginate.new(per_page: 2).per_page)
25
+ assert_equal(Workarea.config.per_page, Paginate.new(per_page: -1).per_page)
26
+ assert_equal(Workarea.config.per_page, Paginate.new(per_page: 0).per_page)
27
+ assert_equal(3, Paginate.new(per_page: '3').per_page)
28
+ assert_equal(Workarea.config.per_page, Paginate.new(per_page: 'asdf').per_page)
29
+ end
30
+
22
31
  def test_from
23
32
  Workarea.config.per_page = 30
24
33
  assert_equal(0, Paginate.new(page: 1).from)
@@ -427,6 +427,9 @@ module Workarea
427
427
  end
428
428
 
429
429
  def test_locale
430
+ # No simple way to run this test without fallbacks or localized fields
431
+ return unless Workarea.config.localized_active_fields
432
+
430
433
  set_locales(available: [:en, :es], default: :en, current: :en)
431
434
  Search::Storefront.reset_indexes!
432
435
 
@@ -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
- assert_equal('true', Workarea.redis.get('cors_https_example_com'))
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
@@ -2,23 +2,23 @@ require 'test_helper'
2
2
 
3
3
  module Workarea
4
4
  class HashUpdateTest < TestCase
5
- def test_apply
6
- hash = { 'foo' => 'bar' }
5
+ def test_result
6
+ original = { 'foo' => 'bar' }
7
7
 
8
- HashUpdate.new(adds: %w(key value)).apply(hash)
9
- assert_equal(%w(value), hash['key'])
8
+ result = HashUpdate.new(original: original, adds: %w(key value)).result
9
+ assert_equal(%w(value), result['key'])
10
10
 
11
- HashUpdate.new(updates: %w(foo baz)).apply(hash)
12
- assert_equal(%w(baz), hash['foo'])
11
+ result = HashUpdate.new(original: original, updates: %w(foo baz)).result
12
+ assert_equal(%w(baz), result['foo'])
13
13
 
14
- HashUpdate.new(removes: %w(foo)).apply(hash)
15
- refute_includes(hash.keys, 'foo')
14
+ result = HashUpdate.new(original: original, removes: %w(foo)).result
15
+ refute_includes(result.keys, 'foo')
16
16
 
17
- HashUpdate.new(adds: ['key', 'one, two ']).apply(hash)
18
- assert_equal(%w(one two), hash['key'])
17
+ result = HashUpdate.new(original: original, adds: ['key', 'one, two ']).result
18
+ assert_equal(%w(one two), result['key'])
19
19
 
20
- HashUpdate.new(updates: ['key', 'one, two, three ']).apply(hash)
21
- assert_equal(%w(one two three), hash['key'])
20
+ result = HashUpdate.new(original: original, updates: ['key', 'one, two, three ']).result
21
+ assert_equal(%w(one two three), result['key'])
22
22
  end
23
23
  end
24
24
  end
@@ -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
@@ -53,5 +53,11 @@ module Workarea
53
53
  t('workarea.admin.data_file_mailer.import_failure.errors')
54
54
  )
55
55
  end
56
+
57
+ def test_perform_with_missing_import
58
+ assert_raises Mongoid::Errors::DocumentNotFound do
59
+ ProcessImport.new.perform('foo')
60
+ end
61
+ end
56
62
  end
57
63
  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
@@ -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', '~> 0.17.0'
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.4.4'
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', '~> 5.0.1'
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'
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.9
4
+ version: 3.5.14
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-04-15 00:00:00.000000000 Z
11
+ date: 2020-06-25 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: 0.17.0
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: 0.17.0
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.4.4
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.4.4
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: 5.0.1
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: 5.0.1
754
+ version: 6.3.1
741
755
  - !ruby/object:Gem::Dependency
742
756
  name: jquery-livetype-rails
743
757
  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
@@ -1919,6 +1935,7 @@ files:
1919
1935
  - lib/workarea/ext/freedom_patches/dragonfly_job_fetch_url.rb
1920
1936
  - lib/workarea/ext/freedom_patches/float.rb
1921
1937
  - lib/workarea/ext/freedom_patches/global_id.rb
1938
+ - lib/workarea/ext/freedom_patches/i18n_js.rb
1922
1939
  - lib/workarea/ext/freedom_patches/money.rb
1923
1940
  - lib/workarea/ext/freedom_patches/mongoid_localized_defaults.rb
1924
1941
  - lib/workarea/ext/freedom_patches/mongoid_simple_tags.rb
@@ -1963,6 +1980,7 @@ files:
1963
1980
  - lib/workarea/ping_home_base.rb
1964
1981
  - lib/workarea/plugin.rb
1965
1982
  - lib/workarea/plugin/asset_appends_helper.rb
1983
+ - lib/workarea/queues_pauser.rb
1966
1984
  - lib/workarea/routes_constraints/redirect.rb
1967
1985
  - lib/workarea/routes_constraints/super_admin.rb
1968
1986
  - lib/workarea/scheduled_jobs.rb
@@ -2313,6 +2331,7 @@ files:
2313
2331
  - test/models/workarea/search/storefront/product/inventory_test.rb
2314
2332
  - test/models/workarea/search/storefront/product/pricing_test.rb
2315
2333
  - test/models/workarea/search/storefront/product/text_test.rb
2334
+ - test/models/workarea/search/storefront/product_releases_test.rb
2316
2335
  - test/models/workarea/search/storefront/product_test.rb
2317
2336
  - test/models/workarea/search/storefront_test.rb
2318
2337
  - test/models/workarea/segment/life_cycle_test.rb
@@ -2364,7 +2383,6 @@ files:
2364
2383
  - test/queries/workarea/pricing_override_params_test.rb
2365
2384
  - test/queries/workarea/product_primary_image_url_test.rb
2366
2385
  - test/queries/workarea/product_primary_navigation_test.rb
2367
- - test/queries/workarea/product_releases_test.rb
2368
2386
  - test/queries/workarea/recommendation/order_based_test.rb
2369
2387
  - test/queries/workarea/recommendation/product_based_test.rb
2370
2388
  - test/queries/workarea/recommendation/searches_test.rb
@@ -2425,6 +2443,7 @@ files:
2425
2443
  - test/services/workarea/direct_upload_test.rb
2426
2444
  - test/services/workarea/export_report_test.rb
2427
2445
  - test/services/workarea/hash_update_test.rb
2446
+ - test/services/workarea/index_release_schedule_previews_test.rb
2428
2447
  - test/services/workarea/inventory_adjustment_test.rb
2429
2448
  - test/services/workarea/login_test.rb
2430
2449
  - test/services/workarea/order_merge_test.rb
@@ -2457,6 +2476,7 @@ files:
2457
2476
  - test/workers/workarea/index_payment_transactions_test.rb
2458
2477
  - test/workers/workarea/index_product_rule_test.rb
2459
2478
  - test/workers/workarea/index_product_test.rb
2479
+ - test/workers/workarea/index_release_schedule_change_test.rb
2460
2480
  - test/workers/workarea/index_skus_test.rb
2461
2481
  - test/workers/workarea/keep_product_index_fresh_test.rb
2462
2482
  - 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