require "spec_helper" module LicenseFinder module CLI describe Main do let(:decisions) { Decisions.new } let(:packages) { [] } let!(:decision_applier) do DecisionApplier.new( decisions: decisions, packages: packages ) end let(:configuration) { double(:configuration, valid_project_path?: true) } let(:license_finder_instance) { double(:license_finder, unapproved: [unapproved_dependency], blacklisted: [], project_name: 'taco stand', config: configuration) } let(:license) { double(:license, name: "thing") } let(:unapproved_dependency) { double(:dependency, name: "a dependency", version: "2.4.1", missing?: false, licenses: [license]) } before do allow(Decisions).to receive(:fetch_saved) { decisions } allow(DecisionApplier).to receive(:new) { decision_applier } end describe "default" do it "checks for action items" do decisions.add_package("a dependency", nil) expect_any_instance_of(LicenseFinder::Core).to receive(:unapproved).and_return([unapproved_dependency]) silence_stdout do expect { described_class.start(["--quiet"]) }.to raise_error(SystemExit) end end end describe "cli options" do let(:config_options) { [ "--decisions_file=whatever.yml", "--project_path=../other_project", "--gradle_command=do_things", "--rebar_command=do_other_things", "--rebar_deps_dir=rebar_dir", "--save" ] } let(:logger_options) { [ '--quiet', '--debug' ] } let(:parsed_config) { { decisions_file: 'whatever.yml', project_path: '../other_project', gradle_command: 'do_things', rebar_command: 'do_other_things', rebar_deps_dir: 'rebar_dir', save: 'license_report', logger: {} } } it "passes the config options to the new LicenseFinder::Core instance" do expect(LicenseFinder::Core).to receive(:new).with(parsed_config).and_return(license_finder_instance) silence_stdout do expect { described_class.start(config_options) }.to raise_error(SystemExit) end end it "passes the logger options to the new LicenseFinder::Core instance" do expect(LicenseFinder::Core).to receive(:new).with({logger: {debug: true, quiet: true}}).and_return(license_finder_instance) silence_stdout do expect { described_class.start(logger_options) }.to raise_error(SystemExit) end end end describe "#report" do let(:packages) { [Package.new('one dependency', "1.1")] } def report capture_stdout { subject.report } end it "reports acknowleged dependencies" do expect(report).to eq "\"one dependency\", 1.1, unknown\n" end it "will output a specific format" do subject.options = {format: 'markdown'} expect(report).to include "## Action" end it "will output a custom csv" do subject.options = {format: 'csv', columns: ['name', 'version']} expect(report).to eq "one dependency,1.1\n" end context 'when the package is a nuget package' do let(:packages) { [NugetPackage.new('one dependency', "1.1")] } it "will includes package_manager for csv report" do subject.options = {format: 'csv', columns: ['name', 'version', 'package_manager']} expect(report).to eq "one dependency,1.1,Nuget\n" end end context "in html reports" do before do subject.options = {format: 'html'} end context "when the project has a name" do before { decisions.name_project("given project name") } it "should show the project name" do expect(report).to include "given project name" end end context "when the project has no name" do before { allow_any_instance_of(Pathname).to receive(:basename).and_return("a_project") } it "should default to the directory name" do expect(report).to include "a_project" end end end context "when the --save option is passed" do it "calls report method and calls save_report" do subject.options = {save: "license_report", format: 'text'} expect(subject).to receive(:report).and_call_original expect(subject).to receive(:save_report) subject.report end context "when file name is not specified (--save)" do it "creates report that is called the default file name" do provided_by_thor_as_default_name = "license_report" #####FIX ME subject.options = {save: provided_by_thor_as_default_name, format: 'text'} expect(subject).to receive(:report).and_call_original expect(subject).to receive(:save_report).with(instance_of(String), "license_report") subject.report end it "saves the output report to default file ('license_report.txt') in project root" do mock_file = double(:file) expect(File).to receive(:open).with("license_report.txt", "w").and_yield(mock_file) expect(mock_file).to receive(:write).with("content of file") subject.send(:save_report, "content of file", "license_report.txt") end end context "when file name is specified (--save='FILENAME')" do it "saves with a specified file name" do subject.options = {save: 'my_report' , format: 'text'} expect(subject).to receive(:report).and_call_original expect(subject).to receive(:save_report).with(instance_of(String), "my_report") subject.report end end end context "when the --save option is not passed" do it "calls report method and does not call save_report" do subject.options = {format: 'text'} expect(subject).to receive(:report).and_call_original expect(subject).not_to receive(:save_report) expect(subject).to receive(:report_of) report end end end describe "#action_items" do def action_items subject.options = {quiet: true, format: 'text'} subject.action_items end context "with unapproved dependencies" do let(:packages) { [Package.new('one dependency')] } it "reports unapproved dependencies" do result = capture_stdout do expect { action_items }.to raise_error(SystemExit) end expect(result).to match /dependencies/i expect(result).to match /one dependency/ end end context "with blacklisted dependencies" do let(:decisions) { Decisions.new.blacklist('GPLv3')} let(:packages) { [Package.new('blacklisted', '1.0', spec_licenses: ['GPLv3'])] } it "reports blacklisted dependencies" do result = capture_stdout do expect { action_items }.to raise_error(SystemExit) end expect(result).to include "Blacklisted dependencies:\nblacklisted, 1.0, GPLv3" end end it "reports that all dependencies are approved" do result = capture_stdout do expect { action_items }.not_to raise_error end expect(result).to match /approved/i end end end end end