workarea-core 3.5.20 → 3.5.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/workarea/current_tracking.rb +3 -1
- data/app/models/workarea/configuration/params.rb +3 -1
- data/app/models/workarea/metrics/user.rb +18 -8
- data/app/models/workarea/release.rb +10 -3
- data/app/models/workarea/release/changeset.rb +27 -1
- data/app/models/workarea/search/admin.rb +7 -3
- data/app/models/workarea/search/admin/releasable.rb +3 -1
- data/app/models/workarea/search/admin/search_customization.rb +25 -0
- data/app/models/workarea/search/storefront.rb +1 -5
- data/app/models/workarea/search/storefront/product.rb +1 -14
- data/app/queries/workarea/product_releases.rb +1 -11
- data/app/queries/workarea/search/product_entries.rb +12 -6
- data/app/workers/workarea/build_release_undo_changesets.rb +23 -0
- data/app/workers/workarea/index_admin_search.rb +6 -1
- data/app/workers/workarea/update_email.rb +33 -0
- data/config/initializers/00_configuration.rb +1 -0
- data/config/initializers/05_scheduled_jobs.rb +1 -1
- data/lib/workarea.rb +10 -0
- data/lib/workarea/changelog.rake +1 -1
- data/lib/workarea/configuration.rb +4 -1
- data/lib/workarea/configuration/administrable/field.rb +1 -1
- data/lib/workarea/configuration/administrable_options.rb +2 -1
- data/lib/workarea/configuration/localized_active_fields.rb +1 -1
- data/lib/workarea/scheduled_jobs.rb +1 -1
- data/lib/workarea/version.rb +1 -1
- data/lib/workarea/warnings.rb +1 -1
- data/test/lib/workarea/configuration/administrable/field_test.rb +8 -0
- data/test/lib/workarea/scheduled_jobs_test.rb +1 -5
- data/test/models/workarea/configuration/params_test.rb +3 -0
- data/test/models/workarea/data_file/csv_test.rb +2 -1
- data/test/models/workarea/metrics/user_test.rb +55 -52
- data/test/models/workarea/releasable_active_test.rb +16 -8
- data/test/models/workarea/release/changeset_test.rb +17 -0
- data/test/models/workarea/search/admin/releasable_test.rb +14 -0
- data/test/workers/workarea/build_release_undo_changesets_test.rb +26 -0
- data/test/workers/workarea/index_admin_search_test.rb +21 -0
- data/test/workers/workarea/status_reporter_test.rb +3 -1
- data/test/workers/workarea/update_email_test.rb +39 -0
- data/workarea-core.gemspec +2 -2
- metadata +24 -15
- data/app/workers/workarea/update_payment_profile_email.rb +0 -22
- data/test/workers/workarea/update_payment_profile_email_test.rb +0 -27
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 9cf9f289653a43299ab536ddc3ec1604053f3c2369e8895ed41660cc948f4a0d
         | 
| 4 | 
            +
              data.tar.gz: a233ee0d02143bda5eb371d384fc5e69c34920cb9c666e489f00229a49c0554c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9fd77445de6a50cceaf70957f1a8b5bb9cc920a18ac26cd7ba88ec36d4d8fb547cd342fcf3145b9969ff40d76047476e9934f9f87dcadb1cb496a115d38f70ca
         | 
| 7 | 
            +
              data.tar.gz: b52b85609a5b1524ca88ba659847a8497826b2e3367246a3855f3f60f289d8dc924e7fc5e976219b761526ac3f564a0267fce8da28f478f2e9b313dc3ee6f9df
         | 
| @@ -27,7 +27,9 @@ module Workarea | |
| 27 27 | 
             
                    cookies.delete(:email)
         | 
| 28 28 | 
             
                  elsif email != cookies.signed[:email]
         | 
| 29 29 | 
             
                    unless impersonating?
         | 
| 30 | 
            -
                      Metrics::User | 
| 30 | 
            +
                      Metrics::User
         | 
| 31 | 
            +
                        .find_or_initialize_by(id: email)
         | 
| 32 | 
            +
                        .merge_views!(current_visit&.metrics)
         | 
| 31 33 | 
             
                    end
         | 
| 32 34 |  | 
| 33 35 | 
             
                    cookies.permanent.signed[:email] = email
         | 
| @@ -110,6 +110,8 @@ module Workarea | |
| 110 110 | 
             
                  end
         | 
| 111 111 |  | 
| 112 112 | 
             
                  def merge!(other)
         | 
| 113 | 
            +
                    return if other.blank?
         | 
| 114 | 
            +
             | 
| 113 115 | 
             
                    # To recalculate average_order_value
         | 
| 114 116 | 
             
                    self.orders += other.orders
         | 
| 115 117 | 
             
                    self.revenue += other.revenue
         | 
| @@ -132,14 +134,8 @@ module Workarea | |
| 132 134 | 
             
                    update['$max'] = { last_order_at: other.last_order_at.utc } if other.last_order_at.present?
         | 
| 133 135 |  | 
| 134 136 | 
             
                    self.class.collection.update_one({ _id: id }, update, upsert: true)
         | 
| 137 | 
            +
                    other.delete
         | 
| 135 138 |  | 
| 136 | 
            -
                    self.class.save_affinity(
         | 
| 137 | 
            -
                      id: id,
         | 
| 138 | 
            -
                      action: 'viewed',
         | 
| 139 | 
            -
                      product_ids: other.viewed.product_ids,
         | 
| 140 | 
            -
                      category_ids: other.viewed.category_ids,
         | 
| 141 | 
            -
                      search_ids: other.viewed.search_ids
         | 
| 142 | 
            -
                    )
         | 
| 143 139 | 
             
                    self.class.save_affinity(
         | 
| 144 140 | 
             
                      id: id,
         | 
| 145 141 | 
             
                      action: 'purchased',
         | 
| @@ -148,7 +144,21 @@ module Workarea | |
| 148 144 | 
             
                      search_ids: other.purchased.search_ids
         | 
| 149 145 | 
             
                    )
         | 
| 150 146 |  | 
| 151 | 
            -
                     | 
| 147 | 
            +
                    merge_views!(other)
         | 
| 148 | 
            +
                  end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                  def merge_views!(other)
         | 
| 151 | 
            +
                    return if other.blank?
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                    self.class.save_affinity(
         | 
| 154 | 
            +
                      id: id,
         | 
| 155 | 
            +
                      action: 'viewed',
         | 
| 156 | 
            +
                      product_ids: other.viewed.product_ids,
         | 
| 157 | 
            +
                      category_ids: other.viewed.category_ids,
         | 
| 158 | 
            +
                      search_ids: other.viewed.search_ids
         | 
| 159 | 
            +
                    )
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                    reload rescue self # save_affinity might not have actually persisted anything
         | 
| 152 162 | 
             
                  end
         | 
| 153 163 | 
             
                end
         | 
| 154 164 | 
             
              end
         | 
| @@ -13,7 +13,7 @@ module Workarea | |
| 13 13 | 
             
                field :undo_job_id, type: String # TODO deprecated, remove in v3.6
         | 
| 14 14 |  | 
| 15 15 | 
             
                has_many :changesets, class_name: 'Workarea::Release::Changeset'
         | 
| 16 | 
            -
                 | 
| 16 | 
            +
                has_many :undos, class_name: 'Workarea::Release', inverse_of: :undoes
         | 
| 17 17 | 
             
                belongs_to :undoes, class_name: 'Workarea::Release', inverse_of: :undo, optional: true
         | 
| 18 18 |  | 
| 19 19 | 
             
                index({ publish_at: 1 })
         | 
