mls 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.gitignore +1 -0
  2. data/README.rdoc +54 -0
  3. data/Rakefile +20 -2
  4. data/lib/mls.rb +307 -78
  5. data/lib/mls/errors.rb +13 -4
  6. data/lib/mls/model.rb +36 -5
  7. data/lib/mls/models/account.rb +74 -66
  8. data/lib/mls/models/address.rb +87 -6
  9. data/lib/mls/models/area.rb +27 -0
  10. data/lib/mls/models/flyer.rb +41 -0
  11. data/lib/mls/models/listing.rb +180 -34
  12. data/lib/mls/models/photo.rb +25 -3
  13. data/lib/mls/models/tour_request.rb +18 -31
  14. data/lib/mls/parser.rb +5 -4
  15. data/lib/mls/properties/datetime.rb +5 -1
  16. data/lib/mls/properties/decimal.rb +3 -1
  17. data/lib/mls/properties/hash.rb +7 -0
  18. data/lib/mls/resource.rb +35 -5
  19. data/lib/rdoc/generator/template/42floors/_context.rhtml +209 -0
  20. data/lib/rdoc/generator/template/42floors/_head.rhtml +7 -0
  21. data/lib/rdoc/generator/template/42floors/class.rhtml +39 -0
  22. data/lib/rdoc/generator/template/42floors/file.rhtml +35 -0
  23. data/lib/rdoc/generator/template/42floors/index.rhtml +13 -0
  24. data/lib/rdoc/generator/template/42floors/resources/apple-touch-icon.png +0 -0
  25. data/lib/rdoc/generator/template/42floors/resources/css/github.css +129 -0
  26. data/lib/rdoc/generator/template/42floors/resources/css/main.css +339 -0
  27. data/lib/rdoc/generator/template/42floors/resources/css/panel.css +389 -0
  28. data/lib/rdoc/generator/template/42floors/resources/css/reset.css +48 -0
  29. data/lib/rdoc/generator/template/42floors/resources/favicon.ico +0 -0
  30. data/lib/rdoc/generator/template/42floors/resources/i/arrows.png +0 -0
  31. data/lib/rdoc/generator/template/42floors/resources/i/results_bg.png +0 -0
  32. data/lib/rdoc/generator/template/42floors/resources/i/tree_bg.png +0 -0
  33. data/lib/rdoc/generator/template/42floors/resources/js/highlight.pack.js +1 -0
  34. data/lib/rdoc/generator/template/42floors/resources/js/jquery-1.3.2.min.js +19 -0
  35. data/lib/rdoc/generator/template/42floors/resources/js/jquery-effect.js +593 -0
  36. data/lib/rdoc/generator/template/42floors/resources/js/main.js +20 -0
  37. data/lib/rdoc/generator/template/42floors/resources/js/searchdoc.js +442 -0
  38. data/lib/rdoc/generator/template/42floors/resources/panel/index.html +73 -0
  39. data/lib/rdoc/generator/template/42floors/se_index.rhtml +8 -0
  40. data/mls.gemspec +7 -4
  41. data/test/factories/account.rb +18 -0
  42. data/test/factories/address.rb +15 -0
  43. data/test/factories/listing.rb +30 -0
  44. data/test/factories/tour_request.rb +9 -0
  45. data/test/fixtures/flyer.pdf +68 -0
  46. data/test/test_helper.rb +44 -5
  47. data/test/units/models/test_account.rb +20 -43
  48. data/test/units/models/test_flyer.rb +22 -0
  49. data/test/units/models/test_listing.rb +119 -0
  50. data/test/units/models/test_photo.rb +136 -3
  51. data/test/units/models/test_tour_request.rb +25 -20
  52. data/test/units/test_errors.rb +12 -4
  53. data/test/units/test_mls.rb +263 -3
  54. data/test/units/test_resource.rb +1 -0
  55. metadata +78 -57
  56. data/lib/mls/models/user.rb +0 -7
  57. data/lib/mls/version.rb +0 -3
