chrome_data 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +114 -0
- data/Rakefile +8 -0
- data/chrome_data.gemspec +31 -0
- data/lib/chrome_data/base_request.rb +88 -0
- data/lib/chrome_data/caching.rb +31 -0
- data/lib/chrome_data/collection_request.rb +19 -0
- data/lib/chrome_data/division.rb +14 -0
- data/lib/chrome_data/model.rb +13 -0
- data/lib/chrome_data/model_year.rb +16 -0
- data/lib/chrome_data/style.rb +15 -0
- data/lib/chrome_data/vehicle.rb +43 -0
- data/lib/chrome_data/version.rb +3 -0
- data/lib/chrome_data.rb +32 -0
- data/test/chrome_data/caching_test.rb +74 -0
- data/test/chrome_data/division_test.rb +57 -0
- data/test/chrome_data/model_test.rb +57 -0
- data/test/chrome_data/model_year_test.rb +13 -0
- data/test/chrome_data/style_test.rb +49 -0
- data/test/chrome_data/vehicle_test.rb +78 -0
- data/test/chrome_data_test.rb +13 -0
- data/test/fixtures/vcr_cassettes/2013/divisions/13/models/24997/styles.yml +55 -0
- data/test/fixtures/vcr_cassettes/2013/divisions/13/models.yml +70 -0
- data/test/fixtures/vcr_cassettes/2013/divisions.yml +63 -0
- data/test/fixtures/vcr_cassettes/vehicles/WDDGF4HB1CR000000.yml +276 -0
- data/test/fixtures/vcr_cassettes/wsdl.yml +757 -0
- data/test/minitest_helper.rb +13 -0
- metadata +213 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8afb6ab74cdffac02f50225de7260a9ef4e1456a
|
4
|
+
data.tar.gz: 33e84a8718d9cfe54b5e255ddf68a474a93138cd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e6cdddc5b6a76f2d4d5e103f17961daa30945f5fb8e8abb9be8c10f5316415061dc4fd8bab1a7026dddfb8da1338d834e822136a0b4512a51a9d7c43fe910d90
|
7
|
+
data.tar.gz: c9cec11f40b545fdcb87ab665b0b9b73d1584ba2c4a06a9cb972bfa0a82260ef22be0be34d8a01cab9ce323dee0a0646567d98b3338055315360a22554d3fcae
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Room 118 Solutions, Inc.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# ChromeData
|
2
|
+
|
3
|
+
Provides a simple ruby interface for Chrome Data's API. Read more about it here: http://www.chromedata.com/
|
4
|
+
|
5
|
+
The wonderful [lolsoap](https://github.com/loco2/lolsoap) gem does most of the heavy lifting.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this gem to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'chrome_data'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install chrome_data
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### Configuration
|
24
|
+
Valid options:
|
25
|
+
|
26
|
+
* account_number (required)
|
27
|
+
* account_secret (required)
|
28
|
+
* country (default: 'US')
|
29
|
+
* language (default: 'en')
|
30
|
+
* cache_store
|
31
|
+
|
32
|
+
Configuration:
|
33
|
+
|
34
|
+
ChromeData.config.merge! { account_number: 1234, account_secret: '5678' }
|
35
|
+
|
36
|
+
### Requests
|
37
|
+
#### Data Collection
|
38
|
+
#### Makes (Divisions)
|
39
|
+
Fields:
|
40
|
+
|
41
|
+
* id (Integer)
|
42
|
+
* name (String)
|
43
|
+
|
44
|
+
Request a set of divisions:
|
45
|
+
|
46
|
+
ChromeData::Division.find_all_by_year(1999)
|
47
|
+
|
48
|
+
Request models for a division (same as ChromeData::Model.find_all_by_year_and_division_id)
|
49
|
+
|
50
|
+
mazda = ChromeData::Division.new(id: 26, name: "Mazda")
|
51
|
+
mazda_models = mazda.models_for_year(1999)
|
52
|
+
|
53
|
+
#### Models
|
54
|
+
Fields:
|
55
|
+
|
56
|
+
* id (Integer)
|
57
|
+
* name (String)
|
58
|
+
|
59
|
+
Find models for year and division
|
60
|
+
|
61
|
+
mazda_models = ChromeData::Model.find_all_by_year_and_division_id(1999, 26)
|
62
|
+
|
63
|
+
Find styles for a specific model (same as ChromeData::Style.find_all_by_model_id)
|
64
|
+
|
65
|
+
miata = ChromeData::Model.new(id: 4768, name: "MX-5 Miata") # 1999 Mazda MX-5 Miata
|
66
|
+
miata_styles = miata.styles
|
67
|
+
|
68
|
+
#### Styles
|
69
|
+
Fields:
|
70
|
+
|
71
|
+
* id (Integer)
|
72
|
+
* name (String)
|
73
|
+
|
74
|
+
Only loaded through a Vehicle:
|
75
|
+
|
76
|
+
* trim (String)
|
77
|
+
* name_without_trim (String)
|
78
|
+
|
79
|
+
Find styles for a model by model id
|
80
|
+
|
81
|
+
miata_styles = ChromeData::Style.find_all_by_model_id(4768)
|
82
|
+
|
83
|
+
#### Vehicle
|
84
|
+
Fields:
|
85
|
+
|
86
|
+
* division (String)
|
87
|
+
* engines (Array of Engine)
|
88
|
+
* model (String)
|
89
|
+
* model_year (Integer)
|
90
|
+
* styles (Array of Style)
|
91
|
+
|
92
|
+
Find a vehicle by VIN
|
93
|
+
|
94
|
+
vehicle = ChromeData::Vehicle.find_by_vin('JM1NB3536X0131402')
|
95
|
+
|
96
|
+
#### Engine
|
97
|
+
Engines are only loaded through a find_by_vin request
|
98
|
+
|
99
|
+
Fields:
|
100
|
+
|
101
|
+
* type (String)
|
102
|
+
|
103
|
+
#### Model Years
|
104
|
+
Years start at 1981 due to VIN standardization
|
105
|
+
|
106
|
+
ChromeData::ModelYears.all
|
107
|
+
|
108
|
+
## Contributing
|
109
|
+
|
110
|
+
1. Fork it
|
111
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
112
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
113
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
114
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/chrome_data.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'chrome_data/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "chrome_data"
|
8
|
+
spec.version = ChromeData::VERSION
|
9
|
+
spec.authors = ["Jim Ryan"]
|
10
|
+
spec.email = ["jim@room118solutions.com"]
|
11
|
+
spec.description = %q{Provides a ruby interface for Chrome Data's API. Read more about it here: http://www.chromedata.com/}
|
12
|
+
spec.summary = %q{A ruby interface for Chrome Data's API}
|
13
|
+
spec.homepage = "http://github.com/room118solutions/chrome_data"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "minitest"
|
24
|
+
spec.add_development_dependency "vcr"
|
25
|
+
spec.add_development_dependency "webmock", '~> 1.10.0' # Locked at 1.10.x to prevent VCR warnings
|
26
|
+
spec.add_development_dependency "mocha"
|
27
|
+
|
28
|
+
spec.add_dependency "symboltable"
|
29
|
+
spec.add_dependency "activesupport", '>= 3.0'
|
30
|
+
spec.add_dependency "lolsoap", "~> 0.2.0"
|
31
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "lolsoap"
|
3
|
+
|
4
|
+
module ChromeData
|
5
|
+
class BaseRequest
|
6
|
+
def initialize(attrs={})
|
7
|
+
attrs.each do |k, v|
|
8
|
+
send "#{k}=", v
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# Builds request, sets additional data on request element, makes request,
|
14
|
+
# and returns array of child elements wrapped in instances of this class
|
15
|
+
def request(data)
|
16
|
+
request = build_request
|
17
|
+
|
18
|
+
request.body do |b|
|
19
|
+
# Set configured account info on builder
|
20
|
+
b.accountInfo(
|
21
|
+
number: ChromeData.config.account_number,
|
22
|
+
secret: ChromeData.config.account_secret,
|
23
|
+
country: ChromeData.config.country,
|
24
|
+
language: ChromeData.config.language
|
25
|
+
)
|
26
|
+
|
27
|
+
# Set additional elements on builder
|
28
|
+
data.each do |k, v|
|
29
|
+
# Add the key/value pair as an attribute to the request element if that's what it should be,
|
30
|
+
# otherwise add it as a sub-element
|
31
|
+
# NOTE: This basically mirrors LolSoap::Builder#method_missing
|
32
|
+
# because Builder undefines most methods, including #send
|
33
|
+
if b.__type__.has_attribute?(k)
|
34
|
+
b.__attribute__ k, v
|
35
|
+
else
|
36
|
+
b.__tag__ k, v
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Make the request
|
42
|
+
response = make_request(request)
|
43
|
+
|
44
|
+
parse_response(response)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Makes request, returns LolSoap::Response
|
48
|
+
def make_request(request)
|
49
|
+
raw_response = Net::HTTP.start(endpoint_uri.host, endpoint_uri.port) do |http|
|
50
|
+
http.request_post(endpoint_uri.path, request.content, request.headers)
|
51
|
+
end
|
52
|
+
|
53
|
+
client.response(request, raw_response.body)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Builds request, returns LolSoap::Request
|
57
|
+
def build_request
|
58
|
+
client.request request_name
|
59
|
+
end
|
60
|
+
|
61
|
+
def client
|
62
|
+
@@client ||= LolSoap::Client.new(wsdl_body)
|
63
|
+
end
|
64
|
+
|
65
|
+
def wsdl_body
|
66
|
+
@@wsdl_body ||= Net::HTTP.get_response(URI('http://services.chromedata.com/Description/7a?wsdl')).body
|
67
|
+
end
|
68
|
+
|
69
|
+
def endpoint_uri
|
70
|
+
@@endpoint_uri ||= URI(client.wsdl.endpoint)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Given an element_name and LolSoap::Response, returns an array of Nokogiri::XML::Elements
|
74
|
+
def find_elements(element_name, response)
|
75
|
+
response.body.xpath(".//x:#{element_name}", 'x' => response.body.namespace.href)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Internal: Given a LolSoap::Response, returns appropriately parsed response
|
79
|
+
def parse_response(response)
|
80
|
+
raise NotImplementedError, '.parse_response should be implemented in subclass'
|
81
|
+
end
|
82
|
+
|
83
|
+
def request_name
|
84
|
+
raise NotImplementedError, '.request_name should be implemented in subclass'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ChromeData::Caching
|
2
|
+
# Creates CacheStore object based on config.cache_store options
|
3
|
+
# reverse merges 'chromedata' namespace to options hash
|
4
|
+
def _cache_store
|
5
|
+
return @@_cache_store if defined? @@_cache_store
|
6
|
+
|
7
|
+
if ChromeData.config.cache_store
|
8
|
+
cache_opts = { namespace: 'chromedata' }
|
9
|
+
|
10
|
+
if ChromeData.config.cache_store.is_a?(Array)
|
11
|
+
if ChromeData.config.cache_store.last.is_a?(Hash)
|
12
|
+
ChromeData.config.cache_store.last.reverse_merge! cache_opts
|
13
|
+
else
|
14
|
+
ChromeData.config.cache_store << cache_opts
|
15
|
+
end
|
16
|
+
elsif ChromeData.config.cache_store.is_a?(Symbol)
|
17
|
+
ChromeData.config.cache_store = [ChromeData.config.cache_store, cache_opts]
|
18
|
+
end
|
19
|
+
|
20
|
+
@@_cache_store = ActiveSupport::Cache.lookup_store(ChromeData.config.cache_store)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def cache(key, &blk)
|
25
|
+
if ChromeData._cache_store
|
26
|
+
ChromeData._cache_store.fetch key, &blk
|
27
|
+
else
|
28
|
+
blk.call
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ChromeData
|
2
|
+
class CollectionRequest < BaseRequest
|
3
|
+
attr_accessor :id, :name
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def request_name
|
7
|
+
# Cheap-o inflector
|
8
|
+
"get#{name.split('::').last}s"
|
9
|
+
end
|
10
|
+
|
11
|
+
# Find elements matching class name and instantiate them using their id attribute and text
|
12
|
+
def parse_response(response)
|
13
|
+
find_elements(name.split('::').last.downcase, response).map do |e|
|
14
|
+
new id: e.attr('id').to_i, name: e.text
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ChromeData
|
2
|
+
class Division < CollectionRequest
|
3
|
+
|
4
|
+
def models_for_year(year)
|
5
|
+
Model.find_all_by_year_and_division_id year, id
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.find_all_by_year(year)
|
9
|
+
ChromeData.cache "#{request_name.underscore}-model_year-#{year}" do
|
10
|
+
request 'modelYear' => year
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ChromeData
|
2
|
+
class Model < CollectionRequest
|
3
|
+
def styles
|
4
|
+
Style.find_all_by_model_id id
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.find_all_by_year_and_division_id(year, division_id)
|
8
|
+
ChromeData.cache "#{request_name.underscore}-model_year-#{year}-division_id-#{division_id}" do
|
9
|
+
request 'modelYear' => year, 'divisionId' => division_id
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# NOTE: Chrome Data's API offers a getModelYears method that returns every year from 1981 through to next year.
|
2
|
+
# We could hit the API for that data, but I think that's silly, so this class calculates the years
|
3
|
+
# that Chrome Data would return.
|
4
|
+
|
5
|
+
module ChromeData
|
6
|
+
class ModelYear
|
7
|
+
|
8
|
+
# Chrome Data returns years in the opposite order, but that's not typically
|
9
|
+
# how selects are built, so they're reversed here,
|
10
|
+
# since that's the only purpose that I can see for this method.
|
11
|
+
def self.all
|
12
|
+
(Time.now.year + 1).downto(1981).to_a
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ChromeData
|
2
|
+
class Style < CollectionRequest
|
3
|
+
class BodyType < Struct.new(:id, :name); end
|
4
|
+
|
5
|
+
# These are only populated when accessing a style through a Vehicle
|
6
|
+
attr_accessor :trim, :name_without_trim, :body_types
|
7
|
+
|
8
|
+
def self.find_all_by_model_id(model_id)
|
9
|
+
ChromeData.cache "#{request_name.underscore}-model_id-#{model_id}" do
|
10
|
+
request 'modelId' => model_id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ChromeData
|
2
|
+
class Vehicle < BaseRequest
|
3
|
+
class Engine < Struct.new(:type); end
|
4
|
+
|
5
|
+
attr_accessor :model_year, :division, :model, :styles, :engines
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def request_name
|
9
|
+
"describeVehicle"
|
10
|
+
end
|
11
|
+
|
12
|
+
def find_by_vin(vin)
|
13
|
+
request 'vin' => vin
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_response(response)
|
17
|
+
if vin_description = find_elements('vinDescription', response).first
|
18
|
+
new.tap do |v|
|
19
|
+
v.model_year = vin_description.attr('modelYear').to_i
|
20
|
+
v.division = vin_description.attr('division')
|
21
|
+
v.model = vin_description.attr('modelName')
|
22
|
+
|
23
|
+
v.styles = find_elements('style', response).map do |e|
|
24
|
+
Style.new(
|
25
|
+
id: e.attr('id').to_i,
|
26
|
+
name: e.attr('name'),
|
27
|
+
trim: e.attr('trim'),
|
28
|
+
name_without_trim: e.attr('nameWoTrim'),
|
29
|
+
body_types: e.xpath("x:bodyType", 'x' => response.body.namespace.href).map do |bt|
|
30
|
+
Style::BodyType.new(bt.attr('id').to_i, bt.text)
|
31
|
+
end
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
v.engines = find_elements('engine', response).map do |e|
|
36
|
+
Engine.new(e.at_xpath("x:engineType", 'x' => response.body.namespace.href).text)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/chrome_data.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "chrome_data/version"
|
2
|
+
require "chrome_data/caching"
|
3
|
+
require "chrome_data/base_request"
|
4
|
+
require "chrome_data/collection_request"
|
5
|
+
require "chrome_data/division"
|
6
|
+
require "chrome_data/model"
|
7
|
+
require "chrome_data/style"
|
8
|
+
require "chrome_data/model_year"
|
9
|
+
require "chrome_data/vehicle"
|
10
|
+
require "active_support/cache"
|
11
|
+
require "active_support/core_ext/hash"
|
12
|
+
|
13
|
+
require "symboltable"
|
14
|
+
|
15
|
+
module ChromeData
|
16
|
+
extend Caching
|
17
|
+
extend self
|
18
|
+
|
19
|
+
def configure
|
20
|
+
yield config
|
21
|
+
end
|
22
|
+
|
23
|
+
# Valid options:
|
24
|
+
# account_number
|
25
|
+
# account_secret
|
26
|
+
# country (default: 'US')
|
27
|
+
# language (default: 'en')
|
28
|
+
# cache_store
|
29
|
+
def config
|
30
|
+
@@config ||= SymbolTable.new country: 'US', language: 'en'
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative '../minitest_helper'
|
2
|
+
|
3
|
+
describe ChromeData::Caching do
|
4
|
+
before do
|
5
|
+
ChromeData.remove_class_variable :@@config if ChromeData.class_variable_defined? :@@config
|
6
|
+
ChromeData::Caching.remove_class_variable :@@_cache_store if ChromeData::Caching.class_variable_defined? :@@_cache_store
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.cache' do
|
10
|
+
it 'caches request when caching is on' do
|
11
|
+
ChromeData.config.cache_store = :memory_store
|
12
|
+
|
13
|
+
foo = stub('foo')
|
14
|
+
foo.expects(:bar).once.returns 'bar'
|
15
|
+
|
16
|
+
2.times do
|
17
|
+
ChromeData.cache 'foo' do
|
18
|
+
foo.bar
|
19
|
+
end.must_equal 'bar'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'does not cache request when caching is off' do
|
24
|
+
foo = stub('foo')
|
25
|
+
foo.expects(:bar).twice.returns 'bar'
|
26
|
+
|
27
|
+
2.times do
|
28
|
+
ChromeData.cache 'foo' do
|
29
|
+
foo.bar
|
30
|
+
end.must_equal 'bar'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '._cache_store' do
|
36
|
+
before { ChromeData::Caching.remove_class_variable :@@_cache_store if ChromeData::Caching.class_variable_defined? :@@_cache_store }
|
37
|
+
|
38
|
+
it 'returns nil with no cache_store config' do
|
39
|
+
ChromeData._cache_store.must_equal nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'looks up cache with appropriate namespace when cache_store is an array without options hash' do
|
43
|
+
ChromeData.config.cache_store = :file_store, '/path/to/cache'
|
44
|
+
|
45
|
+
ActiveSupport::Cache.expects(:lookup_store).with([:file_store, '/path/to/cache', { namespace: 'chromedata' }])
|
46
|
+
|
47
|
+
ChromeData._cache_store
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'looks up cache with appropriate namespace when cache_store is an array with an options hash' do
|
51
|
+
ChromeData.config.cache_store = :memory_store, { foo: 'bar' }
|
52
|
+
|
53
|
+
ActiveSupport::Cache.expects(:lookup_store).with([:memory_store, { foo: 'bar', namespace: 'chromedata' }])
|
54
|
+
|
55
|
+
ChromeData._cache_store
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'does not replace user-defined namespace' do
|
59
|
+
ChromeData.config.cache_store = :memory_store, { namespace: 'mynamespace' }
|
60
|
+
|
61
|
+
ActiveSupport::Cache.expects(:lookup_store).with([:memory_store, { namespace: 'mynamespace' }])
|
62
|
+
|
63
|
+
ChromeData._cache_store
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'looks up cache with appropriate namespace when cache_store is a symbol' do
|
67
|
+
ChromeData.config.cache_store = :memory_store
|
68
|
+
|
69
|
+
ActiveSupport::Cache.expects(:lookup_store).with([:memory_store, { namespace: 'chromedata' }])
|
70
|
+
|
71
|
+
ChromeData._cache_store
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative '../minitest_helper'
|
2
|
+
|
3
|
+
describe ChromeData::Division do
|
4
|
+
it 'returns a proper request name' do
|
5
|
+
ChromeData::Division.request_name.must_equal 'getDivisions'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '.find_all_by_year' do
|
9
|
+
before do
|
10
|
+
ChromeData.configure do |c|
|
11
|
+
c.account_number = '123456'
|
12
|
+
c.account_secret = '1111111111111111'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_divisions
|
17
|
+
VCR.use_cassette('wsdl') do
|
18
|
+
VCR.use_cassette('2013/divisions') do
|
19
|
+
@divisions = ChromeData::Division.find_all_by_year(2013)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns array of Division objects' do
|
25
|
+
find_divisions
|
26
|
+
|
27
|
+
@divisions.first.must_be_instance_of ChromeData::Division
|
28
|
+
@divisions.size.must_equal 38
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets ID on Division objects' do
|
32
|
+
find_divisions
|
33
|
+
|
34
|
+
@divisions.first.id.must_equal 1
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'sets name on Division objects' do
|
38
|
+
find_divisions
|
39
|
+
|
40
|
+
@divisions.first.name.must_equal 'Acura'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'caches with proper key' do
|
44
|
+
ChromeData.expects(:cache).with('get_divisions-model_year-2013')
|
45
|
+
|
46
|
+
find_divisions
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#models_for_year' do
|
51
|
+
it 'finds models for given year and Division ID' do
|
52
|
+
ChromeData::Model.expects(:find_all_by_year_and_division_id).with(2013, 13)
|
53
|
+
|
54
|
+
ChromeData::Division.new(id: 13, name: 'Ford').models_for_year 2013
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative '../minitest_helper'
|
2
|
+
|
3
|
+
describe ChromeData::Model do
|
4
|
+
it 'returns a proper request name' do
|
5
|
+
ChromeData::Model.request_name.must_equal 'getModels'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '.find_all_by_year_and_division_id' do
|
9
|
+
before do
|
10
|
+
ChromeData.configure do |c|
|
11
|
+
c.account_number = '123456'
|
12
|
+
c.account_secret = '1111111111111111'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_models
|
17
|
+
VCR.use_cassette('wsdl') do
|
18
|
+
VCR.use_cassette('2013/divisions/13/models') do
|
19
|
+
@models = ChromeData::Model.find_all_by_year_and_division_id(2013, 13) # 2013 Fords
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns array of Model objects' do
|
25
|
+
find_models
|
26
|
+
|
27
|
+
@models.first.must_be_instance_of ChromeData::Model
|
28
|
+
@models.size.must_equal 39
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets ID on Model objects' do
|
32
|
+
find_models
|
33
|
+
|
34
|
+
@models.first.id.must_equal 25459
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'sets name on Model objects' do
|
38
|
+
find_models
|
39
|
+
|
40
|
+
@models.first.name.must_equal 'C-Max Energi'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'caches with proper key' do
|
44
|
+
ChromeData.expects(:cache).with('get_models-model_year-2013-division_id-13')
|
45
|
+
|
46
|
+
find_models
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#styles' do
|
51
|
+
it 'finds styles for Model' do
|
52
|
+
ChromeData::Style.expects(:find_all_by_model_id).with(24997)
|
53
|
+
|
54
|
+
ChromeData::Model.new(id: 24997, name: 'Mustang').styles
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|