summaryrefslogtreecommitdiff
path: root/spec/unit/provider/group/windows_adsi_spec.rb
blob: 7c9366f72aaa722c104bcb72f73d290e37931ef6 (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
166
167
168
#!/usr/bin/env ruby

require 'spec_helper'

describe Puppet::Type.type(:group).provider(:windows_adsi), :if => Puppet.features.microsoft_windows? do
  let(:resource) do
    Puppet::Type.type(:group).new(
      :title => 'testers',
      :provider => :windows_adsi
    )
  end

  let(:provider) { resource.provider }

  let(:connection) { stub 'connection' }

  before :each do
    Puppet::Util::Windows::ADSI.stubs(:computer_name).returns('testcomputername')
    Puppet::Util::Windows::ADSI.stubs(:connect).returns connection
  end

  describe ".instances" do
    it "should enumerate all groups" do
      names = ['group1', 'group2', 'group3']
      stub_groups = names.map{|n| stub(:name => n)}

      connection.stubs(:execquery).with('select name from win32_group where localaccount = "TRUE"').returns stub_groups

      described_class.instances.map(&:name).should =~ names
    end
  end

  describe "group type :members property helpers" do

    let(:user1) { stub(:account => 'user1', :domain => '.', :to_s => 'user1sid') }
    let(:user2) { stub(:account => 'user2', :domain => '.', :to_s => 'user2sid') }

    before :each do
      Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user1').returns(user1)
      Puppet::Util::Windows::SID.stubs(:name_to_sid_object).with('user2').returns(user2)
    end

    describe "#members_insync?" do
      it "should return false when current is nil" do
        provider.members_insync?(nil, ['user2']).should be_false
      end
      it "should return false when should is nil" do
        provider.members_insync?(['user1'], nil).should be_false
      end
      it "should return false for differing lists of members" do
        provider.members_insync?(['user1'], ['user2']).should be_false
        provider.members_insync?(['user1'], []).should be_false
        provider.members_insync?([], ['user2']).should be_false
      end
      it "should return true for same lists of members" do
        provider.members_insync?(['user1', 'user2'], ['user1', 'user2']).should be_true
      end
      it "should return true for same lists of unordered members" do
        provider.members_insync?(['user1', 'user2'], ['user2', 'user1']).should be_true
      end
      it "should return true for same lists of members irrespective of duplicates" do
        provider.members_insync?(['user1', 'user2', 'user2'], ['user2', 'user1', 'user1']).should be_true
      end
    end

    describe "#members_to_s" do
      it "should return an empty string on non-array input" do
        [Object.new, {}, 1, :symbol, ''].each do |input|
          provider.members_to_s(input).should be_empty
        end
      end
      it "should return an empty string on empty or nil users" do
        provider.members_to_s([]).should be_empty
        provider.members_to_s(nil).should be_empty
      end
      it "should return a user string like DOMAIN\\USER" do
        provider.members_to_s(['user1']).should == '.\user1'
      end
      it "should return a user string like DOMAIN\\USER,DOMAIN2\\USER2" do
        provider.members_to_s(['user1', 'user2']).should == '.\user1,.\user2'
      end
    end
  end

  describe "when managing members" do
    it "should be able to provide a list of members" do
      provider.group.stubs(:members).returns ['user1', 'user2', 'user3']

      provider.members.should =~ ['user1', 'user2', 'user3']
    end

    it "should be able to set group members" do
      provider.group.stubs(:members).returns ['user1', 'user2']

      member_sids = [
        stub(:account => 'user1', :domain => 'testcomputername'),
        stub(:account => 'user2', :domain => 'testcomputername'),
        stub(:account => 'user3', :domain => 'testcomputername'),
      ]

      provider.group.stubs(:member_sids).returns(member_sids[0..1])

      Puppet::Util::Windows::SID.expects(:name_to_sid_object).with('user2').returns(member_sids[1])
      Puppet::Util::Windows::SID.expects(:name_to_sid_object).with('user3').returns(member_sids[2])

      provider.group.expects(:remove_member_sids).with(member_sids[0])
      provider.group.expects(:add_member_sids).with(member_sids[2])

      provider.members = ['user2', 'user3']
    end
  end

  describe 'when creating groups' do
    it "should be able to create a group" do
      resource[:members] = ['user1', 'user2']

      group = stub 'group'
      Puppet::Util::Windows::ADSI::Group.expects(:create).with('testers').returns group

      create = sequence('create')
      group.expects(:commit).in_sequence(create)
      group.expects(:set_members).with(['user1', 'user2']).in_sequence(create)

      provider.create
    end

    it 'should not create a group if a user by the same name exists' do
      Puppet::Util::Windows::ADSI::Group.expects(:create).with('testers').raises( Puppet::Error.new("Cannot create group if user 'testers' exists.") )
      expect{ provider.create }.to raise_error( Puppet::Error,
        /Cannot create group if user 'testers' exists./ )
    end

    it 'should commit a newly created group' do
      provider.group.expects( :commit )

      provider.flush
    end
  end

  it "should be able to test whether a group exists" do
    Puppet::Util::Windows::ADSI.stubs(:sid_uri_safe).returns(nil)
    Puppet::Util::Windows::ADSI.stubs(:connect).returns stub('connection')
    provider.should be_exists

    Puppet::Util::Windows::ADSI.stubs(:connect).returns nil
    provider.should_not be_exists
  end

  it "should be able to delete a group" do
    connection.expects(:Delete).with('group', 'testers')

    provider.delete
  end

  it "should report the group's SID as gid" do
    Puppet::Util::Windows::SID.expects(:name_to_sid).with('testers').returns('S-1-5-32-547')
    provider.gid.should == 'S-1-5-32-547'
  end

  it "should fail when trying to manage the gid property" do
    provider.expects(:fail).with { |msg| msg =~ /gid is read-only/ }
    provider.send(:gid=, 500)
  end

  it "should prefer the domain component from the resolved SID" do
    provider.members_to_s(['.\Administrators']).should == 'BUILTIN\Administrators'
  end
end