Feature/fix ability to pass in supermarket url (#1595)

* Enable customization of supermarket_url

It looks like this was originally supposed to work, but at some point
the default value was put in the method body rather than in the method
parameters.

This change allows you to configure the supermarket_url in test kitchen
like so:

```
verifier:
  inspec_tests:
  - name: linux-hardening
    supermarket: som3guy/apache-disa-stig
    supermarket_url: https://my.supermarket.com
```

Signed-off-by: Ryan Larson <ryan.mango.larson@gmail.com>
This commit is contained in:
Ryan Larson 2017-03-29 09:42:24 -07:00 committed by Adam Leff
parent af7dffaa38
commit 0e187f6117
3 changed files with 138 additions and 4 deletions

View file

@ -42,4 +42,5 @@ Gem::Specification.new do |spec|
spec.add_dependency 'nokogiri', '~> 1.6'
spec.add_dependency 'faraday', '>=0.9.0'
spec.add_dependency 'toml', '~> 0.1'
spec.add_dependency 'addressable', '~> 2.5'
end

View file

@ -4,6 +4,7 @@
# author: Dominik Richter
require 'net/http'
require 'addressable/uri'
module Supermarket
class API
@ -26,9 +27,10 @@ module Supermarket
end
def self.profile_name(profile)
uri = URI(profile)
# We use Addressable::URI here because URI has a bug in Ruby 2.1.x where it doesn't allow underscore in host
uri = Addressable::URI.parse profile
[uri.host, uri.path[1..-1]]
rescue URI::Error => _e
rescue
nil
end
@ -50,8 +52,8 @@ module Supermarket
supermarket_tool['tool_owner'] == tool_owner && supermarket_tool['tool'] == tool
end
def self.find(profile, supermarket_url)
profiles = Supermarket::API.profiles(supermarket_url=SUPERMARKET_URL)
def self.find(profile, supermarket_url = SUPERMARKET_URL)
profiles = Supermarket::API.profiles(supermarket_url)
if !profiles.empty?
index = profiles.index { |t| same?(profile, t, supermarket_url) }
# return profile or nil

View file

@ -0,0 +1,131 @@
require 'helper'
require 'inspec-supermarket/api'
def default_url?(supermarket_url)
supermarket_url == Supermarket::API::SUPERMARKET_URL
end
describe Supermarket::API do
let(:subject) { Supermarket::API }
[Supermarket::API::SUPERMARKET_URL, 'https://my.custom.supermarket'].each do |supermarket_url|
describe "With #{default_url?(supermarket_url) ? 'default' : supermarket_url} Supermarket URL" do
let(:profile_search_response_body) do
{
'start' => 0,
'total' => 1,
'items' => [
{
'tool_name' => 'test_name',
'tool_type' => 'compliance_profile',
'tool_source_url' => supermarket_url,
'tool_description' => 'test_description',
'tool_owner' => 'test_owner',
'tool' => "#{supermarket_url}/api/v1/tools/test_name"
}
]
}
end
let(:profile_name) { 'supermarket://test_owner/test_name' }
describe '#profiles' do
it 'returns the profile list' do
stub_request(:get, "#{supermarket_url}/api/v1/tools-search?items=100&type=compliance_profile").
to_return(:status => 200, :body => profile_search_response_body.to_json)
test_profile = default_url?(supermarket_url) ? subject.profiles.first : subject.profiles(supermarket_url).first
test_profile.must_equal(profile_search_response_body['items'].first.merge({'slug' => 'test_name'}))
end
end
describe '#profile_name' do
it 'returns the profile name and owner from a supermarket://owner/name path' do
tool_owner, tool_name = subject.profile_name('supermarket://test_tool_owner/test_tool_name')
tool_owner.must_equal('test_tool_owner')
tool_name.must_equal('test_tool_name')
end
end
describe '#info' do
let(:profile_list_response_body) do
{
'name' => 'test_name',
'slug' => 'test_slug',
'type' => 'test_type',
'source_url' => supermarket_url,
'description' => 'test_description',
'instructions' => 'test_instructions',
'owner' => 'test_owner'
}
end
it 'returns profile info' do
stub_request(:get, "#{supermarket_url}/api/v1/tools/test_name").
to_return(:status => 200, :body => profile_list_response_body.to_json)
profile_info = default_url?(supermarket_url) ? subject.info('test_owner/test_name') : subject.info('test_owner/test_name', supermarket_url)
profile_info.must_equal(profile_list_response_body)
end
end
describe '#same?' do
let(:tool_url) { "#{supermarket_url}/api/v1/tools/test_name" }
it 'is the same on a match' do
supermarket_tool = {'tool_owner' => 'test_owner', 'tool' => tool_url}
same = default_url?(supermarket_url) ? subject.same?(profile_name, supermarket_tool) : subject.same?(profile_name, supermarket_tool, supermarket_url)
same.must_equal(true)
end
it 'is not the same on a mismatched owner' do
supermarket_tool = {'tool_owner' => 'wrong_owner', 'tool' => tool_url}
same = default_url?(supermarket_url) ? subject.same?(profile_name, supermarket_tool) : subject.same?(profile_name, supermarket_tool, supermarket_url)
same.must_equal(false)
end
it 'is not the same on a mismatched supermarket tool' do
supermarket_tool = {'tool_owner' => 'test_owner', 'tool' => 'garbage'}
same = default_url?(supermarket_url) ? subject.same?(profile_name, supermarket_tool) : subject.same?(profile_name, supermarket_tool, supermarket_url)
same.must_equal(false)
end
end
describe '#find' do
let(:empty_profile_search_response_body) do
{start: 0, total: 0, items: []}
end
it 'returns nil if profiles are empty' do
stub_request(:get, "#{supermarket_url}/api/v1/tools-search?items=100&type=compliance_profile").
to_return(:status => 200, :body => empty_profile_search_response_body.to_json)
search = default_url?(supermarket_url) ? subject.find(profile_name) : subject.find(profile_name, supermarket_url)
search.must_be_nil
end
it 'returns nil if profile not found' do
stub_request(:get, "#{supermarket_url}/api/v1/tools-search?items=100&type=compliance_profile").
to_return(:status => 200, :body => profile_search_response_body.to_json)
profile_name_cant_find = 'supermarket://cant_find/not_found'
search = default_url?(supermarket_url) ? subject.find(profile_name_cant_find) : subject.find(profile_name_cant_find, supermarket_url)
search.must_be_nil
end
it 'returns profile if it is found' do
stub_request(:get, "#{supermarket_url}/api/v1/tools-search?items=100&type=compliance_profile").
to_return(:status => 200, :body => profile_search_response_body.to_json)
profile = default_url?(supermarket_url) ? subject.find(profile_name) : subject.find(profile_name, supermarket_url)
profile.must_equal(profile_search_response_body['items'].first.merge({'slug' => 'test_name'}))
end
end
end
end
end