oodler 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +58 -0
- data/Rakefile +64 -0
- data/VERSION +1 -0
- data/examples/listings.rb +18 -0
- data/lib/oodler/category.rb +9 -0
- data/lib/oodler/client.rb +78 -0
- data/lib/oodler/element.rb +19 -0
- data/lib/oodler/image.rb +12 -0
- data/lib/oodler/location.rb +15 -0
- data/lib/oodler/oodle_response.rb +17 -0
- data/lib/oodler/region.rb +7 -0
- data/lib/oodler/source.rb +9 -0
- data/lib/oodler/web_client.rb +27 -0
- data/lib/oodler.rb +66 -0
- data/test/client_test.rb +137 -0
- data/test/element_test.rb +85 -0
- data/test/fixtures/blank.xml +0 -0
- data/test/fixtures/fail.xml +5 -0
- data/test/fixtures/listings.xml +679 -0
- data/test/image_test.rb +20 -0
- data/test/test_helper.rb +42 -0
- data/test/web_client_test.rb +24 -0
- metadata +151 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Mike Hagedorn
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Oodler
|
2
|
+
|
3
|
+
Ruby wrapper for the [Oodle API](http://developer.oodle.com). Heavily inspired by [Wynn Nederlands's](http://github.com/pengwynn) [LinkedIn gem](http://github.com/pengwynn/linkedin), the Oodler gem provides an easy-to-use wrapper for Oodles's XML APIs.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
sudo gem install gemcutter
|
8
|
+
gem tumble
|
9
|
+
sudo gem install oodler
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
### Authenticate
|
14
|
+
|
15
|
+
Ooodle's API uses a key for authentication, you can get a key at http://developer.oodle.com/request-api-key/
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
require 'oodler'
|
19
|
+
|
20
|
+
# get your api keys at https://www.linkedin.com/secure/developer
|
21
|
+
client = Oodler::Client.new("YOURAPIKEY")
|
22
|
+
|
23
|
+
### Listing examples
|
24
|
+
|
25
|
+
# get the profile for the authenticated user
|
26
|
+
result = client.listing({:region => "chicago",:category => "vehicle/car"})
|
27
|
+
|
28
|
+
puts result.listings[0].id
|
29
|
+
puts result.listings[0].title
|
30
|
+
puts result.listings[0].id
|
31
|
+
puts result.listings[0].body
|
32
|
+
puts result.listings[0].url
|
33
|
+
puts result.listings[0].images[0].src
|
34
|
+
|
35
|
+
..etc
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
TODO
|
42
|
+
|
43
|
+
* Nothing yet
|
44
|
+
|
45
|
+
## Note on Patches/Pull Requests
|
46
|
+
|
47
|
+
* Fork the project.
|
48
|
+
* Make your feature addition or bug fix.
|
49
|
+
* Add tests for it. This is important so I don't break it in a
|
50
|
+
future version unintentionally.
|
51
|
+
* Commit, do not mess with rakefile, version, or history.
|
52
|
+
(if you want to have your own version, that is fine but
|
53
|
+
bump version in a commit by itself I can ignore when I pull)
|
54
|
+
* Send me a pull request. Bonus points for topic branches.
|
55
|
+
|
56
|
+
## Copyright
|
57
|
+
|
58
|
+
Copyright (c) 2010 [Mike Hagedorn](http://silverchairsolutions.com). See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "oodler"
|
8
|
+
gem.summary = %Q{Ruby wrapper for the Oodle API}
|
9
|
+
gem.description = %Q{Ruby wrapper for the Oodle API}
|
10
|
+
gem.email = "mike@silverchairsolutions.com"
|
11
|
+
gem.homepage = "http://github.com/mwhagedorn/oodler"
|
12
|
+
gem.authors = ["Mike Hagedorn"]
|
13
|
+
gem.files = FileList["[A-Z]*", "{lib,test}/**/*"]
|
14
|
+
|
15
|
+
|
16
|
+
gem.add_dependency('roxml', '~> 3.1.3')
|
17
|
+
gem.add_dependency('crack', '~> 0.1.4')
|
18
|
+
|
19
|
+
gem.add_development_dependency('shoulda', '>= 2.10.1')
|
20
|
+
gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
|
21
|
+
gem.add_development_dependency('mocha', '0.9.4')
|
22
|
+
gem.add_development_dependency('fakeweb', '>= 1.2.5')
|
23
|
+
gem.add_development_dependency("httparty", ">= 0.5.2")
|
24
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
25
|
+
end
|
26
|
+
Jeweler::GemcutterTasks.new
|
27
|
+
rescue LoadError
|
28
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'rake/testtask'
|
32
|
+
Rake::TestTask.new(:test) do |test|
|
33
|
+
test.libs << 'test'
|
34
|
+
test.ruby_opts << '-rubygems'
|
35
|
+
test.pattern = 'test/**/*_test.rb'
|
36
|
+
test.verbose = true
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
require 'rcov/rcovtask'
|
41
|
+
Rcov::RcovTask.new do |test|
|
42
|
+
test.libs << 'test'
|
43
|
+
test.pattern = 'test/**/test_*.rb'
|
44
|
+
test.verbose = true
|
45
|
+
end
|
46
|
+
rescue LoadError
|
47
|
+
task :rcov do
|
48
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
task :test => :check_dependencies
|
53
|
+
|
54
|
+
task :default => :test
|
55
|
+
|
56
|
+
require 'rake/rdoctask'
|
57
|
+
Rake::RDocTask.new do |rdoc|
|
58
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
59
|
+
|
60
|
+
rdoc.rdoc_dir = 'rdoc'
|
61
|
+
rdoc.title = "oodler #{version}"
|
62
|
+
rdoc.rdoc_files.include('README*')
|
63
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
64
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'oodler'
|
3
|
+
|
4
|
+
# get your api keys at http://developer.oodle.com/request-api-key
|
5
|
+
client = Oodler::Client.new('your_api_key')
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
#most generic
|
10
|
+
|
11
|
+
client.listing({:region =>"chicago", :category=>"vehicle/cars"})
|
12
|
+
|
13
|
+
#other formulations of same search
|
14
|
+
client.search("chicago", {:category => "vehicle/cars"})
|
15
|
+
client.search_by_category("chicago", "vehicle/cars",{})
|
16
|
+
|
17
|
+
#adding criteria
|
18
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Oodler
|
2
|
+
class Client
|
3
|
+
include HTTParty
|
4
|
+
|
5
|
+
attr_reader :key, :http_options
|
6
|
+
|
7
|
+
def initialize(key=Oodle.key,options={})
|
8
|
+
@key, @http_options = key,options
|
9
|
+
end
|
10
|
+
|
11
|
+
def web_client
|
12
|
+
@web_client ||= Oodler::WebClient.new(@key)
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def get(path, options={})
|
17
|
+
path = "/listings#{path}"
|
18
|
+
validate_parameters(options)
|
19
|
+
response = web_client.get(path, options)
|
20
|
+
raise_errors(response)
|
21
|
+
response.body
|
22
|
+
end
|
23
|
+
|
24
|
+
#client.search("chicago", {:category =>"vehicle/cars"})
|
25
|
+
def search( region, options={})
|
26
|
+
path = ""
|
27
|
+
|
28
|
+
options= {:query =>options}
|
29
|
+
options[:query].merge!({:region => region}) if region
|
30
|
+
|
31
|
+
OodleResponse.from_xml(get(path, options))
|
32
|
+
end
|
33
|
+
|
34
|
+
#helper method - client.search_by_category("chicago", "vehicle/car")
|
35
|
+
def search_by_category(region,category, options={})
|
36
|
+
path=""
|
37
|
+
options= {:query =>options}
|
38
|
+
options[:query].merge!({:region => region}) if region
|
39
|
+
options[:query].merge!({:category => category}) if category
|
40
|
+
|
41
|
+
OodleResponse.from_xml(get(path, options))
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
#the generic pash a hash version
|
47
|
+
#example client.listing(:region=>"chicago", :category => "vehicle/car")
|
48
|
+
#returns an OodleResponse
|
49
|
+
def listing(options={})
|
50
|
+
path = ""
|
51
|
+
options= {:query =>options}
|
52
|
+
OodleResponse.from_xml(get(path, options))
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def validate_parameters(options)
|
58
|
+
params = options[:query]
|
59
|
+
unless params[:region]
|
60
|
+
raise OodleArgumentError, 'Missing region paramter. Visit http://developer.oodle.com/regions-list/ for possible regions.'
|
61
|
+
end
|
62
|
+
unless params[:category] || options[:q]
|
63
|
+
raise OodleArgumentError, 'You must supply a category or query parameter. Visit http://developer.oodle.com/categories-list/ for possible categories.'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def raise_errors(response)
|
68
|
+
if response["oodle_response"]["error"]
|
69
|
+
data = response["oodle_response"]["error"]
|
70
|
+
raise OodlerError.new(data), "(fail: #{data}"
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Oodler
|
2
|
+
class Element
|
3
|
+
include ROXML
|
4
|
+
xml_reader :id
|
5
|
+
xml_reader :title
|
6
|
+
xml_reader :body
|
7
|
+
xml_reader :url
|
8
|
+
xml_reader :category, :as => Category
|
9
|
+
xml_reader :source, :as => Source
|
10
|
+
xml_reader :location, :as => Location
|
11
|
+
xml_reader :images, :as => [Image], :in =>"images"
|
12
|
+
xml_reader :ctime
|
13
|
+
xml_reader :paid?
|
14
|
+
xml_reader :revenue_score
|
15
|
+
xml_reader :similar_url
|
16
|
+
xml_reader :properties ,:as => {:key => :name,:value => :content}, :in => "attributes"
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/oodler/image.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Oodler
|
2
|
+
class Location
|
3
|
+
include ROXML
|
4
|
+
xml_reader :latitude
|
5
|
+
xml_reader :longitude
|
6
|
+
xml_reader :address
|
7
|
+
xml_reader :zip
|
8
|
+
xml_reader :addresscode
|
9
|
+
xml_reader :citycode
|
10
|
+
xml_reader :name
|
11
|
+
xml_reader :state
|
12
|
+
xml_reader :country
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Oodler
|
2
|
+
class OodleResponse
|
3
|
+
include ROXML
|
4
|
+
xml_reader :region, :as => Region, :in => "current"
|
5
|
+
xml_reader :category, :as => Category, :in => "current"
|
6
|
+
xml_reader :elements, :as =>[Element], :in => "listings"
|
7
|
+
xml_reader :start, :in =>"current"
|
8
|
+
xml_reader :num, :in => "current"
|
9
|
+
xml_reader :stat, :from => :attr
|
10
|
+
xml_reader :error
|
11
|
+
|
12
|
+
def listings
|
13
|
+
elements
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Oodler
|
2
|
+
class WebClient
|
3
|
+
include HTTParty
|
4
|
+
|
5
|
+
attr_accessor :key
|
6
|
+
base_uri 'api.oodle.com/api/v2/'
|
7
|
+
format :xml
|
8
|
+
|
9
|
+
def initialize(key=nil)
|
10
|
+
@key = key
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(path,options)
|
14
|
+
options[:query].merge!({:key => @key}) if @key
|
15
|
+
validate_parameters(options)
|
16
|
+
self.class.get(path,options)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def validate_parameters(options)
|
21
|
+
params = options[:query]
|
22
|
+
unless params[:key]
|
23
|
+
raise OodleArgumentError, 'Missing API key parameter. Visit http://developer.oodle.com/request-api-key/ to get one'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/oodler.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
gem 'roxml', '~> 3.1.3'
|
5
|
+
require 'roxml'
|
6
|
+
|
7
|
+
gem 'crack', '~> 0.1.4'
|
8
|
+
require 'crack'
|
9
|
+
|
10
|
+
gem 'httparty'
|
11
|
+
require 'httparty'
|
12
|
+
|
13
|
+
require 'cgi'
|
14
|
+
|
15
|
+
module Oodler
|
16
|
+
class OodlerError < StandardError
|
17
|
+
attr_reader :data
|
18
|
+
|
19
|
+
def initialize(data)
|
20
|
+
@data = data
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class OodleArgumentError <OodlerError; end
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
# config/initializers/oodler.rb (for instance)
|
30
|
+
#
|
31
|
+
# Oodler.configure do |config|
|
32
|
+
# config.key = 'api_key'
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# elsewhere
|
36
|
+
#
|
37
|
+
# client = Oodler::Client.new
|
38
|
+
def self.configure
|
39
|
+
yield self
|
40
|
+
|
41
|
+
Oodler.key = key
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.key
|
46
|
+
@key
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.key=(key)
|
50
|
+
@key = key
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
directory = File.expand_path(File.dirname(__FILE__))
|
57
|
+
require File.join(directory, "oodler", 'category')
|
58
|
+
require File.join(directory, "oodler", 'region')
|
59
|
+
require File.join(directory, 'oodler', 'web_client')
|
60
|
+
require File.join(directory, 'oodler', 'location')
|
61
|
+
require File.join(directory, 'oodler', 'image')
|
62
|
+
require File.join(directory, 'oodler', 'source')
|
63
|
+
require File.join(directory, 'oodler', 'category')
|
64
|
+
require File.join(directory, 'oodler', 'element')
|
65
|
+
require File.join(directory, 'oodler', 'oodle_response')
|
66
|
+
require File.join(directory, 'oodler', 'client')
|
data/test/client_test.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class ClientTest < Test::Unit::TestCase
|
5
|
+
context "when hitting the Oodle API" do
|
6
|
+
setup do
|
7
|
+
@oodler = Oodler::Client.new('key')
|
8
|
+
end
|
9
|
+
should "have a web client" do
|
10
|
+
stub_get("/listings?region=chicago&category=vehicle%2fcar&key=key", "listings.xml")
|
11
|
+
wc = mock('webclient')
|
12
|
+
|
13
|
+
Oodler::WebClient.expects(:new).with('keyval').returns(wc)
|
14
|
+
@oodler = Oodler::Client.new('keyval')
|
15
|
+
|
16
|
+
@oodler.web_client.should == wc
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
context "and a region is not provided" do
|
21
|
+
should "throw an error" do
|
22
|
+
stub_get("/v2/listings?region=chicago&category=vehicle%2Fcar&key=key", "listings.xml")
|
23
|
+
assert_raise(Oodler::OodleArgumentError) do
|
24
|
+
@oodler.search(nil, {:category=>"vehicle/car"})
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
should "retrieve a listing" do
|
31
|
+
stub_get("/api/v2/listings?key=key®ion=chicago&category=vehicle%2Fcars", "listings.xml")
|
32
|
+
p = @oodler.search("chicago", {:category => "vehicle/cars"})
|
33
|
+
|
34
|
+
p.region.id.should == "chicago"
|
35
|
+
p.region.name.should == "Chicago"
|
36
|
+
p.category.id.should == "vehicle/car"
|
37
|
+
p.start.should == "1"
|
38
|
+
p.listings.size.should == 10
|
39
|
+
p.listings[0].id.should == "1899168373"
|
40
|
+
p.listings[0].title.should == "2002 Mazda Tribute"
|
41
|
+
p.listings[0].category.name.should == "SUVs"
|
42
|
+
p.listings[0].source.name.should == "EveryCarListed.com"
|
43
|
+
p.listings[0].location.zip.should == "60453"
|
44
|
+
p.listings[0].images.size.should == 2
|
45
|
+
p.listings[0].images[0].src.should == "http://i.oodleimg.com/item/1899168373_1m?1271098477"
|
46
|
+
p.listings[0].paid?.should == true
|
47
|
+
p.listings[0].properties.should_not == nil
|
48
|
+
p.listings[0].properties["color"].should == "Grey"
|
49
|
+
end
|
50
|
+
|
51
|
+
should "retrieve a listing using convenience method" do
|
52
|
+
stub_get("/api/v2/listings?key=key®ion=chicago&category=vehicle%2Fcars", "listings.xml")
|
53
|
+
p = @oodler.search_by_category("chicago", "vehicle/cars")
|
54
|
+
|
55
|
+
p.region.id.should == "chicago"
|
56
|
+
p.region.name.should == "Chicago"
|
57
|
+
p.category.id.should == "vehicle/car"
|
58
|
+
p.start.should == "1"
|
59
|
+
p.listings.size.should == 10
|
60
|
+
p.listings[0].id.should == "1899168373"
|
61
|
+
p.listings[0].title.should == "2002 Mazda Tribute"
|
62
|
+
p.listings[0].category.name.should == "SUVs"
|
63
|
+
p.listings[0].source.name.should == "EveryCarListed.com"
|
64
|
+
p.listings[0].location.zip.should == "60453"
|
65
|
+
p.listings[0].images.size.should == 2
|
66
|
+
p.listings[0].images[0].src.should == "http://i.oodleimg.com/item/1899168373_1m?1271098477"
|
67
|
+
p.listings[0].paid?.should == true
|
68
|
+
p.listings[0].properties.should_not == nil
|
69
|
+
p.listings[0].properties["color"].should == "Grey"
|
70
|
+
end
|
71
|
+
context "when using the listing method " do
|
72
|
+
should "retrieve a listing " do
|
73
|
+
stub_get("/api/v2/listings?key=key®ion=chicago&category=vehicle%2Fcars", "listings.xml")
|
74
|
+
p = @oodler.listing({:region =>"chicago", :category=>"vehicle/cars"})
|
75
|
+
|
76
|
+
p.region.id.should == "chicago"
|
77
|
+
p.region.name.should == "Chicago"
|
78
|
+
p.category.id.should == "vehicle/car"
|
79
|
+
p.start.should == "1"
|
80
|
+
p.listings.size.should == 10
|
81
|
+
p.listings[0].id.should == "1899168373"
|
82
|
+
p.listings[0].title.should == "2002 Mazda Tribute"
|
83
|
+
p.listings[0].category.name.should == "SUVs"
|
84
|
+
p.listings[0].source.name.should == "EveryCarListed.com"
|
85
|
+
p.listings[0].location.zip.should == "60453"
|
86
|
+
p.listings[0].images.size.should == 2
|
87
|
+
p.listings[0].images[0].src.should == "http://i.oodleimg.com/item/1899168373_1m?1271098477"
|
88
|
+
p.listings[0].paid?.should == true
|
89
|
+
p.listings[0].properties.should_not == nil
|
90
|
+
p.listings[0].properties["color"].should == "Grey"
|
91
|
+
end
|
92
|
+
|
93
|
+
should "throw an error with empty hash" do
|
94
|
+
stub_get("/api/v2/listings?key=key®ion=chicago&category=vehicle%2Fcars", "listings.xml")
|
95
|
+
assert_raise(Oodler::OodleArgumentError) do
|
96
|
+
@oodler.listing()
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
should "allow inclusion of attributes in the query" do
|
103
|
+
stub_get("/api/v2/listings?region=chicago&attributes=make_honda%2Cmodel_civic%2Cprice_12000_15000&key=key&category=vehicle%2Fcars", "listings.xml")
|
104
|
+
|
105
|
+
@oodler.listing({:region =>"chicago", :category=>"vehicle/cars", :attributes=>"make_honda,model_civic,price_12000_15000"})
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
should "display error details" do
|
110
|
+
stub_get("/api/v2/listings?region=chicago&attributes=make_honda%2Cmodel_civic%2Cprice_12000_15000&key=key&category=vehicle%2Fbogus", "fail.xml")
|
111
|
+
assert_raise(Oodler::OodlerError) do
|
112
|
+
@oodler.listing({:region =>"chicago", :category=>"vehicle/bogus", :attributes=>"make_honda,model_civic,price_12000_15000"})
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
should "encode spaces as %20" do
|
121
|
+
stub_get("/api/v2/listings?key=key®ion=sf&category=job&q=software%20engineer", "listings.xml")
|
122
|
+
p = @oodler.search("sf", {:category => "job", :q =>"software engineer"})
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
should "encode commas as %2C" do
|
127
|
+
stub_get("/api/v2/listings?location=San%20Mateo%2C%20CA®ion=usa&key=key&category=job&", "listings.xml")
|
128
|
+
p = @oodler.search("usa", {:category => "job", :location =>"San Mateo, CA"})
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ElementTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
should "parse element correctly from xml" do
|
6
|
+
element = Oodler::Element.from_xml('<element>
|
7
|
+
<id>1900074984</id>
|
8
|
+
<title>2010 Chrysler Town & Country Touring</title>
|
9
|
+
<body>Driver manual lumbar adjust, Active headrests, Front center console w/cupholder, Pwr adjustable pedals, Tip start, Tilt steering column, Leather-wrapped steering wheel, Steering wheel audio controls, Trip computer w/temp & compass, Door ajar warning light, Sliding door alert, Low washer fluid warning signal, Dark maple/silver instrument panel bezel, Satin silver instrument panel bezel center stack, Pwr front windows w/one-touch, 2nd row pwr windows, Pwr rear quarter vent windows, Pwr door locks, Keyless entry w/immobilizer, Speed control, Universal garage door opener, Rear window defroster, Analog clock, Dual glove boxes, Lower instrument panel cubby bin, Cupholders w/overhead illumination, Front/rear 12V DC pwr outlets, 12V auxiliary pwr outlets, 115V pwr outlet, Driver door sill storage bin, Door trim panel w/dark maple accents, Illuminated front door storage, Interior observation mirror, Overhead console, Overhead storage bins, Rear overhead console, Visors w/illuminated vanity mirrors</body>
|
10
|
+
<url>http://cars.oodle.com/r_a2xx_/1900074984-11202p454,10-EST/www.everycarlisted.com___chKLl2fSDGxSt6l73uN6064DyBKKek7cFjfdds1IVF0TXnFPtwBGejSLLeJvnwcNbSGADeRrrSEW8TQWmq9mTnxTRMpCVoogInIUUrMi4fVYmgrW86CjxEqU3RRWlP5g</url>
|
11
|
+
<category>
|
12
|
+
<id>vehicle/car</id>
|
13
|
+
<name>Cars</name>
|
14
|
+
</category>
|
15
|
+
<source>
|
16
|
+
<id>everycarlisted-bronze</id>
|
17
|
+
<name>EveryCarListed.com</name>
|
18
|
+
</source>
|
19
|
+
<location>
|
20
|
+
<latitude>42.0657997</latitude>
|
21
|
+
<longitude>-87.9197998</longitude>
|
22
|
+
<address>77 Rand Rd</address>
|
23
|
+
<zip>60016</zip>
|
24
|
+
<addresscode>addr:usa:il:desplaines:77+rand+rd</addresscode>
|
25
|
+
<citycode>usa:il:desplaines</citycode>
|
26
|
+
<name>Des Plaines</name>
|
27
|
+
<state>IL</state>
|
28
|
+
<country>USA</country>
|
29
|
+
</location>
|
30
|
+
<images>
|
31
|
+
<element>
|
32
|
+
<src>http://i.oodleimg.com/item/1900074984_1m?1271160266</src>
|
33
|
+
<width>144</width>
|
34
|
+
<height>108</height>
|
35
|
+
<alt>2010 Chrysler Town & Country T</alt>
|
36
|
+
</element>
|
37
|
+
<element>
|
38
|
+
<src>http://i.oodleimg.com/item/1900074984_1s?1271160266</src>
|
39
|
+
<width>112</width>
|
40
|
+
<height>84</height>
|
41
|
+
<alt>2010 Chrysler Town & Country T</alt>
|
42
|
+
</element>
|
43
|
+
</images>
|
44
|
+
<ctime>1271160145</ctime>
|
45
|
+
<paid>Yes</paid>
|
46
|
+
<revenue_score>10</revenue_score>
|
47
|
+
<similar_url>http://cars.oodle.com/2009_2011-hrysler-town_and_country/chicago-area/price_27000_36000/mileage_0_20000/?inbs=1</similar_url>
|
48
|
+
<attributes>
|
49
|
+
<color>Blue</color>
|
50
|
+
<condition>New</condition>
|
51
|
+
<currency>USD</currency>
|
52
|
+
<dealer_id>Advantage Chrysler Jeep Dodge of Des Pla</dealer_id>
|
53
|
+
<delivery>Local Delivery</delivery>
|
54
|
+
<engine_type>4.0L V6 24V MPFI SOHC</engine_type>
|
55
|
+
<features>Trip Computer,Keyless Entry,Clock,Center Console,Air Conditioning,Air Bags</features>
|
56
|
+
<fee>No</fee>
|
57
|
+
<has_photo>Thumbnail</has_photo>
|
58
|
+
<make>Chrysler</make>
|
59
|
+
<mileage>2</mileage>
|
60
|
+
<model>Town and Country</model>
|
61
|
+
<price>31415</price>
|
62
|
+
<price_display>$31,415</price_display>
|
63
|
+
<seller_type>Dealer</seller_type>
|
64
|
+
<transmission>Automatic</transmission>
|
65
|
+
<trim>Touring</trim>
|
66
|
+
<vin>2A4RR5DX9AR201012</vin>
|
67
|
+
<year>2010</year>
|
68
|
+
</attributes>
|
69
|
+
</element>')
|
70
|
+
|
71
|
+
element.id.should == "1900074984"
|
72
|
+
element.category.name.should == "Cars"
|
73
|
+
element.location.latitude.should == "42.0657997"
|
74
|
+
element.images.size.should == 2
|
75
|
+
element.images.first.src.should == "http://i.oodleimg.com/item/1900074984_1m?1271160266"
|
76
|
+
element.paid?.should == true
|
77
|
+
element.properties.keys.size.should == 19
|
78
|
+
element.properties["color"].should == "Blue"
|
79
|
+
element.properties["mileage"].should == "2"
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
File without changes
|