<commit_before>#
# Author:: Dreamcat4 (<<EMAIL>>)
# Copyright:: Copyright 2009-2019, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require "spec_helper"
require "ostruct"

describe Chef::Provider::User::Dscl do
  before do
    allow(ChefConfig).to receive(:windows?) { false }
  end
  let(:shellcmdresult) do
    Struct.new(:stdout, :stderr, :exitstatus)
  end
  let(:node) do
    node = Chef::Node.new
    allow(node).to receive(:[]).with(:platform).and_return("mac_os_x")
    node
  end

  let(:events) do
    Chef::EventDispatch::Dispatcher.new
  end

  let(:run_context) do
    Chef::RunContext.new(node, {}, events)
  end

  let(:new_resource) do
    r = Chef::Resource::User::DsclUser.new("toor")
    r.password(password)
    r.salt(salt)
    r.iterations(iterations)
    r
  end

  let(:provider) do
    Chef::Provider::User::Dscl.new(new_resource, run_context)
  end

  let(:password) { nil }
  let(:salt) { nil }
  let(:iterations) { nil }

  let(:salted_sha512_password) do
    "<PASSWORD>\
<PASSWORD>db9b56a2520bc8fff63a\
2ba6b7984c0737ff0b7949455071581f7affcd536d\
402b6cdb097"
  end

  let(:salted_sha512_pbkdf2_password) do
    "<PASSWORD>29<PASSWORD>2b97c\
1de12df509577a045728255ec7c6c5f5\
c18efa05ed02b682ffa7ebc05119900e\
b1d4880833aa7a190afc13e2bf0936b8\
20123e8c98f0f9bcac2a629d9163caac\
9464a8c234f3919082400b4f939bb77b\
c5adbbac718b7eb99463a7b679571e0f\
1c9fef2ef08d0b9e9c2bcf644eed2ffc"
  end

  let(:salted_sha512_pbkdf2_salt) do
    "2d942d8364a9ccf2b8e5cb7ed1ff58f78\
e29dbfee7f9db58859144d061fd0058"
  end

  let(:salted_sha512_pbkdf2_iterations) do
    25000
  end

  let(:vagrant_sha_512) do
    "6f75d7190441facc34291ebbea1fc756b242d4f\
e9bcff141bccb84f1979e27e539539aa31f9f7dcc92c0cea959\
ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
  end

  let(:vagrant_sha_512_pbkdf2) do
    "12601a90db17cbf\
8ba4808e6382fb0d3b9d8a6c1a190477bf680ab21afb\
6065467136e55cc208a6f74156e3daf20fb13369ef4b\
7bafa047d80359fb46a48a4adccd548ebb33851b093\
47cca84341a7f93a27147343f89fb843fb46c0017d2\
64afa4976baacf941b915bd1ec1ca24c30b3e759e02\
403e02f59fe7ff5938a7636c"
  end

  let(:vagrant_sha_512_pbkdf2_salt) do
    "ee954be472fdc60ddf89484781433993625f006af6ec810c08f49a7e413946a1"
  end

  let(:vagrant_sha_512_pbkdf2_iterations) do
    34482
  end

  describe "when shelling out to dscl" do
    it "should run dscl with the supplied cmd /Path args" do
      shell_return = shellcmdresult.new("stdout", "err", 0)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return)
      expect(provider.run_dscl("cmd", "/Path", "args")).to eq("stdout")
    end

    it "returns an empty string from delete commands" do
      shell_return = shellcmdresult.new("out", "err", 23)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-delete", "/Path", "args").and_return(shell_return)
      expect(provider.run_dscl("delete", "/Path", "args")).to eq("")
    end

    it "should raise an exception for any other command" do
      shell_return = shellcmdresult.new("out", "err", 23)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "arguments").and_return(shell_return)
      expect { provider.run_dscl("cmd", "/Path", "arguments") }.to raise_error(Chef::Exceptions::DsclCommandFailed)
    end

    it "raises an exception when dscl reports 'no such key'" do
      shell_return = shellcmdresult.new("No such key: ", "err", 23)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return)
      expect { provider.run_dscl("cmd", "/Path", "args") }.to raise_error(Chef::Exceptions::DsclCommandFailed)
    end

    it "raises an exception when dscl reports 'eDSRecordNotFound'" do
      shell_return = shellcmdresult.new("<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)", "err", -14136)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return)
      expect { provider.run_dscl("cmd", "/Path", "args") }.to raise_error(Chef::Exceptions::DsclCommandFailed)
    end
  end

  describe "get_free_uid" do
    before do
      expect(provider).to receive(:run_dscl).with("list", "/Users", "uid").and_return("\nwheel      200\nstaff      201\nbrahms      500\nchopin      501\n")
    end

    describe "when resource is configured as system" do
      before do
        new_resource.system(true)
      end

      it "should return the first unused uid number on or above 200" do
        expect(provider.get_free_uid).to eq(202)
      end<commit_msg>Improve the lets in the dscl provider specs<commit_after>#