data/.gitignore CHANGED
@@ -4,3 +4,4 @@ Gemfile.lock
4
4
  pkg/*
5
5
  .rvmrc
6
6
  coverage
7
+ doc
data/README.rdoc ADDED
@@ -0,0 +1,54 @@
1
+ = \MLS - 42Floors Multiple Listing Service
2
+
3
+ MLS provides an Ruby interface for interacting with Commercial Real Estate
4
+ Listings provided by 42Floors.com.
5
+
6
+ *home* - https://mls.42floors.com
7
+
8
+ *docs* - The best way to get this is to run `rake docs`. We plan to upload this
9
+
10
+ *bugs* - https://github.com/42floors/mls/issues
11
+
12
+ == System Requirements
13
+
14
+ == Installation
15
+
16
+ $ gem install mls
17
+
18
+ == Configuration
19
+
20
+ The Gem needs to be configured with your API key and URL to connect to the
21
+ 42Floors MLS. For now, ask us to provide you with an API key.
22
+
23
+ #!ruby
24
+ require 'mls'
25
+
26
+ MLS.url = "https://{API_KEY}@mls.42floors.com"
27
+
28
+ You can also override the MLS asset host if you are connecting to the staging
29
+ environment and want the photos to load.
30
+
31
+ #!ruby
32
+ MLS.asset_host = "assets.42floors.com"
33
+
34
+ == Bugs
35
+
36
+ If you think you found a bug, file a ticket on the {issues
37
+ tracker}[https://github.com/42floors/mls/issues] on github.
38
+
39
+ To get your bug fixed as fast as possible please include a sample file that
40
+ illustrates the problem or link to a repository and include steps to reproduce
41
+ the issue. Here are some examples of good issues:
42
+
43
+ * https://github.com/rdoc/rdoc/issues/55
44
+ * https://github.com/rdoc/rdoc/issues/61
45
+
46
+ == License
47
+
48
+ #TODO
49
+
50
+ == Warranty
51
+
52
+ This software is provided "as is" and without any express or implied
53
+ warranties, including, without limitation, the implied warranties of
54
+ merchantability and fitness for a particular purpose.
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
2
  require 'rake/testtask'
3
+ require 'sdoc'
4
+ require 'rdoc/task'
3
5
 
4
6
  task :console do
5
7
  exec 'irb -I lib -r mls.rb'
@@ -10,8 +12,24 @@ task :c => :console
10
12
  Rake::TestTask.new do |t|
11
13
  t.libs << 'lib' << 'test'
12
14
  t.test_files = FileList['test/units/**/test*.rb']
13
- t.warning = true
14
- t.verbose = true
15
+ #t.warning = true
16
+ #t.verbose = true
17
+ end
18
+
19
+ Rake::RDocTask.new do |rd|
20
+ rd.main = 'README.rdoc'
21
+ rd.title = 'MLS Documentation'
22
+ rd.rdoc_dir = 'doc'
23
+
24
+ rd.options << '-f' << 'sdoc' # explictly set shtml generator
25
+ rd.options << '-T' << '42floors'
26
+ rd.options << '-e' << 'UTF-8'
27
+ rd.options << '-g'
28
+ rd.options << '--include' << 'lib/rdoc'
29
+
30
+ rd.rdoc_files.include('README.rdoc')
31
+ rd.rdoc_files.include('lib/**/*.rb')
32
+ rd.rdoc_files.exclude('lib/rdoc/**/*.rb')
15
33
  end
16
34
 
17
35
  desc "Run tests"
data/lib/mls.rb CHANGED
@@ -6,159 +6,385 @@ require 'singleton'
6
6
  require 'yajl'
7
7
  require 'bigdecimal'
8
8
  require 'bigdecimal/util'
9
- require 'active_support'
10
- require 'active_resource'
9
+ require 'active_support/core_ext'
11
10
  require 'date'
12
11
  require 'time'
13
12
 
14
- class BigDecimal
15
- old_to_s = instance_method :to_s
16
-
17
- define_method :to_s do |param='F'|
18
- old_to_s.bind(self).(param)
19
- end
13
+ class Decimal #:nodoc:
20
14
  end
21
15
 
22
- class Decimal
23
- end
24
- class Boolean
16
+ class Boolean #:nodoc:
25
17
  end
26
18
 
19
+ # _MLS_ is a low-level API. It provides basic HTTP #get, #post, #put, and #delete
20
+ # calls to the MLS. It can also provides basic error checking of responses.
27
21
  class MLS
28
22
  include Singleton
29
23
 
30
24
  API_VERSION = '0.1.0'
31
25
 
32
- attr_accessor :url, :api_key, :auth_key, :logger, :asset_host
26
+ attr_reader :url
27
+ attr_writer :asset_host
28
+ attr_accessor :api_key, :auth_key, :logger
33
29
 
