vinquery 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +2 -2
- data/lib/vinquery.rb +22 -31
- data/lib/vinquery/version.rb +1 -1
- data/lib/vinquery/vinquery_exception.rb +7 -0
- data/spec/vin_exploder_adapter_spec.rb +8 -6
- data/spec/vinquery_spec.rb +35 -46
- metadata +50 -54
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vinquery (0.4.
|
4
|
+
vinquery (0.4.2)
|
5
5
|
nokogiri (>= 1.4.4)
|
6
6
|
|
7
7
|
GEM
|
@@ -21,7 +21,7 @@ GEM
|
|
21
21
|
rspec-mocks (2.6.0)
|
22
22
|
vin_exploder (0.4.3)
|
23
23
|
webmock (1.6.4)
|
24
|
-
addressable (
|
24
|
+
addressable (~> 2.2, > 2.2.5)
|
25
25
|
crack (>= 0.1.7)
|
26
26
|
|
27
27
|
PLATFORMS
|
data/lib/vinquery.rb
CHANGED
@@ -1,80 +1,71 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'logger'
|
4
|
+
require 'vinquery/vinquery_exception'
|
4
5
|
|
5
6
|
class Vinquery
|
6
7
|
attr_reader :attributes, :errors, :result
|
7
|
-
|
8
|
+
|
8
9
|
def self.get(vin, options={})
|
9
|
-
request = Vinquery.new(options[:url], options[:access_code], options[:report_type], options[:logger])
|
10
|
-
|
11
|
-
|
10
|
+
request = Vinquery.new(vin, options[:url], options[:access_code], options[:report_type], options[:logger])
|
11
|
+
request.fetch
|
12
|
+
request.parse
|
12
13
|
request
|
13
14
|
end
|
14
15
|
|
15
|
-
def initialize(url, access_code, report_type, log = nil)
|
16
|
+
def initialize(vin, url, access_code, report_type, log = nil)
|
17
|
+
@vin = vin
|
16
18
|
@url = url
|
19
|
+
@errors = []
|
17
20
|
@access_code = access_code
|
18
21
|
@report_type = report_type
|
19
22
|
log ||= Logger.new(nil)
|
20
23
|
@log = log
|
21
24
|
end
|
22
25
|
|
23
|
-
def fetch
|
26
|
+
def fetch
|
24
27
|
# use reducable=FALSE to get additional fields like fuel_type
|
25
28
|
# use vt=true to get vehicle_type
|
29
|
+
# use gvwr=TRUE to get GVWR
|
26
30
|
# http://www.vinquery.com/ws_POQCXTYNO1D/xml_v100_QA7RTS8Y.aspx?accessCode=6958785b-ac0a-4303-8b28-40e14aa836ce&vin=YourVINToDecode&reportType=0&vt=true&gvwr=true
|
27
31
|
@uri ||= "#{@url}?accessCode=#{@access_code}&reportType=#{@report_type}&reducable=FALSE&vt=TRUE&gvwr=TRUE"
|
28
|
-
url_s = @uri + "&vin=#{vin}"
|
32
|
+
url_s = @uri + "&vin=#{@vin}"
|
29
33
|
@log.info{"Vinquery#fetch - uri: #{url_s}"}
|
30
34
|
url = URI.parse(url_s)
|
31
35
|
begin
|
32
36
|
@result = Net::HTTP.get url
|
33
37
|
@log.debug{"Vinquery#fetch - result: #{@result}"}
|
38
|
+
@doc = Nokogiri::HTML(@result)
|
34
39
|
rescue Exception => e
|
35
|
-
|
36
|
-
@log.error{"ERROR - #{e.backtrace[0]}"}
|
37
|
-
xml = Nokogiri::XML::Builder.new do |doc|
|
38
|
-
doc.vin(:number => vin,:status => "FAILED") {
|
39
|
-
doc.message(:Key => "VinQuery unavailable", :Value => "Oops, it looks like our VIN decoder is unavailable at the moment. Please try again later.")
|
40
|
-
}
|
41
|
-
end
|
42
|
-
@result = xml.to_xml
|
40
|
+
raise VinqueryException.new(e.message, e)
|
43
41
|
end
|
44
|
-
@doc = Nokogiri::HTML(@result)
|
45
42
|
end
|
46
43
|
|
47
|
-
def parse
|
48
|
-
|
49
|
-
set_errors_hash doc
|
50
|
-
attributes
|
51
|
-
end
|
44
|
+
def parse
|
45
|
+
raise create_exception unless valid?
|
52
46
|
|
53
|
-
def set_attributes(doc)
|
54
47
|
attributes = {}
|
55
|
-
doc.xpath('//vehicle[1]/item').each do |item|
|
48
|
+
@doc.xpath('//vehicle[1]/item').each do |item|
|
56
49
|
attributes[item.attributes['key'].value.downcase.gsub('.', '').gsub(/ /, '_').to_sym] = item.attributes['value'].value
|
57
50
|
end
|
58
51
|
@log.info{"Vinquery#set_attributes - number of attributes parsed: #{attributes.size}"}
|
59
52
|
if attributes.size > 0
|
60
|
-
vin = doc.css('vin').first.attributes['number'].value
|
53
|
+
vin = @doc.css('vin').first.attributes['number'].value
|
61
54
|
attributes[:vin_key] = make_vin_key(vin)
|
62
|
-
attributes[:vendor_result] = doc.to_xml
|
55
|
+
attributes[:vendor_result] = @doc.to_xml
|
63
56
|
attributes[:number_of_cylinders] = attributes[:engine_type].upcase.match(/ [LV](\d{1,2}) /) ? $1 : nil
|
64
57
|
attributes[:has_turbo] = attributes[:engine_type].upcase.match(/ ([TURBO|SUPERCHARGED]) /) ? true : false
|
65
58
|
end
|
66
59
|
@attributes = attributes
|
67
60
|
end
|
68
61
|
|
69
|
-
def
|
70
|
-
@errors
|
71
|
-
|
72
|
-
doc.css('message').each{|msg| @errors << {msg.attributes['key'].value => msg.attributes['value'].value} } unless valid?
|
73
|
-
@errors.each{|msg| @log.error{"Vinquery#set_errors_hash - error: #{msg.to_s}"}} unless @errors.empty?
|
62
|
+
def create_exception
|
63
|
+
@doc.css('message').each{|msg| @errors << {msg.attributes['key'].value => msg.attributes['value'].value} }
|
64
|
+
VinqueryException.new(@errors.map{|msg| "#{msg.keys[0]}: #{msg.values[0]}"}.join("\n")) unless @errors.empty?
|
74
65
|
end
|
75
66
|
|
76
67
|
def valid?
|
77
|
-
@valid
|
68
|
+
@valid ||= @doc.css('vin').first.attributes['status'].value == "SUCCESS" rescue false
|
78
69
|
end
|
79
70
|
|
80
71
|
def make_vin_key(vin)
|
data/lib/vinquery/version.rb
CHANGED
@@ -9,7 +9,7 @@ describe VinqueryAdapter do
|
|
9
9
|
|
10
10
|
before(:each) do
|
11
11
|
|
12
|
-
@query = Vinquery.new 'http://www.vinlookupservice.com', 'access_code', 'report_type_2'
|
12
|
+
@query = Vinquery.new 'valid_vin', 'http://www.vinlookupservice.com', 'access_code', 'report_type_2'
|
13
13
|
@adapter = VinqueryAdapter.new({})
|
14
14
|
@test_xml_data ||= File.new("#{File.dirname(__FILE__)}/vinquery_test.xml", "r").read
|
15
15
|
stub_request(:any, /.*vinlookupservice.*/).to_return(:body => @test_xml_data, :status => 200, :headers => { 'Content-Length' => @test_xml_data.length})
|
@@ -26,14 +26,16 @@ describe VinqueryAdapter do
|
|
26
26
|
hash[:errors].empty?.should == true
|
27
27
|
end
|
28
28
|
|
29
|
-
it 'should
|
29
|
+
it 'should raise an error with an invalid vin number' do
|
30
30
|
res = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>\r\n<VINquery Version="1.0.0" Report_Type="BASIC" Date="2/19/2011">\r\n <VIN Number="ABCDEFGHIJKLMNOPQ" Status="FAILED">\r\n <Message Key="5" Value="Invalid VIN number: This VIN number contains invalid letters: I,O or Q." />\r\n </VIN>\r\n</VINquery>'
|
31
31
|
stub_request(:any, /.*invalidvin.*/).to_return(:body => res, :status => 200, :headers => { 'Content-Length' => res.length})
|
32
|
-
query = Vinquery.new('http://www.invalidvin.com', 'access_code', 'report_type_2')
|
32
|
+
query = Vinquery.new('BAD_VIN', 'http://www.invalidvin.com', 'access_code', 'report_type_2')
|
33
33
|
Vinquery.should_receive(:new){ query }
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
|
35
|
+
expect { @adapter.explode('BAD_VIN') }.to raise_error(VinqueryException, /Invalid VIN number/)
|
36
|
+
|
37
|
+
# hash[:errors].size.should == 1
|
38
|
+
# hash[:errors].first['5'].should == 'Invalid VIN number: This VIN number contains invalid letters: I,O or Q.'
|
37
39
|
end
|
38
40
|
|
39
41
|
end
|
data/spec/vinquery_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Vinquery do
|
|
6
6
|
|
7
7
|
before(:each) do
|
8
8
|
|
9
|
-
@query = Vinquery.new 'http://www.vinlookupservice.com', 'access_code', 'report_type_2'
|
9
|
+
@query = Vinquery.new 'valid_vin', 'http://www.vinlookupservice.com', 'access_code', 'report_type_2'
|
10
10
|
|
11
11
|
@test_xml_data ||= File.new("#{File.dirname(__FILE__)}/vinquery_test.xml", "r").read
|
12
12
|
stub_request(:any, /.*vinlookupservice.*/).to_return(:body => @test_xml_data, :status => 200, :headers => { 'Content-Length' => @test_xml_data.length})
|
@@ -16,63 +16,54 @@ describe Vinquery do
|
|
16
16
|
WebMock.reset!
|
17
17
|
end
|
18
18
|
|
19
|
-
describe '
|
20
|
-
it 'should return
|
19
|
+
describe '#valid?' do
|
20
|
+
it 'should return true when the returned doc has a status of SUCCESS' do
|
21
21
|
doc = Nokogiri::HTML(@test_xml_data)
|
22
|
-
|
23
|
-
|
24
|
-
@query.
|
25
|
-
@query.attributes[:vin_key].should == "3D7LU38C3G"
|
22
|
+
|
23
|
+
@query.instance_variable_set("@doc", doc)
|
24
|
+
@query.valid?.should == true
|
26
25
|
end
|
27
26
|
|
28
|
-
it 'should
|
29
|
-
|
30
|
-
|
31
|
-
@query.
|
27
|
+
it 'should return false when status is anything other than SUCCESS' do
|
28
|
+
doc = Nokogiri::HTML(@test_xml_data.gsub(/SUCCESS/, 'FAILED'))
|
29
|
+
|
30
|
+
@query.instance_variable_set("@doc", doc)
|
31
|
+
@query.valid?.should == false
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
describe '#
|
36
|
-
it 'should
|
35
|
+
describe '#create_exception' do
|
36
|
+
it 'should return a VinqueryException with the vinquery error message' do
|
37
37
|
doc = Nokogiri::HTML '<?xml version="1.0" encoding="utf-8" standalone="yes"?>\r\n<VINquery Version="1.0.0" Report_Type="BASIC" Date="2/19/2011">\r\n <VIN Number="ABCDEFGHIJKLMNOPQ" Status="FAILED">\r\n <Message Key="5" Value="Invalid VIN number: This VIN number contains invalid letters: I,O or Q." />\r\n </VIN>\r\n</VINquery>'
|
38
|
-
@query.
|
38
|
+
@query.instance_variable_set("@doc", doc)
|
39
39
|
@query.valid?.should == false
|
40
|
-
@query.
|
40
|
+
e = @query.create_exception
|
41
|
+
e.class.should == VinqueryException
|
42
|
+
e.message.should == "5: Invalid VIN number: This VIN number contains invalid letters: I,O or Q."
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
describe '
|
45
|
-
it "should return
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
describe '#parse' do
|
47
|
+
it "should return a hash with all vin attributes" do
|
48
|
+
doc = Nokogiri::HTML(@test_xml_data)
|
49
|
+
|
50
|
+
@query.instance_variable_set("@doc", doc)
|
51
|
+
@query.valid?.should == true
|
52
|
+
h = @query.parse
|
53
|
+
h.class.should == Hash
|
54
|
+
h[:vin_key].should == '3D7LU38C3G'
|
50
55
|
end
|
51
56
|
|
52
|
-
it "should
|
53
|
-
|
54
|
-
@query.instance_variable_set(
|
55
|
-
|
56
|
-
|
57
|
-
doc.css('message').first.attributes['key'].value.should == "VinQuery unavailable"
|
58
|
-
doc.css('message').first.attributes['value'].value.should == "Oops, it looks like our VIN decoder is unavailable at the moment. Please try again later."
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe 'parse_doc' do
|
63
|
-
it 'should take nokogiri document and separate to attributes and errors hash' do
|
64
|
-
doc = Nokogiri::HTML(@test_xml_data)
|
65
|
-
@query.should_receive(:set_attributes).with(an_instance_of(Nokogiri::HTML::Document))
|
66
|
-
@query.parse(doc)
|
57
|
+
it "should raise an VinException if request FAILED" do
|
58
|
+
doc = Nokogiri::HTML '<?xml version="1.0" encoding="utf-8" standalone="yes"?>\r\n<VINquery Version="1.0.0" Report_Type="BASIC" Date="2/19/2011">\r\n <VIN Number="ABCDEFGHIJKLMNOPQ" Status="FAILED">\r\n <Message Key="5" Value="Invalid VIN number: This VIN number contains invalid letters: I,O or Q." />\r\n </VIN>\r\n</VINquery>'
|
59
|
+
@query.instance_variable_set("@doc", doc)
|
60
|
+
@query.valid?.should == false
|
61
|
+
expect { @query.parse }.to raise_error(VinqueryException, /Invalid VIN number/)
|
67
62
|
end
|
68
63
|
end
|
69
64
|
|
70
|
-
describe '
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'should make the call to VinQuery.com and return attributes on valid number' do
|
65
|
+
describe '#get' do
|
66
|
+
it 'should make the call to VinQuery.com and return attributes on valid vin' do
|
76
67
|
stub_request(:any, /.*fakeurl.*/).to_return(:body => @test_xml_data, :status => 200, :headers => { 'Content-Length' => @test_xml_data.length})
|
77
68
|
query = Vinquery.get('1G1ND52F14M587843', {:url => 'http://www.fakeurl.com', :access_code => 'access_code', :report_type => 'report_type_2'})
|
78
69
|
query.valid?.should == true
|
@@ -81,12 +72,10 @@ describe Vinquery do
|
|
81
72
|
query.attributes[:make].should == 'Dodge'
|
82
73
|
end
|
83
74
|
|
84
|
-
it 'should
|
75
|
+
it 'should raise an exception with an invalid vin number' do
|
85
76
|
res = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>\r\n<VINquery Version="1.0.0" Report_Type="BASIC" Date="2/19/2011">\r\n <VIN Number="ABCDEFGHIJKLMNOPQ" Status="FAILED">\r\n <Message Key="5" Value="Invalid VIN number: This VIN number contains invalid letters: I,O or Q." />\r\n </VIN>\r\n</VINquery>'
|
86
77
|
stub_request(:any, /.*invalidvin.*/).to_return(:body => res, :status => 200, :headers => { 'Content-Length' => res.length})
|
87
|
-
|
88
|
-
results.valid?.should == false
|
89
|
-
results.errors.class.should == Array
|
78
|
+
expect { Vinquery.get('BADVIN', {:url => 'http://www.invalidvin.com', :access_code => 'access_code', :report_type => 'report_type_2'}) }.to raise_error(VinqueryException)
|
90
79
|
end
|
91
80
|
end
|
92
81
|
|
metadata
CHANGED
@@ -1,76 +1,74 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: vinquery
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.4.2
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Jake Mallory
|
9
9
|
- George South
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2011-10-28 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
17
16
|
name: nokogiri
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &70282070376260 !ruby/object:Gem::Requirement
|
20
18
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
24
22
|
version: 1.4.4
|
25
23
|
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rspec
|
29
24
|
prerelease: false
|
30
|
-
|
25
|
+
version_requirements: *70282070376260
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: &70282070375780 !ruby/object:Gem::Requirement
|
31
29
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
35
33
|
version: 2.6.0
|
36
34
|
type: :development
|
37
|
-
version_requirements: *id002
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: webmock
|
40
35
|
prerelease: false
|
41
|
-
|
36
|
+
version_requirements: *70282070375780
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: webmock
|
39
|
+
requirement: &70282070375300 !ruby/object:Gem::Requirement
|
42
40
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
46
44
|
version: 1.6.4
|
47
45
|
type: :development
|
48
|
-
version_requirements: *id003
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: vin_exploder
|
51
46
|
prerelease: false
|
52
|
-
|
47
|
+
version_requirements: *70282070375300
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: vin_exploder
|
50
|
+
requirement: &70282070374820 !ruby/object:Gem::Requirement
|
53
51
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
57
55
|
version: 0.4.0
|
58
56
|
type: :development
|
59
|
-
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *70282070374820
|
60
59
|
description: A client for the Vinquery.com vin decoding web service.
|
61
60
|
email: tinomen@gmail.com
|
62
61
|
executables: []
|
63
|
-
|
64
62
|
extensions: []
|
65
|
-
|
66
|
-
extra_rdoc_files:
|
63
|
+
extra_rdoc_files:
|
67
64
|
- Gemfile
|
68
65
|
- Gemfile.lock
|
69
66
|
- Rakefile
|
70
67
|
- README.textile
|
71
|
-
files:
|
68
|
+
files:
|
72
69
|
- lib/vinquery/version.rb
|
73
70
|
- lib/vinquery/vin_exploder/adapter.rb
|
71
|
+
- lib/vinquery/vinquery_exception.rb
|
74
72
|
- lib/vinquery.rb
|
75
73
|
- Gemfile
|
76
74
|
- Gemfile.lock
|
@@ -82,37 +80,35 @@ files:
|
|
82
80
|
- spec/vinquery_test.xml
|
83
81
|
homepage: http://github.com/tinomen/vinquery
|
84
82
|
licenses: []
|
85
|
-
|
86
83
|
post_install_message:
|
87
|
-
rdoc_options:
|
84
|
+
rdoc_options:
|
88
85
|
- --title
|
89
86
|
- A client for vinquery.com
|
90
87
|
- --main
|
91
88
|
- README.rdoc
|
92
89
|
- --line-numbers
|
93
90
|
- --charset=UTF-8
|
94
|
-
require_paths:
|
91
|
+
require_paths:
|
95
92
|
- lib
|
96
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
94
|
none: false
|
98
|
-
requirements:
|
99
|
-
- -
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version:
|
102
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
100
|
none: false
|
104
|
-
requirements:
|
105
|
-
- -
|
106
|
-
- !ruby/object:Gem::Version
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
107
104
|
version: 1.3.6
|
108
105
|
requirements: []
|
109
|
-
|
110
106
|
rubyforge_project:
|
111
|
-
rubygems_version: 1.
|
107
|
+
rubygems_version: 1.8.10
|
112
108
|
signing_key:
|
113
109
|
specification_version: 3
|
114
110
|
summary: A client for vinquery.com
|
115
|
-
test_files:
|
111
|
+
test_files:
|
116
112
|
- spec/spec_helper.rb
|
117
113
|
- spec/vin_exploder_adapter_spec.rb
|
118
114
|
- spec/vinquery_spec.rb
|