summaryrefslogtreecommitdiff
path: root/spec/unit/data_bag_item_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/data_bag_item_spec.rb')
-rw-r--r--spec/unit/data_bag_item_spec.rb280
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