zoopla 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/README.markdown +5 -3
- data/lib/zoopla.rb +17 -1
- data/lib/zoopla/api.rb +32 -4
- data/lib/zoopla/listings/listing.rb +187 -190
- data/lib/zoopla/listings/rentals.rb +30 -34
- data/lib/zoopla/listings/sales.rb +22 -25
- data/lib/zoopla/version.rb +3 -3
- data/test/api_replies/empty.js +1 -0
- data/test/test_api.rb +63 -0
- data/test/test_zoopla_listings.rb +6 -5
- metadata +6 -2
data/Gemfile.lock
CHANGED
data/README.markdown
CHANGED
@@ -4,6 +4,8 @@ Use this gem to access real estate data using zoopla.co.uk API from ruby code:
|
|
4
4
|
|
5
5
|
* property listings with addresses, prices, agent details etc
|
6
6
|
* more to come
|
7
|
+
|
8
|
+
**This gem is pre-alpha, therefore it's missing important features and it not production ready. Also, the interface may change considerably in the future**
|
7
9
|
|
8
10
|
## Documentation
|
9
11
|
The gem documentation can be found on [Rdoc.info](http://rdoc.info/github/shadchnev/zoopla/master/frames)
|
@@ -16,7 +18,7 @@ The API documentation can be found on the [Zoopla Website](http://developer.zoop
|
|
16
18
|
|
17
19
|
First, initialise the object with the API key [you got from Zoopla](http://developer.zoopla.com/member/register/)
|
18
20
|
|
19
|
-
$ sales = Zoopla
|
21
|
+
$ sales = Zoopla.new('my_api_key').sales
|
20
22
|
|
21
23
|
Then chain the parameter calls and provide a block to process the listings
|
22
24
|
|
@@ -31,8 +33,8 @@ This will produce
|
|
31
33
|
|
32
34
|
To search for rentals, do a similar query:
|
33
35
|
|
34
|
-
$ rentals = Zoopla
|
35
|
-
$ rentals.flats.in({:postcode => 'NW1 0DU'}).within(0.5).
|
36
|
+
$ rentals = Zoopla.new('my_api_key').rentals
|
37
|
+
$ rentals.flats.in({:postcode => 'NW1 0DU'}).within(0.5).for(300..350).each{|l| puts "#{l.num_bedrooms}-bedrooms flat for #{l.price}/week at #{l.displayable_address}"}
|
36
38
|
|
37
39
|
The input and output parameters for property listings are described in the [Zoopla documentation](http://developer.zoopla.com/docs/read/Property_listings)
|
38
40
|
|
data/lib/zoopla.rb
CHANGED
@@ -7,6 +7,22 @@ require File.expand_path('../zoopla/version', __FILE__)
|
|
7
7
|
require File.expand_path('../zoopla/api', __FILE__)
|
8
8
|
require File.expand_path('../zoopla/listings', __FILE__)
|
9
9
|
|
10
|
-
|
10
|
+
class Zoopla
|
11
|
+
|
12
|
+
def initialize(key)
|
13
|
+
@api_key = key
|
14
|
+
end
|
15
|
+
|
16
|
+
# Delegates to the Rentals class
|
17
|
+
# @return [Rentals]
|
18
|
+
def rentals
|
19
|
+
Rentals.new(@api_key)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Delegates to the Sales class
|
23
|
+
# @return [Sales]
|
24
|
+
def sales
|
25
|
+
Sales.new(@api_key)
|
26
|
+
end
|
11
27
|
|
12
28
|
end
|
data/lib/zoopla/api.rb
CHANGED
@@ -1,6 +1,24 @@
|
|
1
|
-
|
1
|
+
class Zoopla
|
2
2
|
|
3
|
-
|
3
|
+
# Raised when Zoopla returns the HTTP status code 400
|
4
|
+
class BadRequestError < StandardError; end
|
5
|
+
|
6
|
+
# Raised when Zoopla returns the HTTP status code 401
|
7
|
+
class UnauthorizedRequestError < StandardError; end
|
8
|
+
|
9
|
+
# Raised when Zoopla returns the HTTP status code 403
|
10
|
+
class ForbiddenError < StandardError; end
|
11
|
+
|
12
|
+
# Raised when Zoopla returns the HTTP status code 404
|
13
|
+
class NotFoundError < StandardError; end
|
14
|
+
|
15
|
+
# Raised when Zoopla returns the HTTP status code 405
|
16
|
+
class MethodNotAllowedError < StandardError; end
|
17
|
+
|
18
|
+
# Raised when Zoopla returns the HTTP status code 500
|
19
|
+
class InternalServerError < StandardError; end
|
20
|
+
|
21
|
+
class API # abstract
|
4
22
|
|
5
23
|
def initialize(api_key)
|
6
24
|
@key = api_key
|
@@ -9,13 +27,23 @@ module Zoopla
|
|
9
27
|
private
|
10
28
|
|
11
29
|
def fetch_data(params)
|
12
|
-
|
30
|
+
response_code, body = call(url(params))
|
31
|
+
return preprocess(body) if response_code == 200
|
32
|
+
raise case response_code
|
33
|
+
when 400 then BadRequestError.new "Not enough parameters to produce a valid response."
|
34
|
+
when 401 then UnauthorizedRequestError.new "The API key could not be recognised and the request is not authorized."
|
35
|
+
when 403 then ForbiddenError.new "The requested method is not available for the API key specified (the API key is invalid?)."
|
36
|
+
when 404 then NotFoundError.new "A method was requested that is not available in the API version specified."
|
37
|
+
when 405 then MethodNotAllowedError.new "The HTTP request that was made requested an API method that can not process the HTTP method used."
|
38
|
+
when 500 then InternalServerError.new "Internal Server Error"
|
39
|
+
else StandardError.new "Unexpected HTTP error"
|
40
|
+
end
|
13
41
|
end
|
14
42
|
|
15
43
|
def call(url)
|
16
44
|
curl = Curl::Easy.new(url)
|
17
45
|
curl.perform
|
18
|
-
|
46
|
+
[curl.response_code, curl.body_str]
|
19
47
|
end
|
20
48
|
|
21
49
|
def url(params)
|
@@ -1,194 +1,191 @@
|
|
1
|
-
|
2
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
listings.each do |listing|
|
143
|
-
yield listing
|
144
|
-
end
|
145
|
-
end while fetched_so_far < number_of_results
|
146
|
-
end
|
147
|
-
|
148
|
-
# Resets all parameters except the API key
|
149
|
-
# @return [Rentals, Sales]
|
150
|
-
def reset!
|
151
|
-
@request = default_parameters
|
152
|
-
self
|
153
|
-
end
|
154
|
-
|
155
|
-
private
|
156
|
-
|
157
|
-
def set_limiting_value(limit, attribute, value)
|
158
|
-
ensure_valid_parameter("#{limit} #{attribute}", value, lambda {|p| p.is_a? Fixnum and p >= 0})
|
159
|
-
@request["#{limit}_#{attribute}".to_sym] = value
|
160
|
-
self
|
161
|
-
end
|
162
|
-
|
163
|
-
def set_range_parameter(attribute, value)
|
164
|
-
ensure_valid_parameter(attribute.to_s, value, lambda {|pr| pr.is_a? Fixnum or (pr.is_a?(Range) and pr.first <= pr.last)})
|
165
|
-
value = value..value if value.is_a? Fixnum
|
166
|
-
self.send("minimum_#{attribute}", value.first)
|
167
|
-
self.send("maximum_#{attribute}", value.last)
|
168
|
-
self
|
169
|
-
end
|
170
|
-
|
171
|
-
def ensure_valid_parameter(parameter, value, valid_options)
|
172
|
-
raise "#{parameter} not specified" unless value
|
173
|
-
raise "Unknown #{parameter}: #{value}" if valid_options.is_a? Array and !valid_options.include?(value.to_s)
|
174
|
-
raise "Invalid #{parameter}: #{value}" if valid_options.is_a? Proc and !valid_options.call(value)
|
175
|
-
end
|
176
|
-
|
177
|
-
def preprocess(reply)
|
178
|
-
number_of_results = reply["result_count"]
|
179
|
-
listings = reply["listing"].inject([]) do |memo, listing|
|
180
|
-
parse_values_if_possible(listing)
|
181
|
-
memo << Hashie::Mash.new.update(listing)
|
1
|
+
class Zoopla
|
2
|
+
|
3
|
+
# Common methods for Sales and Rentals classes
|
4
|
+
module Listing
|
5
|
+
|
6
|
+
# Defines the search area. All possible params are described at http://developer.zoopla.com/docs/
|
7
|
+
# @param [Hash] Location hash
|
8
|
+
# @return [Sales, Rentals]
|
9
|
+
def in(location)
|
10
|
+
@request.merge! location
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sets the price range
|
15
|
+
# @param [Range] price range (weekly in case of rentals), e.g. 200..300
|
16
|
+
# @return [Sales, Rentals]
|
17
|
+
def price(price_range)
|
18
|
+
set_range_parameter(:price, price_range)
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :for, :price
|
22
|
+
|
23
|
+
# Sets the number of bedrooms range
|
24
|
+
# @param [Range] bedrooms range, e.g. 2..3
|
25
|
+
# @return [Sales, Rentals]
|
26
|
+
def beds(beds_range)
|
27
|
+
set_range_parameter(:beds, beds_range)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Defines the size of the search area in miles. E.g. 2 miles around a location
|
31
|
+
# @param [Fixum] radius in miles
|
32
|
+
# @return [Sales, Rentals]
|
33
|
+
def within(miles)
|
34
|
+
ensure_valid_parameter('radius', miles, lambda {|p| (p.is_a? Float or p.is_a? Fixnum) and p >= 0})
|
35
|
+
@request[:radius] = miles
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :radius, :within
|
40
|
+
|
41
|
+
# The field by which the results should be ordered, either :price or :age of listing.
|
42
|
+
# @param [Symbol, String] sorting field
|
43
|
+
# @return [Sales, Rentals]
|
44
|
+
def order_by(field)
|
45
|
+
ensure_valid_parameter('sorting order', field, %w(price age))
|
46
|
+
@request[:order_by] = field.to_s
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Sort order for the listings returned. Either :descending or :ascending
|
51
|
+
# @param [Symbol, String] sorting order
|
52
|
+
# @return [Sales, Rentals]
|
53
|
+
def ordering(order)
|
54
|
+
ensure_valid_parameter('ordering', order, %w(ascending descending))
|
55
|
+
@request[:ordering] = order.to_s
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
# Property type. Either :houses or :flats
|
60
|
+
# @param [Symbol, String] property type
|
61
|
+
# @return [Sales, Rentals]
|
62
|
+
def property_type(type)
|
63
|
+
ensure_valid_parameter('property type', type, %w(houses flats))
|
64
|
+
@request[:property_type] = type.to_s
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
# Search only for houses
|
69
|
+
# @return [Sales, Rentals]
|
70
|
+
def houses
|
71
|
+
@request[:property_type] = 'houses'
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# Search only for flats
|
76
|
+
# @return [Sales, Rentals]
|
77
|
+
def flats
|
78
|
+
@request[:property_type] = 'flats'
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
# Keywords to search for within the listing description.
|
83
|
+
# @param [Array, String] keywords
|
84
|
+
# @return [Sales, Rentals]
|
85
|
+
def keywords(keywords)
|
86
|
+
ensure_valid_parameter('keywords', keywords, lambda {|k| k.is_a? Array or k.is_a? String})
|
87
|
+
keywords = keywords.join(' ') if keywords.is_a? Array
|
88
|
+
@request[:keywords] = keywords
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
92
|
+
# Sets the minimum price. Weekly prices in case of rentals
|
93
|
+
# @param [Fixnum] price
|
94
|
+
# @return [Sales, Rentals]
|
95
|
+
def minimum_price(price)
|
96
|
+
set_limiting_value(:minimum, :price, price)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Sets the maximum price. Weekly prices in case of rentals
|
100
|
+
# @param [Fixnum] price
|
101
|
+
# @return [Sales, Rentals]
|
102
|
+
def maximum_price(price)
|
103
|
+
set_limiting_value(:maximum, :price, price)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Sets the minimum number of bedrooms
|
107
|
+
# @param [Fixnum] number of bedrooms
|
108
|
+
# @return [Sales, Rentals]
|
109
|
+
def minimum_beds(beds)
|
110
|
+
set_limiting_value(:minimum, :beds, beds)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Sets the maximum number of bedrooms
|
114
|
+
# @param [Fixnum] number of bedrooms
|
115
|
+
# @return [Sales, Rentals]
|
116
|
+
def maximum_beds(beds)
|
117
|
+
set_limiting_value(:maximum, :beds, beds)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Adds another listing id to the query. Calling this function multiple times will add multiple ids.
|
121
|
+
# Please note that other provided arguments will still be taken into account when filtering listings
|
122
|
+
# @param [Fixnum] listing id
|
123
|
+
# @return [Sales, Rentals]
|
124
|
+
def listing_id(listing_id)
|
125
|
+
ensure_valid_parameter('listing id', listing_id, lambda {|k| k.is_a? Fixnum and k >= 0})
|
126
|
+
@request[:listing_id] ||= []
|
127
|
+
@request[:listing_id] << listing_id
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
# Iterates over the results. Possible fields are described at http://developer.zoopla.com/docs/read/Property_listings
|
132
|
+
# @yield [Hashie::Mash] a listing with data, e.g. sales.each{|listing| puts listing.price }
|
133
|
+
def each
|
134
|
+
fetched_so_far, number_of_results = 0, 0
|
135
|
+
@request[:page_number] = 1
|
136
|
+
begin
|
137
|
+
number_of_results, listings = fetch_data(@request)
|
138
|
+
fetched_so_far += listings.size
|
139
|
+
@request[:page_number] += 1
|
140
|
+
listings.each do |listing|
|
141
|
+
yield listing
|
182
142
|
end
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
143
|
+
end while fetched_so_far < number_of_results
|
144
|
+
end
|
145
|
+
|
146
|
+
# Resets all parameters except the API key
|
147
|
+
# @return [Rentals, Sales]
|
148
|
+
def reset!
|
149
|
+
@request = default_parameters
|
150
|
+
self
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def set_limiting_value(limit, attribute, value)
|
156
|
+
ensure_valid_parameter("#{limit} #{attribute}", value, lambda {|p| p.is_a? Fixnum and p >= 0})
|
157
|
+
@request["#{limit}_#{attribute}".to_sym] = value
|
158
|
+
self
|
190
159
|
end
|
191
160
|
|
192
|
-
|
193
|
-
|
161
|
+
def set_range_parameter(attribute, value)
|
162
|
+
ensure_valid_parameter(attribute.to_s, value, lambda {|pr| pr.is_a? Fixnum or (pr.is_a?(Range) and pr.first <= pr.last)})
|
163
|
+
value = value..value if value.is_a? Fixnum
|
164
|
+
self.send("minimum_#{attribute}", value.first)
|
165
|
+
self.send("maximum_#{attribute}", value.last)
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
def ensure_valid_parameter(parameter, value, valid_options)
|
170
|
+
raise "#{parameter} not specified" unless value
|
171
|
+
raise "Unknown #{parameter}: #{value}" if valid_options.is_a? Array and !valid_options.include?(value.to_s)
|
172
|
+
raise "Invalid #{parameter}: #{value}" if valid_options.is_a? Proc and !valid_options.call(value)
|
173
|
+
end
|
174
|
+
|
175
|
+
def preprocess(reply)
|
176
|
+
reply = JSON.parse reply
|
177
|
+
number_of_results = reply["result_count"] || 0
|
178
|
+
listings = reply["listing"].inject([]) do |memo, listing|
|
179
|
+
parse_values_if_possible(listing)
|
180
|
+
memo << Hashie::Mash.new.update(listing)
|
181
|
+
end
|
182
|
+
[number_of_results, listings]
|
183
|
+
end
|
184
|
+
|
185
|
+
def api_call
|
186
|
+
'property_listings'
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
194
191
|
end
|
@@ -1,40 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
class Zoopla
|
2
|
+
|
3
|
+
# Searches for rental listings
|
4
|
+
class Rentals < API
|
5
|
+
|
6
|
+
include Zoopla::Listing
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
# Include property listings that are already rented in the results
|
16
|
-
# @return [Rentals]
|
17
|
-
def include_rented
|
18
|
-
@request[:include_rented] = '1'
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
|
-
# Specify whether or not the apartment is "furnished", "unfurnished" or "part-furnished".
|
23
|
-
# @return [Rentals]
|
24
|
-
def furnished(value)
|
25
|
-
ensure_valid_parameter('furnished', value, %w(furnished unfurnished part-furnished))
|
26
|
-
@request[:furnished] = value.to_s
|
27
|
-
self
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def default_parameters
|
33
|
-
{:listing_status => 'rent'}
|
34
|
-
end
|
35
|
-
|
8
|
+
def initialize(*args)
|
9
|
+
super(*args)
|
10
|
+
reset!
|
11
|
+
end
|
12
|
+
|
13
|
+
# Include property listings that are already rented in the results
|
14
|
+
# @return [Rentals]
|
15
|
+
def include_rented
|
16
|
+
@request[:include_rented] = '1'
|
17
|
+
self
|
36
18
|
end
|
37
19
|
|
20
|
+
# Specify whether or not the apartment is "furnished", "unfurnished" or "part-furnished".
|
21
|
+
# @return [Rentals]
|
22
|
+
def furnished(value)
|
23
|
+
ensure_valid_parameter('furnished', value, %w(furnished unfurnished part-furnished))
|
24
|
+
@request[:furnished] = value.to_s
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def default_parameters
|
31
|
+
{:listing_status => 'rent'}
|
32
|
+
end
|
33
|
+
|
38
34
|
end
|
39
35
|
|
40
36
|
end
|
@@ -1,32 +1,29 @@
|
|
1
|
-
|
1
|
+
class Zoopla
|
2
2
|
|
3
|
-
|
3
|
+
# Searches for sales listings
|
4
|
+
class Sales < API
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def default_parameters
|
25
|
-
{:listing_status => 'sale'}
|
26
|
-
end
|
27
|
-
|
6
|
+
include Zoopla::Listing
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
super(*args)
|
10
|
+
reset!
|
11
|
+
end
|
12
|
+
|
13
|
+
# Whether to include property listings that are already sold in the results
|
14
|
+
# @return [Sales]
|
15
|
+
def include_sold
|
16
|
+
@request[:include_sold] = '1'
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def default_parameters
|
23
|
+
{:listing_status => 'sale'}
|
28
24
|
end
|
29
25
|
|
30
26
|
end
|
31
27
|
|
28
|
+
|
32
29
|
end
|
data/lib/zoopla/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
{"result_count":null,"country":"England","area_name":null,"longitude":-0.137052,"listing":[],"street":null,"town":"","latitude":51.537402,"county":"London","postcode":"NW1 0DU","bounding_box":{"latitude_min":"51.537402","longitude_min":"-0.137052","longitude_max":"-0.137052","latitude_max":"51.537402"}}
|
data/test/test_api.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestAPI < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@rentals = Zoopla.new('my_api_key').rentals
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_no_results_returned
|
10
|
+
number_of_results, reply = @rentals.send(:preprocess, api_reply('empty'))
|
11
|
+
assert_equal 0, number_of_results
|
12
|
+
assert_equal [], reply
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_bad_request
|
16
|
+
Curl::Easy.any_instance.stubs(:perform)
|
17
|
+
Curl::Easy.any_instance.stubs(:response_code).returns(400)
|
18
|
+
assert_raises Zoopla::BadRequestError do
|
19
|
+
@rentals.each{}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_unauthorised_request
|
24
|
+
Curl::Easy.any_instance.stubs(:perform)
|
25
|
+
Curl::Easy.any_instance.stubs(:response_code).returns(401)
|
26
|
+
assert_raises Zoopla::UnauthorizedRequestError do
|
27
|
+
@rentals.each{}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_wrong_api_key
|
32
|
+
Curl::Easy.any_instance.stubs(:perform)
|
33
|
+
Curl::Easy.any_instance.stubs(:response_code).returns(403)
|
34
|
+
assert_raises Zoopla::ForbiddenError do
|
35
|
+
@rentals.each{}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_not_found
|
40
|
+
Curl::Easy.any_instance.stubs(:perform)
|
41
|
+
Curl::Easy.any_instance.stubs(:response_code).returns(404)
|
42
|
+
assert_raises Zoopla::NotFoundError do
|
43
|
+
@rentals.each{}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_method_not_allowed
|
48
|
+
Curl::Easy.any_instance.stubs(:perform)
|
49
|
+
Curl::Easy.any_instance.stubs(:response_code).returns(405)
|
50
|
+
assert_raises Zoopla::MethodNotAllowedError do
|
51
|
+
@rentals.each{}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_internal_server_error
|
56
|
+
Curl::Easy.any_instance.stubs(:perform)
|
57
|
+
Curl::Easy.any_instance.stubs(:response_code).returns(500)
|
58
|
+
assert_raises Zoopla::InternalServerError do
|
59
|
+
@rentals.each{}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -3,8 +3,9 @@ require 'helper'
|
|
3
3
|
class TestZooplaListings < Test::Unit::TestCase
|
4
4
|
|
5
5
|
def setup
|
6
|
-
|
7
|
-
@
|
6
|
+
zoopla = Zoopla.new('my_api_key')
|
7
|
+
@rentals = zoopla.rentals
|
8
|
+
@sales = zoopla.sales
|
8
9
|
end
|
9
10
|
|
10
11
|
def test_reset_for_sales
|
@@ -215,8 +216,8 @@ class TestZooplaListings < Test::Unit::TestCase
|
|
215
216
|
def test_requesting_multiple_results_pages_transparently
|
216
217
|
mock = mock();
|
217
218
|
mock.expects(:process_listing).times(12);
|
218
|
-
page1 = @rentals.send :preprocess,
|
219
|
-
page2 = @rentals.send :preprocess,
|
219
|
+
page1 = @rentals.send :preprocess, api_reply('big_request_page1')
|
220
|
+
page2 = @rentals.send :preprocess, api_reply('big_request_page2')
|
220
221
|
@rentals.stubs(:fetch_data).returns(page1, page2)
|
221
222
|
@rentals.in({:postcode => 'E1W 3TJ'}).within(0.1).price(300..400).each {|listing|
|
222
223
|
mock.process_listing
|
@@ -224,7 +225,7 @@ class TestZooplaListings < Test::Unit::TestCase
|
|
224
225
|
end
|
225
226
|
|
226
227
|
def test_deep_parsing_the_reply
|
227
|
-
_, reply = @rentals.send(:preprocess,
|
228
|
+
_, reply = @rentals.send(:preprocess, api_reply('postcode'))
|
228
229
|
listing = reply.first
|
229
230
|
assert_equal 11695072, listing.listing_id
|
230
231
|
assert_equal 'rent', listing.listing_status
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: zoopla
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Evgeny Shadchnev
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-04 00:00:00 +00:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -82,8 +82,10 @@ files:
|
|
82
82
|
- lib/zoopla/version.rb
|
83
83
|
- test/api_replies/big_request_page1.js
|
84
84
|
- test/api_replies/big_request_page2.js
|
85
|
+
- test/api_replies/empty.js
|
85
86
|
- test/api_replies/postcode.js
|
86
87
|
- test/helper.rb
|
88
|
+
- test/test_api.rb
|
87
89
|
- test/test_zoopla_listings.rb
|
88
90
|
- zoopla.gemspec
|
89
91
|
has_rdoc: true
|
@@ -117,6 +119,8 @@ summary: Access zoopla.co.uk API from ruby scripts
|
|
117
119
|
test_files:
|
118
120
|
- test/api_replies/big_request_page1.js
|
119
121
|
- test/api_replies/big_request_page2.js
|
122
|
+
- test/api_replies/empty.js
|
120
123
|
- test/api_replies/postcode.js
|
121
124
|
- test/helper.rb
|
125
|
+
- test/test_api.rb
|
122
126
|
- test/test_zoopla_listings.rb
|