summaryrefslogtreecommitdiff
path: root/spec/unit/config_fetcher_spec.rb
blob: 84aad388769b3f0ba3913be52de477a0e6d1dafd (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
require "spec_helper"
require "chef/config_fetcher"

describe Chef::ConfigFetcher do
  let(:valid_json) { Chef::JSONCompat.to_json({:a=>"b"}) }
  let(:invalid_json) { %q[{"syntax-error": "missing quote}] }
  let(:http) { double("Chef::HTTP::Simple") }

  let(:config_location_regex) { Regexp.escape(config_location) }
  let(:invalid_json_error_regex) { %r{Could not parse the provided JSON file \(#{config_location_regex}\)} }

  let(:fetcher) { Chef::ConfigFetcher.new(config_location) }

  context "when loading a local file" do
    let(:config_location) { "/etc/chef/client.rb" }
    let(:config_content) { "# The client.rb content" }

    it "reads the file from disk" do
      expect(::File).to receive(:read).
        with(config_location).
        and_return(config_content)
      expect(fetcher.read_config).to eq(config_content)
    end

    it "gives the expanded path to the config file" do
      expect(fetcher.expanded_path).to eq(File.expand_path(config_location))
    end

    context "with a relative path" do

      let(:config_location) { "client.rb" }

      it "gives the expanded path to the config file" do
        expected = File.join(Dir.pwd, config_location)
        expect(fetcher.expanded_path).to eq(expected)
      end

    end

    context "and consuming JSON" do

      let(:config_location) { "/etc/chef/first-boot.json" }


      it "returns the parsed JSON" do
        expect(::File).to receive(:read).
          with(config_location).
          and_return(valid_json)

        expect(fetcher.fetch_json).to eq({"a" => "b"})
      end

      context "and the JSON is invalid" do

        it "reports the JSON error" do


          expect(::File).to receive(:read).
            with(config_location).
            and_return(invalid_json)

          expect(Chef::Application).to receive(:fatal!).
            with(invalid_json_error_regex, 2)
          fetcher.fetch_json
        end
      end
    end

  end

  context "with an HTTP URL config location" do

    let(:config_location) { "https://example.com/client.rb" }
    let(:config_content) { "# The client.rb content" }

    it "returns the config location unchanged for #expanded_path" do
      expect(fetcher.expanded_path).to eq(config_location)
    end

    describe "reading the file" do

      before do
        expect(Chef::HTTP::Simple).to receive(:new).
          with(config_location).
          and_return(http)
      end

      it "reads the file over HTTP" do
          expect(http).to receive(:get).
            with("").and_return(config_content)
        expect(fetcher.read_config).to eq(config_content)
      end

      context "and consuming JSON" do
        let(:config_location) { "https://example.com/foo.json" }

        it "fetches the file and parses it" do
          expect(http).to receive(:get).
            with("").and_return(valid_json)
          expect(fetcher.fetch_json).to eq({"a" => "b"})
        end

        context "and the JSON is invalid" do
          it "reports the JSON error" do
            expect(http).to receive(:get).
              with("").and_return(invalid_json)

            expect(Chef::Application).to receive(:fatal!).
              with(invalid_json_error_regex, 2)
            fetcher.fetch_json
          end
        end
      end
    end

  end

  context "with a nil config file argument" do

    let(:config_location) { nil }

    it "returns the config location unchanged for #expanded_path" do
      expect(fetcher.expanded_path).to eq(nil)
    end
  end


end