Skip to content

Commit

Permalink
Added country/state validations and test cases for the store.
Browse files Browse the repository at this point in the history
  • Loading branch information
rahulsingh321 committed Feb 11, 2025
1 parent 5fbb438 commit 2567caf
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 76 deletions.
4 changes: 2 additions & 2 deletions api/lib/spree/api_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ def promotion_attributes=(value)
preference :store_attributes, :array, default: [
:id, :name, :legal_name, :url, :meta_description, :meta_keywords, :seo_title,
:mail_from_address, :default_currency, :code, :default,
:bcc_email, :contact_phone, :contact_email, :tax_id, :vat_id, :description,
:address1, :address2, :city, :postal_code, :country_id, :state_id, :state_name, :available_locales
:bcc_email, :phone, :contact_email, :tax_id, :vat_id, :description,
:address1, :address2, :city, :zipcode, :country_id, :state_id, :state_name, :available_locales
]

preference :store_credit_history_attributes, :array, default: [
Expand Down
102 changes: 94 additions & 8 deletions api/spec/requests/spree/api/stores_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

module Spree::Api
describe 'Stores', type: :request do
let(:country) { create :country, states_required: true }
let(:state) { create :state, name: 'maryland', abbr: 'md', country: }
let!(:base_attributes) { Spree::Api::Config.store_attributes }

let!(:store) do
create(:store, name: "My Spree Store", url: "spreestore.example.com")
end
Expand All @@ -22,6 +26,60 @@ module Spree::Api
default: false)
end

let(:country_with_states) { create(:country, states: [create(:state)]) }
let(:country_without_states) { create(:country) }

describe "Validations" do
context "when the country has states" do
it "is invalid without a state" do
store = Spree::Store.new(name: "Test Store", country: country_with_states, state: nil, url: "spreestore.example.com",
mail_from_address: "spreestore.example.com", code: "test-store",)
expect(store).not_to be_valid
expect(store.errors[:state]).to include("can't be blank")
end

it "is valid with a state" do
store = Spree::Store.new(name: "Test Store", country: country_with_states, state: state, url: "spreestore.example.com",
mail_from_address: "spreestore.example.com", code: "test-store",)
expect(store).to be_valid
end
end

context "when the country has no states" do
it "is valid without a state" do
store = Spree::Store.new(name: "Test Store", country: country_without_states, state: nil, url: "spreestore.example.com",
mail_from_address: "spreestore.example.com", code: "test-store",)
expect(store).to be_valid
end
end

it "is valid without an address and without country/state" do
expect(store).to be_valid
end

it "is valid with only correct country and state" do
store = Spree::Store.create!(
name: "Test Store",
url: "spreestore.example.com",
mail_from_address: "spreestore.example.com",
code: "test-store",
address1: "123 Main St",
city: "New York",
zipcode: "10001",
country: country,
)
expect(store).to be_valid
end
end

describe "#index" do
it "ensures the API store attributes match the expected attributes" do
get spree.api_stores_path
first_store = json_response["stores"].first
expect(first_store.keys).to include(*base_attributes.map(&:to_s))
end
end

