diff --git a/app/controllers/spree/admin/general_settings_controller.rb b/app/controllers/spree/admin/general_settings_controller.rb new file mode 100644 index 0000000000..7389ee0890 --- /dev/null +++ b/app/controllers/spree/admin/general_settings_controller.rb @@ -0,0 +1,35 @@ +module Spree + module Admin + class GeneralSettingsController < Spree::Admin::BaseController + def edit + @preferences_general = [:site_name, :default_seo_title, :default_meta_keywords, + :default_meta_description, :site_url, :bugherd_api_key] + @preferences_security = [:allow_ssl_in_production, + :allow_ssl_in_staging, :allow_ssl_in_development_and_test, + :check_for_spree_alerts] + @preferences_currency = [:display_currency, :hide_cents] + end + + def update + params.each do |name, value| + next unless Spree::Config.has_preference? name + Spree::Config[name] = value + end + flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:general_settings)) + + redirect_to edit_admin_general_settings_path + end + + def dismiss_alert + return unless request.xhr? && params[:alert_id] + dismissed = Spree::Config[:dismissed_spree_alerts] || '' + Spree::Config.set(dismissed_spree_alerts: dismissed. + split(','). + push(params[:alert_id]). + join(',')) + filter_dismissed_alerts + render nothing: true + end + end + end +end diff --git a/app/controllers/spree/admin/general_settings_controller_decorator.rb b/app/controllers/spree/admin/general_settings_controller_decorator.rb deleted file mode 100644 index 7e6c1fc71a..0000000000 --- a/app/controllers/spree/admin/general_settings_controller_decorator.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Spree - module Admin - GeneralSettingsController.class_eval do - end - - module GeneralSettingsEditPreferences - def edit - super - @preferences_general << :bugherd_api_key - end - end - GeneralSettingsController.prepend(GeneralSettingsEditPreferences) - end -end diff --git a/app/controllers/spree/admin/image_settings_controller.rb b/app/controllers/spree/admin/image_settings_controller.rb new file mode 100644 index 0000000000..32aae5c783 --- /dev/null +++ b/app/controllers/spree/admin/image_settings_controller.rb @@ -0,0 +1,79 @@ +module Spree + module Admin + class ImageSettingsController < Spree::Admin::BaseController + def edit + @styles = ActiveSupport::JSON.decode(Spree::Config[:attachment_styles]) + @headers = ActiveSupport::JSON.decode(Spree::Config[:s3_headers]) + end + + def update + update_styles(params) + update_headers(params) if Spree::Config[:use_s3] + + Spree::Config.set(params[:preferences]) + update_paperclip_settings + + respond_to do |format| + format.html { + flash[:success] = Spree.t(:image_settings_updated) + redirect_to spree.edit_admin_image_settings_path + } + end + end + + private + + def update_styles(params) + if params[:new_attachment_styles].present? + params[:new_attachment_styles].each do |_index, style| + params[:attachment_styles][style[:name]] = style[:value] unless style[:value].empty? + end + end + + styles = params[:attachment_styles] + + Spree::Config[:attachment_styles] = ActiveSupport::JSON.encode(styles) unless styles.nil? + end + + def update_headers(params) + if params[:new_s3_headers].present? + params[:new_s3_headers].each do |_index, header| + params[:s3_headers][header[:name]] = header[:value] unless header[:value].empty? + end + end + + headers = params[:s3_headers] + + Spree::Config[:s3_headers] = ActiveSupport::JSON.encode(headers) unless headers.nil? + end + + def update_paperclip_settings + if Spree::Config[:use_s3] + s3_creds = { access_key_id: Spree::Config[:s3_access_key], + secret_access_key: Spree::Config[:s3_secret], + bucket: Spree::Config[:s3_bucket] } + Spree::Image.attachment_definitions[:attachment][:storage] = :s3 + Spree::Image.attachment_definitions[:attachment][:s3_credentials] = s3_creds + Spree::Image.attachment_definitions[:attachment][:s3_headers] = + ActiveSupport::JSON.decode(Spree::Config[:s3_headers]) + Spree::Image.attachment_definitions[:attachment][:bucket] = Spree::Config[:s3_bucket] + else + Spree::Image.attachment_definitions[:attachment].delete :storage + end + + Spree::Image.attachment_definitions[:attachment][:styles] = + ActiveSupport::JSON.decode(Spree::Config[:attachment_styles]).symbolize_keys! + Spree::Image.attachment_definitions[:attachment][:path] = Spree::Config[:attachment_path] + Spree::Image.attachment_definitions[:attachment][:default_url] = + Spree::Config[:attachment_default_url] + Spree::Image.attachment_definitions[:attachment][:default_style] = + Spree::Config[:attachment_default_style] + + # Spree stores attachent definitions in JSON. This converts the style name and format to + # strings. However, when paperclip encounters these, it doesn't recognise the format. + # Here we solve that problem by converting format and style name to symbols. + Spree::Image.reformat_styles + end + end + end +end diff --git a/app/controllers/spree/admin/image_settings_controller_decorator.rb b/app/controllers/spree/admin/image_settings_controller_decorator.rb deleted file mode 100644 index 5fe7dae551..0000000000 --- a/app/controllers/spree/admin/image_settings_controller_decorator.rb +++ /dev/null @@ -1,11 +0,0 @@ -Spree::Admin::ImageSettingsController.class_eval do - # Spree stores attachent definitions in JSON. This converts the style name and format to - # strings. However, when paperclip encounters these, it doesn't recognise the format. - # Here we solve that problem by converting format and style name to symbols. - def update_paperclip_settings_with_format_styles - update_paperclip_settings_without_format_styles - Spree::Image.reformat_styles - end - - alias_method_chain :update_paperclip_settings, :format_styles -end diff --git a/app/controllers/spree/admin/mail_methods_controller.rb b/app/controllers/spree/admin/mail_methods_controller.rb new file mode 100644 index 0000000000..867829c0bd --- /dev/null +++ b/app/controllers/spree/admin/mail_methods_controller.rb @@ -0,0 +1,39 @@ +module Spree + module Admin + class MailMethodsController < Spree::Admin::BaseController + after_filter :initialize_mail_settings + + def update + if params[:smtp_password].blank? + params.delete(:smtp_password) + end + + params.each do |name, value| + next unless Spree::Config.has_preference? name + Spree::Config[name] = value + end + + flash[:success] = Spree.t(:successfully_updated, resource: Spree.t(:mail_methods)) + render :edit + end + + def testmail + if TestMailer.test_email(try_spree_current_user).deliver + flash[:success] = Spree.t('admin.mail_methods.testmail.delivery_success') + else + flash[:error] = Spree.t('admin.mail_methods.testmail.delivery_error') + end + rescue StandardError => e + flash[:error] = Spree.t('admin.mail_methods.testmail.error') % { e: e } + ensure + redirect_to edit_admin_mail_method_url + end + + private + + def initialize_mail_settings + Spree::Core::MailSettings.init + end + end + end +end diff --git a/app/helpers/spree/admin/general_settings_helper.rb b/app/helpers/spree/admin/general_settings_helper.rb new file mode 100644 index 0000000000..c1c39ea58a --- /dev/null +++ b/app/helpers/spree/admin/general_settings_helper.rb @@ -0,0 +1,13 @@ +module Spree + module Admin + module GeneralSettingsHelper + def currency_options + currencies = ::Money::Currency.table.map do |_code, details| + iso = details[:iso_code] + [iso, "#{details[:name]} (#{iso})"] + end + options_from_collection_for_select(currencies, :first, :last, Spree::Config[:currency]) + end + end + end +end diff --git a/app/views/spree/admin/mail_methods/_form.html.haml b/app/views/spree/admin/mail_methods/_form.html.haml new file mode 100644 index 0000000000..670e37140e --- /dev/null +++ b/app/views/spree/admin/mail_methods/_form.html.haml @@ -0,0 +1,60 @@ +%div + .row + .alpha.six.columns + %fieldset.no-border-bottom + %legend{align: "center"}= t("spree.general") + .field + = preference_field_tag("enable_mail_delivery", Spree::Config[:enable_mail_delivery], type: :boolean) + = label_tag :enable_mail_delivery, t("spree.enable_mail_delivery") + .field + = label_tag :mails_from, t("spree.send_mails_as") + %br/ + = text_field_tag :mails_from, Spree::Config[:mails_from], maxlength: 256, class: 'fullwidth' + %br/ + %span.info + = t("spree.smtp_send_all_emails_as_from_following_address") + .field + = label_tag :mail_bcc, t("spree.send_copy_of_all_mails_to") + %br/ + = text_field_tag :mail_bcc, Spree::Config[:mail_bcc], maxlength: 256, class: 'fullwidth' + %br/ + %span.info + = t("spree.smtp_send_copy_to_this_addresses") + .field + = label_tag :intercept_email, t("spree.intercept_email_address") + %br/ + = text_field_tag :intercept_email, Spree::Config[:intercept_email], maxlength: 256, class: 'fullwidth' + %br/ + %span.info + = t("spree.intercept_email_instructions") + .six.columns.omega + %fieldset.no-border-bottom + %legend{align: "center"}= t("spree.smtp") + .field + = label_tag :mail_domain, t("spree.smtp_domain") + %br/ + = text_field_tag :mail_domain, Spree::Config[:mail_domain], class: 'fullwidth' + .field + = label_tag :mail_host, t("spree.smtp_mail_host") + %br/ + = text_field_tag :mail_host, Spree::Config[:mail_host], class: 'fullwidth' + .field + = label_tag :mail_port, t("spree.smtp_port") + %br/ + = text_field_tag :mail_port, Spree::Config[:mail_port], class: 'fullwidth' + .field + = label_tag :secure_connection_type, t("spree.secure_connection_type") + %br/ + = select_tag(:secure_connection_type, options_from_collection_for_select(Spree::Core::MailSettings::SECURE_CONNECTION_TYPES.map{|w| Spree.t(w.downcase.to_sym, default: w)}, :to_s, :to_s, Spree::Config[:secure_connection_type]), class: 'select2 fullwidth') + .field + = label_tag :mail_auth_type, t("spree.smtp_authentication_type") + %br/ + = select_tag(:mail_auth_type, options_from_collection_for_select(Spree::Core::MailSettings::MAIL_AUTH.map{|w| Spree.t(w.downcase.to_sym, default: w)}, :to_s, :to_s, Spree::Config[:mail_auth_type]), class: 'select2 fullwidth') + .field + = label_tag :smtp_username, t("spree.smtp_username") + %br/ + = text_field_tag :smtp_username, Spree::Config[:smtp_username], class: 'fullwidth' + .field + = label_tag :preferred_smtp_password, t("spree.smtp_password") + %br/ + = password_field_tag :smtp_password, Spree::Config[:smtp_password], class: 'fullwidth' diff --git a/app/views/spree/admin/mail_methods/edit.html.haml b/app/views/spree/admin/mail_methods/edit.html.haml new file mode 100644 index 0000000000..90938e4542 --- /dev/null +++ b/app/views/spree/admin/mail_methods/edit.html.haml @@ -0,0 +1,15 @@ += render partial: 'spree/admin/shared/configuration_menu' + +- content_for :page_title do + = t("spree.mail_method_settings") + +- content_for :page_actions do + %li + = link_to_with_icon 'icon-envelope-alt', t("spree.admin.mail_methods.send_testmail"), testmail_admin_mail_method_path, method: :post, title: t("spree.admin.mail_methods.send_testmail"), class: 'send_mail button no-text' + += render partial: 'spree/shared/error_messages', locals: { target: @mail_method } + += form_tag admin_mail_method_path, method: :put do |f| + %fieldset.no-border-top + = render partial: 'form', locals: { f: f } + .form-buttons.filter-actions.actions= button t("spree.actions.update"), 'icon-refresh' diff --git a/config/routes/spree.rb b/config/routes/spree.rb index 68a1dd9dda..77a954081e 100644 --- a/config/routes/spree.rb +++ b/config/routes/spree.rb @@ -90,6 +90,23 @@ Spree::Core::Engine.routes.prepend do end # Configuration section + resource :general_settings do + collection do + post :dismiss_alert + end + end + resource :mail_method, :only => [:edit, :update] do + post :testmail, :on => :collection + end + + resource :image_settings + + resources :zones + resources :countries do + resources :states + end + resources :states + resources :taxonomies do collection do post :update_positions @@ -109,12 +126,6 @@ Spree::Core::Engine.routes.prepend do resources :tax_rates resource :tax_settings resources :tax_categories - - resources :zones - resources :countries do - resources :states - end - resources :states end resources :orders do diff --git a/spec/controllers/spree/admin/image_settings_controller_spec.rb b/spec/controllers/spree/admin/image_settings_controller_spec.rb new file mode 100644 index 0000000000..8582b19eeb --- /dev/null +++ b/spec/controllers/spree/admin/image_settings_controller_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +describe Spree::Admin::ImageSettingsController do + include AuthenticationWorkflow + + before { login_as_admin } + + context "updating image settings" do + it "should be able to update paperclip settings" do + spree_put :update, preferences: { "attachment_path" => "foo/bar", + "attachment_default_url" => "baz/bar" } + + expect(Spree::Config[:attachment_path]).to eq("foo/bar") + expect(Spree::Config[:attachment_default_url]).to eq("baz/bar") + end + + context "paperclip styles" do + it "should be able to update the paperclip styles" do + spree_put :update, "attachment_styles" => { "thumb" => "25x25>" } + updated_styles = ActiveSupport::JSON.decode(Spree::Config[:attachment_styles]) + expect(updated_styles["thumb"]).to eq("25x25>") + end + + it "should be able to add a new style" do + spree_put :update, "attachment_styles" => {}, + "new_attachment_styles" => { "1" => { "name" => "jumbo", + "value" => "2000x2000>" } } + styles = ActiveSupport::JSON.decode(Spree::Config[:attachment_styles]) + expect(styles["jumbo"]).to eq("2000x2000>") + end + end + + context "amazon s3" do + after(:all) do + Spree::Image.attachment_definitions[:attachment].delete :storage + end + + it "should be able to update s3 settings" do + spree_put :update, preferences: + { + "use_s3" => "1", + "s3_access_key" => "a_valid_key", + "s3_secret" => "a_secret", + "s3_bucket" => "some_bucket" + } + expect(Spree::Config[:use_s3]).to be_truthy + expect(Spree::Config[:s3_access_key]).to eq("a_valid_key") + expect(Spree::Config[:s3_secret]).to eq("a_secret") + expect(Spree::Config[:s3_bucket]).to eq("some_bucket") + end + + context "headers" do + before(:each) { Spree::Config[:use_s3] = true } + + it "should be able to update the s3 headers" do + spree_put :update, "preferences" => { "use_s3" => "1" }, + "s3_headers" => { "Cache-Control" => "max-age=1111" } + headers = ActiveSupport::JSON.decode(Spree::Config[:s3_headers]) + expect(headers["Cache-Control"]).to eq("max-age=1111") + end + + it "should be able to add a new header" do + spree_put :update, "s3_headers" => {}, + "new_s3_headers" => { "1" => { "name" => "Charset", + "value" => "utf-8" } } + headers = ActiveSupport::JSON.decode(Spree::Config[:s3_headers]) + expect(headers["Charset"]).to eq("utf-8") + end + end + end + end +end diff --git a/spec/controllers/spree/admin/mail_methods_controller_spec.rb b/spec/controllers/spree/admin/mail_methods_controller_spec.rb new file mode 100644 index 0000000000..b58fc75da5 --- /dev/null +++ b/spec/controllers/spree/admin/mail_methods_controller_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe Spree::Admin::MailMethodsController do + include AuthenticationWorkflow + + before { login_as_admin } + + context "#update" do + it "should reinitialize the mail settings" do + expect(Spree::Core::MailSettings).to receive(:init) + spree_put :update, enable_mail_delivery: "1", mails_from: "spree@example.com" + end + end + + it "can trigger testmail" do + request.env["HTTP_REFERER"] = "/" + user = double('User', email: 'user@spree.com', + spree_api_key: 'fake', + id: nil, + owned_groups: nil) + allow(user).to receive_messages(enterprises: [create(:enterprise)], has_spree_role?: true) + allow(controller).to receive_messages(try_spree_current_user: user) + Spree::Config[:enable_mail_delivery] = "1" + ActionMailer::Base.perform_deliveries = true + + expect { + spree_post :testmail + }.to change { ActionMailer::Base.deliveries.size }.by(1) + end +end diff --git a/spec/features/admin/configuration/general_settings_spec.rb b/spec/features/admin/configuration/general_settings_spec.rb new file mode 100644 index 0000000000..0577d44cd6 --- /dev/null +++ b/spec/features/admin/configuration/general_settings_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe "General Settings" do + include AuthenticationWorkflow + + before(:each) do + quick_login_as_admin + visit spree.admin_path + click_link "Configuration" + click_link "General Settings" + end + + context "visiting general settings (admin)" do + it "should have the right content" do + expect(page).to have_content("General Settings") + expect(find("#site_name").value).to eq("Spree Demo Site") + expect(find("#site_url").value).to eq("demo.spreecommerce.com") + end + end + + context "editing general settings (admin)" do + it "should be able to update the site name" do + fill_in "site_name", with: "Spree Demo Site99" + click_button "Update" + + assert_successful_update_message(:general_settings) + + expect(find("#site_name").value).to eq("Spree Demo Site99") + end + + def assert_successful_update_message(resource) + flash = Spree.t(:successfully_updated, resource: Spree.t(resource)) + within("[class='flash success']") do + expect(page).to have_content(flash) + end + end + end +end diff --git a/spec/features/admin/configuration/image_settings_spec.rb b/spec/features/admin/configuration/image_settings_spec.rb new file mode 100644 index 0000000000..ff22c6a7c6 --- /dev/null +++ b/spec/features/admin/configuration/image_settings_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe "image settings" do + include AuthenticationWorkflow + + before do + quick_login_as_admin + visit spree.admin_path + click_link "Configuration" + click_link "Image Settings" + end + + # Regression test for #2344 + it "can update attachment_url" do + fill_in "Attachments URL", with: "foobar" + fill_in "Attachments Default URL", with: "barfoo" + fill_in "Attachments Path", with: "spec/dummy/tmp/bfaoro" + click_button "Update" + + expect(Spree::Config[:attachment_url]).to eq("foobar") + expect(Spree::Config[:attachment_default_url]).to eq("barfoo") + expect(Spree::Config[:attachment_path]).to eq("spec/dummy/tmp/bfaoro") + end + + # Regression test for #3069 + context "updates style configs and uploads products" do + let!(:product) { create(:product) } + let(:file_path) { Rails.root + "spec/support/fixtures/thinking-cat.jpg" } + + it "still uploads image gracefully" do + click_button "Update" + + visit spree.new_admin_product_image_path(product) + attach_file('image_attachment', file_path) + expect { + click_on "Update" + }.to_not raise_error + end + end +end diff --git a/spec/features/admin/configuration/mail_methods_spec.rb b/spec/features/admin/configuration/mail_methods_spec.rb new file mode 100644 index 0000000000..834b3dabe7 --- /dev/null +++ b/spec/features/admin/configuration/mail_methods_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe "Mail Methods" do + include AuthenticationWorkflow + + before(:each) do + quick_login_as_admin + visit spree.admin_path + click_link "Configuration" + end + + context "edit" do + before(:each) do + click_link "Mail Method Settings" + end + + it "should be able to edit mail method settings" do + fill_in "mail_bcc", with: "spree@example.com99" + click_button "Update" + expect(page).to have_content("successfully updated!") + end + + # Regression test for #2094 + it "does not clear password if not provided" do + Spree::Config[:smtp_password] = "haxme" + click_button "Update" + expect(page).to have_content("successfully updated!") + + expect(Spree::Config[:smtp_password]).not_to be_blank + end + end +end