fireeagle 0.0.2 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +1 -1
- data/Manifest.txt +11 -9
- data/README.txt +38 -10
- data/Rakefile +4 -123
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/lib/fireeagle.rb +32 -42
- data/lib/fireeagle/client.rb +343 -0
- data/lib/fireeagle/location.rb +62 -66
- data/lib/fireeagle/response.rb +31 -0
- data/lib/fireeagle/user.rb +29 -35
- data/lib/fireeagle/version.rb +2 -2
- data/spec/fireeagle_location_spec.rb +60 -0
- data/spec/fireeagle_response_spec.rb +65 -0
- data/spec/fireeagle_spec.rb +150 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +128 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- metadata +91 -58
- data/lib/fireeagle/apibase.rb +0 -6
- data/lib/fireeagle/application.rb +0 -37
- data/lib/fireeagle/base.rb +0 -89
- data/scripts/txt2html +0 -67
- data/test/test_fireeagle.rb +0 -30
- data/test/test_fireeagle_application.rb +0 -46
- data/test/test_fireeagle_location.rb +0 -97
- data/test/test_fireeagle_user.rb +0 -103
- data/test/test_helper.rb +0 -14
data/lib/fireeagle/location.rb
CHANGED
@@ -1,74 +1,70 @@
|
|
1
1
|
#Describes a location
|
2
|
-
class FireEagle
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
raise FireEagle::ArgumentError, "Requires :country with :postal if not in US" if (options.has_key?(:postal) and options.has_key?(:country)) and (options[:country] != "US")
|
2
|
+
class FireEagle
|
3
|
+
class Location
|
4
|
+
|
5
|
+
#Initialize a Location from an XML response
|
6
|
+
def initialize(doc)
|
7
|
+
doc = Hpricot(doc) unless doc.is_a?(Hpricot::Doc || Hpricot::Elem)
|
8
|
+
@doc = doc
|
9
|
+
end
|
10
|
+
|
11
|
+
def label
|
12
|
+
@label ||= @doc.at("/location/label").innerText rescue nil
|
13
|
+
end
|
14
|
+
|
15
|
+
#Level of granularity for this Location
|
16
|
+
def level
|
17
|
+
@level ||= @doc.at("/location/level").innerText.to_i rescue nil
|
18
|
+
end
|
19
|
+
|
20
|
+
#Name of the level of granularity for this Location
|
21
|
+
def level_name
|
22
|
+
@level_name ||= @doc.at("/location/level-name").innerText rescue nil
|
23
|
+
end
|
24
|
+
|
25
|
+
#Human Name for this Location
|
26
|
+
def name
|
27
|
+
@name ||= @doc.at("/location/name").innerText rescue nil
|
28
|
+
end
|
29
|
+
alias_method :to_s, :name
|
30
|
+
|
31
|
+
#Unique identifier for this place. Pro-tip: This is the same place_id used by Flickr.
|
32
|
+
def place_id
|
33
|
+
@place_id ||= @doc.at("/location/place-id").innerText rescue nil
|
35
34
|
end
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
doc = doc.at("/resultset")
|
46
|
-
options[:locale] = doc.at("locale").innerText unless doc.at("locale").nil?
|
47
|
-
# quick parse of the xml
|
48
|
-
puts doc if FireEagle::DEBUG
|
49
|
-
doc.at("result").containers.each do |attribute|
|
50
|
-
options[attribute.xpath.split("/")[-1].to_sym] = attribute.inner_text unless attribute.nil?
|
51
|
-
end
|
52
|
-
#fixup types
|
53
|
-
options[:updatetime] = Time.parse(options[:updatetime])
|
54
|
-
options[:radius] = options[:radius].to_i
|
55
|
-
options[:quality] = options[:radius].to_i
|
56
|
-
%w(latitude longitude offsetlat offsetlon :boundinglatnorth boundinglatsouth boundinglateast boundinglatwest).each do |attribute|
|
57
|
-
options[attribute.to_sym].nil? || options[attribute.to_sym].empty? ? (options[attribute.to_sym] = '') : (options[attribute.to_sym] = options[attribute.to_sym].to_f)
|
58
|
-
end
|
59
|
-
|
60
|
-
FireEagle::Location.new(options, false)
|
36
|
+
#Numeric unique identifier for this place.
|
37
|
+
def woeid
|
38
|
+
@woeid ||= @doc.at("/location/woeid").innerText rescue nil
|
39
|
+
end
|
40
|
+
|
41
|
+
#The Time at which the User last updated in this Location
|
42
|
+
def located_at
|
43
|
+
@located_at ||= Time.parse(@doc.at("/location/located-at").innerText) rescue nil
|
61
44
|
end
|
62
|
-
end
|
63
45
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
return false unless options.include?(a)
|
46
|
+
#The coordinates of the lower corner of a bounding box surrounding this Location
|
47
|
+
def lower_corner
|
48
|
+
@georss ||= @doc.at("/location//georss:box").innerText.split.map{ |l| l.to_f } rescue nil
|
49
|
+
@lower_corner ||= @georss[0..1] rescue nil
|
69
50
|
end
|
70
|
-
|
51
|
+
|
52
|
+
# The GeoRuby[http://georuby.rubyforge.org/] representation of this location
|
53
|
+
def geom
|
54
|
+
if @doc.at("/location//georss:box")
|
55
|
+
@geo ||= GeoRuby::SimpleFeatures::Geometry.from_georss(@doc.at("/location//georss:box").to_s)
|
56
|
+
elsif @doc.at("/location//georss:point")
|
57
|
+
@geo ||= GeoRuby::SimpleFeatures::Geometry.from_georss(@doc.at("/location//georss:point").to_s)
|
58
|
+
else
|
59
|
+
return nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
alias_method :geo, :geom
|
63
|
+
|
64
|
+
#Is this Location FireEagle's best guess?
|
65
|
+
def best_guess?
|
66
|
+
@best_guess ||= @doc.at("/location").attributes["best-guess"] == "true" rescue false
|
67
|
+
end
|
68
|
+
|
71
69
|
end
|
72
|
-
|
73
|
-
|
74
70
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class FireEagle
|
2
|
+
class Response
|
3
|
+
|
4
|
+
#Parses the XML response from FireEagle
|
5
|
+
def initialize(doc)
|
6
|
+
doc = Hpricot(doc) unless doc.is_a?(Hpricot::Doc || Hpricot::Elem)
|
7
|
+
@doc = doc
|
8
|
+
raise FireEagle::FireEagleException, @doc.at("/rsp/err").attributes["msg"] if !success?
|
9
|
+
end
|
10
|
+
|
11
|
+
#does the response indicate success?
|
12
|
+
def success?
|
13
|
+
@doc.at("/rsp").attributes["stat"] == "ok" rescue false
|
14
|
+
end
|
15
|
+
|
16
|
+
#An array of of User-specific tokens and their Location at all levels the Client can see and larger.
|
17
|
+
def users
|
18
|
+
@users ||= @doc.search("/rsp//user").map do |user|
|
19
|
+
FireEagle::User.new(user.to_s)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#A Location array.
|
24
|
+
def locations
|
25
|
+
@locations ||= @doc.search("/rsp/locations/location").map do |location|
|
26
|
+
FireEagle::Location.new(location.to_s)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/fireeagle/user.rb
CHANGED
@@ -1,39 +1,33 @@
|
|
1
|
-
class FireEagle
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@token = token.to_s
|
9
|
-
end
|
10
|
-
|
11
|
-
class << self
|
12
|
-
#Create a new instance of FireEagle::User from the XML returned from Yahoo!
|
13
|
-
def new_from_xml(fireeagle, doc)
|
14
|
-
FireEagle::User.new(fireeagle, doc.at("/rsp/token").innerText)
|
1
|
+
class FireEagle
|
2
|
+
class User
|
3
|
+
|
4
|
+
#Parses the XML response from FireEagle.
|
5
|
+
def initialize(doc)
|
6
|
+
doc = Hpricot(doc) unless doc.is_a?(Hpricot::Doc || Hpricot::Elem)
|
7
|
+
@doc = doc
|
15
8
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
9
|
+
|
10
|
+
#The User-specific token for this Client.
|
11
|
+
def token
|
12
|
+
@token ||= @doc.at("/user").attributes["token"] rescue nil
|
13
|
+
end
|
14
|
+
|
15
|
+
#FireEagle's "best guess" form this User's Location. This best guess is derived as the most accurate
|
16
|
+
#level of the hierarchy with a timestamp in the last half an hour <b>or</b> as the most accurate
|
17
|
+
#level of the hierarchy with the most recent timestamp.
|
18
|
+
def best_guess
|
19
|
+
@best_guess ||= locations.select { |location| location.best_guess? }.first rescue nil
|
20
|
+
end
|
21
|
+
|
22
|
+
#An Array containing all Location granularity that the Client has been allowed to
|
23
|
+
#see for the User. The Location elements returned are arranged in hierarchy order consisting of:
|
24
|
+
#Country, State, County, Large Cities, Neighbourhoods/Local Area, Postal Code and exact location.
|
25
|
+
#The Application should therefore be prepared to receive a response that may consist of (1) only
|
26
|
+
#country, or (2) country & state or (3) country, state & county and so forth.
|
27
|
+
def locations
|
28
|
+
@locations ||= @doc.search("/user/location-hierarchy/location").map do |location|
|
29
|
+
FireEagle::Location.new(location.to_s)
|
30
|
+
end
|
28
31
|
end
|
29
32
|
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def parse_response(doc)
|
34
|
-
raise FireEagle::FireEagleException, doc.at("/resultset/errormessage").innerText if doc.at("/resultset/error").innerText.to_i != 0
|
35
|
-
return if doc.at("/resultset/result").nil?
|
36
|
-
FireEagle::Location.new_from_xml(doc)
|
37
|
-
end
|
38
|
-
|
39
33
|
end
|
data/lib/fireeagle/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "FireEagle Location" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
location = Hpricot.XML(XML_LOCATION_CHUNK)
|
7
|
+
@location = FireEagle::Location.new(location)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should know if this is a best guess" do
|
11
|
+
@location.best_guess?.should == false
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should represent the level" do
|
15
|
+
@location.level.should == 3
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should represent the level name" do
|
19
|
+
@location.level_name.should == 'city'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should represent the location name" do
|
23
|
+
@location.name.should == 'Davis, CA'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should represent the location place id" do
|
27
|
+
@location.place_id.should == 'u4L9ZOObApTdx1q3'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should represent the location's timestamp" do
|
31
|
+
@location.located_at.should == Time.parse("2008-01-22T14:23:11-08:00")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should use the name for #to_s" do
|
35
|
+
@location.to_s.should == @location.name
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "GeoRuby support" do
|
39
|
+
|
40
|
+
it "should represent a bounding box as a GeoRuby Envelope" do
|
41
|
+
location = Hpricot.XML(XML_LOCATION_CHUNK)
|
42
|
+
@location = FireEagle::Location.new(location)
|
43
|
+
@location.geom.class.should == GeoRuby::SimpleFeatures::Envelope
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should represent an exact point as a GeoRuby Point" do
|
47
|
+
location = Hpricot.XML(XML_EXACT_LOCATION_CHUNK)
|
48
|
+
@location = FireEagle::Location.new(location)
|
49
|
+
@location.geom.class.should == GeoRuby::SimpleFeatures::Point
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be aliased as 'geo'" do
|
53
|
+
location = Hpricot.XML(XML_EXACT_LOCATION_CHUNK)
|
54
|
+
@location = FireEagle::Location.new(location)
|
55
|
+
@location.geo.class.should == GeoRuby::SimpleFeatures::Point
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "FireEagle Response" do
|
4
|
+
|
5
|
+
describe "user / location parsing" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@response = FireEagle::Response.new(XML_LOCATION_RESPONSE)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should indicate success" do
|
12
|
+
@response.success?.should == true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have an array of users" do
|
16
|
+
@response.users.size.should == 1
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have each users' token" do
|
20
|
+
@response.users.first.token.should == "16w3z6ysudxt"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should flag the best guess" do
|
24
|
+
@response.users.first.best_guess.name.should == "Yolo County, California"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have users' loactions" do
|
28
|
+
@response.users.first.locations.size.should == 4
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "location parsing" do
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
@response = FireEagle::Response.new(XML_LOOKUP_RESPONSE)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should indicate success" do
|
40
|
+
@response.success?.should == true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have an array of locations" do
|
44
|
+
@response.locations.size.should == 9
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have each location's place_id" do
|
48
|
+
@response.locations.first.place_id.should == "IrhZMHuYA5s1fFi4Qw"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have each location's name" do
|
52
|
+
@response.locations.first.name.should == "Alpharetta, GA 30022"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "error handling" do
|
58
|
+
|
59
|
+
it "should raise an exception when returned xml with a status of fail" do
|
60
|
+
lambda { FireEagle::Response.new(XML_ERROR_RESPONSE) }.should raise_error(FireEagle::FireEagleException)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe "FireEagle" do
|
4
|
+
|
5
|
+
describe "being initialized" do
|
6
|
+
|
7
|
+
it "should require OAuth Consumer Key and Secret" do
|
8
|
+
lambda do
|
9
|
+
client = FireEagle::Client.new({})
|
10
|
+
end.should raise_error(FireEagle::ArgumentError)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should initialize an OAuth::Consumer" do
|
14
|
+
@consumer = mock(OAuth::Consumer)
|
15
|
+
OAuth::Consumer.should_receive(:new).and_return(@consumer)
|
16
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "web app authentication scenario" do
|
22
|
+
|
23
|
+
it "should initialize a OAuth::Token if given it's token and secret" do
|
24
|
+
@access_token = mock(OAuth::Token)
|
25
|
+
OAuth::Token.stub!(:new).and_return(@access_token)
|
26
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
|
27
|
+
client.access_token.should == @access_token
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should initialize a request token if given one" do
|
31
|
+
@request_token = mock(OAuth::Token)
|
32
|
+
OAuth::Token.stub!(:new).and_return(@request_token)
|
33
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :request_token => 'toke', :request_token_secret => 'sekret')
|
34
|
+
client.request_token.should == @request_token
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "request token scenario" do
|
39
|
+
it "shouldn't initialize with a access_token" do
|
40
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
|
41
|
+
client.access_token.should == nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should require token exchange before calling any API methods" do
|
45
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
|
46
|
+
lambda do
|
47
|
+
client.user
|
48
|
+
end.should raise_error(FireEagle::ArgumentError)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should generate a Request Token URL" do
|
52
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
|
53
|
+
@token = mock("token", :token => 'foo')
|
54
|
+
client.stub!(:get).and_return('')
|
55
|
+
client.stub!(:create_token).and_return(@token)
|
56
|
+
client.get_request_token
|
57
|
+
client.authorization_url.should =~ /\?oauth_token=foo/
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should require #get_request_token be called before #convert_to_access_token" do
|
61
|
+
lambda do
|
62
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
|
63
|
+
client.convert_to_access_token
|
64
|
+
end.should raise_error(FireEagle::ArgumentError)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should require #get_request_token be called before #authorization_url" do
|
68
|
+
lambda do
|
69
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
|
70
|
+
client.authorization_url
|
71
|
+
end.should raise_error(FireEagle::ArgumentError)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should generate a Request Token URL" do
|
75
|
+
client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
|
76
|
+
@token = mock("token", :token => 'foo')
|
77
|
+
client.stub!(:get).and_return('')
|
78
|
+
client.stub!(:create_token).and_return(@token)
|
79
|
+
client.get_request_token
|
80
|
+
client.convert_to_access_token
|
81
|
+
client.access_token.should == @token
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "update method" do
|
87
|
+
|
88
|
+
before(:each) do
|
89
|
+
@client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
|
90
|
+
@response = mock('response', :body => XML_SUCCESS_RESPONSE)
|
91
|
+
@client.stub!(:request).and_return(@response)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "requires all or none of :lat, :lon" do
|
95
|
+
lambda { @client.update(:lat => 1) }.should raise_error(FireEagle::ArgumentError)
|
96
|
+
lambda { @client.update(:lat => 1, :lon => 2) }.should_not raise_error(FireEagle::ArgumentError)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "requires all or none of :mnc, :mcc, :lac, :cid" do
|
100
|
+
lambda { @client.update(:mcc => 123, :lac => "whatever", :cid => true) }.should raise_error(FireEagle::ArgumentError)
|
101
|
+
lambda { @client.update(:mcc => 123, :mnc => 123123, :lac => "whatever", :cid => true) }.should_not raise_error(FireEagle::ArgumentError)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should wrap the result" do
|
105
|
+
@client.update(:mcc => 123, :mnc => 123123, :lac => "whatever", :cid => true).users.first.token.should == "16w3z6ysudxt"
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "user method" do
|
111
|
+
|
112
|
+
before(:each) do
|
113
|
+
@client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
|
114
|
+
@response = mock('response', :body => XML_LOCATION_RESPONSE)
|
115
|
+
@client.stub!(:request).and_return(@response)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return a best guess" do
|
119
|
+
@client.user.best_guess.name.should == "Yolo County, California"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return several locations" do
|
123
|
+
@client.user.locations.size.should == 4
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "lookup method" do
|
129
|
+
|
130
|
+
before(:each) do
|
131
|
+
@client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
|
132
|
+
@response = mock('response', :body => XML_LOOKUP_RESPONSE)
|
133
|
+
@client.stub!(:request).and_return(@response)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return an array of Locations" do
|
137
|
+
@client.lookup(:q => "30022").size.should == 9
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return a place id for each" do
|
141
|
+
@client.lookup(:q => "30022").first.place_id.should == "IrhZMHuYA5s1fFi4Qw"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should return a name for each" do
|
145
|
+
@client.lookup(:q => "30022").first.name.should == "Alpharetta, GA 30022"
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|