regions and cities requests plus tests

This commit is contained in:
Mike Slemmer 2012-12-15 12:17:41 -08:00
parent 2a63593726
commit 6768472528
5 changed files with 90 additions and 6 deletions

View File

@ -0,0 +1,23 @@
class ApiMaxMindRequestsController < ApiController
respond_to :json
def regions
regions = MaxMindManager.regions(params[:country])
if regions && regions.length > 0
render :json => { :regions => regions }, :status => 200
else
render :json => { :message => "Unrecognized Country" }, :status => 404
end
end
def cities
cities = MaxMindManager.cities(params[:country], params[:region])
if cities && cities.length > 0
render :json => { :cities => cities }, :status => 200
else
render :json => { :message => "Unrecognzied country or region" }, :status => 404
end
end
end

View File

@ -150,5 +150,9 @@ SampleApp::Application.routes.draw do
match '/join_requests/:id' => 'api_join_requests#delete', :via => :delete
match '/join_requests' => 'api_join_requests#create', :via => :post
match '/join_requests' => 'api_join_requests#index', :via => :get
# Location lookups
match '/regions' => 'api_maxmind_requests#regions', :via => :get
match '/cities' => 'api_maxmind_requests#cities', :via => :get
end
end

View File

@ -33,6 +33,27 @@ class MaxMindManager < BaseManager
end
def self.regions(country)
ActiveRecord::Base.connection_pool.with_connection do |connection|
pg_conn = connection.instance_variable_get("@connection")
pg_conn.exec("SELECT DISTINCT region FROM max_mind WHERE country = $1 ORDER BY region ASC", [country]).map do |tuple|
tuple["region"]
end
end
end
def self.cities(country, region)
ActiveRecord::Base.connection_pool.with_connection do |connection|
pg_conn = connection.instance_variable_get("@connection")
pg_conn.exec("SELECT DISTINCT city FROM max_mind WHERE country = $1 AND region = $2 ORDER BY city ASC", [country, region]).map do |tuple|
tuple["city"]
end
end
end
# Do this in a transaction so there's no partial import.
def import_database(filename)
@ -59,6 +80,7 @@ class MaxMindManager < BaseManager
end
end
# Note that there's one big country, and then two cities in each region.
def create_phony_database()
clear_table
(0..255).each do |top_octet|
@ -66,14 +88,13 @@ class MaxMindManager < BaseManager
[
self.class.ip_address_to_int("#{top_octet}.0.0.0"),
self.class.ip_address_to_int("#{top_octet}.255.255.255"),
"Country #{top_octet}",
"Region #{top_octet}",
"Country",
"Region #{(top_octet / 2).floor}",
"City #{top_octet}"
]).clear
]).clear
end
end
private
# Make an IP address fit in a signed int. Just divide it by 2, as the least significant part

View File

@ -0,0 +1,36 @@
require 'spec_helper'
# these tests avoid the use of ActiveRecord and FactoryGirl to do blackbox, non test-instrumented tests
describe MaxMindManager do
before(:each) do
@maxmind_manager = MaxMindManager.new(:conn => @conn)
end
it "looks up regions successfully" do
MaxMindManager.active_record_transaction do |manager|
manager.create_phony_database()
end
regions = MaxMindManager.regions("Country")
regions.length.should == 128
regions.first.should == "Region 0"
regions.last.should == "Region 99" # Based on sort order this will be the top.
end
it "looks up cities successfully" do
MaxMindManager.active_record_transaction do |manager|
manager.create_phony_database()
end
cities = MaxMindManager.cities("Country", "Region 1")
cities.length.should == 2
cities.first.should == "City 2"
cities.last.should == "City 3"
end
end

View File

@ -55,8 +55,8 @@ describe UserManager do
@user.errors.any?.should be_false
@user.city.should == 'City 127'
@user.state.should == 'Region 127'
@user.country.should == 'Country 127'
@user.state.should == 'Region 63'
@user.country.should == 'Country'
end