34
- def url=(uri)
35
- @url = uri
36
-
37
- uri = URI.parse(uri)
38
- @api_key = CGI.unescape(uri.user)
39
- @host = uri.host
40
- @port = uri.port
30
+ # Sets the API Token and Host of the MLS Server
31
+ #
32
+ # #!ruby
33
+ # MLS.url = "https://mls.42floors.com/API_KEY"
34
+ def url=(uri) # TODO: testme
35
+ @url = URI.parse(uri)
36
+ @api_key = CGI.unescape(@url.user)
37
+ @host, @port = @url.host, @url.port
41
38
  end
42
39
 
43
- def logger
40
+ def logger # TODO: testme
44
41
  @logger ||= default_logger
45
42
  end
46
43
 
47
- def connection
44
+ # Returns the current connection to the MLS or if connection has been made
45
+ # it returns a new connection
46
+ def connection # TODO: testme
48
47
  @connection ||= Net::HTTP.new(@host, @port)
49
48
  end
50
49
 
51
- def asset_host
50
+ # provides the asset host, if asset_host is set then it is returned,
51
+ # otherwise it queries the MLS for this configuration.
52
+ def asset_host # TODO: testme
52
53
  @asset_host ||= get('/asset_host').body
53
54
  end
54
55
 
55
- def add_headers(req)
56
- req['Content-Type'] = 'application/json'
57
- req['X-42Floors-API-Version'] = API_VERSION
58
- req['X-42Floors-API-Key'] = api_key
59
- req['X-42Floors-API-Auth-Key'] = auth_key if auth_key
56
+ def headers # TODO: testme
57
+ h = {
58
+ 'Content-Type' => 'application/json',
59
+ 'X-42Floors-API-Version' => API_VERSION,
60
+ 'X-42Floors-API-Key' => api_key
61
+ }
62
+ h['X-42Floors-API-Auth-Key'] = auth_key if auth_key
63
+ h
60
64
  end
61
65
 
62
- def put(url, body={})
63
- req = Net::HTTP::Put.new("/api#{url}")
64
- req.body = Yajl::Encoder.encode(body)
65
- add_headers(req)
66
+ def add_headers(req) # TODO: testme
67
+ headers.each { |k, v| req[k] = v }
68
+ end
69
+
70
+ # Gets to +url+ on the MLS Server. Automatically includes any headers returned
71
+ # by the MLS#headers function.
72
+ #
73
+ # Paramaters::
74
+ #
75
+ # * +url+ - The +url+ on the server to Get to. This url will automatically
76
+ # be prefixed with <tt>"/api"</tt>. To get to <tt>"/api/accounts"</tt>
77
+ # pass <tt>"/accounts"</tt> as +url+
78
+ # * +params+ - A Hash or Ruby Object that responds to #to_param. The result
79
+ # of this method is appended on the URL as query params
80
+ # * +valid_response_codes+ - An Array of HTTP response codes that should be
81
+ # considered accepable and not raise exceptions. For example If you don't
82
+ # want a MLS::Exception::NotFound to be raised when a GET request returns
83
+ # a 404 pass in 404, and the response body will be returned if the status
84
+ # code is a 404 as it does if the status code is in the 200..299 rage. Status
85
+ # codes in the 200..299 range are *always* considred acceptable
86
+ #
87
+ # Return Value::
88
+ #
89
+ # Returns the return value of the <tt>&block</tt> if given, otherwise the response
90
+ # object
91
+ #
92
+ # Examples:
93
+ #
94
+ # #!ruby
95
+ # MLS.get('/example') # => #<Net::HTTP::Response>
96
+ #
97
+ # MLS.get('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>
98
+ #
99
+ # MLS.get('/404') # => raises MLS::Exception::NotFound
100
+ #
101
+ # MLS.get('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>
102
+ #
103
+ # MLS.get('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>
104
+ #
105
+ # MLS.get('/404', nil, 404) # => #<Net::HTTP::Response>
106
+ #
107
+ # # this will still raise an exception if the response_code is not valid
108
+ # # and the block will not be called
109
+ # MLS.get('/act') do |response, response_code|
110
+ # # ...
111
+ # end
112
+ def get(url, params={}, *valid_response_codes, &block)
113
+ params ||= {}
66
114
 
115
+ req = Net::HTTP::Get.new("/api#{url}?" + params.to_param)
116
+ add_headers(req)
117
+
67
118
  response = connection.request(req)