| @@ -129,6 +129,14 @@ module Workarea | |
| 129 129 | 
             
                  scoped.sort_by { |r| [r.publish_at, r.created_at] }
         | 
| 130 130 | 
             
                end
         | 
| 131 131 |  | 
| 132 | 
            +
                def self.schedule_affected_by_changesets(changesets)
         | 
| 133 | 
            +
                  changesets
         | 
| 134 | 
            +
                    .uniq(&:release)
         | 
| 135 | 
            +
                    .reject { |cs| cs.release.blank? }
         | 
| 136 | 
            +
                    .flat_map { |cs| [cs.release] + cs.release.scheduled_after }
         | 
| 137 | 
            +
                    .uniq
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 132 140 | 
             
                def as_current
         | 
| 133 141 | 
             
                  self.class.with_current(self) { yield }
         | 
| 134 142 | 
             
                end
         | 
| @@ -172,11 +180,10 @@ module Workarea | |
| 172 180 | 
             
                end
         | 
| 173 181 |  | 
| 174 182 | 
             
                def build_undo(attributes = {})
         | 
| 175 | 
            -
                  result =  | 
| 183 | 
            +
                  result = undos.build(attributes)
         | 
| 176 184 |  | 
| 177 185 | 
             
                  result.name ||= I18n.t('workarea.release.undo', name: name)
         | 
| 178 186 | 
             
                  result.tags = %w(undo) if result.tags.blank?
         | 
| 179 | 
            -
                  self.undo = result
         | 
| 180 187 |  | 
| 181 188 | 
             
                  result
         | 
| 182 189 | 
             
                end
         | 
| @@ -15,10 +15,36 @@ module Workarea | |
| 15 15 | 
             
                  belongs_to :release, class_name: 'Workarea::Release', index: true
         | 
| 16 16 | 
             
                  belongs_to :releasable, polymorphic: true, index: true, optional: true
         | 
