diff options
Diffstat (limited to 'spec/unit/data_bag_item_spec.rb')
-rw-r--r-- | spec/unit/data_bag_item_spec.rb | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb new file mode 100644 index 0000000000..6f46c81054 --- /dev/null +++ b/spec/unit/data_bag_item_spec.rb @@ -0,0 +1,280 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, 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 'chef/data_bag_item' + +describe Chef::DataBagItem do + before(:each) do + @data_bag_item = Chef::DataBagItem.new + end + + describe "initialize" do + it "should be a Chef::DataBagItem" do + @data_bag_item.should be_a_kind_of(Chef::DataBagItem) + end + end + + describe "data_bag" do + it "should let you set the data_bag to a string" do + @data_bag_item.data_bag("clowns").should == "clowns" + end + + it "should return the current data_bag type" do + @data_bag_item.data_bag "clowns" + @data_bag_item.data_bag.should == "clowns" + end + + it "should not accept spaces" do + lambda { @data_bag_item.data_bag "clown masters" }.should raise_error(ArgumentError) + end + + it "should throw an ArgumentError if you feed it anything but a string" do + lambda { @data_bag_item.data_bag Hash.new }.should raise_error(ArgumentError) + end + end + + describe "raw_data" do + it "should let you set the raw_data with a hash" do + lambda { @data_bag_item.raw_data = { "id" => "octahedron" } }.should_not raise_error + end + + it "should let you set the raw_data from a mash" do + lambda { @data_bag_item.raw_data = Mash.new({ "id" => "octahedron" }) }.should_not raise_error + end + + it "should raise an exception if you set the raw data without a key" do + lambda { @data_bag_item.raw_data = { "monkey" => "pants" } }.should raise_error(ArgumentError) + end + + it "should raise an exception if you set the raw data to something other than a hash" do + lambda { @data_bag_item.raw_data = "katie rules" }.should raise_error(ArgumentError) + end + + it "should accept alphanum/-/_ for the id" do + lambda { @data_bag_item.raw_data = { "id" => "h1-_" } }.should_not raise_error(ArgumentError) + end + + it "should raise an exception if the id contains anything but alphanum/-/_" do + lambda { @data_bag_item.raw_data = { "id" => "!@#" } }.should raise_error(ArgumentError) + end + + it "should return the raw data" do + @data_bag_item.raw_data = { "id" => "highway_of_emptiness" } + @data_bag_item.raw_data.should == { "id" => "highway_of_emptiness" } + end + + it "should be a Mash by default" do + @data_bag_item.raw_data.should be_a_kind_of(Mash) + end + end + + describe "object_name" do + before(:each) do + @data_bag_item.data_bag("dreams") + @data_bag_item.raw_data = { "id" => "the_beatdown" } + end + + it "should return an object name based on the bag name and the raw_data id" do + @data_bag_item.object_name.should == "data_bag_item_dreams_the_beatdown" + end + end + + describe "class method object_name" do + it "should return an object name based based on the bag name and an id" do + Chef::DataBagItem.object_name("zen", "master").should == "data_bag_item_zen_master" + end + end + + describe "when used like a Hash" do + before(:each) do + @data_bag_item.raw_data = { "id" => "journey", "trials" => "been through" } + end + + it "responds to keys" do + @data_bag_item.keys.should include("id") + @data_bag_item.keys.should include("trials") + end + + it "supports element reference with []" do + @data_bag_item["id"].should == "journey" + end + + it "implements all the methods of Hash" do + methods = [:rehash, :to_hash, :[], :fetch, :[]=, :store, :default, + :default=, :default_proc, :index, :size, :length, + :empty?, :each_value, :each_key, :each_pair, :each, :keys, :values, + :values_at, :delete, :delete_if, :reject!, :clear, + :invert, :update, :replace, :merge!, :merge, :has_key?, :has_value?, + :key?, :value?] + methods.each do |m| + @data_bag_item.should respond_to(m) + end + end + + end + + describe "to_hash" do + before(:each) do + @data_bag_item.data_bag("still_lost") + @data_bag_item.raw_data = { "id" => "whoa", "i_know" => "kung_fu" } + @to_hash = @data_bag_item.to_hash + end + + it "should return a hash" do + @to_hash.should be_a_kind_of(Hash) + end + + it "should have the raw_data keys as top level keys" do + @to_hash["id"].should == "whoa" + @to_hash["i_know"].should == "kung_fu" + end + + it "should have the chef_type of data_bag_item" do + @to_hash["chef_type"].should == "data_bag_item" + end + + it "should have the data_bag set" do + @to_hash["data_bag"].should == "still_lost" + end + end + + describe "when deserializing from JSON" do + before(:each) do + @data_bag_item.data_bag('mars_volta') + @data_bag_item.raw_data = { "id" => "octahedron", "snooze" => { "finally" => :world_will }} + @deserial = Chef::JSONCompat.from_json(@data_bag_item.to_json) + end + + it "should deserialize to a Chef::DataBagItem object" do + @deserial.should be_a_kind_of(Chef::DataBagItem) + end + + it "should have a matching 'data_bag' value" do + @deserial.data_bag.should == @data_bag_item.data_bag + end + + it "should have a matching 'id' key" do + @deserial["id"].should == "octahedron" + end + + it "should have a matching 'snooze' key" do + @deserial["snooze"].should == { "finally" => "world_will" } + end + end + + describe "when converting to a string" do + it "converts to a string in the form data_bag_item[ID]" do + @data_bag_item['id'] = "heart of darkness" + @data_bag_item.to_s.should == 'data_bag_item[heart of darkness]' + end + + it "inspects as data_bag_item[BAG, ID, RAW_DATA]" do + raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"} + @data_bag_item.raw_data = raw_data + @data_bag_item.data_bag("books") + + @data_bag_item.inspect.should == "data_bag_item[\"books\", \"heart_of_darkness\", #{raw_data.inspect}]" + end + end + + describe "save" do + before do + @rest = mock("Chef::REST") + Chef::REST.stub!(:new).and_return(@rest) + @data_bag_item['id'] = "heart of darkness" + raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"} + @data_bag_item.raw_data = raw_data + @data_bag_item.data_bag("books") + end + it "should update the item when it already exists" do + @rest.should_receive(:put_rest).with("data/books/heart_of_darkness", @data_bag_item) + @data_bag_item.save + end + + it "should create if the item is not found" do + exception = mock("404 error", :code => "404") + @rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception)) + @rest.should_receive(:post_rest).with("data/books", @data_bag_item) + @data_bag_item.save + end + describe "when whyrun mode is enabled" do + before do + Chef::Config[:why_run] = true + end + after do + Chef::Config[:why_run] = false + end + it "should not save" do + @rest.should_not_receive(:put_rest) + @rest.should_not_receive(:post_rest) + @data_bag_item.data_bag("books") + @data_bag_item.save + end + end + + + end + + describe "when loading" do + before do + @data_bag_item.raw_data = {"id" => "charlie", "shell" => "zsh", "ssh_keys" => %w{key1 key2}} + @data_bag_item.data_bag("users") + end + + describe "from an API call" do + before do + @http_client = mock("Chef::REST") + Chef::REST.stub!(:new).and_return(@http_client) + end + + it "converts raw data to a data bag item" do + @http_client.should_receive(:get_rest).with("data/users/charlie").and_return(@data_bag_item.to_hash) + item = Chef::DataBagItem.load(:users, "charlie") + item.should be_a_kind_of(Chef::DataBagItem) + item.should == @data_bag_item + end + + it "does not convert when a DataBagItem is returned from the API call" do + @http_client.should_receive(:get_rest).with("data/users/charlie").and_return(@data_bag_item) + item = Chef::DataBagItem.load(:users, "charlie") + item.should be_a_kind_of(Chef::DataBagItem) + item.should equal(@data_bag_item) + end + end + + describe "in solo mode" do + before do + Chef::Config[:solo] = true + end + + after do + Chef::Config[:solo] = false + end + + it "converts the raw data to a data bag item" do + Chef::DataBag.should_receive(:load).with('users').and_return({'charlie' => @data_bag_item.to_hash}) + item = Chef::DataBagItem.load('users', 'charlie') + item.should be_a_kind_of(Chef::DataBagItem) + item.should == @data_bag_item + end + end + + end + +end |