119
+ handle_response(response, valid_response_codes)
68
120
  if block_given?
69
- yield(response.code.to_i, response)
121
+ yield(response, response.code.to_i)
70
122
  else
71
- handle_response(response)
123
+ response
72
124
  end
73
125
  end
74
-
75
- def post(url, body={})
76
- req = Net::HTTP::Post.new("/api#{url}")
126
+
127
+ # Puts to +url+ on the MLS Server. Automatically includes any headers returned
128
+ # by the MLS#headers function.
129
+ #
130
+ # Paramaters::
131
+ #
132
+ # * +url+ - The +url+ on the server to Put to. This url will automatically
133
+ # be prefixed with <tt>"/api"</tt>. To put to <tt>"/api/accounts"</tt>
134
+ # pass <tt>"/accounts"</tt> as +url+
135
+ # * +body+ - A Ruby object which is converted into JSON and added in the request
136
+ # Body.
137
+ # * +valid_response_codes+ - An Array of HTTP response codes that should be
138
+ # considered accepable and not raise exceptions. For example If you don't
139
+ # want a MLS::Exception::NotFound to be raised when a PUT request returns
140
+ # a 404 pass in 404, and the response body will be returned if the status
141
+ # code is a 404 as it does if the status code is in the 200..299 rage. Status
142
+ # codes in the 200..299 range are *always* considred acceptable
143
+ #
144
+ # Return Value::
145
+ #
146
+ # Returns the return value of the <tt>&block</tt> if given, otherwise the response
147
+ # object
148
+ #
149
+ # Examples:
150
+ #
151
+ # #!ruby
152
+ # MLS.put('/example') # => #<Net::HTTP::Response>
153
+ #
154
+ # MLS.put('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>
155
+ #
156
+ # MLS.put('/404') # => raises MLS::Exception::NotFound
157
+ #
158
+ # MLS.put('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>
159
+ #
160
+ # MLS.put('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>
161
+ #
162
+ # MLS.put('/404', nil, 404) # => #<Net::HTTP::Response>
163
+ #
164
+ # # this will still raise an exception if the response_code is not valid
165
+ # # and the block will not be called
166
+ # MLS.put('/act') do |response, response_code|
167
+ # # ...
168
+ # end
169
+ def put(url, body={}, *valid_response_codes, &block)
170
+ body ||= {}
171
+
172
+ req = Net::HTTP::Put.new("/api#{url}")
77
173
  req.body = Yajl::Encoder.encode(body)
78
174
  add_headers(req)
79
175
 
80
176
  response = connection.request(req)
177
+ handle_response(response, valid_response_codes)
178
+
81
179
  if block_given?
82
- yield(response.code.to_i, response)
180
+ yield(response, response.code.to_i)
83
181
  else
84
- handle_response(response)
182
+ response
85
183
  end
86
- end
87
-
88
- def delete(url, body={})
89
- req = Net::HTTP::Delete.new("/api#{url}")
184
+ end
185
+
186
+ # Posts to +url+ on the MLS Server. Automatically includes any headers returned
187
+ # by the MLS#headers function.
188
+ #
189
+ # Paramaters::
190
+ #
191
+ # * +url+ - The +url+ on the server to Post to. This url will automatically
192
+ # be prefixed with <tt>"/api"</tt>. To post to <tt>"/api/accounts"</tt>
193
+ # pass <tt>"/accounts"</tt> as +url+
194
+ # * +body+ - A Ruby object which is converted into JSON and added in the request
195
+ # Body.
196
+ # * +valid_response_codes+ - An Array of HTTP response codes that should be
197
+ # considered accepable and not raise exceptions. For example If you don't
198
+ # want a MLS::Exception::NotFound to be raised when a POST request returns
199
+ # a 404 pass in 404, and the response body will be returned if the status
200
+ # code is a 404 as it does if the status code is in the 200..299 rage. Status
201
+ # codes in the 200..299 range are *always* considred acceptable
202
+ #
203
+ # Return Value::
204
+ #
205
+ # Returns the return value of the <tt>&block</tt> if given, otherwise the response
206
+ # object
207
+ #
208
+ # Examples:
209
+ #
210
+ # #!ruby
211
+ # MLS.post('/example') # => #<Net::HTTP::Response>
212
+ #
213
+ # MLS.post('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>
214
+ #
215
+ # MLS.post('/404') # => raises MLS::Exception::NotFound
216
+ #
217
+ # MLS.post('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>
218
+ #
219
+ # MLS.post('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>
220
+ #
221
+ # MLS.post('/404', nil, 404) # => #<Net::HTTP::Response>
222
+ #
223
+ # # this will still raise an exception if the response_code is not valid
224
+ # # and the block will not be called
225
+ # MLS.post('/act') do |response, response_code|
226
+ # # ...
227
+ # end
228
+ def post(url, body={}, *valid_response_codes, &block)
229
+ body ||= {}
230
+
231
+ req = Net::HTTP::Post.new("/api#{url}")
90
232
  req.body = Yajl::Encoder.encode(body)
