spice 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/.DS_Store +0 -0
  2. data/.document +0 -0
  3. data/.gitignore +5 -0
  4. data/.rspec +1 -1
  5. data/CHANGELOG.md +16 -0
  6. data/Gemfile +0 -0
  7. data/Gemfile.lock +2 -5
  8. data/LICENSE.txt +0 -0
  9. data/Notes.md +0 -0
  10. data/README.md +2 -2
  11. data/Rakefile +0 -0
  12. data/TODO.md +2 -2
  13. data/features/spice.feature +0 -0
  14. data/features/step_definitions/spice_steps.rb +0 -0
  15. data/features/support/env.rb +0 -0
  16. data/file.txt +0 -0
  17. data/lib/spice/authentication.rb +0 -0
  18. data/lib/spice/chef.rb +0 -15
  19. data/lib/spice/client.rb +3 -3
  20. data/lib/spice/connection.rb +34 -26
  21. data/lib/spice/cookbook.rb +0 -0
  22. data/lib/spice/data_bag.rb +103 -4
  23. data/{spec/support/authentication.rb → lib/spice/mock.rb} +17 -14
  24. data/lib/spice/node.rb +0 -0
  25. data/lib/spice/role.rb +0 -0
  26. data/lib/spice/version.rb +1 -1
  27. data/lib/spice.rb +8 -0
  28. data/pkg/spice-0.0.1.alpha.1.gem +0 -0
  29. data/spec/spec_helper.rb +2 -0
  30. data/spec/spice/authentication_spec.rb +0 -0
  31. data/spec/spice/chef_spec.rb +1 -1
  32. data/spec/spice/client_spec.rb +4 -4
  33. data/spec/spice/connection_spec.rb +0 -0
  34. data/spec/spice/cookbook_spec.rb +91 -14
  35. data/spec/spice/data_bag_spec.rb +151 -8
  36. data/spec/spice/node_spec.rb +0 -29
  37. data/spec/spice/role_spec.rb +1 -29
  38. data/spec/spice_spec.rb +0 -0
  39. data/spec/support/client_requests.rb +97 -0
  40. data/spec/support/cookbook_requests.rb +172 -0
  41. data/spec/support/data_bag_item_requests.rb +138 -0
  42. data/spec/support/data_bag_requests.rb +95 -0
  43. data/spec/support/respond_with_matcher.rb +53 -0
  44. data/spec/support/vcr.rb +0 -0
  45. data/spice.gemspec +0 -0
  46. metadata +16 -5
