From 3a2129ef53a359dfde9690ee9d966870b796f03d Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Thu, 24 Sep 2026 10:59:39 +0200 Subject: [PATCH 1/4] Add optional address to Spree::Store Stores had no way to record their own postal address. Invoices usually have to show the seller's address, and so can packing slips, order emails, return labels and the storefront footer. --- core/app/models/spree/store.rb | 6 +++ ...60924120000_add_address_to_spree_stores.rb | 9 ++++ core/lib/spree/permitted_attributes.rb | 3 +- .../factories/store_factory.rb | 4 ++ core/spec/models/spree/store_spec.rb | 46 +++++++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 core/db/migrate/20260924120000_add_address_to_spree_stores.rb diff --git a/core/app/models/spree/store.rb b/core/app/models/spree/store.rb index 75902a43cb7..96866402e87 100644 --- a/core/app/models/spree/store.rb +++ b/core/app/models/spree/store.rb @@ -17,6 +17,8 @@ class Store < Spree::Base has_many :orders, class_name: "Spree::Order" + belongs_to :address, class_name: "Spree::Address", optional: true, validate: true + validates :code, presence: true, uniqueness: {allow_blank: true, case_sensitive: true} validates :name, presence: true validates :url, presence: true @@ -51,6 +53,10 @@ def available_locales=(locales) end end + def address_attributes=(attributes) + self.address = Spree::Address.immutable_merge(address, attributes) + end + def self.default where(default: true).first || new end diff --git a/core/db/migrate/20260924120000_add_address_to_spree_stores.rb b/core/db/migrate/20260924120000_add_address_to_spree_stores.rb new file mode 100644 index 00000000000..db8c02dc290 --- /dev/null +++ b/core/db/migrate/20260924120000_add_address_to_spree_stores.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddAddressToSpreeStores < ActiveRecord::Migration[7.0] + def change + change_table :spree_stores do |t| + t.references :address, type: :integer, foreign_key: {to_table: :spree_addresses} + end + end +end diff --git a/core/lib/spree/permitted_attributes.rb b/core/lib/spree/permitted_attributes.rb index 63e007446de..2e43fd003b2 100644 --- a/core/lib/spree/permitted_attributes.rb +++ b/core/lib/spree/permitted_attributes.rb @@ -125,7 +125,8 @@ module PermittedAttributes @@store_attributes = [:name, :url, :seo_title, :meta_keywords, :meta_description, :default_currency, :mail_from_address, :cart_tax_country_iso, - :bcc_email, :reverse_charge_status] + :bcc_email, :reverse_charge_status, + address_attributes:] @@taxonomy_attributes = [:name] diff --git a/core/lib/spree/testing_support/factories/store_factory.rb b/core/lib/spree/testing_support/factories/store_factory.rb index 008e2c9a823..747054adb7a 100644 --- a/core/lib/spree/testing_support/factories/store_factory.rb +++ b/core/lib/spree/testing_support/factories/store_factory.rb @@ -6,5 +6,9 @@ sequence(:name) { |i| "Spree Test Store #{i}" } sequence(:url) { |i| "www.example#{i}.com" } mail_from_address { "solidus@example.org" } + + trait :with_address do + address + end end end diff --git a/core/spec/models/spree/store_spec.rb b/core/spec/models/spree/store_spec.rb index 24b0d3e404d..c03e25d58eb 100644 --- a/core/spec/models/spree/store_spec.rb +++ b/core/spec/models/spree/store_spec.rb @@ -137,6 +137,52 @@ end end + describe "#address" do + it "is optional" do + expect(build(:store, address: nil)).to be_valid + end + + it "can be assigned" do + store = create(:store, :with_address) + expect(store.reload.address).to be_a(Spree::Address) + end + end + + describe "#address_attributes=" do + let(:address_attributes) { attributes_for(:address).merge(country_id: create(:country, states_required: false).id) } + + it "creates an address" do + store = create(:store, address_attributes:) + expect(store.reload.address).to have_attributes(address_attributes.slice(:name, :address1, :city)) + end + + it "invalidates the store if the address is invalid" do + store = build(:store, address_attributes: address_attributes.merge(city: nil)) + expect(store).not_to be_valid + expect(store.errors).to include(:address) + end + + it "does not modify the existing address on change" do + store = create(:store, :with_address) + original_address = store.address + + store.update!(address_attributes: {city: "New City"}) + + expect(store.reload.address).not_to eq(original_address) + expect(store.address.city).to eq("New City") + expect(original_address.reload.city).not_to eq("New City") + end + + it "keeps the existing address if nothing changed" do + store = create(:store, :with_address) + original_address = store.address + + store.update!(address_attributes: {city: original_address.city}) + + expect(store.reload.address).to eq(original_address) + end + end + describe "#validate_not_default" do context "when deleting a default store" do it "prevents deletion" do From 561554fd3bf3ec936fb1c74bae6ee9863f4ad07d Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Thu, 24 Sep 2026 11:15:03 +0200 Subject: [PATCH 2/4] Add address field to stores API Render the address field if an address is connected to the store. The index and show views share a new `_store` partial, and the OpenAPI spec documents both the new response field and the new input field. --- .../spree/api/stores/_store.json.jbuilder | 10 ++++ .../spree/api/stores/index.json.jbuilder | 2 +- .../views/spree/api/stores/show.json.jbuilder | 2 +- api/openapi/solidus-api.oas.yml | 4 ++ api/spec/requests/spree/api/stores_spec.rb | 53 +++++++++++++++++-- 5 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 api/app/views/spree/api/stores/_store.json.jbuilder diff --git a/api/app/views/spree/api/stores/_store.json.jbuilder b/api/app/views/spree/api/stores/_store.json.jbuilder new file mode 100644 index 00000000000..138b5ab5bcd --- /dev/null +++ b/api/app/views/spree/api/stores/_store.json.jbuilder @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +json.call(store, *store_attributes) +json.address do + if store.address + json.partial!("spree/api/addresses/address", address: store.address) + else + json.nil! + end +end diff --git a/api/app/views/spree/api/stores/index.json.jbuilder b/api/app/views/spree/api/stores/index.json.jbuilder index 35f4557e9ef..c08b8810b9b 100644 --- a/api/app/views/spree/api/stores/index.json.jbuilder +++ b/api/app/views/spree/api/stores/index.json.jbuilder @@ -1,3 +1,3 @@ # frozen_string_literal: true -json.stores(@stores) { |store| json.call(store, *store_attributes) } +json.stores(@stores) { |store| json.partial!("spree/api/stores/store", store:) } diff --git a/api/app/views/spree/api/stores/show.json.jbuilder b/api/app/views/spree/api/stores/show.json.jbuilder index 84c286ae281..183b546599f 100644 --- a/api/app/views/spree/api/stores/show.json.jbuilder +++ b/api/app/views/spree/api/stores/show.json.jbuilder @@ -1,3 +1,3 @@ # frozen_string_literal: true -json.call(@store, *store_attributes) +json.partial!("spree/api/stores/store", store: @store) diff --git a/api/openapi/solidus-api.oas.yml b/api/openapi/solidus-api.oas.yml index a59c2662b8f..624a1847d99 100644 --- a/api/openapi/solidus-api.oas.yml +++ b/api/openapi/solidus-api.oas.yml @@ -6474,6 +6474,8 @@ components: type: string url: type: string + address: + $ref: '#/components/schemas/address' taxonomy: type: object properties: @@ -6955,6 +6957,8 @@ components: type: string cart_tax_country_iso: type: string + address_attributes: + $ref: '#/components/schemas/address-input' taxonomy-input: type: object title: Taxonomy input diff --git a/api/spec/requests/spree/api/stores_spec.rb b/api/spec/requests/spree/api/stores_spec.rb index e036e081d9c..2c34dbda8e7 100644 --- a/api/spec/requests/spree/api/stores_spec.rb +++ b/api/spec/requests/spree/api/stores_spec.rb @@ -38,7 +38,8 @@ module Spree::Api "default_currency" => nil, "code" => store.code, "default" => true, - "available_locales" => ["en"] + "available_locales" => ["en"], + "address" => nil }, { "id" => non_default_store.id, @@ -53,7 +54,8 @@ module Spree::Api "default_currency" => nil, "code" => non_default_store.code, "default" => false, - "available_locales" => ["en"] + "available_locales" => ["en"], + "address" => nil } ]) end @@ -73,7 +75,8 @@ module Spree::Api "default_currency" => nil, "code" => store.code, "default" => true, - "available_locales" => ["en"] + "available_locales" => ["en"], + "address" => nil ) end @@ -101,6 +104,50 @@ module Spree::Api expect(store.reload.bcc_email).to eql "bcc@example.net" end + context "address" do + let(:country) { create(:country, states_required: false) } + let(:address_params) do + attributes_for(:address).slice(:name, :address1, :city, :zipcode, :phone).merge(country_id: country.id) + end + + it "includes the address in the store details" do + store.update!(address: create(:address)) + get spree.api_store_path(store) + expect(json_response["address"]).to include( + "id" => store.address.id, + "address1" => store.address.address1, + "city" => store.address.city + ) + expect(json_response["address"]["country"]).to include("iso" => store.address.country.iso) + end + + it "can create a new store with an address" do + store_hash = { + code: "spree123", + name: "Hack0rz", + url: "spree123.example.com", + mail_from_address: "me@example.com", + address_attributes: address_params + } + post spree.api_stores_path, params: {store: store_hash} + expect(response.status).to eq(201) + expect(json_response["address"]).to include("address1" => address_params[:address1]) + end + + it "can update the address of an existing store" do + put spree.api_store_path(store), params: {store: {address_attributes: address_params}} + expect(response.status).to eq(200) + expect(store.reload.address.address1).to eq(address_params[:address1]) + expect(store.address.country).to eq(country) + end + + it "responds with an error for an invalid address" do + put spree.api_store_path(store), params: {store: {address_attributes: address_params.merge(city: "")}} + expect(response.status).to eq(422) + expect(json_response["errors"]).to include("address") + end + end + context "deleting a store" do it "will fail if it's the default Store" do delete spree.api_store_path(store) From 2c531242c1279d9934bca2c454bc39b73a85ce40 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Thu, 24 Sep 2026 12:23:51 +0200 Subject: [PATCH 3/4] Add address form to solidus_admin Add the address form to the stores edit view. Add only basic address information including vat_id to reduce the number of form fields and make the address panel a bit more compact. Email and phone number are normally not necessary on invoices or packaging slips. The phone number is only available if the address_requires_phone is enabled. --- .../stores/form/component.html.erb | 9 ++++ .../solidus_admin/stores/form/component.rb | 10 ++++ .../solidus_admin/stores/form/component.yml | 1 + .../solidus_admin/stores_controller.rb | 8 ++- admin/spec/features/stores_spec.rb | 23 +++++++++ .../requests/solidus_admin/stores_spec.rb | 49 +++++++++++++++++++ 6 files changed, 98 insertions(+), 2 deletions(-) diff --git a/admin/app/components/solidus_admin/stores/form/component.html.erb b/admin/app/components/solidus_admin/stores/form/component.html.erb index f22c6c5328b..a82f303ec16 100644 --- a/admin/app/components/solidus_admin/stores/form/component.html.erb +++ b/admin/app/components/solidus_admin/stores/form/component.html.erb @@ -11,6 +11,15 @@ <% end %> <% end %> + <%= render component('ui/panel').new(title: t('.address')) do |panel| %> + <% panel.with_section do %> + <%= render component('ui/forms/address').new( + addressable: address, + form_field_name: "store[address_attributes]", + excludes: address_excludes + ) %> + <% end %> + <% end %> <%= render component('ui/panel').new(title: t('.localization')) do |panel| %> <% panel.with_section(class: "flex flex-col gap-4") do %>
diff --git a/admin/app/components/solidus_admin/stores/form/component.rb b/admin/app/components/solidus_admin/stores/form/component.rb index 7ff6fbb4198..0d849e46bad 100644 --- a/admin/app/components/solidus_admin/stores/form/component.rb +++ b/admin/app/components/solidus_admin/stores/form/component.rb @@ -9,6 +9,16 @@ def initialize(store:, id:, url:) @url = url end + def address + @store.address || Spree::Address.new(country: Spree::Country.find_by(iso: Spree::Config.default_country_iso)) + end + + def address_excludes + excludes = [:email, :street_contd] + excludes << :phone unless Spree::Config.address_requires_phone + excludes + end + def available_locales Spree.i18n_available_locales.map do |locale| [I18n.t("spree.i18n.this_file_language", locale: locale, default: locale.to_s, fallback: false), locale] diff --git a/admin/app/components/solidus_admin/stores/form/component.yml b/admin/app/components/solidus_admin/stores/form/component.yml index 9f8ce0ff5b5..72fdf85aadf 100644 --- a/admin/app/components/solidus_admin/stores/form/component.yml +++ b/admin/app/components/solidus_admin/stores/form/component.yml @@ -1,4 +1,5 @@ en: + address: Address localization: Localization plugins: install: Install diff --git a/admin/app/controllers/solidus_admin/stores_controller.rb b/admin/app/controllers/solidus_admin/stores_controller.rb index d86d03f6e97..c6fcba3cd5b 100644 --- a/admin/app/controllers/solidus_admin/stores_controller.rb +++ b/admin/app/controllers/solidus_admin/stores_controller.rb @@ -55,8 +55,12 @@ def permitted_resource_params :mail_from_address, :default_currency, :cart_tax_country_iso, - available_locales: [] - ) + available_locales: [], + address_attributes: Spree::PermittedAttributes.address_attributes + ).tap do |store_params| + without_address_parameter = store_params[:address_attributes]&.except(:country_id, :state_id, :reverse_charge_status)&.compact_blank&.empty? + store_params.delete(:address_attributes) if without_address_parameter + end end end end diff --git a/admin/spec/features/stores_spec.rb b/admin/spec/features/stores_spec.rb index 40ea5a9f4cc..7382909693d 100644 --- a/admin/spec/features/stores_spec.rb +++ b/admin/spec/features/stores_spec.rb @@ -83,6 +83,7 @@ available_locales: %w[en]) create(:country, iso: "US") + create(:country, iso: "DE", states_required: false) visit "/admin/stores" click_on "B2C Store" expect(page).to be_axe_clean @@ -111,6 +112,28 @@ expect(solidus_select_control("Default Currency")).to have_content("USD") expect(solidus_select_control("Tax Country")).to have_content("United States") end + + it "updates store address" do + expect(page).not_to have_field("Email", exact: true) + + fill_in "Name", with: "B2C Store Inc." + fill_in "Street Address", with: "1 Store Street" + fill_in "City", with: "Storetown" + fill_in "Zip Code", with: "12345" + fill_in "Phone", with: "555-555-0199" + solidus_select("Germany", from: "Country") + + within("header") { click_on "Save" } + + expect(page).to have_content("Store was successfully updated") + expect(Spree::Store.find_by(name: "B2C Store").address).to have_attributes( + name: "B2C Store Inc.", + address1: "1 Store Street", + city: "Storetown", + phone: "555-555-0199", + country: Spree::Country.find_by(iso: "DE") + ) + end end describe "clicking Discard" do diff --git a/admin/spec/requests/solidus_admin/stores_spec.rb b/admin/spec/requests/solidus_admin/stores_spec.rb index 0c8718bd945..f409528d807 100644 --- a/admin/spec/requests/solidus_admin/stores_spec.rb +++ b/admin/spec/requests/solidus_admin/stores_spec.rb @@ -11,4 +11,53 @@ let(:valid_attributes) { {name: "Store", code: "store", url: "store.com", mail_from_address: "store@example.com"} } let(:invalid_attributes) { {name: ""} } end + + describe "address" do + let(:admin_user) { create(:admin_user) } + let(:store) { create(:store, default: false) } + let(:country) { create(:country, states_required: false) } + let(:address_attributes) do + {name: "Store Inc.", address1: "1 Store Street", city: "Storetown", zipcode: "12345", phone: "555-555-0199", vat_id: "DE123456789", country_id: country.id} + end + + before { allow_any_instance_of(SolidusAdmin::BaseController).to receive(:spree_current_user).and_return(admin_user) } + + it "renders the address fields without email, address2 and VAT-ID" do + get solidus_admin.edit_store_path(store) + expect(response.body).to include('name="store[address_attributes][address1]"') + expect(response.body).to include('name="store[address_attributes][phone]"') + expect(response.body).not_to include('name="store[address_attributes][email]"') + expect(response.body).not_to include('name="store[address_attributes][address2]"') + expect(response.body).not_to include('name="store[address_attributes][vat_id]"') + end + + it "does not render the phone field if phone is not required" do + allow(Spree::Config).to receive(:address_requires_phone).and_return(false) + get solidus_admin.edit_store_path(store) + expect(response.body).not_to include('name="store[address_attributes][phone]"') + end + + it "renders the VAT-ID once if reverse charge fields are shown" do + allow(Spree::Backend::Config).to receive(:show_reverse_charge_fields).and_return(true) + get solidus_admin.edit_store_path(store) + expect(response.body.scan('name="store[address_attributes][vat_id]"').size).to eq(1) + end + + it "saves the address" do + patch solidus_admin.store_path(store), params: {store: {address_attributes:}} + expect(store.reload.address).to have_attributes(address_attributes) + end + + it "does not create an address from blank fields" do + patch solidus_admin.store_path(store), params: {store: {address_attributes: {name: "", address1: "", country_id: country.id, reverse_charge_status: "disabled"}}} + expect(response).to have_http_status(:see_other) + expect(store.reload.address).to be_nil + end + + it "creates a store without address from blank fields" do + post solidus_admin.stores_path, params: {store: {name: "New Store", code: "new-store", url: "new-store.com", mail_from_address: "store@example.com", address_attributes: {name: "", address1: "", country_id: country.id}}} + expect(response).to have_http_status(:see_other) + expect(Spree::Store.find_by!(code: "new-store").address).to be_nil + end + end end From 8c1734d7cfddfabcb2b9e773db0b7a14afb92c66 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz Date: Thu, 24 Sep 2026 12:54:11 +0200 Subject: [PATCH 4/4] Add address form also to backend store settings Lets backend users set the store address for invoices, matching the new admin. Both forms hide email and the second street line, and hide phone unless `address_requires_phone` is enabled. The shared address partial now accepts an optional `excludes` local. This change was necessary to reduce the number of fields. --- .../spree/admin/stores_controller.rb | 7 +++ .../spree/admin/shared/_address_form.html.erb | 30 ++++++----- .../views/spree/admin/stores/_form.html.erb | 7 +++ .../spree/admin/stores_controller_spec.rb | 50 +++++++++++++++++++ .../admin/configuration/store_spec.rb | 23 +++++++++ 5 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 backend/spec/controllers/spree/admin/stores_controller_spec.rb diff --git a/backend/app/controllers/spree/admin/stores_controller.rb b/backend/app/controllers/spree/admin/stores_controller.rb index 6c78c6f8752..3fc5c9789fc 100644 --- a/backend/app/controllers/spree/admin/stores_controller.rb +++ b/backend/app/controllers/spree/admin/stores_controller.rb @@ -13,6 +13,13 @@ def index private + def permitted_resource_params + super.tap do |store_params| + without_address_parameters = store_params[:address_attributes]&.except(:country_id, :state_id, :reverse_charge_status)&.compact_blank&.empty? + store_params.delete(:address_attributes) if without_address_parameters + end + end + def store_params params.require(:store).permit(permitted_params) end diff --git a/backend/app/views/spree/admin/shared/_address_form.html.erb b/backend/app/views/spree/admin/shared/_address_form.html.erb index b595ef47142..e94fa2cea14 100644 --- a/backend/app/views/spree/admin/shared/_address_form.html.erb +++ b/backend/app/views/spree/admin/shared/_address_form.html.erb @@ -18,10 +18,12 @@ <%= f.text_field :address1, class: 'fullwidth' %>
-
"> - <%= f.label :address2 %> - <%= f.text_field :address2, class: 'fullwidth' %> -
+ <% unless local_assigns.fetch(:excludes, []).include?(:address2) %> +
"> + <%= f.label :address2 %> + <%= f.text_field :address2, class: 'fullwidth' %> +
+ <% end %>
"> <%= f.label :city %> @@ -59,15 +61,19 @@
-
"> - <%= f.label :phone %> - <%= f.phone_field :phone, class: 'fullwidth' %> -
+ <% unless local_assigns.fetch(:excludes, []).include?(:phone) %> +
"> + <%= f.label :phone %> + <%= f.phone_field :phone, class: 'fullwidth' %> +
+ <% end %> -
"> - <%= f.label :email %> - <%= f.email_field :email, class: 'fullwidth' %> -
+ <% unless local_assigns.fetch(:excludes, []).include?(:email) %> +
"> + <%= f.label :email %> + <%= f.email_field :email, class: 'fullwidth' %> +
+ <% end %> <% if Spree::Backend::Config.show_reverse_charge_fields %>
"> diff --git a/backend/app/views/spree/admin/stores/_form.html.erb b/backend/app/views/spree/admin/stores/_form.html.erb index 52cdaf346e8..ae615d900ae 100644 --- a/backend/app/views/spree/admin/stores/_form.html.erb +++ b/backend/app/views/spree/admin/stores/_form.html.erb @@ -41,6 +41,13 @@ <%= f.error_message_on :reverse_charge_status %> <% end %> <% end %> + +
+ <%= Spree::Address.model_name.human %> + <%= f.fields_for :address, f.object.address || Spree::Address.new(country: Spree::Country.find_by(iso: Spree::Config.default_country_iso)) do |address_form| %> + <%= render partial: 'spree/admin/shared/address_form', locals: { f: address_form, type: "store", excludes: Spree::Config.address_requires_phone ? [:address2, :email] : [:address2, :email, :phone] } %> + <% end %> +
<%= f.field_container :url do %> diff --git a/backend/spec/controllers/spree/admin/stores_controller_spec.rb b/backend/spec/controllers/spree/admin/stores_controller_spec.rb new file mode 100644 index 00000000000..05ecd695acd --- /dev/null +++ b/backend/spec/controllers/spree/admin/stores_controller_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Spree::Admin::StoresController, type: :controller do + stub_authorization! + + let(:store) { create(:store) } + let(:country) { create(:country, states_required: false) } + let(:address_attributes) do + {name: "Store Inc.", address1: "1 Store Street", city: "Storetown", zipcode: "12345", phone: "555-555-0199", country_id: country.id} + end + + describe "#edit" do + render_views + + it "renders the address fields without email and address2" do + get :edit, params: {id: store.id} + expect(response.body).to include('name="store[address_attributes][address1]"') + expect(response.body).to include('name="store[address_attributes][phone]"') + expect(response.body).not_to include('name="store[address_attributes][email]"') + expect(response.body).not_to include('name="store[address_attributes][address2]"') + end + + it "does not render the phone field if phone is not required" do + stub_spree_preferences(address_requires_phone: false) + get :edit, params: {id: store.id} + expect(response.body).not_to include('name="store[address_attributes][phone]"') + end + end + + describe "#update" do + it "saves the address" do + put :update, params: {id: store.id, store: {address_attributes:}} + expect(store.reload.address).to have_attributes(address_attributes) + end + + it "does not create an address from blank fields" do + put :update, params: {id: store.id, store: {name: "New Name", address_attributes: {name: "", address1: "", country_id: country.id, reverse_charge_status: "disabled"}}} + expect(store.reload).to have_attributes(name: "New Name", address: nil) + end + end + + describe "#create" do + it "creates a store without address from blank fields" do + post :create, params: {store: {name: "New Store", code: "new-store", url: "new-store.com", mail_from_address: "store@example.com", address_attributes: {name: "", address1: "", country_id: country.id}}} + expect(Spree::Store.find_by!(code: "new-store").address).to be_nil + end + end +end diff --git a/backend/spec/features/admin/configuration/store_spec.rb b/backend/spec/features/admin/configuration/store_spec.rb index 1a566c241d0..7fd5e36400c 100644 --- a/backend/spec/features/admin/configuration/store_spec.rb +++ b/backend/spec/features/admin/configuration/store_spec.rb @@ -11,6 +11,7 @@ end let!(:vat_country) { create(:country, iso: "DE", name: "Germany") } + let!(:store_country) { create(:country, iso: "AT", states_required: false) } before(:each) do visit spree.admin_path @@ -47,6 +48,28 @@ end end + context "editing the store address" do + it "should be able to save the address" do + within("[data-hook='store_address_wrapper']") do + expect(page).not_to have_field("Email") + fill_in "Name", with: "Test Store Inc." + fill_in "Street Address", with: "1 Store Street" + fill_in "City", with: "Storetown" + fill_in "Zip Code", with: "12345" + fill_in "Phone", with: "555-555-0199" + select "Austria", from: "Country" + end + click_button "Update" + + expect(page).to have_content("has been successfully updated") + expect(store.reload.address).to have_attributes( + name: "Test Store Inc.", + address1: "1 Store Street", + country: store_country + ) + end + end + context "update fails" do it "should display the error" do fill_in "Site Name", with: " "