91
233
  add_headers(req)
92
234
 
93
235
  response = connection.request(req)
236
+ handle_response(response, valid_response_codes)
237
+
94
238
  if block_given?
95
- yield(response.code.to_i, response)
239
+ yield(response, response.code.to_i)
96
240
  else
97
- handle_response(response)
241
+ response
98
242
  end
99
243
  end
100
244
 
101
- def get(url, params={})
102
- url = "/api#{url}?" + params.to_param
103
- req = Net::HTTP::Get.new(url)
245
+ # Deletes to +url+ on the MLS Server. Automatically includes any headers returned
246
+ # by the MLS#headers function.
247
+ #
248
+ # Paramaters::
249
+ #
250
+ # * +url+ - The +url+ on the server to Post to. This url will automatically
251
+ # be prefixed with <tt>"/api"</tt>. To delete to <tt>"/api/accounts"</tt>
252
+ # pass <tt>"/accounts"</tt> as +url+
253
+ # * +body+ - A Ruby object which is converted into JSON and added in the request
254
+ # Body.
255
+ # * +valid_response_codes+ - An Array of HTTP response codes that should be
256
+ # considered accepable and not raise exceptions. For example If you don't
257
+ # want a MLS::Exception::NotFound to be raised when a POST request returns
258
+ # a 404 pass in 404, and the response body will be returned if the status
259
+ # code is a 404 as it does if the status code is in the 200..299 rage. Status
260
+ # codes in the 200..299 range are *always* considred acceptable
261
+ #
262
+ # Return Value::
263
+ #
264
+ # Returns the return value of the <tt>&block</tt> if given, otherwise the
265
+ # response object
266
+ #
267
+ # Examples:
268
+ #
269
+ # #!ruby
270
+ # MLS.delete('/example') # => #<Net::HTTP::Response>
271
+ #
272
+ # MLS.delete('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>
273
+ #
274
+ # MLS.delete('/404') # => raises MLS::Exception::NotFound
275
+ #
276
+ # MLS.delete('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>
277
+ #
278
+ # MLS.delete('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>
279
+ #
280
+ # MLS.delete('/404', nil, 404) # => #<Net::HTTP::Response>
281
+ #
282
+ # # this will still raise an exception if the response_code is not valid
283
+ # # and the block will not be called
284
+ # MLS.delete('/act') do |response, response_code|
285
+ # # ...
286
+ # end
287
+ def delete(url, body={}, *valid_response_codes, &block)
288
+ body ||= {}
289
+
290
+ req = Net::HTTP::Delete.new("/api#{url}")
291
+ req.body = Yajl::Encoder.encode(body)
104
292
  add_headers(req)
293
+
105
294
  response = connection.request(req)
295
+ handle_response(response, valid_response_codes)
106
296
  if block_given?
107
- yield(response.code.to_i, response)
297
+ yield(response, response.code.to_i)
108
298
  else
109
- handle_response(response)
299
+ response
110
300
  end
111
-
112
- response
113
301
  end
114
302
 