it "can list the available stores" do
get spree.api_stores_path
expect(json_response["stores"]).to match_array([
Expand All @@ -39,15 +97,15 @@ module Spree::Api
"default" => true,
"available_locales" => ["en"],
"legal_name" => nil,
"contact_phone" => nil,
"contact_email" => nil,
"description" => nil,
"phone" => nil,
"tax_id" => nil,
"vat_id" => nil,
"address1" => nil,
"address2" => nil,
"city" => nil,
"postal_code" => nil,
"zipcode" => nil,
"country_id" => nil,
"state_id" => nil,
"state_name" => nil
Expand All @@ -66,15 +124,15 @@ module Spree::Api
"default" => false,
"available_locales" => ["en"],
"legal_name" => nil,
"contact_phone" => nil,
"contact_email" => nil,
"description" => nil,
"phone" => nil,
"tax_id" => nil,
"vat_id" => nil,
"address1" => nil,
"address2" => nil,
"city" => nil,
"postal_code" => nil,
"zipcode" => nil,
"country_id" => nil,
"state_id" => nil,
"state_name" => nil
Expand All @@ -98,15 +156,15 @@ module Spree::Api
"default" => true,
"available_locales" => ["en"],
"legal_name" => nil,
"contact_phone" => nil,
"contact_email" => nil,
"description" => nil,
"phone" => nil,
"tax_id" => nil,
"vat_id" => nil,
"address1" => nil,
"address2" => nil,
"city" => nil,
"postal_code" => nil,
"zipcode" => nil,
"country_id" => nil,
"state_id" => nil,
"state_name" => nil
Expand All @@ -118,7 +176,14 @@ module Spree::Api
code: "spree123",
name: "Hack0rz",
url: "spree123.example.com",
mail_from_address: "[email protected]"
mail_from_address: "[email protected]",
legal_name: 'ABC Corp',
address1: "123 Main St",
city: 'San Francisco',
country_id: country.id,
state_id: state.id,
phone: "123-456-7890",
zipcode: "12345"
}
post spree.api_stores_path, params: { store: store_hash }
expect(response.status).to eq(201)
Expand All @@ -128,13 +193,34 @@ module Spree::Api
store_hash = {
url: "spree123.example.com",
mail_from_address: "[email protected]",
bcc_email: "[email protected]"
bcc_email: "[email protected]",
legal_name: 'XYZ Corp',
description: "Leading provider of high-quality tech accessories, offering the latest gadgets, peripherals, and electronics to enhance your digital lifestyle.",
tax_id: "TX-987654321",
vat_id: "VAT-123456789",
address1: "123 Innovation Drive",
address2: "Suite 456",
city: "New York",
country_id: country.id,
state_id: state.id,
phone: "123-456-7888",
zipcode: "10001"
}
put spree.api_store_path(store), params: { store: store_hash }
expect(response.status).to eq(200)
expect(store.reload.url).to eql "spree123.example.com"
expect(store.reload.mail_from_address).to eql "[email protected]"
expect(store.reload.bcc_email).to eql "[email protected]"
expect(store.reload.legal_name).to eql "XYZ Corp"
expect(store.reload.tax_id).to eql "TX-987654321"
expect(store.reload.vat_id).to eql "VAT-123456789"
expect(store.reload.address1).to eql "123 Innovation Drive"
expect(store.reload.address2).to eql "Suite 456"
expect(store.reload.city).to eql "New York"
expect(store.reload.country_id).to eql country.id
expect(store.reload.state_id).to eql state.id
expect(store.reload.phone).to eql "123-456-7888"
expect(store.reload.zipcode).to eql "10001"
end

context "deleting a store" do
Expand Down
65 changes: 65 additions & 0 deletions backend/app/views/spree/admin/stores/_address_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

<% s_or_b = type.chars.first %>
<hr>

<div class="row" id="<%= type %>" data-hook="address_fields">
<div class="col-12 col-md-6">
<div class="field <%= "#{type}-row" %>">
<%= f.label :legal_name %>
<%= f.text_field :legal_name, class: 'fullwidth' %>
</div>

<div class="field <%= "#{type}-row" %>">
<%= f.label :address1 %>
<%= f.text_field :address1, class: 'fullwidth' %>
</div>

<div class="field <%= "#{type}-row" %>">
<%= f.label :address2 %>
<%= f.text_field :address2, class: 'fullwidth' %>
</div>

<div class="field <%= "#{type}-row" %>">
<%= f.label :phone %>
<%= f.phone_field :phone, class: 'fullwidth' %>
</div>
</div>

<div class="col-12 col-md-6">
<div class="field <%= "#{type}-row" %>">
<%= f.label :city %>
<%= f.text_field :city, class: 'fullwidth' %>
</div>

<div class="field <%= "#{type}-row" %>">
<%= f.label :zipcode %>
<%= f.text_field :zipcode, class: 'fullwidth' %>
</div>

<div class="field <%= "#{type}-row" %>">
<%= f.label :country_id, Spree::Country.model_name.human %>
<span id="<%= s_or_b %>country">
<%= f.collection_select :country_id, available_countries, :id, :name, { include_blank: true }, {class: 'custom-select fullwidth js-country_id'} %>
</span>
</div>

<div class="field <%= "#{type}-row" %>">
<%= f.label :state_id, Spree::State.model_name.human %>
<span id="<%= s_or_b %>state">
<%= f.hidden_field :state_name, value: nil %>
<% states = f.object.country.try(:states).nil? ? [] : f.object.country.states %>
<%= f.text_field :state_name,
style: "display: #{states.empty? ? 'block' : 'none' };",
disabled: !states.empty?, class: 'fullwidth state_name js-state_name' %>
<%= f.hidden_field :state_id, value: nil %>
<%= f.collection_select :state_id,
states.sort,
:id, :name,
{ include_blank: true },
{ class: 'custom-select fullwidth js-state_id',
style: "display: #{states.empty? ? 'none' : 'block' };",
disabled: states.empty? } %>
</span>
</div>
</div>
</div>
66 changes: 4 additions & 62 deletions backend/app/views/spree/admin/stores/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="row js-addresses-form">
<div class="row">
<div class="col-12 col-md-6">
<%= f.field_container :name do %>
<%= f.label :name, class: 'required' %>
Expand Down Expand Up @@ -31,18 +31,6 @@
<%= f.error_message_on :meta_description %>
<% end %>

<%= f.field_container :legal_name do %>
<%= f.label :legal_name %>
<%= f.text_field :legal_name, class: 'fullwidth' %>
<%= f.error_message_on :legal_name %>
<% end %>

<%= f.field_container :contact_phone do %>
<%= f.label :contact_phone %>
<%= f.phone_field :contact_phone, class: 'fullwidth' %>
<%= f.error_message_on :contact_phone %>
<% end %>

<%= f.field_container :tax_id do %>
<%= f.label :tax_id %>
<%= f.text_field :tax_id, class: 'fullwidth' %>
Expand Down Expand Up @@ -108,62 +96,16 @@
<%= f.error_message_on :default_currency %>
<% end %>

<%= f.field_container :contact_email do %>
<%= f.label :contact_email %>
<%= f.email_field :contact_email, class: 'fullwidth' %>
<%= f.error_message_on :contact_email %>
<% end %>

<%= f.field_container :description do %>
<%= f.label :description %>
<%= f.text_area :description, class: 'fullwidth', rows: 6 %>
<%= f.text_area :description, class: 'fullwidth' %>
<%= f.error_message_on :description %>
<% end %>
</div>

<div class="col-12">
<%= f.label :address %>
<div class="row border mx-1 py-3 border-secondary rounded">
<div class="col-md-6 mb-3">
<%= f.field_container :address1 do %>
<%= f.label :address1 %>
<%= f.text_field :address1, class: 'fullwidth' %>
<% end %>
</div>
<div class="col-md-6 mb-3">
<%= f.field_container :address2 do %>
<%= f.label :address2 %>
<%= f.text_field :address2, class: 'fullwidth' %>
<% end %>
</div>
<div class="col-md-6 mb-3">
<%= f.field_container :city do %>
<%= f.label :city %>
<%= f.text_field :city, class: 'fullwidth' %>
<% end %>
</div>
<div class="col-md-6 mb-3">
<%= f.field_container :postal_code do %>
<%= f.label :postal_code %>
<%= f.text_field :postal_code, class: 'fullwidth' %>
<% end %>
</div>
<div class="col-md-6 mb-3">
<%= f.field_container :country_id do %>
<%= f.label :country_id %>
<span id="country"><%= f.collection_select :country_id, available_countries(restrict_to_zone: nil), :id, :name, { include_blank: true }, { class: 'custom-select js-country_id fullwidth' } %></span>
<% end %>
</div>
<div class="col-md-6 mb-3">
<%= f.field_container :state do %>
<% country = f.object.country %>
<%= f.label :state_id %>
<span id="state" class="region">
<%= f.text_field :state_name, style: "display: none", class: 'fullwidth state_name js-state_name' %>
<%= f.collection_select :state_id, country ? country.states.sort : [], :id, :name, { include_blank: true }, {class: 'custom-select fullwidth js-state_id', style: "display: none" } %>
</span>
<% end %>
</div>
<div class="js-addresses-form">
<%= render partial: 'address_form', locals: { f: f, type: 'store' } %>
</div>
</div>
</div>
1 change: 1 addition & 0 deletions core/app/models/spree/store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class Store < Spree::Base
validates :name, presence: true
validates :url, presence: true
validates :mail_from_address, presence: true
validates :state, presence: true, if: -> { country&.states&.exists? }

self.allowed_ransackable_attributes = %w[name url code]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
class AddStoreAttributesToSpreeStores < ActiveRecord::Migration[7.2]
def change
add_column :spree_stores, :legal_name, :string
add_column :spree_stores, :contact_phone, :string
add_column :spree_stores, :contact_email, :string
add_column :spree_stores, :description, :text
add_column :spree_stores, :vat_id, :string
add_column :spree_stores, :tax_id, :string
add_column :spree_stores, :address1, :string
add_column :spree_stores, :address2, :string
add_column :spree_stores, :city, :string
add_column :spree_stores, :postal_code, :string
add_column :spree_stores, :zipcode, :string
add_column :spree_stores, :state_name, :string
add_column :spree_stores, :phone, :string
add_reference :spree_stores, :country, foreign_key: { to_table: :spree_countries }, index: true
add_reference :spree_stores, :state, foreign_key: { to_table: :spree_states }, index: true
end
Expand Down
4 changes: 2 additions & 2 deletions core/lib/spree/permitted_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ module PermittedAttributes
@@store_attributes = [:name, :legal_name, :url, :seo_title, :meta_keywords,
:meta_description, :default_currency,
:mail_from_address, :cart_tax_country_iso,
:bcc_email, :contact_email, :contact_phone, :code,
:bcc_email, :contact_email, :phone, :code,
:tax_id, :vat_id, :description, :address1, :address2,
:city, :postal_code, :country_id, :state_id, :state_name]
:city, :zipcode, :country_id, :state_id, :state_name]

@@taxonomy_attributes = [:name]

Expand Down

0 comments on commit 2567caf

Please sign in to comment.