chrome_data 0.0.2
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.
- 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
|