| 17 17 |  | 
| 18 | 
            -
                  index( | 
| 18 | 
            +
                  index(
         | 
| 19 | 
            +
                    { 'document_path.type' => 1, 'document_path.document_id' => 1 },
         | 
| 20 | 
            +
                    { name: 'document_path' }
         | 
| 21 | 
            +
                  )
         | 
| 19 22 | 
             
                  index('changeset.product_ids' => 1)
         | 
| 20 23 | 
             
                  index('original.product_ids' => 1)
         | 
| 21 24 | 
             
                  index('releasable_type' => 1, 'releasable_id' => 1)
         | 
| 25 | 
            +
                  index(updated_at: 1)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  def self.latest(limit = Workarea.config.per_page)
         | 
| 28 | 
            +
                    order(updated_at: :desc).limit(limit)
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def self.summary(release_id)
         | 
| 32 | 
            +
                    collection.aggregate([
         | 
| 33 | 
            +
                      { '$match' => { 'release_id' => release_id } },
         | 
| 34 | 
            +
                      {
         | 
| 35 | 
            +
                        '$addFields' => {
         | 
| 36 | 
            +
                          'root' => { '$arrayElemAt' => ['$document_path', 0] }
         | 
| 37 | 
            +
                        }
         | 
| 38 | 
            +
                      },
         | 
| 39 | 
            +
                      {
         | 
| 40 | 
            +
                        '$group' => {
         | 
| 41 | 
            +
                          '_id' => '$root.type',
         | 
| 42 | 
            +
                          'count' => { '$sum' => 1 }
         | 
| 43 | 
            +
                        }
         | 
| 44 | 
            +
                      },
         | 
| 45 | 
            +
                      { '$sort' => { '_id' => 1 } }
         | 
| 46 | 
            +
                    ]).to_a
         | 
| 47 | 
            +
                  end
         | 
| 22 48 |  | 
| 23 49 | 
             
                  # Finds changeset by whether the passed document is in the document
         | 
| 24 50 | 
             
                  # path of the changeset. Useful for showing embedded changes in the
         | 
| @@ -38,7 +38,7 @@ module Workarea | |
| 38 38 | 
             
                    aggregation = search(query)['aggregations']['grouped_by_type']['type']
         | 
| 39 39 | 
             
                    aggregation['buckets']
         | 
| 40 40 | 
             
                      .reduce([]) { |m, b| m + b['top']['hits']['hits'] }
         | 
| 41 | 
            -
                      .sort_by { |r| [r['_source']['jump_to_position'], r['_score']] }
         | 
| 41 | 
            +
                      .sort_by { |r| [r['_source']['jump_to_position'] || 999, r['_score'] || 0] }
         | 
| 42 42 | 
             
                      .map do |result|
         | 
| 43 43 | 
             
                        {
         | 
| 44 44 | 
             
                          label: result['_source']['jump_to_text'],
         | 
| @@ -51,10 +51,14 @@ module Workarea | |
| 51 51 | 
             
                  end
         | 
| 52 52 |  | 
| 53 53 | 
             
                  def self.for(model)
         | 
| 54 | 
            +
                    find_for_model(model)
         | 
| 55 | 
            +
                  rescue NameError
         | 
| 56 | 
            +
                    find_for_model(model._root) rescue nil
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def self.find_for_model(model)
         | 
| 54 60 | 
             
                    subclass = model.model_name.singular_route_key.camelize
         | 
| 55 61 | 
             
                    "Workarea::Search::Admin::#{subclass}".constantize.new(model)
         | 
| 56 | 
            -
                  rescue NameError
         | 
| 57 | 
            -
                    nil
         | 
| 58 62 | 
             
                  end
         | 
| 59 63 |  | 
| 60 64 | 
             
                  # Allows subclass instances to specify whether they should be included in
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              module Search
         | 
| 3 | 
            +
                class Admin
         | 
| 4 | 
            +
                  class SearchCustomization < Search::Admin
         | 
| 5 | 
            +
                    include Admin::Releasable
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                    def type
         | 
| 8 | 
            +
                      'search_customization'
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    def search_text
         | 
| 12 | 
            +
                      model.name
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def jump_to_text
         | 
| 16 | 
            +
                      "#{model.id} - #{model.name}"
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    def jump_to_position
         | 
| 20 | 
            +
                      99
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -83,11 +83,7 @@ module Workarea | |
| 83 83 | 
             
                  end
         | 
| 84 84 |  | 
| 85 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
         | 
| 86 | 
            +
                    Release.schedule_affected_by_changesets(changesets)
         | 
| 91 87 | 
             
                  end
         | 
| 92 88 |  | 
| 93 89 | 
             
                  def as_document
         | 
| @@ -122,21 +122,8 @@ module Workarea | |
| 122 122 | 
             
                      ProductPrimaryImageUrl.new(model).path
         | 
| 123 123 | 
             
                    end
         | 
| 124 124 |  | 
| 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
         | 
| 132 | 
            -
                    #
         | 
| 133 | 
            -
                    # @return [Mongoid::Criteria]
         | 
| 134 | 
            -
                    #
         | 
| 135 125 | 
             
                    def changesets
         | 
| 136 | 
            -
                       | 
| 137 | 
            -
                      pricing.each { |ps| criteria.merge!(ps.changesets_with_children) }
         | 
| 138 | 
            -
                      criteria.merge!(FeaturedProducts.changesets(model.id))
         | 
| 139 | 
            -
                      criteria.includes(:release)
         | 
| 126 | 
            +
                      ProductReleases.new(model).changesets
         | 
| 140 127 | 
             
                    end
         | 
| 141 128 |  | 
| 142 129 | 
             
                    private
         | 
| @@ -1,10 +1,4 @@ | |
| 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 | 
            -
              #
         | 
| 8 2 | 
             
              class ProductReleases
         | 
| 9 3 | 
             
                attr_reader :product
         | 
| 10 4 |  | 
| @@ -13,11 +7,7 @@ module Workarea | |
| 13 7 | 
             
                end
         | 
| 14 8 |  | 
| 15 9 | 
             
                def releases
         | 
| 16 | 
            -
                  changesets
         | 
| 17 | 
            -
                    .uniq(&:release)
         | 
| 18 | 
            -
                    .reject { |cs| cs.release.blank? }
         | 
| 19 | 
            -
                    .flat_map { |cs| [cs.release] + cs.release.scheduled_after }
         | 
| 20 | 
            -
                    .uniq
         | 
| 10 | 
            +
                  Release.schedule_affected_by_changesets(changesets)
         | 
| 21 11 | 
             
                end
         | 
| 22 12 |  | 
| 23 13 | 
             
                # All {Releasable}s that could affect the product's Elasticsearch document
         | 
| @@ -18,17 +18,23 @@ module Workarea | |
| 18 18 |  | 
| 19 19 | 
             
                  def live_entries
         | 
| 20 20 | 
             
                    @live_entries ||= @products.reduce([]) do |memo, product|
         | 
| 21 | 
            -
                      memo +  | 
| 21 | 
            +
                      memo + live_entries_for(product)
         | 
| 22 22 | 
             
                    end
         | 
| 23 23 | 
             
                  end
         | 
| 24 24 |  | 
| 25 25 | 
             
                  def release_entries
         | 
| 26 | 
            -
                    @release_entries ||= @products.reduce([]) do | | 
| 27 | 
            -
                       | 
| 26 | 
            +
                    @release_entries ||= @products.reduce([]) do |memo, product|
         | 
| 27 | 
            +
                      memo + release_entries_for(product)
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def live_entries_for(product)
         | 
| 32 | 
            +
                    Array.wrap(index_entries_for(product.without_release))
         | 
| 33 | 
            +
                  end
         | 
| 28 34 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
                       | 
| 35 | 
            +
                  def release_entries_for(product)
         | 
| 36 | 
            +
                    ProductReleases.new(product).releases.reduce([]) do |memo, release|
         | 
| 37 | 
            +
                      memo + Array.wrap(index_entries_for(product.in_release(release)))
         | 
| 32 38 | 
             
                    end
         | 
| 33 39 | 
             
                  end
         | 
| 34 40 |  | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              class BuildReleaseUndoChangesets
         | 
| 3 | 
            +
                include Sidekiq::Worker
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def perform(undo_release_id, release_id)
         | 
| 6 | 
            +
                  release = Release.find(release_id)
         | 
| 7 | 
            +
                  undo_release = Release.find(undo_release_id)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  existing_changesets = undo_release.changesets.to_a
         | 
| 10 | 
            +
                  matching_changeset = ->(changeset, existing_changesets) do
         | 
| 11 | 
            +
                    existing_changesets.any? do |cs|
         | 
| 12 | 
            +
                      changeset.releasable_type == cs.releasable_type &&
         | 
| 13 | 
            +
                      changeset.releasable_id == cs.releasable_id
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  release.changesets.each_by(500) do |changeset|
         | 
| 18 | 
            +
                    next if matching_changeset.call(changeset, existing_changesets)
         | 
| 19 | 
            +
                    changeset.build_undo(release: undo_release).save!
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -9,7 +9,7 @@ module Workarea | |
| 9 9 | 
             
                  query_cache: true,
         | 
| 10 10 | 
             
                  enqueue_on: {
         | 
| 11 11 | 
             
                    ApplicationDocument => [:save, :touch, :destroy],
         | 
| 12 | 
            -
                    with: -> {  | 
| 12 | 
            +
                    with: -> { IndexAdminSearch.job_arguments(self) },
         | 
| 13 13 | 
             
                    ignore_if: -> { !IndexAdminSearch.should_enqueue?(self) }
         | 
| 14 14 | 
             
                  }
         | 
| 15 15 | 
             
                )
         | 
| @@ -19,6 +19,11 @@ module Workarea | |
| 19 19 | 
             
                  search_model.present? && search_model.should_be_indexed?
         | 
| 20 20 | 
             
                end
         | 
| 21 21 |  | 
| 22 | 
            +
                def self.job_arguments(model)
         | 
| 23 | 
            +
                  search_model = Search::Admin.for(model)
         | 
| 24 | 
            +
                  [search_model.model.class.name, search_model.model.id]
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 22 27 | 
             
                def self.perform(model)
         | 
| 23 28 | 
             
                  search_model = Search::Admin.for(model)
         | 
| 24 29 | 
             
                  return false if search_model.blank?
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              class UpdateEmail
         | 
| 3 | 
            +
                include Sidekiq::Worker
         | 
| 4 | 
            +
                include Sidekiq::CallbacksWorker
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                sidekiq_options(
         | 
| 7 | 
            +
                  enqueue_on: { User => :update, with: -> { [id, changes] } }
         | 
| 8 | 
            +
                )
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def perform(id, changes)
         | 
| 11 | 
            +
                  return unless changes['email'].present? && changes['email'].first.present?
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  old_email, new_email = changes['email']
         | 
| 14 | 
            +
                  update_payment_profile(id, old_email, new_email)
         | 
| 15 | 
            +
                  update_metrics(old_email, new_email)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def update_payment_profile(id, old_email, new_email)
         | 
| 19 | 
            +
                  user = User.find(id)
         | 
| 20 | 
            +
                  user.email = old_email # set old email so we lookup by old email value
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  Payment::Profile.update_email(PaymentReference.new(user), new_email)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def update_metrics(old_email, new_email)
         | 
| 26 | 
            +
                  old_metrics = Metrics::User.find(old_email) rescue nil
         | 
| 27 | 
            +
                  return if old_metrics.blank?
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  new_metrics = Metrics::User.find_or_initialize_by(id: new_email)
         | 
| 30 | 
            +
                  new_metrics.merge!(old_metrics)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -60,6 +60,7 @@ Workarea::Configuration.define_fields do | |
| 60 60 | 
             
                field 'Shipping Dimensions',
         | 
| 61 61 | 
             
                  type: :array,
         | 
| 62 62 | 
             
                  default: [1, 1, 1],
         | 
| 63 | 
            +
                  values_type: :integer,
         | 
| 63 64 | 
             
                  description: %(
         | 
| 64 65 | 
             
                    Default package dimensions to use for calculating shipping costs.
         | 
| 65 66 | 
             
                    It's recommended to set these to your average or standard box size when
         | 
    
        data/lib/workarea.rb
    CHANGED
    
    | @@ -182,6 +182,16 @@ module Workarea | |
| 182 182 | 
             
              def self.deprecation
         | 
| 183 183 | 
             
                @deprecation ||= ActiveSupport::Deprecation.new('3.6', 'Workarea')
         | 
| 184 184 | 
             
              end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              # Whether the app should skip connecting to external services on boot,
         | 
| 187 | 
            +
              # such as Mongo, Elasticsearch, or Redis. Note that this will break
         | 
| 188 | 
            +
              # functionality relying on these services.
         | 
| 189 | 
            +
              #
         | 
| 190 | 
            +
              # @return [Boolean]
         | 
| 191 | 
            +
              #
         | 
| 192 | 
            +
              def self.skip_services?
         | 
| 193 | 
            +
                !!(ENV['WORKAREA_SKIP_SERVICES'] =~ /true/)
         | 
| 194 | 
            +
              end
         | 
| 185 195 | 
             
            end
         | 
| 186 196 |  | 
| 187 197 | 
             
            require 'workarea/core'
         | 
    
        data/lib/workarea/changelog.rake
    CHANGED
    
    
| @@ -940,7 +940,10 @@ module Workarea | |
| 940 940 |  | 
| 941 941 | 
             
                  # Whether the app should skip connecting to external services on boot,
         | 
| 942 942 | 
             
                  # such as Mongo, Elasticsearch, or Redis.
         | 
| 943 | 
            -
                   | 
| 943 | 
            +
                  #
         | 
| 944 | 
            +
                  # @deprecated Use `Workarea.skip_services?` instead
         | 
| 945 | 
            +
                  #
         | 
| 946 | 
            +
                  config.skip_service_connections = Workarea.skip_services?
         | 
| 944 947 |  | 
| 945 948 | 
             
                  # This is a feature flag, which enables localized active fields. If you're
         | 
| 946 949 | 
             
                  # upgrading, you can set this to false to avoid having to do a MongoDB
         | 
| @@ -14,7 +14,7 @@ module Workarea | |
| 14 14 | 
             
                    return if Workarea.config.localized_active_fields
         | 
| 15 15 |  | 
| 16 16 | 
             
                    ::Mongoid.models.each do |klass|
         | 
| 17 | 
            -
                      if klass < Releasable
         | 
| 17 | 
            +
                      if klass < Releasable && klass.localized_fields['active'].present?
         | 
| 18 18 | 
             
                        klass.localized_fields.delete('active')
         | 
| 19 19 | 
             
                        klass.field(:active, type: Boolean, default: true, localize: false)
         | 
| 20 20 | 
             
                        klass.index(active: 1)
         | 
| @@ -5,7 +5,7 @@ module Workarea | |
| 5 5 | 
             
                # removing a previously scheduled job from initializers doesn't
         | 
| 6 6 | 
             
                # actually stop the job from being enqueued.
         | 
| 7 7 | 
             
                def self.clean
         | 
| 8 | 
            -
                  return if Workarea. | 
| 8 | 
            +
                  return if Workarea.skip_services?
         | 
| 9 9 |  | 
| 10 10 | 
             
                  Sidekiq::Cron::Job.all.each do |job|
         | 
| 11 11 | 
             
                    job.destroy unless const_defined?(job.klass)
         | 
    
        data/lib/workarea/version.rb
    CHANGED
    
    
    
        data/lib/workarea/warnings.rb
    CHANGED
    
    | @@ -26,7 +26,7 @@ find their preference. | |
| 26 26 |  | 
| 27 27 | 
             
                def check_mongo_notable_scan
         | 
| 28 28 | 
             
                  if (Rails.env.development? &&
         | 
| 29 | 
            -
                      !Workarea. | 
| 29 | 
            +
                      !Workarea.skip_services? &&
         | 
| 30 30 | 
             
                      Configuration::Mongoid.indexes_enforced?)
         | 
| 31 31 | 
             
                    warn <<~eos
         | 
| 32 32 | 
             
            **************************************************
         | 
| @@ -15,12 +15,8 @@ module Workarea | |
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 17 | 
             
                def test_redis_not_available
         | 
| 18 | 
            -
                   | 
| 19 | 
            -
                  Workarea.config.skip_service_connections = true
         | 
| 20 | 
            -
             | 
| 18 | 
            +
                  Workarea.stubs(skip_services?: true)
         | 
| 21 19 | 
             
                  assert_nil(ScheduledJobs.clean)
         | 
| 22 | 
            -
                ensure
         | 
| 23 | 
            -
                  Workarea.config.skip_service_connections = @_skip_services
         | 
| 24 20 | 
             
                end
         | 
| 25 21 | 
             
              end
         | 
| 26 22 | 
             
            end
         | 
| @@ -11,6 +11,7 @@ module Workarea | |
| 11 11 | 
             
                      field 'baz', type: :string, allow_blank: true
         | 
| 12 12 |  | 
| 13 13 | 
             
                      field 'foo_hash', type: :hash, values_type: :integer
         | 
| 14 | 
            +
                      field 'foo_array', type: :array, values_type: :integer
         | 
| 14 15 | 
             
                      field 'bar_array', type: :array
         | 
| 15 16 | 
             
                      field 'baz_duration', type: :duration
         | 
| 16 17 | 
             
                    end
         | 
| @@ -20,6 +21,7 @@ module Workarea | |
| 20 21 | 
             
                      bar: nil,
         | 
| 21 22 | 
             
                      baz: '',
         | 
| 22 23 | 
             
                      foo_hash: ['one', '1', 'two', '', '', ''],
         | 
| 24 | 
            +
                      foo_array: '1,2,3',
         | 
| 23 25 | 
             
                      bar_array: 'one, two, three',
         | 
| 24 26 | 
             
                      baz_duration: %w(20 minutes)
         | 
| 25 27 | 
             
                    }
         | 
| @@ -29,6 +31,7 @@ module Workarea | |
| 29 31 | 
             
                    assert_equal('test', result[:bar])
         | 
| 30 32 | 
             
                    assert_equal('', result[:baz])
         | 
| 31 33 | 
             
                    assert_equal({ 'one' => 1 }, result[:foo_hash])
         | 
| 34 | 
            +
                    assert_equal([1, 2, 3], result[:foo_array])
         | 
| 32 35 | 
             
                    assert_equal(%w(one two three), result[:bar_array])
         | 
| 33 36 | 
             
                    assert_equal(20.minutes, result[:baz_duration])
         | 
| 34 37 | 
             
                  end
         | 
| @@ -134,7 +134,7 @@ module Workarea | |
| 134 134 | 
             
                  def test_merging_metrics
         | 
| 135 135 | 
             
                    freeze_time
         | 
| 136 136 |  | 
| 137 | 
            -
                     | 
| 137 | 
            +
                    first = User.create!(
         | 
| 138 138 | 
             
                      first_order_at: 2.weeks.ago,
         | 
| 139 139 | 
             
                      last_order_at: 1.day.ago,
         | 
| 140 140 | 
             
                      orders: 2,
         | 
| @@ -147,41 +147,43 @@ module Workarea | |
| 147 147 | 
             
                      purchased: { product_ids: ['qoo'], category_ids: ['quo'], search_ids: ['qux'] }
         | 
| 148 148 | 
             
                    )
         | 
| 149 149 |  | 
| 150 | 
            -
                     | 
| 151 | 
            -
                     | 
| 152 | 
            -
                    assert_equal( | 
| 153 | 
            -
                    assert_equal( | 
| 154 | 
            -
                    assert_equal( | 
| 155 | 
            -
                    assert_equal( | 
| 156 | 
            -
                    assert_equal( | 
| 157 | 
            -
                    assert_equal( | 
| 158 | 
            -
                    assert_equal( | 
| 159 | 
            -
                    assert_equal( | 
| 160 | 
            -
                    assert_equal( | 
| 161 | 
            -
                    assert_equal([' | 
| 162 | 
            -
                    assert_equal([' | 
| 163 | 
            -
                    assert_equal([' | 
| 164 | 
            -
                    assert_equal([' | 
| 165 | 
            -
                    assert_equal([' | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
                     | 
| 169 | 
            -
                     | 
| 170 | 
            -
                    assert_equal(1 | 
| 171 | 
            -
                    assert_equal(2,  | 
| 172 | 
            -
                    assert_equal( | 
| 173 | 
            -
                    assert_equal( | 
| 174 | 
            -
                    assert_equal( | 
| 175 | 
            -
                    assert_equal( | 
| 176 | 
            -
                    assert_equal( | 
| 177 | 
            -
                    assert_equal( | 
| 178 | 
            -
                    assert_equal( | 
| 179 | 
            -
                    assert_equal([' | 
| 180 | 
            -
                    assert_equal([' | 
| 181 | 
            -
                    assert_equal([' | 
| 182 | 
            -
                    assert_equal([' | 
| 183 | 
            -
             | 
| 184 | 
            -
                     | 
| 150 | 
            +
                    first.merge!(User.new)
         | 
| 151 | 
            +
                    first.reload
         | 
| 152 | 
            +
                    assert_equal(1, Metrics::User.count)
         | 
| 153 | 
            +
                    assert_equal(2.weeks.ago, first.first_order_at)
         | 
| 154 | 
            +
                    assert_equal(1.day.ago, first.last_order_at)
         | 
| 155 | 
            +
                    assert_equal(2, first.orders)
         | 
| 156 | 
            +
                    assert_equal(100, first.revenue)
         | 
| 157 | 
            +
                    assert_equal(-10, first.discounts)
         | 
| 158 | 
            +
                    assert_equal(50, first.average_order_value)
         | 
| 159 | 
            +
                    assert_equal(1, first.cancellations)
         | 
| 160 | 
            +
                    assert_equal(-20, first.refund)
         | 
| 161 | 
            +
                    assert_equal(['foo'], first.viewed.product_ids)
         | 
| 162 | 
            +
                    assert_equal(['bar'], first.viewed.category_ids)
         | 
| 163 | 
            +
                    assert_equal(['baz'], first.viewed.search_ids)
         | 
| 164 | 
            +
                    assert_equal(['qoo'], first.purchased.product_ids)
         | 
| 165 | 
            +
                    assert_equal(['quo'], first.purchased.category_ids)
         | 
| 166 | 
            +
                    assert_equal(['qux'], first.purchased.search_ids)
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                    second = User.create!(id: 'foo').tap { |u| u.merge!(first) }
         | 
| 169 | 
            +
                    second.reload
         | 
| 170 | 
            +
                    assert_equal(1, Metrics::User.count)
         | 
| 171 | 
            +
                    assert_equal(2.weeks.ago, second.first_order_at)
         | 
| 172 | 
            +
                    assert_equal(1.day.ago, second.last_order_at)
         | 
| 173 | 
            +
                    assert_equal(2, second.orders)
         | 
| 174 | 
            +
                    assert_equal(100, second.revenue)
         | 
| 175 | 
            +
                    assert_equal(-10, second.discounts)
         | 
| 176 | 
            +
                    assert_equal(50, second.average_order_value)
         | 
| 177 | 
            +
                    assert_equal(1, second.cancellations)
         | 
| 178 | 
            +
                    assert_equal(-20, second.refund)
         | 
| 179 | 
            +
                    assert_equal(['foo'], second.viewed.product_ids)
         | 
| 180 | 
            +
                    assert_equal(['bar'], second.viewed.category_ids)
         | 
| 181 | 
            +
                    assert_equal(['baz'], second.viewed.search_ids)
         | 
| 182 | 
            +
                    assert_equal(['qoo'], second.purchased.product_ids)
         | 
| 183 | 
            +
                    assert_equal(['quo'], second.purchased.category_ids)
         | 
| 184 | 
            +
                    assert_equal(['qux'], second.purchased.search_ids)
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                    third = User.create!(
         | 
| 185 187 | 
             
                      first_order_at: 3.weeks.ago,
         | 
| 186 188 | 
             
                      last_order_at: 3.weeks.ago,
         | 
| 187 189 | 
             
                      orders: 2,
         | 
| @@ -191,22 +193,23 @@ module Workarea | |
| 191 193 | 
             
                      purchased: { product_ids: ['four'], category_ids: ['five'], search_ids: ['six'] }
         | 
| 192 194 | 
             
                    )
         | 
| 193 195 |  | 
| 194 | 
            -
                     | 
| 195 | 
            -
                     | 
| 196 | 
            -
                    assert_equal( | 
| 197 | 
            -
                    assert_equal( | 
| 198 | 
            -
                    assert_equal( | 
| 199 | 
            -
                    assert_equal( | 
| 200 | 
            -
                    assert_equal( | 
| 201 | 
            -
                    assert_equal( | 
| 202 | 
            -
                    assert_equal( | 
| 203 | 
            -
                    assert_equal( | 
| 204 | 
            -
                    assert_equal( | 
| 205 | 
            -
                    assert_equal(%w( | 
| 206 | 
            -
                    assert_equal(%w( | 
| 207 | 
            -
                    assert_equal(%w( | 
| 208 | 
            -
                    assert_equal(%w( | 
| 209 | 
            -
                    assert_equal(%w( | 
| 196 | 
            +
                    third.merge!(second)
         | 
| 197 | 
            +
                    third.reload
         | 
| 198 | 
            +
                    assert_equal(1, Metrics::User.count)
         | 
| 199 | 
            +
                    assert_equal(3.weeks.ago, third.first_order_at)
         | 
| 200 | 
            +
                    assert_equal(1.day.ago, third.last_order_at)
         | 
| 201 | 
            +
                    assert_equal(4, third.orders)
         | 
| 202 | 
            +
                    assert_equal(220, third.revenue)
         | 
| 203 | 
            +
                    assert_equal(-10, third.discounts)
         | 
| 204 | 
            +
                    assert_equal(55, third.average_order_value)
         | 
| 205 | 
            +
                    assert_equal(1, third.cancellations)
         | 
| 206 | 
            +
                    assert_equal(-20, third.refund)
         | 
| 207 | 
            +
                    assert_equal(%w(one foo), third.viewed.product_ids)
         | 
| 208 | 
            +
                    assert_equal(%w(two bar), third.viewed.category_ids)
         | 
| 209 | 
            +
                    assert_equal(%w(three baz), third.viewed.search_ids)
         | 
| 210 | 
            +
                    assert_equal(%w(four qoo), third.purchased.product_ids)
         | 
| 211 | 
            +
                    assert_equal(%w(five quo), third.purchased.category_ids)
         | 
| 212 | 
            +
                    assert_equal(%w(six qux), third.purchased.search_ids)
         | 
| 210 213 | 
             
                  end
         | 
| 211 214 | 
             
                end
         | 
| 212 215 | 
             
              end
         | 
| @@ -35,6 +35,14 @@ module Workarea | |
| 35 35 | 
             
                  @release = create_release
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 | 
            +
                def active?(changeset)
         | 
| 39 | 
            +
                  if Workarea.config.localized_active_fields
         | 
| 40 | 
            +
                    changeset['active'][I18n.locale.to_s]
         | 
| 41 | 
            +
                  else
         | 
| 42 | 
            +
                    changeset['active']
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 38 46 | 
             
                def test_save_can_schedule_activation
         | 
| 39 47 | 
             
                  model = Foo.create!(
         | 
| 40 48 | 
             
                    name: 'Test',
         | 
| @@ -48,9 +56,9 @@ module Workarea | |
| 48 56 | 
             
                  assert_equal(1, model.changesets.length)
         | 
| 49 57 | 
             
                  assert_equal(@release.id, model.changesets.first.release_id)
         | 
| 50 58 | 
             
                  assert_equal(1, model.changesets.first.changeset.size)
         | 
| 51 | 
            -
                  assert(model.changesets.first.changeset | 
| 59 | 
            +
                  assert(active?(model.changesets.first.changeset))
         | 
| 52 60 | 
             
                  assert_equal(1, model.changesets.first.original.size)
         | 
| 53 | 
            -
                  refute(model.changesets.first.original | 
| 61 | 
            +
                  refute(active?(model.changesets.first.original))
         | 
| 54 62 | 
             
                end
         | 
| 55 63 |  | 
| 56 64 | 
             
                def test_save_can_schedule_activation_for_an_embedded_document
         | 
| @@ -74,17 +82,17 @@ module Workarea | |
| 74 82 | 
             
                  assert_equal(1, embedded_1.changesets.length)
         | 
| 75 83 | 
             
                  assert_equal(@release.id, embedded_1.changesets.first.release_id)
         | 
| 76 84 | 
             
                  assert_equal(1, embedded_1.changesets.first.changeset.size)
         | 
| 77 | 
            -
                  assert(embedded_1.changesets.first.changeset | 
| 85 | 
            +
                  assert(active?(embedded_1.changesets.first.changeset))
         | 
| 78 86 | 
             
                  assert_equal(1, embedded_1.changesets.first.original.size)
         | 
| 79 | 
            -
                  refute(embedded_1.changesets.first.original | 
| 87 | 
            +
                  refute(active?(embedded_1.changesets.first.original))
         | 
| 80 88 |  | 
| 81 89 | 
             
                  refute(embedded_2.active)
         | 
| 82 90 | 
             
                  assert_equal(1, embedded_2.changesets.length)
         | 
| 83 91 | 
             
                  assert_equal(@release.id, embedded_2.changesets.first.release_id)
         | 
| 84 92 | 
             
                  assert_equal(1, embedded_2.changesets.first.changeset.size)
         | 
| 85 | 
            -
                  assert(embedded_2.changesets.first.changeset | 
| 93 | 
            +
                  assert(active?(embedded_2.changesets.first.changeset))
         | 
| 86 94 | 
             
                  assert_equal(1, embedded_2.changesets.first.original.size)
         | 
| 87 | 
            -
                  refute(embedded_2.changesets.first.original | 
| 95 | 
            +
                  refute(active?(embedded_2.changesets.first.original))
         | 
| 88 96 | 
             
                end
         | 
| 89 97 |  | 
| 90 98 | 
             
                def test_creating_and_activating_embedded
         | 
| @@ -104,9 +112,9 @@ module Workarea | |
| 104 112 | 
             
                  assert_equal(1, embedded.changesets.length)
         | 
| 105 113 | 
             
                  assert_equal(@release.id, embedded.changesets.first.release_id)
         | 
| 106 114 | 
             
                  assert_equal(1, embedded.changesets.first.changeset.size)
         | 
| 107 | 
            -
                  assert(embedded.changesets.first.changeset | 
| 115 | 
            +
                  assert(active?(embedded.changesets.first.changeset))
         | 
| 108 116 | 
             
                  assert_equal(1, embedded.changesets.first.original.size)
         | 
| 109 | 
            -
                  refute(embedded.changesets.first.original | 
| 117 | 
            +
                  refute(active?(embedded.changesets.first.original))
         | 
| 110 118 | 
             
                  assert(embedded.changesets.first.document_path.present?)
         | 
| 111 119 | 
             
                end
         | 
| 112 120 | 
             
              end
         | 
| @@ -3,6 +3,23 @@ require 'test_helper' | |
| 3 3 | 
             
            module Workarea
         | 
| 4 4 | 
             
              class Release
         | 
| 5 5 | 
             
                class ChangesetTest < TestCase
         | 
| 6 | 
            +
                  def test_summary
         | 
| 7 | 
            +
                    release = create_release
         | 
| 8 | 
            +
                    product_one = create_product(id: 'PROD1')
         | 
| 9 | 
            +
                    product_two = create_product(id: 'PROD2')
         | 
| 10 | 
            +
                    page = create_page
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    release.as_current do
         | 
| 13 | 
            +
                      product_one.variants.first.update!(details: { 'Color' => 'Orange' })
         | 
| 14 | 
            +
                      product_two.update!(name: 'Test Product Changed')
         | 
| 15 | 
            +
                      page.update!(name: 'Test Page Changed')
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    summary = Changeset.summary(release.id)
         | 
| 19 | 
            +
                    assert_includes(summary, { '_id' => 'Workarea::Catalog::Product', 'count' => 2 })
         | 
| 20 | 
            +
                    assert_includes(summary, { '_id' => 'Workarea::Content::Page', 'count' => 1 })
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 6 23 | 
             
                  def test_build_undo
         | 
| 7 24 | 
             
                    releasable = create_page(name: 'Foo')
         | 
| 8 25 | 
             
                    release = create_release
         | 
| @@ -28,6 +28,20 @@ module Workarea | |
| 28 28 | 
             
                      assert_includes(search_model.facets[:upcoming_changes], release_two.id)
         | 
| 29 29 | 
             
                      refute_includes(search_model.facets[:upcoming_changes], release_three.id)
         | 
| 30 30 | 
             
                    end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    def test_upcoming_changes
         | 
| 33 | 
            +
                      release_one = create_release
         | 
| 34 | 
            +
                      release_two = create_release
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      product = create_product
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                      release_one.as_current { product.update!(name: 'Changed Name') }
         | 
| 39 | 
            +
                      release_two.as_current { product.variants.first.update!(name: 'Changed Name') }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                      search_model = Foo.new(product)
         | 
| 42 | 
            +
                      assert_includes(search_model.facets[:upcoming_changes], release_one.id)
         | 
| 43 | 
            +
                      assert_includes(search_model.facets[:upcoming_changes], release_two.id)
         | 
| 44 | 
            +
                    end
         | 
| 31 45 | 
             
                  end
         | 
| 32 46 | 
             
                end
         | 
| 33 47 | 
             
              end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Workarea
         | 
| 4 | 
            +
              class BuildReleaseUndoChangesetsTest < TestCase
         | 
| 5 | 
            +
                def test_perform
         | 
| 6 | 
            +
                  releasable_one = create_page(name: 'Foo')
         | 
| 7 | 
            +
                  releasable_two = create_page(name: 'Bar')
         | 
| 8 | 
            +
                  release = create_release
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  release.as_current do
         | 
| 11 | 
            +
                    releasable_one.update!(name: 'Changed Foo')
         | 
| 12 | 
            +
                    releasable_two.update!(name: 'Changed Bar')
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  undo_release = release.build_undo.tap(&:save!)
         | 
| 16 | 
            +
                  release.changesets.first.build_undo(release: undo_release).save!
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  BuildReleaseUndoChangesets.new.perform(undo_release.id, release.id)
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  undo_release.reload
         | 
| 21 | 
            +
                  assert_equal(2, undo_release.changesets.count)
         | 
| 22 | 
            +
                  assert_includes(undo_release.changesets.map(&:releasable), releasable_one)
         | 
| 23 | 
            +
                  assert_includes(undo_release.changesets.map(&:releasable), releasable_two)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -6,5 +6,26 @@ module Workarea | |
| 6 6 | 
             
                  refute(IndexAdminSearch.should_enqueue?(create_order))
         | 
| 7 7 | 
             
                  assert(IndexAdminSearch.should_enqueue?(create_placed_order))
         | 
| 8 8 | 
             
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def test_enqueuing_embedded_documents
         | 
| 11 | 
            +
                  content = create_content
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  Sidekiq::Testing.fake!
         | 
| 14 | 
            +
                  IndexAdminSearch.drain
         | 
| 15 | 
            +
                  Sidekiq::Callbacks.async(IndexAdminSearch)
         | 
| 16 | 
            +
                  Sidekiq::Callbacks.enable(IndexAdminSearch)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  assert_difference 'IndexAdminSearch.jobs.size', 1 do
         | 
| 19 | 
            +
                    content.blocks.create!(type: :html)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  args = IndexAdminSearch.jobs.first['args']
         | 
| 23 | 
            +
                  assert_equal(Content.name, args.first)
         | 
| 24 | 
            +
                  assert_equal(content.id.to_s, args.second)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                ensure
         | 
| 27 | 
            +
                  IndexAdminSearch.drain
         | 
| 28 | 
            +
                  Sidekiq::Testing.inline!
         | 
| 29 | 
            +
                end
         | 
| 9 30 | 
             
              end
         | 
| 10 31 | 
             
            end
         | 
| @@ -12,8 +12,10 @@ module Workarea | |
| 12 12 |  | 
| 13 13 | 
             
                  StatusReporter.new.perform
         | 
| 14 14 |  | 
| 15 | 
            -
                   | 
| 15 | 
            +
                  assert_equal(2, ActionMailer::Base.deliveries.count)
         | 
| 16 | 
            +
             | 
| 16 17 | 
             
                  delivery_emails = ActionMailer::Base.deliveries.map(&:to).flatten
         | 
| 18 | 
            +
             | 
| 17 19 | 
             
                  assert(delivery_emails.include?('foo@workarea.com'))
         | 
| 18 20 | 
             
                  assert(delivery_emails.include?('bar@workarea.com'))
         | 
| 19 21 | 
             
                end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Workarea
         | 
| 4 | 
            +
              class UpdateEmailTest < TestCase
         | 
| 5 | 
            +
                def test_updating_payment_profile
         | 
| 6 | 
            +
                  user = create_user(email: 'user@workarea.com')
         | 
| 7 | 
            +
                  profile = Payment::Profile.lookup(PaymentReference.new(user))
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  UpdateEmail.new.perform(user.id.to_s, 'email' => [nil, 'user@workarea.com'])
         | 
| 10 | 
            +
                  assert_equal(profile.reload.email, 'user@workarea.com')
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  UpdateEmail.new.perform(
         | 
| 13 | 
            +
                    user.id.to_s,
         | 
| 14 | 
            +
                    'email' => ['user@workarea.com', 'test@workarea.com']
         | 
| 15 | 
            +
                  )
         | 
| 16 | 
            +
                  assert_equal(profile.reload.email, 'test@workarea.com')
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def test_updating_metrics
         | 
| 20 | 
            +
                  user = create_user(email: 'user@workarea.com')
         | 
| 21 | 
            +
                  old_metrics = Metrics::User.find_or_initialize_by(id: 'user@workarea.com')
         | 
| 22 | 
            +
                  old_metrics.update!(orders: 3)
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  UpdateEmail.new.perform(user.id.to_s, 'email' => [nil, 'user@workarea.com'])
         | 
| 25 | 
            +
                  assert_equal(1, Metrics::User.count)
         | 
| 26 | 
            +
                  assert_equal(3, old_metrics.reload.orders)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  new_metrics = Metrics::User.create!(id: 'test@workarea.com', orders: 1)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  UpdateEmail.new.perform(
         | 
| 31 | 
            +
                    user.id.to_s,
         | 
| 32 | 
            +
                    'email' => ['user@workarea.com', 'test@workarea.com']
         | 
| 33 | 
            +
                  )
         | 
| 34 | 
            +
                  assert_equal(1, Metrics::User.count)
         | 
| 35 | 
            +
                  assert_raises(Mongoid::Errors::DocumentNotFound) { old_metrics.reload }
         | 
| 36 | 
            +
                  assert_equal(4, new_metrics.reload.orders)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
    
        data/workarea-core.gemspec
    CHANGED
    
    | @@ -59,7 +59,7 @@ Gem::Specification.new do |s| | |
| 59 59 | 
             
              s.add_dependency 'i18n-js', '~> 3.2.1'
         | 
| 60 60 | 
             
              s.add_dependency 'local_time', '~> 1.0.3'
         | 
| 61 61 | 
             
              s.add_dependency 'lodash-rails', '~> 4.17.4'
         | 
| 62 | 
            -
              s.add_dependency 'jquery-rails', '~> 4. | 
| 62 | 
            +
              s.add_dependency 'jquery-rails', '~> 4.4.0'
         | 
| 63 63 | 
             
              s.add_dependency 'jquery-ui-rails', '~> 6.0.1'
         | 
| 64 64 | 
             
              s.add_dependency 'tooltipster-rails', '~> 4.1.2'
         | 
| 65 65 | 
             
              s.add_dependency 'chart-js-rails', '~> 0.0.9' # TODO remove v4
         | 
| @@ -68,7 +68,7 @@ Gem::Specification.new do |s| | |
| 68 68 | 
             
              s.add_dependency 'wysihtml-rails', '~> 0.6.0.beta2'
         | 
| 69 69 | 
             
              s.add_dependency 'rack-attack', '~> 6.3.1'
         | 
| 70 70 | 
             
              s.add_dependency 'jquery-livetype-rails', '~> 0.1.0' # TODO remove v4
         | 
| 71 | 
            -
              s.add_dependency 'redcarpet', '~> 3. | 
| 71 | 
            +
              s.add_dependency 'redcarpet', '~> 3.5.1', '>= 3.5.1'
         | 
| 72 72 | 
             
              s.add_dependency 'jquery-unique-clone-rails', '~> 1.0.0'
         | 
| 73 73 | 
             
              s.add_dependency 'avalanche-rails', '~> 1.2.0'
         | 
| 74 74 | 
             
              s.add_dependency 'inline_svg', '~> 1.3.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. | 
| 4 | 
            +
              version: 3.5.26
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Ben Crouse
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-01-20 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -646,14 +646,14 @@ dependencies: | |
| 646 646 | 
             
                requirements:
         | 
| 647 647 | 
             
                - - "~>"
         | 
| 648 648 | 
             
                  - !ruby/object:Gem::Version
         | 
| 649 | 
            -
                    version: 4. | 
| 649 | 
            +
                    version: 4.4.0
         | 
| 650 650 | 
             
              type: :runtime
         | 
| 651 651 | 
             
              prerelease: false
         | 
| 652 652 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 653 653 | 
             
                requirements:
         | 
| 654 654 | 
             
                - - "~>"
         | 
| 655 655 | 
             
                  - !ruby/object:Gem::Version
         | 
| 656 | 
            -
                    version: 4. | 
| 656 | 
            +
                    version: 4.4.0
         | 
| 657 657 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 658 658 | 
             
              name: jquery-ui-rails
         | 
| 659 659 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -772,14 +772,20 @@ dependencies: | |
| 772 772 | 
             
                requirements:
         | 
| 773 773 | 
             
                - - "~>"
         | 
| 774 774 | 
             
                  - !ruby/object:Gem::Version
         | 
| 775 | 
            -
                    version: 3. | 
| 775 | 
            +
                    version: 3.5.1
         | 
| 776 | 
            +
                - - ">="
         | 
| 777 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 778 | 
            +
                    version: 3.5.1
         | 
| 776 779 | 
             
              type: :runtime
         | 
| 777 780 | 
             
              prerelease: false
         | 
| 778 781 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 779 782 | 
             
                requirements:
         | 
| 780 783 | 
             
                - - "~>"
         | 
| 781 784 | 
             
                  - !ruby/object:Gem::Version
         | 
| 782 | 
            -
                    version: 3. | 
| 785 | 
            +
                    version: 3.5.1
         | 
| 786 | 
            +
                - - ">="
         | 
| 787 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 788 | 
            +
                    version: 3.5.1
         | 
| 783 789 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 784 790 | 
             
              name: jquery-unique-clone-rails
         | 
| 785 791 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -910,22 +916,22 @@ dependencies: | |
| 910 916 | 
             
              name: minitest
         | 
| 911 917 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 912 918 | 
             
                requirements:
         | 
| 913 | 
            -
                - - ">="
         | 
| 914 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 915 | 
            -
                    version: 5.10.1
         | 
| 916 919 | 
             
                - - "~>"
         | 
| 917 920 | 
             
                  - !ruby/object:Gem::Version
         | 
| 918 921 | 
             
                    version: 5.10.3
         | 
| 922 | 
            +
                - - ">="
         | 
| 923 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 924 | 
            +
                    version: 5.10.1
         | 
| 919 925 | 
             
              type: :runtime
         | 
| 920 926 | 
             
              prerelease: false
         | 
| 921 927 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 922 928 | 
             
                requirements:
         | 
| 923 | 
            -
                - - ">="
         | 
| 924 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 925 | 
            -
                    version: 5.10.1
         | 
| 926 929 | 
             
                - - "~>"
         | 
| 927 930 | 
             
                  - !ruby/object:Gem::Version
         | 
| 928 931 | 
             
                    version: 5.10.3
         | 
| 932 | 
            +
                - - ">="
         | 
| 933 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 934 | 
            +
                    version: 5.10.1
         | 
| 929 935 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 930 936 | 
             
              name: countries
         | 
| 931 937 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -1532,6 +1538,7 @@ files: | |
| 1532 1538 | 
             
            - app/models/workarea/search/admin/pricing_sku.rb
         | 
| 1533 1539 | 
             
            - app/models/workarea/search/admin/releasable.rb
         | 
| 1534 1540 | 
             
            - app/models/workarea/search/admin/release.rb
         | 
| 1541 | 
            +
            - app/models/workarea/search/admin/search_customization.rb
         | 
| 1535 1542 | 
             
            - app/models/workarea/search/admin/segment.rb
         | 
| 1536 1543 | 
             
            - app/models/workarea/search/admin/user.rb
         | 
| 1537 1544 | 
             
            - app/models/workarea/search/customization.rb
         | 
| @@ -1749,6 +1756,7 @@ files: | |
| 1749 1756 | 
             
            - app/view_models/workarea/shipping_carrier_view_model.rb
         | 
| 1750 1757 | 
             
            - app/workers/sidekiq/callbacks.rb
         | 
| 1751 1758 | 
             
            - app/workers/sidekiq/callbacks_worker.rb
         | 
| 1759 | 
            +
            - app/workers/workarea/build_release_undo_changesets.rb
         | 
| 1752 1760 | 
             
            - app/workers/workarea/bulk_index_admin.rb
         | 
| 1753 1761 | 
             
            - app/workers/workarea/bulk_index_products.rb
         | 
| 1754 1762 | 
             
            - app/workers/workarea/bulk_index_searches.rb
         | 
| @@ -1795,7 +1803,7 @@ files: | |
| 1795 1803 | 
             
            - app/workers/workarea/status_reporter.rb
         | 
| 1796 1804 | 
             
            - app/workers/workarea/synchronize_user_metrics.rb
         | 
| 1797 1805 | 
             
            - app/workers/workarea/update_elasticsearch_settings.rb
         | 
| 1798 | 
            -
            - app/workers/workarea/ | 
| 1806 | 
            +
            - app/workers/workarea/update_email.rb
         | 
| 1799 1807 | 
             
            - app/workers/workarea/verify_scheduled_releases.rb
         | 
| 1800 1808 | 
             
            - bin/rails
         | 
| 1801 1809 | 
             
            - config/i18n-js.yml
         | 
| @@ -2466,6 +2474,7 @@ files: | |
| 2466 2474 | 
             
            - test/view_models/workarea/shipping_carrier_view_model_test.rb
         | 
| 2467 2475 | 
             
            - test/workarea_test.rb
         | 
| 2468 2476 | 
             
            - test/workers/sidekiq/callbacks_test.rb
         | 
| 2477 | 
            +
            - test/workers/workarea/build_release_undo_changesets_test.rb
         | 
| 2469 2478 | 
             
            - test/workers/workarea/bulk_index_admin_test.rb
         | 
| 2470 2479 | 
             
            - test/workers/workarea/bulk_index_products_test.rb
         | 
| 2471 2480 | 
             
            - test/workers/workarea/bulk_index_searches_test.rb
         | 
| @@ -2499,7 +2508,7 @@ files: | |
| 2499 2508 | 
             
            - test/workers/workarea/send_refund_email_test.rb
         | 
| 2500 2509 | 
             
            - test/workers/workarea/status_reporter_test.rb
         | 
| 2501 2510 | 
             
            - test/workers/workarea/synchronize_user_metrics_test.rb
         | 
| 2502 | 
            -
            - test/workers/workarea/ | 
| 2511 | 
            +
            - test/workers/workarea/update_email_test.rb
         | 
| 2503 2512 | 
             
            - test/workers/workarea/verify_scheduled_releases_test.rb
         | 
| 2504 2513 | 
             
            - vendor/active_shipping/.gitignore
         | 
| 2505 2514 | 
             
            - vendor/active_shipping/.travis.yml
         | 
| @@ -2747,7 +2756,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 2747 2756 | 
             
                - !ruby/object:Gem::Version
         | 
| 2748 2757 | 
             
                  version: '0'
         | 
| 2749 2758 | 
             
            requirements: []
         | 
| 2750 | 
            -
            rubygems_version: 3. | 
| 2759 | 
            +
            rubygems_version: 3.2.3
         | 
| 2751 2760 | 
             
            signing_key: 
         | 
| 2752 2761 | 
             
            specification_version: 4
         | 
| 2753 2762 | 
             
            summary: Core of the Workarea Commerce Platform
         | 
| @@ -1,22 +0,0 @@ | |
| 1 | 
            -
            module Workarea
         | 
| 2 | 
            -
              class UpdatePaymentProfileEmail
         | 
| 3 | 
            -
                include Sidekiq::Worker
         | 
| 4 | 
            -
                include Sidekiq::CallbacksWorker
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                sidekiq_options(
         | 
| 7 | 
            -
                  enqueue_on: { User => :update, with: -> { [id, changes] } }
         | 
| 8 | 
            -
                )
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                def perform(id, changes)
         | 
| 11 | 
            -
                  if changes['email'].present? && changes['email'].first.present?
         | 
| 12 | 
            -
                    old_email = changes['email'].first
         | 
| 13 | 
            -
                    new_email = changes['email'].last
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                    user = User.find(id)
         | 
| 16 | 
            -
                    user.email = old_email # set old email so we lookup by old email value
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    Payment::Profile.update_email(PaymentReference.new(user), new_email)
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
              end
         | 
| 22 | 
            -
            end
         | 
| @@ -1,27 +0,0 @@ | |
| 1 | 
            -
            require 'test_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Workarea
         | 
| 4 | 
            -
              class UpdatePaymentProfileEmailTest < Workarea::TestCase
         | 
| 5 | 
            -
                setup do
         | 
| 6 | 
            -
                  @user = create_user(email: 'user@workarea.com')
         | 
| 7 | 
            -
                  @profile = Payment::Profile.lookup(PaymentReference.new(@user))
         | 
| 8 | 
            -
                  @worker = UpdatePaymentProfileEmail.new
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                def test_updating_payment_profile_email_address
         | 
| 12 | 
            -
                  @worker.perform(
         | 
| 13 | 
            -
                    @user.id.to_s,
         | 
| 14 | 
            -
                    'email' => ['user@workarea.com', 'test@workarea.com']
         | 
| 15 | 
            -
                  )
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                  @profile.reload
         | 
| 18 | 
            -
                  assert_equal(@profile.email, 'test@workarea.com')
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                def test_skipping_update_if_email_change_is_nil
         | 
| 22 | 
            -
                  @worker.perform(@user.id.to_s, 'email' => [nil, 'user@workarea.com'])
         | 
| 23 | 
            -
                  @profile.reload
         | 
| 24 | 
            -
                  assert_equal(@profile.email, 'user@workarea.com')
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
              end
         | 
| 27 | 
            -
            end
         |