Commit 74d3cdde authored by Alex Buijs's avatar Alex Buijs

Add API for states by country

Add an API route for fetching states by country
parent fac7279f
...@@ -118,6 +118,7 @@ Rails.application.routes.draw do ...@@ -118,6 +118,7 @@ Rails.application.routes.draw do
draw :trial draw :trial
draw :trial_registration draw :trial_registration
draw :country draw :country
draw :country_state
end end
Gitlab.ee do Gitlab.ee do
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
class CountriesController < ActionController::Metal class CountriesController < ActionController::Metal
include AbstractController::Rendering include AbstractController::Rendering
include ActionController::Renderers::All include ActionController::ApiRendering
include ActionController::Renderers
use_renderers :json
def index def index
countries = World.countries_for_select countries = World.countries_for_select
......
# frozen_string_literal: true
class CountryStatesController < ActionController::Metal
include AbstractController::Rendering
include ActionController::ApiRendering
include ActionController::Renderers
use_renderers :json
def index
country = params[:country]
states = World.states_for_country(country)
render json: states, status: (states ? :ok : :not_found)
end
end
---
title: Add API for states by country
merge_request: 21417
author:
type: added
# frozen_string_literal: true
resources :country_states, only: [:index]
...@@ -10,6 +10,18 @@ module World ...@@ -10,6 +10,18 @@ module World
strong_memoize(:countries_for_select) { all_countries.sort_by(&:name).map { |c| [c.name, c.alpha2] } } strong_memoize(:countries_for_select) { all_countries.sort_by(&:name).map { |c| [c.name, c.alpha2] } }
end end
def states_for_country(country_code)
strong_memoize("states_for_country_#{country_code}") do
country = ISO3166::Country.find_country_by_alpha2(country_code)
next unless country
country.states
&.reject { |_, state| state.name.nil? }
&.sort_by { |_, state| state.name }
&.map { |code, state| [state.name, code] }.to_h
end
end
def all_countries def all_countries
strong_memoize(:all_countries) { ISO3166::Country.all.reject {|item| DENYLIST.include?(item.name) } } strong_memoize(:all_countries) { ISO3166::Country.all.reject {|item| DENYLIST.include?(item.name) } }
end end
......
# frozen_string_literal: true
require 'spec_helper'
describe CountryStatesController do
describe 'GET #index' do
it 'returns a list of states as json' do
country = 'NL'
get :index, params: { country: country }
expected_json = World.states_for_country(country).to_json
expect(response.status).to eq(200)
expect(response.body).to eq(expected_json)
end
it 'returns "null" when the provided country is not found' do
country = 'NLX'
get :index, params: { country: country }
expect(response.status).to eq(404)
expect(response.body).to eq("null")
end
end
end
...@@ -18,4 +18,18 @@ describe World do ...@@ -18,4 +18,18 @@ describe World do
expect(result.first).to eq(%w[Afghanistan AF]) expect(result.first).to eq(%w[Afghanistan AF])
end end
end end
describe '.states_for_country' do
it 'returns a list of state names for a country in alphabetical order' do
result = described_class.states_for_country('NL')
expect(result.first).to eq(%w[Drenthe DR])
end
it 'returns nil when given country cannot be found' do
result = described_class.states_for_country('NLX')
expect(result).to be_nil
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment