diff --git a/core/app/assets/javascripts/workarea/core/templates/ui_menu_item.jst.ejs b/core/app/assets/javascripts/workarea/core/templates/ui_menu_item.jst.ejs deleted file mode 100644 index a6fad07ba3..0000000000 --- a/core/app/assets/javascripts/workarea/core/templates/ui_menu_item.jst.ejs +++ /dev/null @@ -1,10 +0,0 @@ -<% -throw new Error( - 'workarea/core/templates/ui_menu_item.jst.ejs: this template has ' + - 'moved from core into both the admin and storefront, respectively. ' + - 'Please adjust your overridden admin and/or storefront manifests to \n\n' + - 'Find: "workarea/core/templates/ui_menu_item"\n' + - 'Replace with either: "workarea/admin/templates/ui_menu_item" or\n' + - ' "workarea/storefront/templates/ui_menu_item"' -); -%> diff --git a/core/app/queries/workarea/search/search_suggestions.rb b/core/app/queries/workarea/search/search_suggestions.rb deleted file mode 100644 index 01ad7c2570..0000000000 --- a/core/app/queries/workarea/search/search_suggestions.rb +++ /dev/null @@ -1,45 +0,0 @@ -module Workarea - module Search - class SearchSuggestions - include Query - include ReleaseDisplayRules - - document Search::Storefront - - def results - response['hits']['hits'] - end - - def sanitized_string - @sanitized_query ||= QueryString.new(params[:q]).sanitized - end - - def query - { - bool: { - must: [ - { - match_phrase_prefix: { - 'content.name': { - query: sanitized_string, - max_expansions: 10 - } - } - }, - active_for_release_clause, - include_current_release_clause - ] - } - } - end - - def sort - { type: :desc } - end - - def size - Workarea.config.search_suggestions - end - end - end -end diff --git a/core/test/queries/workarea/search/search_suggestions_test.rb b/core/test/queries/workarea/search/search_suggestions_test.rb deleted file mode 100644 index 35c5608974..0000000000 --- a/core/test/queries/workarea/search/search_suggestions_test.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'test_helper' - -module Workarea - module Search - class SearchSuggestionsTest < IntegrationTest - def test_results - Metrics::SearchByDay.save_search('test', 1) - 2.times { Metrics::SearchByDay.save_search('test product', 2) } - travel_to 1.week.from_now - GenerateInsights.generate_all! - BulkIndexSearches.perform - - create_product(name: 'test product 1') - create_product(name: 'test product 2', active: false) - BulkIndexProducts.perform - - results = SearchSuggestions.new(q: 'tes').results - - assert_equal(3, results.length) - assert_results_include(results, 'test product') - assert_results_include(results, 'test') - assert_results_include(results, 'test product 1') - end - - def test_results_in_release - Metrics::SearchByDay.save_search('test', 1) - 2.times { Metrics::SearchByDay.save_search('test product', 2) } - travel_to 1.week.from_now - GenerateInsights.generate_all! - BulkIndexSearches.perform - - product_one = create_product(name: 'test product 1') - product_two = create_product(name: 'test product 2') - BulkIndexProducts.perform - - results = SearchSuggestions.new(q: 'tes').results - assert_equal(4, results.length) - assert_results_include(results, 'test product') - assert_results_include(results, 'test') - assert_results_include(results, 'test product 1') - assert_results_include(results, 'test product 2') - - create_release.as_current do - product_two.update!(active: false) - - results = SearchSuggestions.new(q: 'tes').results - assert_equal(3, results.length) - assert_results_include(results, 'test product') - assert_results_include(results, 'test') - assert_results_include(results, 'test product 1') - end - - results = SearchSuggestions.new(q: 'tes').results - assert_equal(4, results.length) - assert_results_include(results, 'test product') - assert_results_include(results, 'test') - assert_results_include(results, 'test product 1') - assert_results_include(results, 'test product 2') - - create_release.as_current do - product_two.update!(name: 'test 4', active: true) - - results = SearchSuggestions.new(q: 'tes').results - assert_equal(4, results.length) - assert_results_include(results, 'test product') - assert_results_include(results, 'test') - assert_results_include(results, 'test product 1') - assert_results_include(results, 'test 4') - end - end - - def assert_results_include(results, name) - refute_nil(results.detect { |r| r['_source']['content']['name'] == name }) - end - end - end -end diff --git a/docs/source/articles/analyze-storefront-search-results.html.md b/docs/source/articles/analyze-storefront-search-results.html.md index eacf382171..29a5e050a4 100644 --- a/docs/source/articles/analyze-storefront-search-results.html.md +++ b/docs/source/articles/analyze-storefront-search-results.html.md @@ -184,8 +184,6 @@ Depending on the search query class these may include the following: * `Workarea.config.search_facet_sorts` * `Workarea.config.search_name_phrase_match_boost` * `Workarea.config.search_query_options` - * `Workarea.config.search_suggestion_min_doc_freq` - * `Workarea.config.search_suggestions` You may need to examine these values to determine how the request body reached its final state. diff --git a/docs/source/articles/change-storefront-search-results.html.md b/docs/source/articles/change-storefront-search-results.html.md index 3d57cfb6b9..adf7663115 100644 --- a/docs/source/articles/change-storefront-search-results.html.md +++ b/docs/source/articles/change-storefront-search-results.html.md @@ -124,11 +124,7 @@ At this point, searching for "promo" returns all 4 test products. ![Before: promo products included in search results](../images/promo-products-included-search-results-before.png) To complete the change request, you must write the code necessary to exclude the promo products from these results. -However, the retailer wants to exclude these products from _all_ search results, which includes autocomplete, categories, and product recommendations as well. - -You can see the products are currently included in autocomplete results: - -![Before: promo products included in autocomplete results](../images/promo-products-included-autocomplete-results-before.png) +However, the retailer wants to exclude these products from _all_ search results, which includes categories, and product recommendations as well. And all four products are included in the "Promo Search" category, which merchandises the products using a product rule: @@ -226,27 +222,6 @@ The example uses the logic "keywords.promo must not contain true" rather than "k The chosen logic excludes only those product search documents that have a `keywords.promo` field and whose value contains `'true'`. Existing search documents without a keywords.promo field will continue to match queries as expected. -The decorator above does not cover the autocomplete feature, which relies on a separate query. -So you must additionally decorate the `SearchSuggestions` query class, adding similar logic to this query's request body. -This query's body is implemented almost entirely within the `#query` method, so apply your changes there: - -```ruby -# app/queries/workarea/search/search_suggestions.decorator -module Workarea - decorate Search::SearchSuggestions do - def query - result = super - # add a compound query clause to exclude promo products - result[:bool][:must_not] = [ - { term: { 'keywords.promo' => true } } - ] - result - end - end -end -``` - - Result -------------------------------------------------------------------------------- @@ -258,10 +233,6 @@ Search results: ![After: promo products excluded from search results](../images/promo-products-excluded-search-results-after.png) -Autocomplete: - -![After: promo products excluded from autocomplete results](../images/promo-products-excluded-autocomplete-results-after.png) - Categories: ![After: promo products excluded from search-based category results](../images/promo-products-excluded-search-category-results-after.png) diff --git a/docs/source/articles/searching.html.md b/docs/source/articles/searching.html.md index 2b7cbecb4a..9c5cf4b31f 100644 --- a/docs/source/articles/searching.html.md +++ b/docs/source/articles/searching.html.md @@ -764,7 +764,6 @@ puts searches.map(&:to_s).sort # Workarea::Search::ProductSearch # Workarea::Search::RelatedHelp # Workarea::Search::RelatedProducts -# Workarea::Search::SearchSuggestions ``` Each search query searches for results of a particular Elasticsearch document type. The following example groups the search queries by type. @@ -772,8 +771,7 @@ Each search query searches for results of a particular Elasticsearch document ty ```ruby pp searches.group_by(&:document) # {Workarea::Search::Storefront=> -# [Workarea::Search::SearchSuggestions, -# Workarea::Search::RelatedProducts, +# [Workarea::Search::RelatedProducts, # Workarea::Search::ProductSearch, # Workarea::Search::CategoryBrowse, # Workarea::Search::Categorization], diff --git a/docs/source/articles/storefront-search-features.html.md b/docs/source/articles/storefront-search-features.html.md index ace75c4e68..33f6afb73d 100644 --- a/docs/source/articles/storefront-search-features.html.md +++ b/docs/source/articles/storefront-search-features.html.md @@ -24,16 +24,6 @@ These queries are built via a user interface and include a query string and opti Admins can customize the results of all searches via _search settings_ (terms facets, range facets, field boosts, product popularity multiplier), and they can customize specific searches via _search customizations_ (featured products, product rules, query rewrite). -### Autocomplete - -Another obvious search feature in the Storefront is _autocomplete_. -Storefront autocomplete is a _search-as-you-type_ feature that matches products, categories, pages, and searches to shoppers' queries as they type. - -![Storefront autocomplete](../images/storefront-autocomplete.png) - -There is no administration specific to this feature, but plugins and applications can extend autocomplete. For example, the Workarea Blog plugin extends this feature to include blog entries in the results. - - ### Categories Less evidently, _categories_ (i.e. category pages) in the Storefront are also a search feature. @@ -82,7 +72,7 @@ Extending any of these features therefore requires an understanding of their sha Querying -------------------------------------------------------------------------------- -In each of the features above, shoppers are requesting pages (or updating pages in the case of autocomplete) which contain search results. +In each of the features above, shoppers are requesting pages which contain search results. Application code responsible for handling these _Storefront requests_ must make additional _search requests_ to Elasticsearch. Elasticsearch responds to these requests, and the application processes the results, allowing it to respond to the original Storefront requests. @@ -122,7 +112,6 @@ The following table maps each search feature to its corresponding search query c Search Feature | Search Query Class | Potential Callers ---------------------------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------- Searches | `Search::ProductSearch` | See [Storefront Searches](storefront-searches.html) -Autocomplete | `Search::SearchSuggestions` | `Storefront::SearchesController#index` Categories and category summary content blocks | `Search::CategoryBrowse` | `Storefront::CategoryViewModel#search_query` Product recommendations | `Search::RelatedProducts` | `Recommendations::ProductBased`, `Recommendations::OrderBased`, `Recommendations::UserActivityBased` @@ -321,8 +310,7 @@ The fields within each of these search documents were derived from data in one o _Search models_ are objects used to index documents into Elasticsearch. They create search documents from MongoDB documents and put the search documents into the appropriate search indexes (i.e. send indexing requests to Elasticsearch). -Storefront search results are primarily products, but autocomplete results may also be categories, pages, searches, and possibly additional types (depending on plugins and extensions). -There are therefore different search model classes to handle the creation and indexing of documents of these various types. +There are different search model classes to handle the creation and indexing of documents of various types. The following table maps each search result type to its corresponding Mongoid model class and Storefront search model class. Search Result | Mongoid Model | Search Model diff --git a/docs/source/upgrade-guides/from-3-4-to-3-5.html.md b/docs/source/upgrade-guides/from-3-4-to-3-5.html.md index d4f182b707..772fceb1e0 100644 --- a/docs/source/upgrade-guides/from-3-4-to-3-5.html.md +++ b/docs/source/upgrade-guides/from-3-4-to-3-5.html.md @@ -103,3 +103,13 @@ As a part of this process, the `digital?` flag on products was no longer necessa ### What Do You Need To Do? The v3.5 migration script creates `Fulfillment::Sku` records for existing digital items, setting their policy to `ignore_digital`. This should preserve any behavior in your system for digital products. However, we strongly recommend reworking any code that relies on the `digital?` method of either `Catalog::Product` or `Order::Item`. Instead use `requires_shipping?` on `Order` and `Order::Item` to determine behaviors within this concern. + +## Move Storefront Search Autocomplete Functionality to Plugin + +### What's Changing? + +We've removed the default Search Autocomplete functionality from the Storefront into a plugin to be able to give applications more flexibility. + +### What Do You Need To Do? + +To keep this functionality present in your application you'll need to install the `workarea-classic_search_autocomplete` plugin. diff --git a/storefront/app/assets/javascripts/workarea/storefront/application.js.erb b/storefront/app/assets/javascripts/workarea/storefront/application.js.erb index 8ddc6e5b44..d2bfffffed 100644 --- a/storefront/app/assets/javascripts/workarea/storefront/application.js.erb +++ b/storefront/app/assets/javascripts/workarea/storefront/application.js.erb @@ -44,8 +44,6 @@ %w( workarea/core/templates/lorem_ipsum_view workarea/core/templates/reveal_password_button - workarea/storefront/templates/ui_menu_heading - workarea/storefront/templates/ui_menu_item workarea/storefront/templates/loading workarea/storefront/templates/message workarea/storefront/templates/message_dismiss_action @@ -66,12 +64,8 @@ # Plugin JST Templates append_javascripts('storefront.templates') - # Library Extensions - %w( - jquery_ui/storefront/categorized_autocomplete - ).each do |asset| - require_asset asset - end + # Plugin Library Extensions + append_javascripts('storefront.extensions') # Workarea Module Controller require_asset 'workarea/core/workarea' @@ -124,7 +118,6 @@ workarea/storefront/modules/primary_nav_content workarea/storefront/modules/product_details_sku_selects workarea/storefront/modules/popup_buttons - workarea/storefront/modules/search_fields workarea/storefront/modules/alternate_image_buttons workarea/storefront/modules/scroll_to_buttons workarea/storefront/modules/address_region_fields diff --git a/storefront/app/assets/javascripts/workarea/storefront/modules/search_fields.js b/storefront/app/assets/javascripts/workarea/storefront/modules/search_fields.js deleted file mode 100644 index 367b59f5ac..0000000000 --- a/storefront/app/assets/javascripts/workarea/storefront/modules/search_fields.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @namespace WORKAREA.searchFields - */ -WORKAREA.registerModule('searchFields', (function () { - 'use strict'; - - var getSource = function (request, response) { - var endpoint = WORKAREA.routes.storefront.searchesPath(); - - $.getJSON(endpoint, { q: request.term }, function (data) { - response(data.results); - }); - }, - - openSelected = function (event, ui) { - if (ui.item.type === "Products") { - WORKAREA.analytics.fireCallback( - 'productClick', - ui.item.analytics - ); - } - - if (WORKAREA.analytics.domEventsDisabled()) { return; } - window.location = ui.item.url; - }, - - /** - * iOS touch devices treat touch events as mouseenter unless there is no - * change in the UI, like a menu-selected state. By unbinding the - * mouseenter event we force those devices to treat the touch event as a - * click. This prevents the user having to tap twice to open a search - * autocomplete result. - */ - openOnTouchDevices = function () { - $('.ui-autocomplete').off('mouseenter'); - }, - - getConfig = function () { - return _.assign({}, WORKAREA.config.searchFieldsAutocomplete, { - source: getSource, - select: openSelected, - open: openOnTouchDevices - }); - }, - - /** - * @method - * @name init - * @memberof WORKAREA.searchFields - */ - init = function ($scope) { - $('[data-search-field]', $scope) - .categorizedAutocomplete(getConfig()); - }; - - return { - init: init - }; -}())); diff --git a/storefront/app/assets/javascripts/workarea/storefront/templates/ui_menu_heading.jst.ejs b/storefront/app/assets/javascripts/workarea/storefront/templates/ui_menu_heading.jst.ejs deleted file mode 100644 index 2f8008c4c8..0000000000 --- a/storefront/app/assets/javascripts/workarea/storefront/templates/ui_menu_heading.jst.ejs +++ /dev/null @@ -1 +0,0 @@ -
  • <%= categoryName %>
  • diff --git a/storefront/app/assets/javascripts/workarea/storefront/templates/ui_menu_item.jst.ejs b/storefront/app/assets/javascripts/workarea/storefront/templates/ui_menu_item.jst.ejs deleted file mode 100644 index b84d75b25e..0000000000 --- a/storefront/app/assets/javascripts/workarea/storefront/templates/ui_menu_item.jst.ejs +++ /dev/null @@ -1,8 +0,0 @@ -
  • - - <% if (image) { %> - - <% } %> - <%= label %> - -
  • diff --git a/storefront/app/assets/stylesheets/jquery_ui/storefront/_ui_autocomplete.scss b/storefront/app/assets/stylesheets/jquery_ui/storefront/_ui_autocomplete.scss deleted file mode 100644 index ee031bad0b..0000000000 --- a/storefront/app/assets/stylesheets/jquery_ui/storefront/_ui_autocomplete.scss +++ /dev/null @@ -1,17 +0,0 @@ -/*------------------------------------*\ - #UI-AUTOCOMPLETE -\*------------------------------------*/ - -$ui-autocomplete-bg-color: $white !default; - -$ui-autocomplete-width: 190px !default; - - -.ui-autocomplete { - @extend %list-reset; - position: absolute; - z-index: index($components, ui-autocomplete); - padding: $spacing-unit; - width: $ui-autocomplete-width; - background: $ui-autocomplete-bg-color; -} diff --git a/storefront/app/assets/stylesheets/jquery_ui/storefront/_ui_menu.scss b/storefront/app/assets/stylesheets/jquery_ui/storefront/_ui_menu.scss deleted file mode 100644 index 27dfe50a13..0000000000 --- a/storefront/app/assets/stylesheets/jquery_ui/storefront/_ui_menu.scss +++ /dev/null @@ -1,40 +0,0 @@ -/*------------------------------------*\ - #UI-MENU -\*------------------------------------*/ - -$ui-menu-item-selected-color: $highlight-color !default; - - -/** - * 1. default menu item state - * 2. hovered menu item state - * 3. the displayed result image - * 4. menu headings - */ - -.ui-menu { - .ui-menu-item { /* [1] */ - @extend %clearfix; - padding: ($spacing-unit / 2) 0; - cursor: pointer; - - &:hover { /* [2] */ - background: $ui-menu-item-selected-color; - } - - img { /* [3] */ - margin: 0 ($spacing-unit / 2) 0 0; - float: left; - } - } - - .ui-menu-heading { /* [4] */ - margin: ($spacing-unit / 2) 0; - padding: ($spacing-unit / 2) 0; - font-weight: bold; - } -} - - .ui-menu-item-wrapper { - display: block; - } diff --git a/storefront/app/assets/stylesheets/workarea/storefront/application.scss.erb b/storefront/app/assets/stylesheets/workarea/storefront/application.scss.erb index 4155a74d08..35f2643278 100644 --- a/storefront/app/assets/stylesheets/workarea/storefront/application.scss.erb +++ b/storefront/app/assets/stylesheets/workarea/storefront/application.scss.erb @@ -45,10 +45,8 @@ <%= append_stylesheets('storefront.typography') %> @import 'avalanche'; -@import 'jquery_ui/storefront/ui_autocomplete'; @import 'jquery_ui/storefront/ui_dialog'; @import 'jquery_ui/storefront/ui_helper_hidden_accessible'; -@import 'jquery_ui/storefront/ui_menu'; @import 'jquery_ui/storefront/ui_state_focus'; @import 'jquery_ui/storefront/ui_widget_overlay'; <%= append_stylesheets('storefront.dependencies') %> diff --git a/storefront/app/controllers/workarea/storefront/searches_controller.rb b/storefront/app/controllers/workarea/storefront/searches_controller.rb index 2879c95dfe..a604b5e392 100644 --- a/storefront/app/controllers/workarea/storefront/searches_controller.rb +++ b/storefront/app/controllers/workarea/storefront/searches_controller.rb @@ -3,17 +3,6 @@ module Storefront class SearchesController < Storefront::ApplicationController before_action :cache_page - def index - render nothing: true and return if search_query.blank? - autocomplete_params = params.permit(:q) - - search = Search::SearchSuggestions.new(autocomplete_params) - - @results = search.results.map do |result| - SearchSuggestionViewModel.new(result).to_h - end - end - def show if search_query.blank? flash[:error] = t('workarea.storefront.flash_messages.no_search_query') diff --git a/storefront/app/view_models/workarea/storefront/search_suggestion_view_model.rb b/storefront/app/view_models/workarea/storefront/search_suggestion_view_model.rb deleted file mode 100644 index 66a7a3a5b2..0000000000 --- a/storefront/app/view_models/workarea/storefront/search_suggestion_view_model.rb +++ /dev/null @@ -1,87 +0,0 @@ -module Workarea - module Storefront - class SearchSuggestionViewModel < ApplicationViewModel - include I18n::DefaultUrlOptions - include Storefront::Engine.routes.url_helpers - include Search::LoadProductResults - include AnalyticsHelper - - def to_h - { - value: name, - type: type, - image: image, - url: url, - analytics: analytics - } - end - - def source - model['_source'] - end - - def name - source['content']['name'] - end - - def type - t("workarea.storefront.searches.#{suggestion_type.pluralize}") - end - - # TODO this can be simplified in v4, when we can be confident the index - # will always have relative paths stored for image cache. - def image - return if source['cache']['image'].blank? - - image_url = URI.parse(source['cache']['image']) - - if asset_host.present? - image_url.scheme = asset_host.scheme - image_url.host = asset_host.host - end - - image_url.to_s - end - - def asset_host - URI.parse(Rails.application.config.action_controller.asset_host) - rescue URI::InvalidURIError - nil - end - - def suggestion_type - source['type'] - end - - def analytics - return unless suggestion_type == 'product' - - product_analytics_data(product) - end - - def product - @product ||= - begin - loaded = load_model_from(model) - - Storefront::ProductViewModel.wrap( - loaded[:model], - loaded.slice(:inventory, :pricing) - ) - end - end - - def url - if suggestion_type == 'product' - product_path(product) - elsif suggestion_type == 'search' - search_path(q: name) - elsif suggestion_type == 'category' - category_path(source['slug']) - elsif suggestion_type == 'page' - page_path(source['slug']) - end - end - end - end -end diff --git a/storefront/app/views/layouts/workarea/storefront/application.html.haml b/storefront/app/views/layouts/workarea/storefront/application.html.haml index 130da34a6e..75aead9097 100644 --- a/storefront/app/views/layouts/workarea/storefront/application.html.haml +++ b/storefront/app/views/layouts/workarea/storefront/application.html.haml @@ -79,7 +79,7 @@ .page-header__search = form_tag search_path, method: 'get', class: 'page-header__search-form', role: 'search' do .page-header__search-value - .value= search_field_tag :q, params[:q], id: 'storefront_search', class: 'text-box', title: t('workarea.storefront.searches.search'), aria: { label: t('workarea.storefront.searches.search') }, placeholder: t('workarea.storefront.searches.search'), data: { search_field: '' } + .value= search_field_tag :q, params[:q], id: 'storefront_search', class: 'text-box', title: t('workarea.storefront.searches.search'), aria: { label: t('workarea.storefront.searches.search') }, placeholder: t('workarea.storefront.searches.search') .page-header__search-button= button_tag t('workarea.storefront.forms.go'), value: 'search', class: 'button' %nav#navigation.primary-nav diff --git a/storefront/app/views/workarea/storefront/searches/index.json.jbuilder b/storefront/app/views/workarea/storefront/searches/index.json.jbuilder deleted file mode 100644 index bb0ab94bd7..0000000000 --- a/storefront/app/views/workarea/storefront/searches/index.json.jbuilder +++ /dev/null @@ -1 +0,0 @@ -json.results @results diff --git a/storefront/config/routes.rb b/storefront/config/routes.rb index f362d83f68..0d226df6f0 100644 --- a/storefront/config/routes.rb +++ b/storefront/config/routes.rb @@ -28,7 +28,6 @@ end resource :email_signup, only: [:show, :create] - resources :searches, only: :index resource :search, only: :show get '/current_user', to: 'application#current_user_info', as: :current_user diff --git a/storefront/test/integration/workarea/storefront/search_integration_test.rb b/storefront/test/integration/workarea/storefront/search_integration_test.rb index 8702eed011..3c51e872c0 100644 --- a/storefront/test/integration/workarea/storefront/search_integration_test.rb +++ b/storefront/test/integration/workarea/storefront/search_integration_test.rb @@ -13,42 +13,6 @@ def test_redirects_when_a_redirect_is_setup assert_redirected_to(storefront.cart_path) end - def test_renders_search_suggestions_in_json - create_product(name: 'Foo') - create_category(name: 'Foo Category') - create_page(name: 'Foo Page') - - Metrics::SearchByDay.save_search('foo', 3) - travel_to 1.week.from_now - GenerateInsights.generate_all! - BulkIndexSearches.perform - - get storefront.searches_path(q: 'foo', format: 'json') - results = JSON.parse(response.body)['results'] - assert_equal(4, results.length) - - search = results.detect { |r| r['type'] == 'Searches' } - assert(search.present?) - assert_equal('foo', search['value']) - assert_equal(storefront.search_path(q: 'foo'), search['url']) - - product = results.detect { |r| r['type'] == 'Products' } - assert(product.present?) - assert_equal('Foo', product['value']) - assert_match(/product_images/, product['image']) - assert_equal(storefront.product_path('foo'), product['url']) - - category = results.detect { |r| r['type'] == 'Categories' } - assert(category.present?) - assert_equal('Foo Category', category['value']) - assert_equal(storefront.category_path('foo-category'), category['url']) - - page = results.detect { |r| r['type'] == 'Pages' } - assert(page.present?) - assert_equal('Foo Page', page['value']) - assert_equal(storefront.page_path('foo-page'), page['url']) - end - def test_handles_invalid_queries get storefront.search_path(q: '{()!}'), headers: { 'HTTP_REFERER' => '/foo' } diff --git a/storefront/test/system/workarea/storefront/analytics_system_test.rb b/storefront/test/system/workarea/storefront/analytics_system_test.rb index 387f64e59b..990c88eed5 100644 --- a/storefront/test/system/workarea/storefront/analytics_system_test.rb +++ b/storefront/test/system/workarea/storefront/analytics_system_test.rb @@ -144,7 +144,7 @@ def test_announcing_product_list_event def test_announcing_product_click_event visit storefront.category_path(@category) - disable_dom_events + disable_analytics_events within '.product-summary__name', match: :first do click_link 'Test Product 2' end @@ -163,25 +163,6 @@ def test_announcing_product_click_event assert_page_view end - def test_announcing_product_click_event_search_type_ahead - @products.each { |p| Search::Storefront::Product.new(p).save } - visit storefront.root_path - disable_dom_events - - page.evaluate_script('$("#storefront_search").categorizedAutocomplete("search", "test");') - - find('li', text: 'Test Product 1').click - - events = find_analytics_events(for_event: 'productClick') - assert_equal(1, events.count) - payload = events.first['arguments'].first - - assert_equal('PROD1', payload['id']) - assert_equal('Test Product 1', payload['name']) - assert_equal(false, payload['sale']) - assert_equal(10, payload['price']) - end - def test_announcing_add_to_cart_event visit storefront.product_path(@products.second) @@ -210,7 +191,7 @@ def test_announcing_update_cart_item_event visit storefront.cart_path - disable_dom_events + disable_analytics_events fill_in 'quantity', with: '1' events = find_analytics_events(for_event: 'updateCartItem') @@ -236,7 +217,7 @@ def test_announcing_remove_from_cart_event click_button t('workarea.storefront.products.add_to_cart') click_link t('workarea.storefront.carts.view_cart') - disable_dom_events + disable_analytics_events click_button t('workarea.storefront.carts.remove') events = find_analytics_events(for_event: 'removeFromCart') @@ -487,7 +468,7 @@ def test_announcing_email_signup_event fill_in 'footer_email_signup_field', with: 'foo@bar.com' - disable_dom_events + disable_analytics_events click_button t('workarea.storefront.users.join') events = find_analytics_events(for_event: 'emailSignup') @@ -502,7 +483,7 @@ def test_announcing_checkout_login_event visit storefront.checkout_path - disable_dom_events + disable_analytics_events click_link t('workarea.storefront.users.login') events = find_analytics_events(for_event: 'checkoutLogin') @@ -526,7 +507,7 @@ def test_announcing_checkout_signup_event fill_in 'password', with: 'W3bl1nc!' - disable_dom_events + disable_analytics_events click_button t('workarea.storefront.users.create_account') events = find_analytics_events(for_event: 'checkoutSignup') @@ -543,7 +524,7 @@ def test_announcing_login_event fill_in 'email', with: 'bcrouse@workarea.com' fill_in 'password', with: 'W3bl1nc!' - disable_dom_events + disable_analytics_events click_button t('workarea.storefront.users.login') end @@ -559,7 +540,7 @@ def test_announcing_forgot_password_event within '#forgot_password_form' do fill_in 'email', with: 'bcrouse@workarea.com' - disable_dom_events + disable_analytics_events click_button t('workarea.storefront.forms.send') end @@ -576,7 +557,7 @@ def test_announcing_signup_event fill_in 'email', with: 'bcrouse@workarea.com' fill_in 'password', with: 'W3bl1nc!' - disable_dom_events + disable_analytics_events click_button t('workarea.storefront.users.create_account') end @@ -592,7 +573,7 @@ def test_announcing_primary_navigation_click_event visit storefront.root_path - disable_dom_events + disable_analytics_events click_link 'First Level' events = find_analytics_events(for_event: 'primaryNavigationClick') @@ -612,7 +593,7 @@ def test_announcing_checkout_edit_event fill_in_shipping_address click_button t('workarea.storefront.checkouts.continue_to_shipping') - disable_dom_events + disable_analytics_events click_link t('workarea.storefront.forms.edit') events = find_analytics_events(for_event: 'checkoutEdit') @@ -744,25 +725,11 @@ def test_sessions private - def find_analytics_events(for_event: nil) - all_events = page.evaluate_script('WORKAREA.analytics.events') - - if for_event.blank? - all_events - else - all_events.select { |e| e['name'] == for_event } - end - end - def assert_page_view page_view = find_analytics_events(for_event: 'pageView') assert_equal(1, page_view.count) end - def disable_dom_events - page.execute_script('WORKAREA.analytics.disableDomEvents();') - end - def expire_analytics_session # Simulate session expiration where this cookie would disappear page.execute_script("WORKAREA.cookie.destroy('analytics_session');") diff --git a/storefront/test/view_models/workarea/storefront/search_suggestion_view_model_test.rb b/storefront/test/view_models/workarea/storefront/search_suggestion_view_model_test.rb deleted file mode 100644 index ce033c0fab..0000000000 --- a/storefront/test/view_models/workarea/storefront/search_suggestion_view_model_test.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'test_helper' - -module Workarea - module Storefront - class SearchSuggestionViewModelTest < TestCase - setup :set_asset_host_config - teardown :restore_asset_host_config - - def set_asset_host_config - @current_asset_host = Rails.application.config.action_controller.asset_host - Rails.application.config.action_controller.asset_host = 'http://cdn.client.com' - end - - def restore_asset_host_config - Rails.application.config.action_controller.asset_host = @current_asset_host - end - - def test_image_handles_blank - search_suggestion = { '_source' => { 'cache' => { 'image' => '' } } } - view_model = SearchSuggestionViewModel.new(search_suggestion) - assert(view_model.image.nil?) - end - - def test_image_handles_different_urls_from_index - possible_index_urls = %w( - /image.jpg - https://staging.client.com/image.jpg - http://cdn.client.com/image.jpg - ) - - possible_index_urls.each do |url_from_index| - search_suggestion = { - '_source' => { 'cache' => { 'image' => url_from_index } } - } - - view_model = SearchSuggestionViewModel.new(search_suggestion) - assert_equal('http://cdn.client.com/image.jpg', view_model.image) - end - end - end - end -end diff --git a/testing/lib/workarea/storefront/system_test.rb b/testing/lib/workarea/storefront/system_test.rb index f8d9cab7cf..aa9dc8dc42 100644 --- a/testing/lib/workarea/storefront/system_test.rb +++ b/testing/lib/workarea/storefront/system_test.rb @@ -137,6 +137,20 @@ def fill_in_billing_address def select_shipping_service choose 'Ground' end + + def disable_analytics_events + page.execute_script('WORKAREA.analytics.disableDomEvents();') + end + + def find_analytics_events(for_event: nil) + all_events = page.evaluate_script('WORKAREA.analytics.events') + + if for_event.blank? + all_events + else + all_events.select { |e| e['name'] == for_event } + end + end end end end