data/.DS_Store ADDED
Binary file
data/.document CHANGED
File without changes
data/.gitignore CHANGED
@@ -1 +1,6 @@
1
1
  pkg/*
2
+ examples/*
3
+ doc/*
4
+ doc/**/*
5
+ .yardoc/**/*
6
+ .yardoc/*
data/.rspec CHANGED
@@ -1 +1 @@
1
- --color
1
+ --color --format doc
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Release Notes - Spice - Version 0.3.0
2
+
3
+ ## Bug
4
+
5
+ * N/A
6
+
7
+ ## Improvement
8
+
9
+ * Improved specification of DataBag class
10
+ * Added additional documentation to DataBag class
11
+ * Add CHANGELOG
12
+
13
+ ## New Feature
14
+
15
+ * Data bag items can now be created
16
+
data/Gemfile CHANGED
File without changes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spice (0.0.2.beta)
4
+ spice (0.2.0)
5
5
  mixlib-authentication
6
6
  rest-client
7
7
  yajl-ruby
@@ -43,7 +43,7 @@ GEM
43
43
  webmock (1.6.1)
44
44
  addressable (>= 2.2.2)
45
45
  crack (>= 0.1.7)
46
- yajl-ruby (0.7.8)
46
+ yajl-ruby (0.7.9)
47
47
  yard (0.6.4)
48
48
 
49
49
  PLATFORMS
@@ -51,12 +51,9 @@ PLATFORMS
51
51
 
52
52
  DEPENDENCIES
53
53
  cucumber (~> 0.10.0)
54
- mixlib-authentication
55
54
  rcov
56
- rest-client
57
55
  rspec (~> 2.4.0)
58
56
  spice!
59
57
  timecop (~> 0.3.5)
60
58
  webmock (~> 1.6.1)
61
- yajl-ruby
62
59
  yard (~> 0.6.4)
data/LICENSE.txt CHANGED
File without changes
data/Notes.md CHANGED
File without changes
data/README.md CHANGED
@@ -4,9 +4,9 @@ Spice is a zesty Chef API wrapper. It's primary purpose is to let you easily int
4
4
 
5
5
  ## Installation
6
6
 
7
- Install this beast via Rubygems (note that for now, you'll need the --pre flag until I deem it to be perfectly stable):
7
+ Install this beast via Rubygems:
8
8
 
9
- gem install spice --pre
9
+ gem install spice
10
10
 
11
11
  Of course, You can always grab the source from http://github.com/danryan/spice.
12
12
 
data/Rakefile CHANGED
File without changes
data/TODO.md CHANGED
@@ -1,2 +1,2 @@
1
- * Allow configurable variables instead of relying on class variables
2
- * Refactor classes that inherity from Spice::Chef to take config values
1
+ * Refactor classes that inherit from Spice::Chef to take config values
2
+ * Add support for data bag item creation
File without changes
File without changes
File without changes
data/file.txt CHANGED
File without changes
File without changes
data/lib/spice/chef.rb CHANGED
@@ -2,21 +2,6 @@ module Spice
2
2
  class Chef
3
3
  attr_accessor :client_name, :key_file, :connection
4
4
 
5
- # def initialize(options={})
6
- # @client_name = options[:client_name] || Spice.client_name
7
- # @key_file = options[:key_file] || Spice.key_file
8
- # @host = options[:host] || Spice.host
9
- # @port = options[:port] || Spice.port
10
- # @scheme = options[:scheme] || Spice.scheme
11
- # # @connection = Connection.new(
12
- # # :url => "#{@scheme}://#{@host}:#{@port}",
13
- # # :client_name => options[:client_name],
14
- # # :key_file => options[:key_file]
15
- # # ) || Spice.connection
16
- # @connection = Spice.connection
17
- # @sign_on_redirect, @sign_request = true, true
18
- # end
19
-
20
5
  def self.connection
21
6
  @connection ||= Spice.connection
22
7
  end
data/lib/spice/client.rb CHANGED
@@ -24,19 +24,19 @@ module Spice
24
24
 
25
25
  def self.create(options={})
26
26
  raise ArgumentError, "Option :name must be present" unless options[:name]
27
- connection.post("/clients", options)
27
+ connection.post("/clients", payload, options)
28
28
  end
29
29
 
30
30
  def self.update(options={})
31
31
  raise ArgumentError, "Option :name must be present" unless options[:name]
32
32
  name = options.delete(:name)
33
- connection.put("/clients/#{name}", options)
33
+ connection.put("/clients/#{name}", payload, options)
34
34
  end
35
35
 
36
36
  def self.delete(options={})
37
37
  raise ArgumentError, "Option :name must be present" unless options[:name]
38
38
  name = options.delete(:name)
39
- connection.delete("/clients/#{name}", options)
39
+ connection.delete("/clients/#{name}", payload, options)
40
40
  end
41
41
  end
42
42
  end
@@ -17,41 +17,49 @@ module Spice
17
17
  end
18
18
 
19
19
  def get(path, headers={})
20
- response = RestClient::Request.execute(
21
- :method => :GET,
22
- :url => "#{@url}#{path}",
23
- :headers => build_headers(:GET, path, headers)
24
- )
25
- JSON.parse(response)
20
+ begin
21
+ RestClient.get(
22
+ "#{@url}#{path}",
23
+ build_headers(:GET, path, headers)
24
+ )
25
+ rescue => e
26
+ e.response
27
+ end
26
28
  end
27
29
 
28
30
  def post(path, payload, headers={})
29
- response = RestClient::Request.execute(
30
- :method => :POST,
31
- :url => "#{@url}#{path}",
32
- :headers => build_headers(:POST, path, headers, JSON.generate(payload)),
33
- :payload => JSON.generate(payload)
34
- )
35
- JSON.parse(response)
31
+ begin
32
+ RestClient.post(
33
+ "#{@url}#{path}",
34
+ JSON.generate(payload),
35
+ build_headers(:POST, path, headers, JSON.generate(payload))
36
+ )
37
+ rescue => e
38
+ e.response
39
+ end
36
40
  end
37
41
 
38
42
  def put(path, payload, headers={})
39
- response = RestClient::Request.execute(
40
- :method => :PUT,
41
- :url => "#{@url}#{path}",
42
- :headers => build_headers(:PUT, path, headers, JSON.generate(payload)),
43
- :payload => JSON.generate(payload)
44
- )
45
- JSON.parse(response)
43
+ begin
44
+ RestClient.put(
45
+ "#{@url}#{path}",
46
+ JSON.generate(payload),
47
+ build_headers(:PUT, path, headers, JSON.generate(payload))
48
+ )
49
+ rescue => e
50
+ e.response
51
+ end
46
52
  end
47
53
 
48
54
  def delete(path, headers={})
49
- response = RestClient::Request.execute(
50
- :method => :DELETE,
51
- :url => "#{@url}#{path}",
52
- :headers => build_headers(:DELETE, path, headers)
53
- )
54
- JSON.parse(response)
55
+ begin
56
+ RestClient.delete(
57
+ "#{@url}#{path}",
58
+ build_headers(:DELETE, path, headers)
59
+ )
60
+ rescue => e
61
+ e.response
62
+ end
55
63
  end
56
64
 
57
65
  def sign_requests?
File without changes
@@ -1,33 +1,132 @@
1
1
  module Spice
2
2
  class DataBag < Spice::Chef
3
+ # Get a list of all data bags in the following syntax
4
+ # Spice::DataBag.all
5
+ #
6
+ # @param [Hash] options the options hash. Currently does nothing
3
7
  def self.all(options={})
4
8
  connection.get("/data")
5
9
  end
6
10
 
11
+ # An alternative format for showing the contents of a data bag
12
+ # @example Retrieve the id and uri of items in a data bag called "users"
13
+ # Spice::DataBag["users"] # => {"adam":"http://localhost:4000/data/users/adam"}
7
14
  def self.[](name)
8
15
  connection.get("/data/#{name}")
9
16
  end
10
17
 
18
+ # Show the contents of a data bag
19
+ # @example Retrieve the id and uri of items in a data bag called "users"
20
+ # Spice::DataBag.show(:name => "users") # => {"adam":"http://localhost:4000/data/users/adam"}
21
+ #
22
+ # @param [Hash] options The options hash
23
+ # @option options [String] :name The name of your data bag
11
24
  def self.show(options={})
12
25
  raise ArgumentError, "Option :name must be present" unless options[:name]
13
26
  name = options.delete(:name)
14
27
  connection.get("/data/#{name}")
15
28
  end
16
29
 
30
+ # Create a a new data bag
31
+ #
32
+ # @example
33
+ # Spice::DataBag.create(:name => "users")
34
+ #
35
+ # @param [Hash] options the options hash from which to create a data bag
36
+ # @option options [String] :name The name of your data bag
37
+
17
38
  def self.create(options={})
18
39
  connection.post("/data", options)
19
40
  end
41
+
42
+ # Delete a data bag
43
+ #
44
+ # @example
45
+ # Spice::DataBag.delete(:name => "users")
46
+ #
47
+ # @param [Hash] options the options hash from which to delete a data bag
48
+ # @option options [String] :name The name of your data bag
49
+
50
+ def self.delete(options={})
51
+ raise ArgumentError, "Option :name must be present" unless options[:name]
52
+ name = options.delete(:name)
53
+ connection.delete("/data/#{name}", options)
54
+ end
55
+
56
+ # Shows a data bag item
57
+ #
58
+ # @example
59
+ # Spice::DataBag.show_item(:name => "users", :id => "adam")
60
+ #
61
+ # @param [Hash] options the options hash from which to create a data bag
62
+ # @option options [String] :name The name of your data bag
63
+ # @option options [String] :id The id of the data bag item
20
64
 
21
- def self.update(options={})
65
+ def self.show_item(options={})
22
66
  raise ArgumentError, "Option :name must be present" unless options[:name]
67
+ raise ArgumentError, "Option :id must be present" unless options[:id]
23
68
  name = options.delete(:name)
24
- connection.put("/data/#{name}", options)
69
+ id = options.delete(:id)
70
+ connection.get("/data/#{name}/#{id}", options)
25
71
  end
26
72
 
27
- def self.delete(options={})
73
+ # Creates a data bag item
74
+ #
75
+ # @example
76
+ # Spice::DataBag.create_item(:name => "users", :id => "adam", :title => "Supreme Awesomer")
77
+ #
78
+ # @param [Hash] options the options hash from which to create a data bag
79
+ # @option options [String] :name The name of your data bag
80
+ # @option options [String] :id The id of the data bag item
81
+ #
82
+ # Any additional keys in the options hash will be used as attributes
83
+ # to be stored in the data bag item
84
+
85
+ def self.create_item(options={})
28
86
  raise ArgumentError, "Option :name must be present" unless options[:name]
87
+ raise ArgumentError, "Option :id must be present" unless options[:id]
29
88
  name = options.delete(:name)
30
- connection.delete("/data/#{name}", options)
89
+ connection.post("/data/#{name}", options)
90
+
91
+ end
92
+
93
+ # Update a data bag item
94
+ #
95
+ # @example
96
+ # Spice::DataBag.update_item(:name => "users", :id => "adam", :title => "Supreme Awesomer")
97
+ #
98
+ # @param [Hash] options the options hash from which to update a data bag
99
+ # @option options [String] :name The name of your data bag
100
+ # @option options [String] :id The id of the data bag item
101
+ #
102
+ # Any additional keys in the options hash will be used as attributes
103
+ # to be stored in the data bag item
104
+
105
+ def self.update_item(options={})
106
+ raise ArgumentError, "Option :name must be present" unless options[:name]
107
+ raise ArgumentError, "Option :id must be present" unless options[:id]
108
+ name = options.delete(:name)
109
+ id = options.delete(:id)
110
+ connection.put("/data/#{name}/#{id}", options)
111
+ end
112
+
113
+ # Delete a data bag item
114
+ #
115
+ # @example
116
+ # Spice::DataBag.delete_item(:name => "users", :id => "adam")
117
+ #
118
+ # @param [Hash] options the options hash from which to delete a data bag
119
+ # @option options [String] :name The name of your data bag
120
+ # @option options [String] :id The id of the data bag item
121
+ #
122
+
123
+ def self.delete_item(options={})
124
+ raise ArgumentError, "Option :name must be present" unless options[:name]
125
+ raise ArgumentError, "Option :id must be present" unless options[:id]
126
+ name = options.delete(:name)
127
+ id = options.delete(:id)
128
+ connection.delete("/data/#{name}/#{id}", options)
129
+
31
130
  end
32
131
  end
33
132
  end
@@ -1,16 +1,17 @@
1
- require 'spec_helper'
1
+ module Spice
2
+ class Mock
3
+ class << self
4
+ def setup_mock_client
5
+ self.setup_authentication
6
+ Spice.host = 'localhost'
7
+ Spice.client_name = "testclient"
8
+ Spice.key_file = "/tmp/keyfile.pem"
9
+ Spice.connect!
10
+ end
2
11
 
3
- def setup_chef_client
4
- setup_authentication
5
- Spice.host = 'localhost'
6
- Spice.client_name = "testclient"
7
- Spice.key_file = "/tmp/keyfile.pem"
8
- Spice.connect!
9
- end
10
-
11
- def setup_authentication
12
- File.open("/tmp/keyfile.pem","w+") do |f|
13
- f.write(%Q{-----BEGIN RSA PRIVATE KEY-----
12
+ def setup_authentication
13
+ File.open("/tmp/keyfile.pem","w+") do |f|
14
+ f.write(%Q{-----BEGIN RSA PRIVATE KEY-----
14
15
  MIIEowIBAAKCAQEAqd1K3siOLkxiU0B98QzP+qbT3uPaCIGGR+EAO8mXMpTUNfPv
15
16
  Kr4NeIV8kqfrngghYF3Y2Ky0e3Ifl3b7UQTfrSofmyoC/EBBA4dH2ygUoYtP0aIi
16
17
  sdxnSpYhX9PXavZ4POkDuO3SKRUEuC71OzIQQ3GijXA8L1JRBTOb0QiC7vBSuwaM
@@ -37,6 +38,8 @@ mZ2vo9R9MYFQe8sv1sHwENk0zby+44afVjt5IkElFC1IWBkcKte99T+POXzu3lyb
37
38
  5h0uCkb5FfgWIOq2tCUYY/ZrSglE17wPmd8iRAN7wb+prKAHOh+o4P0k1EtviNdU
38
39
  8JgshucQzoeIygNfo2QG3vfsfA/4V9aa/yb/bqHPsJHBgnuSVjv+
39
40
  -----END RSA PRIVATE KEY-----})
41
+ end
42
+ end
43
+ end
40
44
  end
41
- end
42
-
45
+ end
data/lib/spice/node.rb CHANGED
File without changes
data/lib/spice/role.rb CHANGED
File without changes
data/lib/spice/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Spice
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/spice.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'bundler'
2
2
  Bundler.require
3
3
 
4
+ require 'rest-client'
4
5
  require 'spice/authentication'
5
6
  require 'spice/chef'
6
7
  require 'spice/role'
@@ -11,7 +12,10 @@ require 'spice/data_bag'
11
12
  require 'spice/node'
12
13
  require 'spice/connection'
13
14
 
15
+ require 'spice/mock'
16
+
14
17
  module Spice
18
+
15
19
  class << self
16
20
  attr_writer :host, :port, :scheme, :client_name, :connection, :key_file, :raw_key
17
21
 
@@ -85,6 +89,10 @@ module Spice
85
89
  yield self
86
90
  end
87
91
 
92
+ def mock
93
+ Spice::Mock.setup_mock_client
94
+ end
95
+
88
96
  private
89
97
 
90
98
  def assert_valid_key_format!(raw_key)
File without changes
data/spec/spec_helper.rb CHANGED
@@ -6,6 +6,7 @@ Bundler.require
6
6
  require 'rspec'
7
7
  require 'webmock/rspec'
8
8
  require 'timecop'
9
+ require 'rest-client'
9
10
  require 'spice'
10
11
 
11
12
  # Requires supporting files with custom matchers and macros, etc,
@@ -15,6 +16,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
15
16
  RSpec.configure do |config|
16
17
  config.before do
17
18
  Timecop.freeze
19
+ Spice.mock
18
20
  end
19
21
  config.after do
20
22
  Timecop.return
File without changes
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module Spice
4
4
  describe Chef do
5
5
  describe '.connection' do
6
- before { setup_chef_client }
6
+ before { }
7
7
  it "returns an instance of Spice::Connection" do
8
8
  Spice::Chef.connection.should be_an_instance_of(Spice::Connection)
9
9
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module Spice
4
4
  describe Client do
5
5
  describe ".all" do
6
- before { setup_chef_client }
6
+ before { }
7
7
 
8
8
  it "returns a list of clients" do
9
9
  stub_client_list
@@ -38,7 +38,7 @@ module Spice
38
38
  end
39
39
 
40
40
  describe ".create" do
41
- before { setup_chef_client }
41
+ before { }
42
42
 
43
43
  context "valid" do
44
44
  it "creates a valid non-admin client" do
@@ -70,7 +70,7 @@ module Spice
70
70
  end
71
71
 
72
72
  describe ".update" do
73
- before { setup_chef_client }
73
+ before { }
74
74
 
75
75
  context "valid" do
76
76
  it "makes a client an admin" do
@@ -86,7 +86,7 @@ module Spice
86
86
  end
87
87
 
88
88
  describe ".delete" do
89
- before { setup_chef_client }
89
+ before { }
90
90
 
91
91
  context "valid" do
92
92
  it "deletes a client" do
File without changes
@@ -3,32 +3,109 @@ require 'spec_helper'
3
3
  module Spice
4
4
  describe Cookbook do
5
5
  describe ".all" do
6
- VCR.use_cassette 'cookbook/list', :record => :new_episodes do
7
- Cookbook.list
6
+ before { setup_chef_cookbook }
7
+
8
+ it "returns a list of cookbooks" do
9
+ stub_cookbook_list
10
+ Cookbook.all.length.should == 1
8
11
  end
9
12
  end
10
-
13
+
11
14
  describe ".show" do
12
- VCR.use_cassette 'cookbook/show', :record => :new_episodes do
13
- Cookbook.show(:name => "testcookbook")
15
+ before { setup_chef_cookbook }
16
+
17
+ context "valid" do
18
+ it "returns a valid cookbook" do
19
+ stub_cookbook_show("monkeypants")
20
+ cookbook = Cookbook.show(:name => "monkeypants")
21
+ cookbook["name"].should == "monkeypants"
22
+ cookbook["admin"].should == true
23
+ end
24
+ end
25
+
26
+ context "errors" do
27
+ it "return a 404 when a cookbook is not found" do
28
+ stub_cookbook_show("applesauce", 404)
29
+ lambda { Cookbook.show(:name => "applesauce") }.
30
+ should raise_error(RestCookbook::ResourceNotFound)
31
+ end
32
+
33
+ it "raises ArgumentError if option :name not present" do
34
+ stub_cookbook_show("pizza")
35
+ lambda {Cookbook.show() }.should raise_error ArgumentError
36
+ end
14
37
  end
15
38
  end
16
-
39
+
17
40
  describe ".create" do
18
- VCR.use_cassette 'cookbook/create', :record => :new_episodes do
19
- Cookbook.create(:name => "testcookbook")
41
+ before { setup_chef_cookbook }
42
+
43
+ context "valid" do
44
+ it "creates a valid non-admin cookbook" do
45
+ stub_cookbook_create("spork")
46
+ cookbook = Cookbook.create(:name => "spork", :admin => false)
47
+ cookbook["private_key"].should == "RSA PRIVATE KEY"
48
+ cookbook["uri"].should == "http://http://localhost:4000/cookbooks/spork"
49
+ end
50
+
51
+ it "creates a valid admin cookbook" do
52
+ stub_cookbook_create("pants", true)
53
+ response = Cookbook.create(:name => "pants", :admin => true)
54
+ response["private_key"].should == "RSA PRIVATE KEY"
55
+ response["uri"].should == "http://http://localhost:4000/cookbooks/pants"
56
+
57
+ stub_cookbook_show("pants")
58
+ cookbook = Cookbook.show(:name => "pants")
59
+ cookbook["admin"].should == true
60
+ end
61
+ end
62
+
63
+ context "errors" do
64
+ it "does not create a cookbook that already exists" do
65
+ stub_cookbook_create("pants", false, 409)
66
+ lambda { Cookbook.create(:name => "pants", :admin => false) }.
67
+ should raise_error(RestCookbook::Conflict)
68
+ end
20
69
  end
21
70
  end
22
-
71
+
23
72
  describe ".update" do
24
- VCR.use_cassette 'cookbook/update', :record => :new_episodes do
25
- Cookbook.update(:name => "testcookbook")
73
+ before { setup_chef_cookbook }
74
+
75
+ context "valid" do
76
+ it "makes a cookbook an admin" do
77
+ stub_cookbook_update("awesome", true, false, 200)
78
+ Cookbook.update(:name => "awesome", :admin => true, :private_key => false)
79
+ end
80
+
81
+ it "regenerates the cookbook private key" do
82
+ stub_cookbook_update("awesome", false, true, 200)
83
+ Cookbook.update(:name => "awesome", :admin => false, :private_key => true)
84
+ end
26
85
  end
27
86
  end
28
-
87
+
29
88
  describe ".delete" do
30
- VCR.use_cassette 'cookbook/delete', :record => :new_episodes do
31
- Cookbook.delete(:name => "testcookbook")
89
+ before { setup_chef_cookbook }
90
+
91
+ context "valid" do
92
+ it "deletes a cookbook" do
93
+ stub_cookbook_delete("spork")
94
+ Cookbook.delete(:name => "spork")
95
+ end
96
+ end
97
+
98
+ context "errors" do
99
+ it "raises ArgumentError if option :name not present" do
100
+ stub_cookbook_delete("pizza")
101
+ lambda {Cookbook.delete }.should raise_error ArgumentError
102
+ end
103
+
104
+ it "does not delete a non-existent cookbook" do
105
+ stub_cookbook_delete("spork", 404)
106
+ lambda { Cookbook.delete(:name => "spork") }.
107
+ should raise_error(RestCookbook::ResourceNotFound)
108
+ end
32
109
  end
33
110
  end
34
111
  end