diff --git a/app/assets/javascripts/admin/spree/orders/address_states.js b/app/assets/javascripts/admin/spree/orders/address_states.js index 5542e5656a..845c501f7f 100644 --- a/app/assets/javascripts/admin/spree/orders/address_states.js +++ b/app/assets/javascripts/admin/spree/orders/address_states.js @@ -4,8 +4,7 @@ var update_state = function(region) { var state_select = $('span#' + region + 'state select.select2'); var state_input = $('span#' + region + 'state input.state_name'); - $.get(Spree.routes.states_search + "?country_id=" + country, function(data) { - var states = data["states"] + $.get(Spree.routes.states_search + "?country_id=" + country, function(states) { if (states.length > 0) { state_select.html(''); var states_with_blank = [{name: '', id: ''}].concat(states); diff --git a/app/controllers/api/states_controller.rb b/app/controllers/api/states_controller.rb new file mode 100644 index 0000000000..708e40d277 --- /dev/null +++ b/app/controllers/api/states_controller.rb @@ -0,0 +1,34 @@ +module Api + class StatesController < Api::BaseController + respond_to :json + + skip_authorization_check + + def index + @states = scope.ransack(params[:q]).result. + includes(:country).order('name ASC') + + if params[:page] || params[:per_page] + @states = @states.page(params[:page]).per(params[:per_page]) + end + + render json: @states, each_serializer: Api::StateSerializer, status: :ok + end + + def show + @state = scope.find(params[:id]) + render json: @state, serializer: Api::StateSerializer, status: :ok + end + + private + + def scope + if params[:country_id] + @country = Spree::Country.find(params[:country_id]) + @country.states + else + Spree::State.all + end + end + end +end diff --git a/app/serializers/api/state_serializer.rb b/app/serializers/api/state_serializer.rb index 38ad444701..2862c24468 100644 --- a/app/serializers/api/state_serializer.rb +++ b/app/serializers/api/state_serializer.rb @@ -1,3 +1,3 @@ class Api::StateSerializer < ActiveModel::Serializer - attributes :id, :name, :abbr + attributes :id, :name, :abbr, :country_id end diff --git a/app/views/spree/admin/shared/_routes.html.erb b/app/views/spree/admin/shared/_routes.html.erb index ba3bbda3fe..15d562e4ef 100644 --- a/app/views/spree/admin/shared/_routes.html.erb +++ b/app/views/spree/admin/shared/_routes.html.erb @@ -2,6 +2,7 @@ Spree.routes = <%== { :variants_search => spree.admin_search_variants_path(:format => 'json'), :taxons_search => main_app.api_taxons_path(:format => 'json'), - :orders_api => main_app.api_orders_path + :orders_api => main_app.api_orders_path, + :states_search => main_app.api_states_path(:format => 'json') }.to_json %>; diff --git a/config/routes/api.rb b/config/routes/api.rb index 1147076112..f50a9c4763 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -61,6 +61,8 @@ Openfoodnetwork::Application.routes.draw do post '/product_images/:product_id', to: 'product_images#update_product_image' + resources :states, :only => [:index, :show] + resources :taxons, :only => [:index] resources :taxonomies do diff --git a/spec/controllers/api/states_controller_spec.rb b/spec/controllers/api/states_controller_spec.rb new file mode 100644 index 0000000000..3badf4a518 --- /dev/null +++ b/spec/controllers/api/states_controller_spec.rb @@ -0,0 +1,76 @@ +require 'spec_helper' + +module Api + describe StatesController do + render_views + + let!(:state) { create(:state, :name => "Victoria") } + let(:attributes) { [:id, :name, :abbr, :country_id] } + let(:current_user) { create(:user) } + + before do + allow(controller).to receive(:spree_current_user) { current_user } + end + + it "gets all states" do + api_get :index + expect(json_response.first.symbolize_keys.keys).to include(*attributes) + expect(json_response.map { |state| state[:name] }).to include(state.name) + end + + context "pagination" do + before do + Spree::State.should_receive(:all).and_return(@scope = double) + @scope.stub_chain(:ransack, :result, :includes, :order).and_return(@scope) + end + + it "does not paginate states results when asked not to do so" do + @scope.should_not_receive(:page) + @scope.should_not_receive(:per) + api_get :index + end + + it "paginates when page parameter is passed through" do + @scope.should_receive(:page).with(1).and_return(@scope) + @scope.should_receive(:per).with(nil) + api_get :index, :page => 1 + end + + it "paginates when per_page parameter is passed through" do + @scope.should_receive(:page).with(nil).and_return(@scope) + @scope.should_receive(:per).with(25) + api_get :index, :per_page => 25 + end + end + + + context "with two states" do + before { create(:state, :name => "New South Wales") } + + it "gets all states for a country" do + country = create(:country, :states_required => true) + state.country = country + state.save + + api_get :index, :country_id => country.id + expect(json_response.first.symbolize_keys.keys).to include(*attributes) + expect(json_response.count).to eq 1 + end + + it "can view all states" do + api_get :index + expect(json_response.first.symbolize_keys.keys).to include(*attributes) + end + + it 'can query the results through a paramter' do + api_get :index, :q => { :name_cont => 'Vic' } + expect(json_response.first['name']).to eq("Victoria") + end + end + + it "can view a state" do + api_get :show, :id => state.id + expect(json_response.symbolize_keys.keys).to include(*attributes) + end + end +end