require "helper" require "bundles/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 it "downcases profile name for Supermarket API URL" do profile_name = "supermarket://test_owner/Test_Name" 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 = if default_url?(supermarket_url) subject.find(profile_name) else subject.find(profile_name, supermarket_url) end _(profile).must_equal(profile_search_response_body["items"].first.merge({ "slug" => "test_name" })) end it "raises an error if tool name is not present" do profile_name = "supermarket://owner_only" 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) e = _ { subject.find(profile_name, supermarket_url) }.must_raise _(e.message).must_equal("Could not parse tool name from #{profile_name}") end end end end end