Add the FrozenStrings magic comment
[puppet-modules/puppetlabs-apt.git] / spec / defines / source_spec.rb
index 9da8b235feff81e8623d255d8d2796ba7dc77454..46aae96b84aed836496ffab5782f0df1f3451cae 100644 (file)
+# frozen_string_literal: true
+
 require 'spec_helper'
-describe 'apt::source', :type => :define do
-  let(:facts) { { :lsbdistid => 'Debian' } }
+
+describe 'apt::source' do
+  GPG_KEY_ID = '6F6B15509CF8E59E6E469F327F438280EF8D349F'.freeze
+
+  let :pre_condition do
+    'class { "apt": }'
+  end
+
   let :title do
     'my_source'
   end
 
-  let :default_params do
+  let :facts do
     {
-      :ensure             => 'present',
-      :location           => '',
-      :release            => 'karmic',
-      :repos              => 'main',
-      :include_src        => true,
-      :required_packages  => false,
-      :key                => false,
-      :key_server         => 'keyserver.ubuntu.com',
-      :key_content        => false,
-      :key_source         => false,
-      :pin                => false
+      os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } },
+      lsbdistid: 'Debian',
+      lsbdistcodename: 'jessie',
+      operatingsystem: 'Debian',
+      osfamily: 'Debian',
     }
   end
 
-  [{},
-   {
-      :location           => 'http://example.com',
-      :release            => 'precise',
-      :repos              => 'security',
-      :include_src        => false,
-      :required_packages  => 'apache',
-      :key                => 'key_name',
-      :key_server         => 'keyserver.debian.com',
-      :pin                => '600',
-      :key_content        => 'ABCD1234'
-    },
-    {
-      :key                => 'key_name',
-      :key_server         => 'keyserver.debian.com',
-      :key_content        => false,
-    },
-    {
-      :ensure             => 'absent',
-      :location           => 'http://example.com',
-      :release            => 'precise',
-      :repos              => 'security',
-    },
-    {
-      :release            => '',
-    },
-    {
-      :release            => 'custom',
-    },
-    {
-      :architecture       => 'amd64',
-    }
-  ].each do |param_set|
-    describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
-      let :param_hash do
-        default_params.merge(param_set)
+  context 'with defaults' do
+    context 'without location' do
+      it do
+        is_expected.to raise_error(Puppet::Error, %r{source entry without specifying a location})
       end
+    end
+    context 'with location' do
+      let(:params) { { location: 'hello.there' } }
 
-      let :facts do
-        {:lsbdistcodename => 'karmic', :lsbdistid => 'Ubuntu'}
-      end
+      it {
+        is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').without_content(%r{# my_source\ndeb-src hello.there wheezy main\n})
+        is_expected.not_to contain_package('apt-transport-https')
+      }
+    end
+  end
 
+  describe 'no defaults' do
+    context 'with complex pin' do
       let :params do
-        param_set
+        {
+          location: 'hello.there',
+          pin: { 'release' => 'wishwash',
+                 'explanation' => 'wishwash',
+                 'priority'    => 1001 },
+        }
       end
 
-      let :filename do
-        "/etc/apt/sources.list.d/#{title}.list"
-      end
+      it {
+        is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{hello.there jessie main\n})
+      }
+
+      it { is_expected.to contain_file('/etc/apt/sources.list.d/my_source.list').that_notifies('Class[Apt::Update]') }
+
+      it {
+        is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
+                                                                                                            priority: 1001,
+                                                                                                            explanation: 'wishwash',
+                                                                                                            release: 'wishwash')
+      }
+    end
 
-      let :content do
-        content = "# #{title}"
-        if param_hash[:architecture]
-          arch = "[arch=#{param_hash[:architecture]}] "
-        end
-        content << "\ndeb #{arch}#{param_hash[:location]} #{param_hash[:release]} #{param_hash[:repos]}\n"
-
-        if param_hash[:include_src]
-          content << "deb-src #{arch}#{param_hash[:location]} #{param_hash[:release]} #{param_hash[:repos]}\n"
-        end
-        content
+    context 'with simple key' do
+      let :params do
+        {
+          comment: 'foo',
+          location: 'http://debian.mirror.iweb.ca/debian/',
+          release: 'sid',
+          repos: 'testing',
+          key: GPG_KEY_ID,
+          pin: '10',
+          architecture: 'x86_64',
+          allow_unsigned: true,
+        }
       end
 
-      it { should contain_apt__params }
+      it {
+        is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# foo\ndeb \[arch=x86_64 trusted=yes\] http://debian.mirror.iweb.ca/debian/ sid testing\n})
+                                                             .without_content(%r{deb-src})
+      }
 
