pezra-fireeagle 0.9.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
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
+ location_with_query = Hpricot.XML(XML_QUERY_LOCATION_CHUNK)
9
+ @location_with_query = FireEagle::Location.new(location_with_query)
10
+ end
11
+
12
+ it "should know if this is a best guess" do
13
+ @location.should_not be_best_guess
14
+ end
15
+
16
+ it "should represent the level" do
17
+ @location.level.should == 3
18
+ end
19
+
20
+ it "should represent the level name" do
21
+ @location.level_name.should == 'city'
22
+ end
23
+
24
+ it "should represent the location name" do
25
+ @location.name.should == 'Davis, CA'
26
+ end
27
+
28
+ it "should represent the location place id" do
29
+ @location.place_id.should == 'u4L9ZOObApTdx1q3'
30
+ end
31
+
32
+ it "should represent the location's timestamp" do
33
+ @location.located_at.should == Time.parse("2008-01-22T14:23:11-08:00")
34
+ end
35
+
36
+ it "should use the name for #to_s" do
37
+ @location.to_s.should == @location.name
38
+ end
39
+
40
+ it "should return the actual query string" do
41
+ @location_with_query.query.should == "333 W Harbor Dr, San Diego, CA"
42
+ end
43
+
44
+ describe "GeoRuby support" do
45
+
46
+ it "should represent a bounding box as a GeoRuby Envelope" do
47
+ location = Hpricot.XML(XML_LOCATION_CHUNK)
48
+ @location = FireEagle::Location.new(location)
49
+ @location.geom.should be_an_instance_of(GeoRuby::SimpleFeatures::Envelope)
50
+ end
51
+
52
+ it "should represent an exact point as a GeoRuby Point" do
53
+ location = Hpricot.XML(XML_EXACT_LOCATION_CHUNK)
54
+ @location = FireEagle::Location.new(location)
55
+ @location.geom.should be_an_instance_of(GeoRuby::SimpleFeatures::Point)
56
+ end
57
+
58
+ it "should be aliased as 'geo'" do
59
+ location = Hpricot.XML(XML_EXACT_LOCATION_CHUNK)
60
+ @location = FireEagle::Location.new(location)
61
+ @location.geo.should be_an_instance_of(GeoRuby::SimpleFeatures::Point)
62
+ end
63
+
64
+ end
65
+
66
+ 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.should be_success
13
+ end
14
+
15
+ it "should have an array of users" do
16
+ @response.should have(1).users
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' locations" do
28
+ @response.users.first.should have(4).locations
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.should be_success
41
+ end
42
+
43
+ it "should have an array of locations" do
44
+ @response.should have(9).locations
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,190 @@
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).with('key', 'sekret', :site => FireEagle::API_SERVER, :authorize_url => FireEagle::AUTHORIZATION_URL).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 an OAuth::AccessToken if given its token and secret" do
24
+ @access_token = mock(OAuth::AccessToken)
25
+ OAuth::AccessToken.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 an OAuth::RequestToken if given its token and secret" do
31
+ @request_token = mock(OAuth::RequestToken)
32
+ OAuth::RequestToken.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 be_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
+ consumer = mock(OAuth::Consumer)
53
+ token = mock(OAuth::RequestToken)
54
+ consumer.should_receive(:get_request_token).and_return(token)
55
+ token.should_receive(:authorize_url)
56
+
57
+ client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
58
+ client.should_receive(:consumer).and_return(consumer)
59
+ client.get_request_token
60
+ client.authorization_url
61
+ end
62
+
63
+ it "should require #get_request_token be called before #convert_to_access_token" do
64
+ lambda do
65
+ client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
66
+ client.convert_to_access_token("oauth-verifier-from-authorized-callback")
67
+ end.should raise_error(FireEagle::ArgumentError)
68
+ end
69
+
70
+ it "should require #get_request_token be called before #authorization_url" do
71
+ lambda do
72
+ client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
73
+ client.authorization_url
74
+ end.should raise_error(FireEagle::ArgumentError)
75
+ end
76
+
77
+ it "should generate an Access Token" do
78
+ consumer = mock(OAuth::Consumer)
79
+ req_token = mock(OAuth::RequestToken)
80
+ acc_token = mock(OAuth::AccessToken)
81
+ consumer.should_receive(:get_request_token).and_return(req_token)
82
+ req_token.should_receive(:get_access_token).and_return(acc_token)
83
+
84
+ client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret')
85
+ client.should_receive(:consumer).and_return(consumer)
86
+
87
+ client.get_request_token
88
+ client.convert_to_access_token("oauth-verifier-from-authorized-callback")
89
+ client.access_token.should == acc_token
90
+ end
91
+
92
+ end
93
+
94
+ describe "update method" do
95
+
96
+ before(:each) do
97
+ @client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
98
+ @response = stub('response', :body => XML_SUCCESS_RESPONSE)
99
+ @client.stub!(:request).and_return(@response)
100
+ end
101
+
102
+ it "requires all or none of :lat, :lon" do
103
+ lambda { @client.update(:lat => 1) }.should raise_error(FireEagle::ArgumentError)
104
+ lambda { @client.update(:lat => 1, :lon => 2) }.should_not raise_error(FireEagle::ArgumentError)
105
+ end
106
+
107
+ it "requires all or none of :mnc, :mcc, :lac, :cellid" do
108
+ lambda { @client.update(:mcc => 123, :lac => "whatever", :cellid => true) }.should raise_error(FireEagle::ArgumentError)
109
+ lambda { @client.update(:mcc => 123, :mnc => 123123, :lac => "whatever", :cellid => true) }.should_not raise_error(FireEagle::ArgumentError)
110
+ end
111
+
112
+ it "should wrap the result" do
113
+ @client.update(:mcc => 123, :mnc => 123123, :lac => "whatever", :cellid => true).users.first.token.should == "16w3z6ysudxt"
114
+ end
115
+
116
+ end
117
+
118
+ describe "user method" do
119
+
120
+ before(:each) do
121
+ @client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
122
+ response = stub('response', :body => XML_LOCATION_RESPONSE)
123
+ @client.stub!(:request).and_return(response)
124
+ end
125
+
126
+ it "should return a best guess" do
127
+ @client.user.best_guess.name.should == "Yolo County, California"
128
+ end
129
+
130
+ it "should return several locations" do
131
+ @client.user.should have(4).locations
132
+ end
133
+
134
+ end
135
+
136
+ describe "lookup method" do
137
+
138
+ before(:each) do
139
+ @client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
140
+ @response = stub('response', :body => XML_LOOKUP_RESPONSE)
141
+ @client.stub!(:request).and_return(@response)
142
+ end
143
+
144
+ it "should return an array of Locations" do
145
+ @client.lookup(:q => "30022").should have(9).items
146
+ end
147
+
148
+ it "should return a place id for each" do
149
+ @client.lookup(:q => "30022").first.place_id.should == "IrhZMHuYA5s1fFi4Qw"
150
+ end
151
+
152
+ it "should return a name for each" do
153
+ @client.lookup(:q => "30022").first.name.should == "Alpharetta, GA 30022"
154
+ end
155
+
156
+ end
157
+
158
+ describe "within method" do
159
+ before do
160
+ @client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
161
+ @response = stub('response', :body => XML_WITHIN_RESPONSE)
162
+ @client.stub!(:request).and_return(@response)
163
+ end
164
+
165
+ it "should return an array of Users" do
166
+ @client.within(:woe => "12796255").should have(2).users
167
+ end
168
+
169
+ it "should return an array of Locations for each" do
170
+ @client.within(:woe => "12796255").first.should have(5).locations
171
+ end
172
+ end
173
+
174
+ describe "recent method" do
175
+ before do
176
+ @client = FireEagle::Client.new(:consumer_key => 'key', :consumer_secret => 'sekret', :access_token => 'toke', :access_token_secret => 'sekret')
177
+ @response = stub('response', :body => XML_RECENT_RESPONSE)
178
+ @client.stub!(:request).and_return(@response)
179
+ end
180
+
181
+ it "should return an array of Users" do
182
+ @client.recent('yesterday', 3, 1).should have(3).users
183
+ end
184
+
185
+ it "should have an 'located_at' timestamp for each user" do
186
+ @client.recent('yesterday', 3, 1).first.located_at.should == Time.parse('2008-07-31T22:31:37+12:00')
187
+ end
188
+ end
189
+
190
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,280 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+ require 'time'
9
+
10
+ XML_ERROR_RESPONSE = <<-RESPONSE
11
+ <?xml version="1.0" encoding="utf-8"?>
12
+ <rsp stat="fail">
13
+ <err code="11" msg="Something bad happened" />
14
+ </rsp>
15
+ RESPONSE
16
+
17
+ XML_LOCATION_RESPONSE = <<-RESPONSE
18
+ <?xml version="1.0" encoding="utf-8"?>
19
+ <rsp stat="ok" xmlns:georss="http://www.georss.org/georss">
20
+ <user token="16w3z6ysudxt">
21
+ <location-hierarchy>
22
+ <location best-guess="false">
23
+ <georss:box>38.5351715088 -121.7948684692 38.575668335 -121.6747894287</georss:box>
24
+ <level>3</level>
25
+ <level-name>city</level-name>
26
+ <located-at>2008-01-22T14:23:11-08:00</located-at>
27
+ <name>Davis, CA</name>
28
+ <place-id>u4L9ZOObApTdx1q3</place-id>
29
+ </location>
30
+ <location best-guess="true">
31
+ <georss:box>38.3131217957 -122.4230804443 38.9261016846 -121.5012969971</georss:box>
32
+ <level>4</level>
33
+ <level-name>region</level-name>
34
+ <located-at>2008-01-22T18:45:26-08:00</located-at>
35
+ <name>Yolo County, California</name>
36
+ <place-id>YUYMh9CbBJ61mgFe</place-id>
37
+ </location>
38
+ <location best-guess="false">
39
+ <georss:box>32.5342788696 -124.4150238037 42.0093803406 -114.1308135986</georss:box>
40
+ <level>5</level>
41
+ <level-name>state</level-name>
42
+ <located-at>2008-01-22T18:45:26-08:00</located-at>
43
+ <name>California</name>
44
+ <place-id>SVrAMtCbAphCLAtP</place-id>
45
+ </location>
46
+ <location best-guess="false">
47
+ <georss:box>18.9108390808 -167.2764129639 72.8960571289 -66.6879425049</georss:box>
48
+ <level>6</level>
49
+ <level-name>country</level-name>
50
+ <located-at>2008-01-22T18:45:26-08:00</located-at>
51
+ <name>United States</name>
52
+ <place-id>4KO02SibApitvSBieQ</place-id>
53
+ </location>
54
+ </location-hierarchy>
55
+ </user>
56
+ </rsp>
57
+ RESPONSE
58
+
59
+ XML_SUCCESS_RESPONSE = <<-RESPONSE
60
+ <?xml version="1.0" encoding="utf-8"?>
61
+ <rsp stat="ok">
62
+ <user token="16w3z6ysudxt"/>
63
+ </rsp>
64
+ RESPONSE
65
+
66
+ XML_LOCATION_CHUNK = <<-RESPONSE
67
+ <location best-guess="false">
68
+ <georss:box>38.5351715088 -121.7948684692 38.575668335 -121.6747894287</georss:box>
69
+ <level>3</level>
70
+ <level-name>city</level-name>
71
+ <located-at>2008-01-22T14:23:11-08:00</located-at>
72
+ <name>Davis, CA</name>
73
+ <place-id>u4L9ZOObApTdx1q3</place-id>
74
+ </location>
75
+ RESPONSE
76
+
77
+ XML_QUERY_LOCATION_CHUNK = <<-RESPONSE
78
+ <location best-guess="true">
79
+ <id>111541</id>
80
+ <georss:point>32.7093315125 -117.1650772095</georss:point>
81
+ <level>0</level>
82
+ <level-name>exact</level-name>
83
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
84
+ <name>333 W Harbor Dr, San Diego, CA</name>
85
+ <query> "q=333%20W%20Harbor%20Dr,%20San%20Diego,%20CA" </query>
86
+ </location>
87
+ RESPONSE
88
+
89
+
90
+ XML_EXACT_LOCATION_CHUNK = <<-RESPONSE
91
+ <location>
92
+ <georss:point>38.5351715088 -121.7948684692</georss:box>
93
+ </location>
94
+ RESPONSE
95
+
96
+ XML_LOOKUP_RESPONSE = <<-RESPONSE
97
+ <?xml version="1.0" encoding="UTF-8"?>
98
+ <rsp stat="ok">
99
+ <querystring>q=30022</querystring>
100
+ <locations start="0" total="9" count="9">
101
+ <location>
102
+ <name>Alpharetta, GA 30022</name>
103
+ <place-id>IrhZMHuYA5s1fFi4Qw</place-id>
104
+ </location>
105
+ <location>
106
+ <name>Hannover, Region Hannover, Deutschland</name>
107
+ <place-id>88Hctc2bBZlhvlwbUg</place-id>
108
+ </location>
109
+ <location>
110
+ <name>N&#238;mes, Gard, France</name>
111
+ <place-id>Sut8q82bBZkF0s1eTg</place-id>
112
+ </location>
113
+ <location>
114
+ <name>Ceggia, Venezia, Italia</name>
115
+ <place-id>s9ulRieYA5TkNK9otw</place-id>
116
+ </location>
117
+ <location>
118
+ <name>Comit&#225;n de Dom&#237;nguez, Comitan de Dominguez, M&#233;xico</name>
119
+ <place-id>.51HvYKbBZnSAeNHWw</place-id>
120
+ </location>
121
+ <location>
122
+ <name>Platanos Aitoloakarnanias, Etolia Kai Akarnania, Greece</name>
123
+ <place-id>CmfJ2H.YA5QKpS56HQ</place-id>
124
+ </location>
125
+ <location>
126
+ <name>Krak&#243;w, Krak&#243;w, Polska</name>
127
+ <place-id>9bYc0l.bA5vPTGscQg</place-id>
128
+ </location>
129
+ <location>
130
+ <name>Nakuru, Kenya</name>
131
+ <place-id>VDprypWYA5sujnZphA</place-id>
132
+ </location>
133
+ <location>
134
+ <name>Fez, Al Magreb</name>
135
+ <place-id>BxOaGgSYA5R40Nm1RA</place-id>
136
+ </location>
137
+ </locations>
138
+ </rsp>
139
+ RESPONSE
140
+
141
+ XML_WITHIN_RESPONSE = <<-RESPONSE
142
+ <?xml version="1.0" encoding="UTF-8"?>
143
+ <rsp stat="ok">
144
+ <users>
145
+ <user token="MQdDrJgXMNJi">
146
+ <location-hierarchy>
147
+ <location best-guess="true">
148
+ <id>111541</id>
149
+ <georss:point>32.7093315125 -117.1650772095</georss:point>
150
+ <level>0</level>
151
+ <level-name>exact</level-name>
152
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
153
+ <name>333 W Harbor Dr, San Diego, CA</name>
154
+ </location>
155
+ <location best-guess="false">
156
+ <id>111551</id>
157
+ <georss:box>
158
+ 32.6916618347 -117.2174377441 32.744140625 -117.1458892822
159
+ </georss:box>
160
+ <level>1</level>
161
+ <level-name>postal</level-name>
162
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
163
+ <name>San Diego, CA 92101</name>
164
+ <place-id>NpiXqwmYA5viX3K3Ew</place-id>
165
+ <woeid>12796255</woeid>
166
+ </location>
167
+ <location best-guess="false">
168
+ <id>111561</id>
169
+ <georss:box>
170
+ 32.5349388123 -117.2884292603 33.1128082275 -116.9142913818
171
+ </georss:box>
172
+ <level>3</level>
173
+ <level-name>city</level-name>
174
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
175
+ <name>San Diego, CA</name>
176
+ <place-id>Nm4O.DebBZTYKUsu</place-id>
177
+ <woeid>2487889</woeid>
178
+ </location>
179
+ <location best-guess="false">
180
+ <id>111571</id>
181
+ <georss:box>
182
+ 32.5342788696 -124.4150238037 42.0093803406 -114.1308135986
183
+ </georss:box>
184
+ <level>5</level>
185
+ <level-name>state</level-name>
186
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
187
+ <name>California</name>
188
+ <place-id>SVrAMtCbAphCLAtP</place-id>
189
+ <woeid>2347563</woeid>
190
+ </location>
191
+ <location best-guess="false">
192
+ <id>111581</id>
193
+ <georss:box>
194
+ 18.9108390808 -167.2764129639 72.8960571289 -66.6879425049
195
+ </georss:box>
196
+ <level>6</level>
197
+ <level-name>country</level-name>
198
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
199
+ <name>United States</name>
200
+ <place-id>4KO02SibApitvSBieQ</place-id>
201
+ <woeid>23424977</woeid>
202
+ </location>
203
+ </location-hierarchy>
204
+ </user>
205
+ <user token="MQdDrJgXMNJi">
206
+ <location-hierarchy>
207
+ <location best-guess="true">
208
+ <id>111541</id>
209
+ <georss:point>32.7093315125 -117.1650772095</georss:point>
210
+ <level>0</level>
211
+ <level-name>exact</level-name>
212
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
213
+ <name>333 W Harbor Dr, San Diego, CA</name>
214
+ </location>
215
+ <location best-guess="false">
216
+ <id>111551</id>
217
+ <georss:box>
218
+ 32.6916618347 -117.2174377441 32.744140625 -117.1458892822
219
+ </georss:box>
220
+ <level>1</level>
221
+ <level-name>postal</level-name>
222
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
223
+ <name>San Diego, CA 92101</name>
224
+ <place-id>NpiXqwmYA5viX3K3Ew</place-id>
225
+ <woeid>12796255</woeid>
226
+ </location>
227
+ <location best-guess="false">
228
+ <id>111561</id>
229
+ <georss:box>
230
+ 32.5349388123 -117.2884292603 33.1128082275 -116.9142913818
231
+ </georss:box>
232
+ <level>3</level>
233
+ <level-name>city</level-name>
234
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
235
+ <name>San Diego, CA</name>
236
+ <place-id>Nm4O.DebBZTYKUsu</place-id>
237
+ <woeid>2487889</woeid>
238
+ </location>
239
+ <location best-guess="false">
240
+ <id>111571</id>
241
+ <georss:box>
242
+ 32.5342788696 -124.4150238037 42.0093803406 -114.1308135986
243
+ </georss:box>
244
+ <level>5</level>
245
+ <level-name>state</level-name>
246
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
247
+ <name>California</name>
248
+ <place-id>SVrAMtCbAphCLAtP</place-id>
249
+ <woeid>2347563</woeid>
250
+ </location>
251
+ <location best-guess="false">
252
+ <id>111581</id>
253
+ <georss:box>
254
+ 18.9108390808 -167.2764129639 72.8960571289 -66.6879425049
255
+ </georss:box>
256
+ <level>6</level>
257
+ <level-name>country</level-name>
258
+ <located-at>2008-03-03T09:05:16-08:00</located-at>
259
+ <name>United States</name>
260
+ <place-id>4KO02SibApitvSBieQ</place-id>
261
+ <woeid>23424977</woeid>
262
+ </location>
263
+ </location-hierarchy>
264
+ </user>
265
+ </users>
266
+ </rsp>
267
+ RESPONSE
268
+
269
+ XML_RECENT_RESPONSE = <<-RESPONSE
270
+ <?xml version="1.0" encoding="UTF-8"?>
271
+ <rsp xmlns:georss="http://www.georss.org/georss" stat="ok">
272
+ <users>
273
+ <user located-at="2008-07-31T22:31:37+12:00" token="5pyl1xip0uh6"/>
274
+ <user located-at="2008-07-31T21:49:03+12:00" token="i71yc3myixg3"/>
275
+ <user located-at="2008-07-30T21:40:54+12:00" token="q1jm8nubnpsi"/>
276
+ </users>
277
+ </rsp>
278
+ RESPONSE
279
+
280
+ require File.dirname(__FILE__) + '/../lib/fireeagle'