diff --git a/Gemfile b/Gemfile
index e201ef2107..aa468612b3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -19,9 +19,8 @@ gem 'activerecord-postgresql-adapter'
gem 'pg', '~> 0.21.0'
# OFN-maintained and patched version of Spree v2.0.4. See
-# https://github.com/openfoodfoundation/openfoodnetwork/wiki/Spree-2.0-upgrade
+# https://github.com/openfoodfoundation/openfoodnetwork/wiki/Tech-Doc:-OFN's-Spree-fork%F0%9F%8D%B4
# for details.
-gem 'spree_backend', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
gem 'spree_core', github: 'openfoodfoundation/spree', branch: '2-0-4-stable'
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
@@ -120,6 +119,8 @@ gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper',
gem 'jquery-migrate-rails'
gem 'jquery-rails', '3.0.4'
+gem 'jquery-ui-rails', '~> 4.0.0'
+gem 'select2-rails', '~> 3.4.7'
gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz', ref: '60da2ae4c44cbb4c8d602f59fb5fff8d0f21db3c'
diff --git a/Gemfile.lock b/Gemfile.lock
index b4d251d234..7a0d3c5f64 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -34,18 +34,6 @@ GIT
revision: 8a8585a43cd04d1a50dc65227f337a91b18d66d5
branch: 2-0-4-stable
specs:
- spree_api (2.0.4)
- rabl (= 0.8.4)
- spree_core (= 2.0.4)
- versioncake (= 1.0.0)
- spree_backend (2.0.4)
- deface (>= 0.9.0)
- jquery-rails (~> 3.0.0)
- jquery-ui-rails (~> 4.0.0)
- rails (~> 3.2.8)
- select2-rails (~> 3.4.7)
- spree_api (= 2.0.4)
- spree_core (= 2.0.4)
spree_core (2.0.4)
activemerchant (~> 1.34)
acts_as_list (= 0.2.0)
@@ -685,10 +673,6 @@ GEM
rack
unicorn
uuidtools (2.1.5)
- versioncake (1.0.0)
- actionpack (>= 3.0)
- activesupport (>= 3.0)
- railties (>= 3.0)
warden (1.2.7)
rack (>= 1.0)
webdrivers (4.2.0)
@@ -759,6 +743,7 @@ DEPENDENCIES
immigrant
jquery-migrate-rails
jquery-rails (= 3.0.4)
+ jquery-ui-rails (~> 4.0.0)
json_spec (~> 1.1.4)
jwt (~> 2.2)
kaminari (~> 0.14.1)
@@ -792,12 +777,12 @@ DEPENDENCIES
rubocop-rails
sass (~> 3.3)
sass-rails (~> 3.2.3)
+ select2-rails (~> 3.4.7)
selenium-webdriver
shoulda-matchers
simple_form!
simplecov
spinjs-rails
- spree_backend!
spree_core!
spree_i18n!
spree_paypal_express!
diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js
index 76a286cc43..5525aa6828 100644
--- a/app/assets/javascripts/admin/all.js
+++ b/app/assets/javascripts/admin/all.js
@@ -16,6 +16,7 @@
//= require jquery.jstree/jquery.jstree
//= require jquery.vAlign
//= require jquery.horizontalNav
+//= require jquery.adaptivemenu
//= require angular
//= require angular-resource
//= require angular-animate
@@ -28,11 +29,9 @@
// spree
//= require spree
-//= require admin/spree-select2
-//= require admin/spree_backend
+//= require admin/spree/spree-select2
//= require modernizr
//= require spin
-//= require jquery.adaptivemenu
//= require equalize
//= require css_browser_selector_dev
//= require responsive-tables
diff --git a/app/assets/javascripts/admin/orders/directives/customer_search_override.js.coffee b/app/assets/javascripts/admin/orders/directives/customer_search_override.js.coffee
index 76200d92ff..79d4ac4a4b 100644
--- a/app/assets/javascripts/admin/orders/directives/customer_search_override.js.coffee
+++ b/app/assets/javascripts/admin/orders/directives/customer_search_override.js.coffee
@@ -3,6 +3,9 @@ angular.module("admin.orders").directive 'customerSearchOverride', ->
scope:
distributorId: '@'
link: (scope, element, attr) ->
+ if $('#customer_autocomplete_template').length > 0
+ customerTemplate = Handlebars.compile($('#customer_autocomplete_template').text())
+
formatCustomerResult = (customer) ->
customerTemplate
customer: customer
diff --git a/app/assets/javascripts/admin/spree/base.js.erb b/app/assets/javascripts/admin/spree/base.js.erb
index b9ba57d9ff..1ddd4a8dd3 100644
--- a/app/assets/javascripts/admin/spree/base.js.erb
+++ b/app/assets/javascripts/admin/spree/base.js.erb
@@ -1,6 +1,6 @@
//= require_self
//= require admin/handlebar_extensions
-//= require admin/variant_autocomplete
+//= require admin/spree/orders/variant_autocomplete
/**
This is a collection of javascript functions and whatnot
@@ -21,12 +21,14 @@ jQuery(function($) {
if (typeof $('.field.checkbox label').vAlign === 'function' )
$('.field.checkbox label').vAlign()
- // if (typeof Spree !== 'undefined') {
- // $('.main-menu-wrapper ul').AdaptiveMenu({
- // text: " " + Spree.translations.more + "",
- // klass: "dropdown"
- // });
- // }
+ // We activate AdaptiveMenu only if not on webdriver
+ // Re-adjusting the admin menu during tests causes tests to fail.
+ if (!navigator.webdriver && typeof Spree !== 'undefined') {
+ $('.main-menu-wrapper ul').AdaptiveMenu({
+ text: " " + Spree.translations.more + "",
+ klass: "dropdown"
+ });
+ }
// Add some tips
if (typeof $('.with-tip').powerTip === 'function' ) {
@@ -174,6 +176,28 @@ $(document).ready(function() {
$(target).prepend(new_table_row);
})
+ $('body').on('click', '.delete-resource', function() {
+ var el = $(this);
+ if (confirm(el.data("confirm"))) {
+ $.ajax({
+ type: 'POST',
+ url: $(this).attr("href"),
+ data: {
+ _method: 'delete',
+ authenticity_token: AUTH_TOKEN
+ },
+ dataType: 'html',
+ success: function(response) {
+ el.parents("tr").fadeOut('hide');
+ },
+ error: function(response, textStatus, errorThrown) {
+ show_flash_error(response.responseText);
+ }
+ });
+ }
+ return false;
+ });
+
// Fix sortable helper
var fixHelper = function(e, ui) {
ui.children().each(function() {
diff --git a/app/assets/javascripts/admin/spree/calculator.js b/app/assets/javascripts/admin/spree/calculator.js
new file mode 100644
index 0000000000..cb8ab4351d
--- /dev/null
+++ b/app/assets/javascripts/admin/spree/calculator.js
@@ -0,0 +1,16 @@
+$(function() {
+ var calculator_select = $('select#calc_type')
+ var original_calc_type = calculator_select.attr('value');
+ $('.calculator-settings-warning').hide();
+ calculator_select.change(function() {
+ if (calculator_select.attr('value') == original_calc_type) {
+ $('div.calculator-settings').show();
+ $('.calculator-settings-warning').hide();
+ $('.calculator-settings').find('input,textarea').prop("disabled", false);
+ } else {
+ $('div.calculator-settings').hide();
+ $('.calculator-settings-warning').show();
+ $('.calculator-settings').find('input,texttarea').prop("disabled", true);
+ }
+ });
+})
diff --git a/app/assets/javascripts/admin/spree/image_settings.js.erb b/app/assets/javascripts/admin/spree/image_settings.js.erb
new file mode 100644
index 0000000000..d8c0b2a635
--- /dev/null
+++ b/app/assets/javascripts/admin/spree/image_settings.js.erb
@@ -0,0 +1,59 @@
+$(document).ready(function() {
+
+ if ($('input#preferences_use_s3[type="checkbox"]:checked').length > 0) {
+ $('#s3_settings, #s3_headers').show();
+ }
+
+ // Toggle display of S3 settings based on value of use_s3 checkbox
+ $('input#preferences_use_s3[type="checkbox"]').click(function() {
+ $('#s3_settings, #s3_headers').toggle();
+ });
+
+ $(document).on('click', '.destroy_style', function(e) {
+ e.preventDefault();
+ $(this).parent().remove();
+ });
+
+ $(document).on('click', '.destroy_new_attachment_styles', function(e) {
+ e.preventDefault();
+ $(this).closest('.new_attachment_styles').remove();
+ });
+
+ $(document).on('click', '.destroy_new_s3_headers', function(e) {
+ e.preventDefault();
+ $(this).closest('.new_s3_headers').remove();
+ });
+
+ // Handle adding new styles
+ var styles_hash_index = 1;
+ $(document).on('click', '.add_new_style', function(e) {
+ e.preventDefault();
+ $('#new-styles').append(generate_html_for_hash("new_attachment_styles", styles_hash_index));
+ });
+
+ // Handle adding new headers
+ var headers_hash_index = 1;
+ $(document).on('click', '.add_header', function(e) {
+ e.preventDefault();
+ $('#headers_list').append(generate_html_for_hash("new_s3_headers", headers_hash_index));
+ });
+
+ // Generates html for new paperclip styles form fields
+ generate_html_for_hash = function(hash_name, index) {
+ var html = '
';
+
+ index += 1;
+ return html;
+ };
+});
diff --git a/app/assets/javascripts/admin/spree/nested-attribute.js b/app/assets/javascripts/admin/spree/nested-attribute.js
new file mode 100644
index 0000000000..0282992ac9
--- /dev/null
+++ b/app/assets/javascripts/admin/spree/nested-attribute.js
@@ -0,0 +1,23 @@
+//On page load
+replace_ids = function(s){
+ var new_id = new Date().getTime();
+ return s.replace(/NEW_RECORD/g, new_id);
+}
+
+$(function() {
+ $('a[id*=nested]').click(function() {
+ var template = $(this).attr('href').replace(/.*#/, '');
+ html = replace_ids(eval(template));
+ $('#ul-' + $(this).attr('id')).append(html);
+ update_remove_links();
+ });
+ update_remove_links();
+})
+
+var update_remove_links = function() {
+ $('.remove').click(function() {
+ $(this).prevAll(':first').val(1);
+ $(this).parent().hide();
+ return false;
+ });
+};
diff --git a/app/assets/javascripts/admin/spree/orders/shipments.js.erb b/app/assets/javascripts/admin/spree/orders/shipments.js.erb
index e86dedead0..cf3d4d6803 100644
--- a/app/assets/javascripts/admin/spree/orders/shipments.js.erb
+++ b/app/assets/javascripts/admin/spree/orders/shipments.js.erb
@@ -15,11 +15,11 @@ $(document).ready(function() {
console.log(msg);
});
}
- // $('[data-hook=admin_order_edit_form] a.ship').click(handle_ship_click);
+ $('[data-hook=admin_order_edit_form] a.ship').click(handle_ship_click);
//handle shipping method edit click
- // $('a.edit-method').click(toggleMethodEdit);
- // $('a.cancel-method').click(toggleMethodEdit);
+ $('a.edit-method').click(toggleMethodEdit);
+ $('a.cancel-method').click(toggleMethodEdit);
handle_shipping_method_save = function(){
var link = $(this);
@@ -38,11 +38,11 @@ $(document).ready(function() {
console.log(msg);
});
}
- // $('[data-hook=admin_order_edit_form] a.save-method').click(handle_shipping_method_save);
+ $('[data-hook=admin_order_edit_form] a.save-method').click(handle_shipping_method_save);
//handle tracking edit click
- // $('a.edit-tracking').click(toggleTrackingEdit);
- // $('a.cancel-tracking').click(toggleTrackingEdit);
+ $('a.edit-tracking').click(toggleTrackingEdit);
+ $('a.cancel-tracking').click(toggleTrackingEdit);
handle_tracking_save = function(){
var link = $(this);
diff --git a/app/assets/javascripts/admin/spree/orders/variant_autocomplete.js.erb b/app/assets/javascripts/admin/spree/orders/variant_autocomplete.js.erb
index c30053facb..c7237e6553 100644
--- a/app/assets/javascripts/admin/spree/orders/variant_autocomplete.js.erb
+++ b/app/assets/javascripts/admin/spree/orders/variant_autocomplete.js.erb
@@ -29,10 +29,10 @@ $(document).ready(function() {
});
//handle edit click
- // $('a.edit-item').click(toggleItemEdit);
+ $('a.edit-item').click(toggleItemEdit);
//handle cancel click
- // $('a.cancel-item').click(toggleItemEdit);
+ $('a.cancel-item').click(toggleItemEdit);
handle_save_click = function(){
var save = $(this);
@@ -46,7 +46,7 @@ $(document).ready(function() {
adjustItems(shipment_number, variant_id, quantity);
return false;
}
- // $('a.save-item').click(handle_save_click);
+ $('a.save-item').click(handle_save_click);
handle_delete_click = function(){
var del = $(this);
@@ -57,7 +57,7 @@ $(document).ready(function() {
adjustItems(shipment_number, variant_id, 0);
}
- // $('a.delete-item').click(handle_delete_click);
+ $('a.delete-item').click(handle_delete_click);
}
});
@@ -139,39 +139,3 @@ addVariantFromStockLocation = function() {
}
return 1
}
-
-formatVariantResult = function(variant) {
- if (variant["images"][0] != undefined && variant["images"][0].urls != undefined) {
- variant.image = variant.images[0].urls.mini
- }
- return variantTemplate({ variant: variant })
-}
-
-$.fn.variantAutocomplete = function() {
- this.parent().children(".options_placeholder").attr('id', this.parent().data('index'))
- this.select2({
- placeholder: Spree.translations.variant_placeholder,
- minimumInputLength: 3,
- ajax: {
- url: Spree.url(Spree.routes.variants_search),
- datatype: 'json',
- data: function(term, page) {
- return {
- q: {
- "product_name_or_sku_cont": term
- }
- }
- },
- results: function (data, page) {
- window.variants = data['variants'];
-
- return { results: data['variants'] }
- }
- },
- formatResult: formatVariantResult,
- formatSelection: function (variant) {
- $(this.element).parent().children('.options_placeholder').html(variant.options_text)
- return variant.name;
- }
- })
-}
diff --git a/app/assets/javascripts/admin/spree/states.js b/app/assets/javascripts/admin/spree/states.js
new file mode 100755
index 0000000000..fccec35a9b
--- /dev/null
+++ b/app/assets/javascripts/admin/spree/states.js
@@ -0,0 +1,8 @@
+$(document).ready(function() {
+ $("#country").change(function() {
+ var new_state_link_href = $('#new_state_link a').attr('href');
+ var selected_country_id = $('#country option:selected').attr('value');
+ var new_link = new_state_link_href.replace(/countries\/(\d+)/, 'countries/'+selected_country_id);
+ $('#new_state_link a').attr('href', new_link);
+ });
+});
diff --git a/app/assets/javascripts/admin/spree/zone.js.coffee b/app/assets/javascripts/admin/spree/zone.js.coffee
new file mode 100644
index 0000000000..885521190d
--- /dev/null
+++ b/app/assets/javascripts/admin/spree/zone.js.coffee
@@ -0,0 +1,43 @@
+$ ->
+ ($ '#country_based').click ->
+ show_country()
+
+ ($ '#state_based').click ->
+ show_state()
+
+ if ($ '#country_based').is(':checked')
+ show_country()
+ else if ($ '#state_based').is(':checked')
+ show_state()
+ else
+ show_state()
+ ($ '#state_based').click()
+
+
+show_country = ->
+ ($ '#state_members :input').each ->
+ ($ this).prop 'disabled', true
+
+ ($ '#state_members').hide()
+ ($ '#zone_members :input').each ->
+ ($ this).prop 'disabled', true
+
+ ($ '#zone_members').hide()
+ ($ '#country_members :input').each ->
+ ($ this).prop 'disabled', false
+
+ ($ '#country_members').show()
+
+show_state = ->
+ ($ '#country_members :input').each ->
+ ($ this).prop 'disabled', true
+
+ ($ '#country_members').hide()
+ ($ '#zone_members :input').each ->
+ ($ this).prop 'disabled', true
+
+ ($ '#zone_members').hide()
+ ($ '#state_members :input').each ->
+ ($ this).prop 'disabled', false
+
+ ($ '#state_members').show()
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/spree_backend.js b/app/assets/javascripts/admin/spree_backend.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/app/assets/javascripts/admin/utils/directives/variant_autocomplete.js.coffee b/app/assets/javascripts/admin/utils/directives/variant_autocomplete.js.coffee
index dd8c9247eb..2b5fca20a6 100644
--- a/app/assets/javascripts/admin/utils/directives/variant_autocomplete.js.coffee
+++ b/app/assets/javascripts/admin/utils/directives/variant_autocomplete.js.coffee
@@ -1,10 +1,6 @@
angular.module("admin.utils").directive "variantAutocomplete", ($timeout) ->
restrict: 'C'
link: (scope, element, attrs) ->
- # Make variantAutocomplete do nothing because it is called
- # from core/app/assets/javascripts/admin/orders/edit.js
- $.fn.variantAutocomplete = angular.noop
-
$timeout ->
if $("#variant_autocomplete_template").length > 0
variantTemplate = Handlebars.compile($("#variant_autocomplete_template").text())
diff --git a/app/assets/stylesheets/admin/all.scss b/app/assets/stylesheets/admin/all.scss
index cd8063d43f..6d5992f8d4 100644
--- a/app/assets/stylesheets/admin/all.scss
+++ b/app/assets/stylesheets/admin/all.scss
@@ -4,15 +4,15 @@
* the top of the compiled file, but it's generally better to create a new file per style scope.
*
- *= require admin/spree_backend
- *= require jquery.powertip
- *= require responsive-tables
*= require normalize
*= require skeleton
+ *= require responsive-tables
+ *= require jquery.powertip
*= require jquery.ui.datepicker
*= require jquery-ui-timepicker-addon
*= require shared/textAngular
*= require shared/ng-tags-input.min
+ *= require select2
*= require_self
*/
@@ -33,6 +33,11 @@
@import 'plugins/powertip';
@import 'plugins/jstree';
@import 'plugins/font-awesome';
+@import 'plugins/select2';
+
+@import 'sections/image_settings';
+@import 'sections/orders';
+@import 'sections/products';
@import 'hacks/mozilla';
@import 'hacks/opera';
diff --git a/app/assets/stylesheets/admin/sections/image_settings.scss b/app/assets/stylesheets/admin/sections/image_settings.scss
new file mode 100644
index 0000000000..dc7a29b1b2
--- /dev/null
+++ b/app/assets/stylesheets/admin/sections/image_settings.scss
@@ -0,0 +1,3 @@
+.destroy_style, .destroy_header {
+ float: right;
+}
diff --git a/app/controllers/spree/admin/base_controller.rb b/app/controllers/spree/admin/base_controller.rb
index 80c50a55f2..1f5fbcfc1e 100644
--- a/app/controllers/spree/admin/base_controller.rb
+++ b/app/controllers/spree/admin/base_controller.rb
@@ -86,10 +86,6 @@ module Spree
raise(ActionController::InvalidAuthenticityToken)
end
- def config_locale
- Spree::Backend::Config[:locale]
- end
-
private
def html_request?
diff --git a/app/helpers/spree/admin/navigation_helper.rb b/app/helpers/spree/admin/navigation_helper.rb
index 3a5495488a..7dc9619a08 100644
--- a/app/helpers/spree/admin/navigation_helper.rb
+++ b/app/helpers/spree/admin/navigation_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: false
+
module Spree
module Admin
module NavigationHelper
@@ -34,7 +36,9 @@ module Spree
end
selected = if options[:match_path]
- request.fullpath.starts_with?("#{spree.root_path}admin#{options[:match_path]}")
+ request.
+ fullpath.
+ starts_with?("#{main_app.root_path}admin#{options[:match_path]}")
else
args.include?(controller.controller_name.to_sym)
end
diff --git a/app/services/permissions/order.rb b/app/services/permissions/order.rb
index 4dcc1f6ffd..5e95ba92c8 100644
--- a/app/services/permissions/order.rb
+++ b/app/services/permissions/order.rb
@@ -1,3 +1,5 @@
+require 'open_food_network/permissions'
+
module Permissions
class Order
def initialize(user)
diff --git a/app/views/spree/admin/images/new.html.haml b/app/views/spree/admin/images/new.html.haml
index 22a1e01998..4026cef6fb 100644
--- a/app/views/spree/admin/images/new.html.haml
+++ b/app/views/spree/admin/images/new.html.haml
@@ -7,4 +7,4 @@
%span.or= t('spree.or')
= link_to_with_icon 'icon-remove', t('spree.actions.cancel'), admin_product_images_url(@product), id: 'cancel_link', class: 'button'
-= javascript_include_tag 'admin/images/new.js'
+= javascript_include_tag 'admin/spree/images/new.js'
diff --git a/app/views/spree/admin/orders/customer_details/_autocomplete.js.erb b/app/views/spree/admin/orders/customer_details/_autocomplete.js.erb
new file mode 100644
index 0000000000..9484fa0dbb
--- /dev/null
+++ b/app/views/spree/admin/orders/customer_details/_autocomplete.js.erb
@@ -0,0 +1,19 @@
+
diff --git a/app/views/spree/admin/shared/_head.html.haml b/app/views/spree/admin/shared/_head.html.haml
index 7c47905b0d..375830063b 100644
--- a/app/views/spree/admin/shared/_head.html.haml
+++ b/app/views/spree/admin/shared/_head.html.haml
@@ -18,7 +18,6 @@
= render "spree/admin/shared/routes"
%script
- = "jQuery.alerts.dialogClass = 'spree';"
= raw "var AUTH_TOKEN = \"#{form_authenticity_token}\";"
= render "layouts/bugherd_script"
diff --git a/config/initializers/form_builder.rb b/config/initializers/form_builder.rb
new file mode 100644
index 0000000000..71b6038dd7
--- /dev/null
+++ b/config/initializers/form_builder.rb
@@ -0,0 +1,15 @@
+#
+# Allow some application_helper methods to be used in the scoped form_for manner
+#
+class ActionView::Helpers::FormBuilder
+ def field_container(method, options = {}, &block)
+ @template.field_container(@object_name,method,options,&block)
+ end
+
+ def error_message_on(method, options = {})
+ @template.error_message_on(@object_name, method, objectify_options(options))
+ end
+end
+
+ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}".html_safe }
+
diff --git a/config/routes/spree.rb b/config/routes/spree.rb
index 4e9c6aca44..095350b699 100644
--- a/config/routes/spree.rb
+++ b/config/routes/spree.rb
@@ -83,6 +83,8 @@ Spree::Core::Engine.routes.draw do
get '/variants/search', :to => "variants#search", :as => :search_variants
+ resources :properties
+
resources :orders do
member do
put :fire
@@ -110,8 +112,16 @@ Spree::Core::Engine.routes.draw do
end
resource :customer, :controller => "orders/customer_details"
+
+ resources :return_authorizations do
+ member do
+ put :fire
+ end
+ end
end
+ resources :reports
+
resources :users do
member do
put :generate_api_key
@@ -126,6 +136,7 @@ Spree::Core::Engine.routes.draw do
end
resource :image_settings
+ resources :trackers
resources :zones
resources :countries do
@@ -152,6 +163,10 @@ Spree::Core::Engine.routes.draw do
resources :tax_rates
resource :tax_settings
resources :tax_categories
+
+ resources :shipping_methods
+ resources :shipping_categories
+ resources :payment_methods
end
resources :orders do
diff --git a/spec/features/admin/products_spec.rb b/spec/features/admin/products_spec.rb
index 26c0af02ba..54c99ba8ea 100644
--- a/spec/features/admin/products_spec.rb
+++ b/spec/features/admin/products_spec.rb
@@ -203,6 +203,16 @@ feature '
expect(p.reload.property('fooprop')).to be_nil
end
+ scenario "loading new image page", js: true do
+ product = create(:simple_product, supplier: @supplier2)
+
+ visit spree.admin_product_images_path(product)
+ expect(page).to have_selector ".no-objects-found"
+
+ page.find('a#new_image_link').click
+ expect(page).to have_selector "#image_attachment"
+ end
+
scenario "deleting product images", js: true do
product = create(:simple_product, supplier: @supplier2)
image = File.open(File.expand_path('../../../app/assets/images/logo-white.png', __dir__))