summaryrefslogtreecommitdiff
path: root/spec/unit/module_tool/applications/uninstaller_spec.rb
blob: 66e71b63827c6c63a22501e23b9870c9571b610f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
require 'spec_helper'
require 'puppet/module_tool'
require 'tmpdir'
require 'puppet_spec/module_tool/shared_functions'
require 'puppet_spec/module_tool/stub_source'

describe Puppet::ModuleTool::Applications::Uninstaller do
  include PuppetSpec::ModuleTool::SharedFunctions
  include PuppetSpec::Files

  before do
    FileUtils.mkdir_p(primary_dir)
    FileUtils.mkdir_p(secondary_dir)
  end

  let(:environment) do
    Puppet.lookup(:current_environment).override_with(
      :vardir     => vardir,
      :modulepath => [ primary_dir, secondary_dir ]
    )
  end

  let(:vardir)   { tmpdir('uninstaller') }
  let(:primary_dir) { File.join(vardir, "primary") }
  let(:secondary_dir) { File.join(vardir, "secondary") }
  let(:remote_source) { PuppetSpec::ModuleTool::StubSource.new }

  let(:module) { 'module-not_installed' }
  let(:application) do
    opts = options
    Puppet::ModuleTool.set_option_defaults(opts)
    Puppet::ModuleTool::Applications::Uninstaller.new(self.module, opts)
  end

  def options
    { :environment => environment }
  end

  subject { application.run }

  context "when the module is not installed" do
    it "should fail" do
      subject.should include :result => :failure
    end
  end

  context "when the module is installed" do
    let(:module) { 'pmtacceptance-stdlib' }

    before { preinstall('pmtacceptance-stdlib', '1.0.0') }
    before { preinstall('pmtacceptance-apache', '0.0.4') }

    it "should uninstall the module" do
      subject[:affected_modules].first.forge_name.should == "pmtacceptance/stdlib"
    end

    it "should only uninstall the requested module" do
      subject[:affected_modules].length == 1
    end

    context 'in two modulepaths' do
      before { preinstall('pmtacceptance-stdlib', '2.0.0', :into => secondary_dir) }

      it "should fail if a module exists twice in the modpath" do
        subject.should include :result => :failure
      end
    end

    context "when options[:version] is specified" do
      def options
        super.merge(:version => '1.0.0')
      end

      it "should uninstall the module if the version matches" do
        subject[:affected_modules].length.should == 1
        subject[:affected_modules].first.version.should == "1.0.0"
      end

      context 'but not matched' do
        def options
          super.merge(:version => '2.0.0')
        end

        it "should not uninstall the module if the version does not match" do
          subject.should include :result => :failure
        end
      end
    end

    context "when the module metadata is missing" do
      before { File.unlink(File.join(primary_dir, 'stdlib', 'metadata.json')) }

      it "should not uninstall the module" do
        application.run[:result].should == :failure
      end
    end

    context "when the module has local changes" do
      before do
        mark_changed(File.join(primary_dir, 'stdlib'))
      end

      it "should not uninstall the module" do
        subject.should include :result => :failure
      end
    end

    context "when uninstalling the module will cause broken dependencies" do
      before { preinstall('pmtacceptance-apache', '0.10.0') }

      it "should not uninstall the module" do
        subject.should include :result => :failure
      end
    end

    context 'with --ignore-changes' do
      def options
        super.merge(:ignore_changes => true)
      end

      context 'with local changes' do
        before do
          mark_changed(File.join(primary_dir, 'stdlib'))
        end

        it 'overwrites the installed module with the greatest version matching that range' do
          subject.should include :result => :success
        end
      end

      context 'without local changes' do
        it 'overwrites the installed module with the greatest version matching that range' do
          subject.should include :result => :success
        end
      end
    end

    context "when using the --force flag" do

      def options
        super.merge(:force => true)
      end

      context "with local changes" do
        before do
          mark_changed(File.join(primary_dir, 'stdlib'))
        end

        it "should ignore local changes" do
          subject[:affected_modules].length.should == 1
          subject[:affected_modules].first.forge_name.should == "pmtacceptance/stdlib"
        end
      end

      context "while depended upon" do
        before { preinstall('pmtacceptance-apache', '0.10.0') }

        it "should ignore broken dependencies" do
          subject[:affected_modules].length.should == 1
          subject[:affected_modules].first.forge_name.should == "pmtacceptance/stdlib"
        end
      end
    end
  end
end