require "spec_helper" describe Berkshelf::CommunityREST do describe "ClassMethods" do describe "::unpack" do let(:target) { "/foo/bar" } let(:destination) { "/destination/bar" } let(:file) { double("file") } let(:gzip_reader) { double("gzip_reader") } let(:archive) { double("mixlib_archive") } before do allow(File).to receive(:open).with(target, "rb").and_return(file) allow(archive).to receive(:extract).with(destination) allow(Mixlib::Archive).to receive(:new).with(target).and_return(archive) end it "unpacks the tar" do expect(::IO).to receive(:binread).with(target, 2).and_return([0x1F, 0x8B].pack("C*")) expect(Mixlib::Archive).to receive(:new).with(target).and_return(archive) expect(archive).to receive(:extract).with(destination) expect(Berkshelf::CommunityREST.unpack(target, destination)).to eq(destination) end end describe "::uri_escape_version" do it "returns a string" do expect(Berkshelf::CommunityREST.uri_escape_version(nil)).to be_a(String) end it 'converts a version to it\'s underscored version' do expect(Berkshelf::CommunityREST.uri_escape_version("1.1.2")).to eq("1_1_2") end it "works when the version has more than three points" do expect(Berkshelf::CommunityREST.uri_escape_version("1.1.1.2")).to eq("1_1_1_2") end it "works when the version has less than three points" do expect(Berkshelf::CommunityREST.uri_escape_version("1.2")).to eq("1_2") end end describe "::version_from_uri" do it "returns a string" do expect(Berkshelf::CommunityREST.version_from_uri(nil)).to be_a(String) end it "extracts the version from the URL" do expect(Berkshelf::CommunityREST.version_from_uri("/api/v1/cookbooks/nginx/versions/1_1_2")).to eq("1.1.2") end it "works when the version has more than three points" do expect(Berkshelf::CommunityREST.version_from_uri("/api/v1/cookbooks/nginx/versions/1_1_1_2")).to eq("1.1.1.2") end it "works when the version has less than three points" do expect(Berkshelf::CommunityREST.version_from_uri("/api/v1/cookbooks/nginx/versions/1_2")).to eq("1.2") end end end let(:api_uri) { Berkshelf::CommunityREST::V1_API } subject { Berkshelf::CommunityREST.new(api_uri) } describe "#initialize" do context "Faraday handlers" do it "includes follow_redirects to prevent 301 from community, stopping some cookbooks installing" do expect(subject.builder.handlers).to include(Ridley::Middleware::FollowRedirects) end end end describe "#download" do let(:archive) { double("archive", path: "/foo/bar", unlink: true) } before do allow(subject).to receive(:stream).with(any_args()).and_return(archive) allow(Berkshelf::CommunityREST).to receive(:unpack) .and_return("/some/path") end it "unpacks the archive" do stub_request(:get, "#{api_uri}/cookbooks/bacon/versions/1_0_0").to_return( status: 200, body: '{ "cookbook": "/path/to/cookbook", "version": "1.0.0" }', headers: { "Content-Type" => "application/json" } ) expect(Berkshelf::CommunityREST).to receive(:unpack) .with("/foo/bar", String) .and_return("/foo/nginx") .once expect(archive).to receive(:unlink).once subject.download("bacon", "1.0.0") end end describe "#find" do it "returns the cookbook and version information" do stub_request(:get, "#{api_uri}/cookbooks/bacon/versions/1_0_0").to_return( status: 200, body: '{ "cookbook": "/path/to/cookbook", "version": "1.0.0" }', headers: { "Content-Type" => "application/json" } ) result = subject.find("bacon", "1.0.0") expect(result.cookbook).to eq("/path/to/cookbook") expect(result.version).to eq("1.0.0") end it "raises a CookbookNotFound error on a 404 response for a non-existent cookbook" do stub_request(:get, "#{api_uri}/cookbooks/not_real/versions/1_0_0").to_return( status: 404, body: nil ) expect do subject.find("not_real", "1.0.0") end.to raise_error(Berkshelf::CookbookNotFound) end it "raises a CommunitySiteError error on any non 200 or 404 response" do stub_request(:get, "#{api_uri}/cookbooks/not_real/versions/1_0_0").to_return( status: 500, body: nil ) expect do subject.find("not_real", "1.0.0") end.to raise_error(Berkshelf::CommunitySiteError) end end describe "#latest_version" do it "returns the version number of the latest version of the cookbook" do stub_request(:get, "#{api_uri}/cookbooks/bacon").to_return( status: 200, body: '{ "latest_version": "1.0.0" }', headers: { "Content-Type" => "application/json" } ) latest = subject.latest_version("bacon") expect(latest).to eq("1.0.0") end it "raises a CookbookNotFound error on a 404 response" do stub_request(:get, "#{api_uri}/cookbooks/not_real").to_return( status: 404, body: nil ) expect do subject.latest_version("not_real") end.to raise_error(Berkshelf::CookbookNotFound) end it "raises a CommunitySiteError error on any non 200 or 404 response" do stub_request(:get, "#{api_uri}/cookbooks/not_real").to_return( status: 500, body: nil ) expect do subject.latest_version("not_real") end.to raise_error(Berkshelf::CommunitySiteError) end end describe "#versions" do it "returns an array containing an item for each version" do stub_request(:get, "#{api_uri}/cookbooks/bacon").to_return( status: 200, body: '{ "versions": ["/bacon/versions/1_0_0", "/bacon/versions/2_0_0"] }', headers: { "Content-Type" => "application/json" } ) versions = subject.versions("bacon") expect(versions.size).to eq(2) end it "raises a CookbookNotFound error on a 404 response" do stub_request(:get, "#{api_uri}/cookbooks/not_real").to_return( status: 404, body: nil ) expect do subject.versions("not_real") end.to raise_error(Berkshelf::CookbookNotFound) end it "raises a CommunitySiteError error on any non 200 or 404 response" do stub_request(:get, "#{api_uri}/cookbooks/not_real").to_return( status: 500, body: nil ) expect do subject.versions("not_real") end.to raise_error(Berkshelf::CommunitySiteError) end end describe "#satisfy" do it "returns the version number of the best solution" do stub_request(:get, "#{api_uri}/cookbooks/bacon").to_return( status: 200, body: '{ "versions": ["/bacon/versions/1_0_0", "/bacon/versions/2_0_0"] }', headers: { "Content-Type" => "application/json" } ) result = subject.satisfy("bacon", "= 1.0.0") expect(result).to eq("1.0.0") end end describe "#stream" do skip end end