-      it { should contain_file("#{title}.list").with({
-          'ensure'    => param_hash[:ensure],
-          'path'      => filename,
-          'owner'     => 'root',
-          'group'     => 'root',
-          'mode'      => '0644',
-          'content'   => content,
-        })
+      it {
+        is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
+                                                                                                            priority: '10',
+                                                                                                            origin: 'debian.mirror.iweb.ca')
       }
 
       it {
-        if param_hash[:pin]
-          should contain_apt__pin(title).with({
-            "priority"  => param_hash[:pin],
-            "before"    => "File[#{title}.list]"
-          })
-        else
-          should_not contain_apt__pin(title).with({
-            "priority"  => param_hash[:pin],
-            "before"    => "File[#{title}.list]"
-          })
-        end
+        is_expected.to contain_apt__key("Add key: #{GPG_KEY_ID} from Apt::Source my_source").that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
+                                                                                                                                                    id: GPG_KEY_ID)
       }
+    end
+
+    context 'with complex key' do
+      let :params do
+        {
+          comment: 'foo',
+          location: 'http://debian.mirror.iweb.ca/debian/',
+          release: 'sid',
+          repos: 'testing',
+          key: { 'ensure' => 'refreshed',
+                 'id' => GPG_KEY_ID,
+                 'server' => 'pgp.mit.edu',
+                 'content' => 'GPG key content',
+                 'source'  => 'http://apt.puppetlabs.com/pubkey.gpg' },
+          pin: '10',
+          architecture: 'x86_64',
+          allow_unsigned: true,
+        }
+      end
 
       it {
-        should contain_exec("apt_update").with({
-          "command"     => "/usr/bin/apt-get update",
-          "refreshonly" => true
-        })
+        is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# foo\ndeb \[arch=x86_64 trusted=yes\] http://debian.mirror.iweb.ca/debian/ sid testing\n})
+                                                             .without_content(%r{deb-src})
       }
 
       it {
-        if param_hash[:required_packages]
-          should contain_exec("Required packages: '#{param_hash[:required_packages]}' for #{title}").with({
-            "command" => "/usr/bin/apt-get -y install #{param_hash[:required_packages]}",
-            "subscribe"   => "File[#{title}.list]",
-            "refreshonly" => true,
-            "before"      => 'Exec[apt_update]',
-          })
-        else
-          should_not contain_exec("Required packages: '#{param_hash[:required_packages]}' for #{title}").with({
-            "command"     => "/usr/bin/apt-get -y install #{param_hash[:required_packages]}",
-            "subscribe"   => "File[#{title}.list]",
-            "refreshonly" => true
-          })
-        end
+        is_expected.to contain_apt__pin('my_source').that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'present',
+                                                                                                            priority: '10',
+                                                                                                            origin: 'debian.mirror.iweb.ca')
       }
 
       it {
-        if param_hash[:key]
-          should contain_apt__key("Add key: #{param_hash[:key]} from Apt::Source #{title}").with({
-            "key"         => param_hash[:key],
-            "ensure"      => :present,
-            "key_server"  => param_hash[:key_server],
-            "key_content" => param_hash[:key_content],
-            "key_source"  => param_hash[:key_source],
-            "before"      => "File[#{title}.list]"
-          })
-        else
-          should_not contain_apt__key("Add key: #{param_hash[:key]} from Apt::Source #{title}").with({
-            "key"         => param_hash[:key],
-            "ensure"      => :present,
-            "key_server"  => param_hash[:key_server],
-            "key_content" => param_hash[:key_content],
-            "key_source"  => param_hash[:key_source],
-            "before"      => "File[#{title}.list]"
-          })
-        end
-      }
-    end
-  end
-  describe "without release should raise a Puppet::Error" do
-    let(:default_params) { Hash.new }
-    let(:facts) { Hash.new }
-    it { expect { should raise_error(Puppet::Error) } }
-    let(:facts) { { :lsbdistcodename => 'lucid', :lsbdistid => 'Ubuntu' } }
-    it { should contain_apt__source(title) }
+        is_expected.to contain_apt__key("Add key: #{GPG_KEY_ID} from Apt::Source my_source").that_comes_before('Apt::Setting[list-my_source]').with(ensure: 'refreshed',
+                                                                                                                                                    id: GPG_KEY_ID,
+                                                                                                                                                    server: 'pgp.mit.edu',
+                                                                                                                                                    content: 'GPG key content',
+                                                                                                                                                    source: 'http://apt.puppetlabs.com/pubkey.gpg')
+      }
+    end
+  end
+
+  context 'with allow_unsigned true' do
+    let :params do
+      {
+        location: 'hello.there',
+        allow_unsigned: true,
+      }
+    end
+
+    it {
+      is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb \[trusted=yes\] hello.there jessie main\n})
+    }
+  end
+
+  context 'with a https location, install apt-transport-https' do
+    let :params do
+      {
+        location: 'HTTPS://foo.bar',
+        allow_unsigned: false,
+      }
+    end
+
+    it {
+      is_expected.to contain_package('apt-transport-https')
+    }
+  end
+
+  context 'with a https location and custom release, install apt-transport-https' do
+    let :facts do
+      {
+        os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } },
+        lsbdistid: 'Debian',
+        lsbdistcodename: 'jessie',
+        osfamily: 'Debian',
+        puppetversion: Puppet.version,
+      }
+    end
+    let :params do
+      {
+        location: 'HTTPS://foo.bar',
+        allow_unsigned: false,
+        release: 'customrelease',
+      }
+    end
+
+    it {
+      is_expected.to contain_package('apt-transport-https')
+    }
+  end
+
+  context 'with a https location, do not install apt-transport-https on oses not in list eg buster' do
+    let :facts do
+      {
+        os: { family: 'Debian', name: 'Debian', release: { major: '10', full: '10.0' } },
+        lsbdistid: 'Debian',
+        lsbdistcodename: 'buster',
+        osfamily: 'Debian',
+      }
+    end
+    let :params do
+      {
+        location: 'https://foo.bar',
+        allow_unsigned: false,
+      }
+    end
+
+    it {
+      is_expected.not_to contain_package('apt-transport-https')
+    }
+  end
+
+  context 'with architecture equals x86_64' do
+    let :facts do
+      {
+        os: { family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } },
+        lsbdistid: 'Debian',
+        lsbdistcodename: 'wheezy',
+        osfamily: 'Debian',
+      }
+    end
+    let :params do
+      {
+        location: 'hello.there',
+        include: { 'deb' => false, 'src' => true },
+        architecture: 'x86_64',
+      }
+    end
+
+    it {
+      is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb-src \[arch=x86_64\] hello.there wheezy main\n})
+    }
+  end
+
+  context 'with architecture fact and unset architecture parameter' do
+    let :facts do
+      super().merge(architecture: 'amd64')
+    end
+    let :params do
+      {
+        location: 'hello.there',
+        include: { 'deb' => false, 'src' => true },
+      }
+    end
+
+    it {
+      is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb-src hello.there jessie main\n})
+    }
+  end
+
+  context 'with include_src => true' do
+    let :params do
+      {
+        location: 'hello.there',
+        include: { 'src' => true },
+      }
+    end
+
+    it {
+      is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{# my_source\ndeb hello.there jessie main\ndeb-src hello.there jessie main\n})
+    }
+  end
+
+  context 'with include deb => false' do
+    let :params do
+      {
+        include: { 'deb' => false },
+        location: 'hello.there',
+      }
+    end
+
+    it {
+      is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').without_content(%r{deb-src hello.there wheezy main\n})
+    }
+    it { is_expected.to contain_apt__setting('list-my_source').without_content(%r{deb hello.there wheezy main\n}) }
+  end
+
+  context 'with include src => true and include deb => false' do
+    let :params do
+      {
+        include: { 'deb' => false, 'src' => true },
+        location: 'hello.there',
+      }
+    end
+
+    it {
+      is_expected.to contain_apt__setting('list-my_source').with(ensure: 'present').with_content(%r{deb-src hello.there jessie main\n})
+    }
+    it { is_expected.to contain_apt__setting('list-my_source').without_content(%r{deb hello.there jessie main\n}) }
+  end
+
+  context 'with ensure => absent' do
+    let :params do
+      {
+        ensure: 'absent',
+      }
+    end
+
+    it {
+      is_expected.to contain_apt__setting('list-my_source').with(ensure: 'absent')
+    }
+  end
+
+  describe 'validation' do
+    context 'with no release' do
+      let :facts do
+        {
+          os: { family: 'Debian', name: 'Debian', release: { major: '8', full: '8.0' } },
+          osfamily: 'Debian',
+        }
+      end
+      let(:params) { { location: 'hello.there' } }
+
+      it do
+        is_expected.to raise_error(Puppet::Error, %r{lsbdistcodename fact not available: release parameter required})
+      end
+    end
+
+    context 'with release is empty string' do
+      let(:params) { { location: 'hello.there', release: '' } }
+
+      it { is_expected.to contain_apt__setting('list-my_source').with_content(%r{hello\.there  main}) }
+    end
+
+    context 'with invalid pin' do
+      let :params do
+        {
+          location: 'hello.there',
+          pin: true,
+        }
+      end
+
+      it do
+        is_expected.to raise_error(Puppet::Error, %r{expects a value})
+      end
+    end
+
+    context 'with notify_update = undef (default)' do
+      let :params do
+        {
+          location: 'hello.there',
+        }
+      end
+
+      it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(true) }
+    end
+
+    context 'with notify_update = true' do
+      let :params do
+        {
+          location: 'hello.there',
+          notify_update: true,
+        }
+      end
+
+      it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(true) }
+    end
+
+    context 'with notify_update = false' do
+      let :params do
+        {
+          location: 'hello.there',
+          notify_update: false,
+        }
+      end
+
+      it { is_expected.to contain_apt__setting("list-#{title}").with_notify_update(false) }
+    end
   end
 end