115
- def handle_response(response)
303
+ # Raise an MLS::Exception based on the response_code, unless the response_code
304
+ # is include in the valid_response_codes Array
305
+ #
306
+ # Paramaters::
307
+ #
308
+ # * +response+ - The Net::HTTP::Response object
309
+ # * +valid_response_codes+ - An Array, Integer, or Range. If it's Array the
310
+ # Array can include both Integers or Ranges.
311
+ #
312
+ # Return Value::
313
+ #
314
+ # If an exception is not raised the +response+ is returned
315
+ #
316
+ # Examples:
317
+ #
318
+ # #!ruby
319
+ # MLS.handle_response(<Net::HTTP::Response @code=200>) # => <Net::HTTP::Response @code=200>
320
+ #
321
+ # MLS.handle_response(<Net::HTTP::Response @code=404>) # => raises MLS::Exception::NotFound
322
+ #
323
+ # MLS.handle_response(<Net::HTTP::Response @code=500>) # => raises MLS::Exception
324
+ #
325
+ # MLS.handle_response(<Net::HTTP::Response @code=404>, 404) # => <Net::HTTP::Response @code=404>
326
+ #
327
+ # MLS.handle_response(<Net::HTTP::Response @code=500>, 404, 500) # => <Net::HTTP::Response @code=500>
328
+ #
329
+ # MLS.handle_response(<Net::HTTP::Response @code=405>, 300, 400..499) # => <Net::HTTP::Response @code=405>
330
+ #
331
+ # MLS.handle_response(<Net::HTTP::Response @code=405>, [300, 400..499]) # => <Net::HTTP::Response @code=405>
332
+ def handle_response(response, *valid_response_codes)
116
333
  if response['X-42Floors-API-Version-Deprecated']
117
334
  logger.warn("DEPRECATION WARNING: API v#{API_VERSION} is being phased out")
118
335
  end
119
336
 
120
- raise(response.code, response.body)
121
- response.body
122
- end
123
-
124
- def raise(error_code, message=nil)
125
- case error_code.to_i
126
- when 401
127
- super Unauthorized, message
128
- when 404, 410
129
- super NotFound, message
130
- when 422
131
- super ApiVersionUnsupported, message
132
- when 300...400
133
- super MLS::Exception, error_code
134
- when 400
135
- super MLS::BadRequest, message
136
- when 401...500
137
- super MLS::Exception, error_code
138
- when 500...600
139
- super MLS::Exception, error_code
337
+ code = response.code.to_i
338
+ valid_response_codes.flatten!
339
+ valid_response_codes << (200..299)
340
+
341
+ if !valid_response_codes.detect{|i| i.is_a?(Range) ? i.include?(code) : i == code}
342
+ case code
343
+ when 400
344
+ raise MLS::Exception::BadRequest, response.body
345
+ when 401
346
+ raise MLS::Exception::Unauthorized, response.body
347
+ when 404, 410
348
+ raise MLS::Exception::NotFound
349
+ when 422
350
+ raise MLS::Exception::ApiVersionUnsupported, response.body
351
+ when 503
352
+ raise MLS::Exception::ServiceUnavailable, response.body
353
+ when 300..599
354
+ raise MLS::Exception, code
355
+ end
140
356
  end
357
+
358
+ response
141
359
  end
142
-
143
- def ping
360
+
361
+ # Ping the MLS. If everything is configured and operating correctly <tt>"pong"</tt>
362
+ # will be returned. Otherwise and MLS::Exception should be thrown.
363
+ #
364
+ # #!ruby
365
+ # MLS.ping # => "pong"
366
+ #
367
+ # MLS.ping # raises MLS::Exception::ServiceUnavailable if a 503 is returned
368
+ def ping # TODO: testme
144
369
  get('/ping').body
145
370
  end
146
371
 
147
- def auth_ping
372
+ def auth_ping # TODO: testme
148
373
  post('/ping').body
149
374
  end
150
375
 
151
- def default_logger
376
+ def default_logger # TODO: testme
152
377
  logger = Logger.new(STDOUT)
153
378
  logger.level = Logger::INFO
154
379
  logger
155
380
  end
156
381
 
157
- def self.method_missing(method, *args, &block)
382
+ # Delegates all uncauge class method calls to the singleton
383
+ def self.method_missing(method, *args, &block) #:nodoc: # TODO: testme
158
384
  instance.__send__(method, *args, &block)
159
385
  end
160
386
 
161
- def self.parse(json)
387
+ def self.parse(json) # TODO: testme
162
388
  Yajl::Parser.new(:symbolize_keys => true).parse(json)
163
389
  end
164
390
 
@@ -175,6 +401,7 @@ require 'mls/properties/boolean'
175
401
  require 'mls/properties/decimal'
176
402
  require 'mls/properties/datetime'
177
403
  require 'mls/properties/string'
404
+ require 'mls/properties/hash'
178
405
 
179
406
  # Models
180
407
  require 'mls/model'
@@ -183,3 +410,5 @@ require 'mls/models/listing'
183
410
  require 'mls/models/address'
184
411
  require 'mls/models/photo'
185
412
  require 'mls/models/tour_request'
413
+ require 'mls/models/flyer'
414
+ require 'mls/models/area'