require 'spec_helper'

describe "CLI" do
  include Helpers

  let(:command) do
    File.expand_path('../bundle/wrapper.rb', __FILE__)
  end

  context "when auditing a bundle with unpatched gems" do
    let(:bundle)    { 'unpatched_gems' }
    let(:directory) { File.join('spec','bundle',bundle) }

    context "in default display mode" do
      subject do
        Dir.chdir(directory) { sh(command, :fail => true) }
      end

      it "should print a warning" do
        subject.should include("Unpatched versions found!")
      end

      it "should print advisory information for the vulnerable gems" do
        advisory_pattern = /(Name: [^\n]+
Version: \d+.\d+.\d+
Advisory: OSVDB-\d+
Criticality: (High|Medium)
URL: http:\/\/(direct|www\.)?osvdb.org\/show\/osvdb\/\d+
Title: [^\n]*?
Solution: upgrade to ((~>|=>) \d+.\d+.\d+, )*(~>|=>) \d+.\d+.\d+[\s\n]*?)+/

        expect(subject).to match(advisory_pattern)
        expect(subject).to include("Unpatched versions found!")
      end
    end

    context "in verbose display mode" do
      subject do
        Dir.chdir(directory) { sh(command + " --verbose", :fail => true) }
      end

      it "should print a warning" do
        subject.should include("Unpatched versions found!")
      end

      it "should print advisory information for the vulnerable gems" do
        advisory_pattern = /(Name: [^\n]+
Version: \d+.\d+.\d+
Advisory: OSVDB-\d+
Criticality: (High|Medium)
URL: http:\/\/(direct|www\.)?osvdb.org\/show\/osvdb\/\d+
Description:

((  .*?)?\n)+
Solution: upgrade to ((~>|=>) \d+.\d+.\d+, )*(~>|=>) \d+.\d+.\d+[\s\n]*?)+/

        expect(subject).to match(advisory_pattern)
        expect(subject).to include("Unpatched versions found!")
      end
    end
  end

  context "when displaying bundler-audit version" do
    let(:bundle)    { 'unpatched_gems' }
    let(:directory) { File.join('spec','bundle',bundle) }

    let(:command) do
      File.expand_path('../bundle/wrapper.rb', __FILE__) + " version"
    end

    subject do
      # Ignoring failure here as bundle-audit version seems to return a
      # non-zero status, and
      Dir.chdir(directory) { sh(command, :fail => false) }
    end

    it "should show the version and number of known advisories" do
      # It prints a name based on $0, so our wrapper mucks up the display in a
      # predictable way.
      subject.should match(/^wrapper\.rb #{Regexp.quote(Bundler::Audit::VERSION)} \(advisories: \d+\)/)
    end
  end

  context "when auditing a bundle with ignored gems" do
    let(:bundle)    { 'unpatched_gems' }
    let(:directory) { File.join('spec','bundle',bundle) }

    let(:command) do
      File.expand_path('../bundle/wrapper.rb', __FILE__) + " -i OSVDB-89026"
    end

    subject do
      Dir.chdir(directory) { sh(command, :fail => true) }
    end

    it "should not print advisory information for ignored gem" do
      subject.should_not include("OSVDB-89026")
    end
  end

  context "when auditing a bundle with insecure sources" do
    let(:bundle)    { 'insecure_sources' }
    let(:directory) { File.join('spec','bundle',bundle) }

    subject do
      Dir.chdir(directory) { sh(command, :fail => true) }
    end

    it "should print warnings about insecure sources" do
      subject.should include(%{
Insecure Source URI found: git://github.com/rails/jquery-rails.git
Insecure Source URI found: http://rubygems.org/
      }.strip)

      subject.should include(%{Insecure sources found!})
    end
  end

  context "when auditing a secure bundle" do
    let(:bundle)    { 'secure' }
    let(:directory) { File.join('spec','bundle',bundle) }

    subject do
      Dir.chdir(directory) { sh(command) }
    end

    it "should notify us properly when everything is fine" do
      # We check the end of the output because a DB install/update "may" (
      # _will_, in the case of the test but _may_ in the real world) have been
      # performed.
      subject.should =~ /^No unpatched versions found$/
      subject.should =~ /^No insecure sources found$/
    end
  end
end