# Author:: Dreamcat4 (<<EMAIL>>)
# Copyright:: Copyright 2009-2019, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require "spec_helper"
require "ostruct"

describe Chef::Provider::User::Dscl do
  before do
    allow(ChefConfig).to receive(:windows?) { false }
  end

  let(:shellcmdresult) { Struct.new(:stdout, :stderr, :exitstatus) }

  let(:password) { nil }
  let(:salt) { nil }
  let(:iterations) { nil }

  let (:events) { Chef::EventDispatch::Dispatcher.new }

  let(:node) do
    Chef::Node.new.tap do |node|
      node.automatic["os"] = "darwin"
    end
  end

  let (:run_context) { Chef::RunContext.new(node, {}, events) }

  let(:new_resource) do
    r = Chef::Resource::User::DsclUser.new("toor", run_context)
    r.password(password)
    r.salt(salt)
    r.iterations(iterations)
    r
  end

  let(:provider) do
    Chef::Provider::User::Dscl.new(new_resource, run_context)
  end

  let(:salted_sha512_password) do
    "<PASSWORD>\
705ddac69e682a33db5dbcdb9b56a2520bc8fff63a\
2ba6b7984c0737ff0b7949455071581f7affcd536d\
402b6cdb097"
  end

  let(:salted_<PASSWORD>512_pbkdf2_password) do
    "<PASSWORD>\
1de12df509577a045728255ec7c6c5f5\
c18efa05ed02b682ffa7ebc05119900e\
b1d4880833aa7a190afc13e2bf0936b8\
20123e8c98f0f9bcac2a629d9163caac\
9464a8c234f3919082400b4f939bb77b\
c5adbbac718b7eb99463a7b679571e0f\
1c9fef2ef08d0b9e9c2bcf644eed2ffc"
  end

  let(:salted_sha512_pbkdf2_salt) do
    "2d942d8364a9ccf2b8e5cb7ed1ff58f78\
e29dbfee7f9db58859144d061fd0058"
  end

  let(:salted_sha512_pbkdf2_iterations) do
    25000
  end

  let(:vagrant_sha_512) do
    "6f75d7190441facc34291ebbea1fc756b242d4f\
e9bcff141bccb84f1979e27e539539aa31f9f7dcc92c0cea959\
ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
  end

  let(:vagrant_sha_512_pbkdf2) do
    "12601a90db17cbf\
8ba4808e6382fb0d3b9d8a6c1a190477bf680ab21afb\
6065467136e55cc208a6f74156e3daf20fb13369ef4b\
7bafa047d80359fb46a48a4adccd548ebb33851b093\
47cca84341a7f93a27147343f89fb843fb46c0017d2\
64afa4976baacf941b915bd1ec1ca24c30b3e759e02\
403e02f59fe7ff5938a7636c"
  end

  let(:vagrant_sha_512_pbkdf2_salt) do
    "ee954be472fdc60ddf89484781433993625f006af6ec810c08f49a7e413946a1"
  end

  let(:vagrant_sha_512_pbkdf2_iterations) do
    34482
  end

  describe "when shelling out to dscl" do
    it "should run dscl with the supplied cmd /Path args" do
      shell_return = shellcmdresult.new("stdout", "err", 0)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return)
      expect(provider.run_dscl("cmd", "/Path", "args")).to eq("stdout")
    end

    it "returns an empty string from delete commands" do
      shell_return = shellcmdresult.new("out", "err", 23)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-delete", "/Path", "args").and_return(shell_return)
      expect(provider.run_dscl("delete", "/Path", "args")).to eq("")
    end

    it "should raise an exception for any other command" do
      shell_return = shellcmdresult.new("out", "err", 23)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "arguments").and_return(shell_return)
      expect { provider.run_dscl("cmd", "/Path", "arguments") }.to raise_error(Chef::Exceptions::DsclCommandFailed)
    end

    it "raises an exception when dscl reports 'no such key'" do
      shell_return = shellcmdresult.new("No such key: ", "err", 23)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return)
      expect { provider.run_dscl("cmd", "/Path", "args") }.to raise_error(Chef::Exceptions::DsclCommandFailed)
    end

    it "raises an exception when dscl reports 'eDSRecordNotFound'" do
      shell_return = shellcmdresult.new("<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)", "err", -14136)
      expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return)
      expect { provider.run_dscl("cmd", "/Path", "args") }.to raise_error(Chef::Exceptions::DsclCommandFailed)
    end
  end

  describe "get_free_uid" do
    before do
      expect(provider).to receive(:run_dscl).with("list", "/Users", "uid").and_return("\nwheel      200\nstaff      201\nbrahms      500\nchopin      501\n")
    end

    describe "when the system property is set to true" do
      before do
        new_resource.system(true)
      end

      it "should return the first unused uid number on or above 200" do
        expect(provider.get_free_uid).to eq(202)
      end
{'fraction_non_alphanumeric': 0.11876392521553812, 'fraction_numerical': 0.11527656688947012, 'mean_word_length': 4.583558680367767, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6327949', 'n_tokens_mistral': 4556, 'n_tokens_neox': 3857, 'n_words': 770}