ridley 0.10.2 → 0.11.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/README.md +147 -216
  2. data/lib/ridley.rb +2 -0
  3. data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +21 -25
  4. data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +29 -34
  5. data/lib/ridley/bootstrapper.rb +2 -2
  6. data/lib/ridley/bootstrapper/context.rb +5 -5
  7. data/lib/ridley/chef.rb +0 -1
  8. data/lib/ridley/chef/cookbook.rb +0 -9
  9. data/lib/ridley/chef_object.rb +128 -0
  10. data/lib/ridley/chef_objects.rb +3 -0
  11. data/lib/ridley/chef_objects/client_object.rb +55 -0
  12. data/lib/ridley/chef_objects/cookbook_object.rb +190 -0
  13. data/lib/ridley/chef_objects/data_bag_item_obect.rb +104 -0
  14. data/lib/ridley/chef_objects/data_bag_object.rb +31 -0
  15. data/lib/ridley/chef_objects/environment_object.rb +59 -0
  16. data/lib/ridley/chef_objects/node_object.rb +161 -0
  17. data/lib/ridley/chef_objects/role_object.rb +62 -0
  18. data/lib/ridley/chef_objects/sandbox_object.rb +58 -0
  19. data/lib/ridley/client.rb +76 -45
  20. data/lib/ridley/connection.rb +1 -1
  21. data/lib/ridley/errors.rb +8 -1
  22. data/lib/ridley/host_connector.rb +26 -6
  23. data/lib/ridley/host_connector/ssh.rb +3 -3
  24. data/lib/ridley/host_connector/ssh/worker.rb +7 -9
  25. data/lib/ridley/host_connector/winrm/worker.rb +4 -5
  26. data/lib/ridley/mixin/bootstrap_binding.rb +1 -12
  27. data/lib/ridley/resource.rb +51 -171
  28. data/lib/ridley/resources/client_resource.rb +18 -68
  29. data/lib/ridley/resources/cookbook_resource.rb +181 -381
  30. data/lib/ridley/resources/data_bag_item_resource.rb +55 -161
  31. data/lib/ridley/resources/data_bag_resource.rb +20 -61
  32. data/lib/ridley/resources/environment_resource.rb +9 -64
  33. data/lib/ridley/resources/node_resource.rb +135 -311
  34. data/lib/ridley/resources/role_resource.rb +1 -57
  35. data/lib/ridley/resources/sandbox_resource.rb +80 -65
  36. data/lib/ridley/resources/search_resource.rb +99 -0
  37. data/lib/ridley/sandbox_uploader.rb +12 -52
  38. data/lib/ridley/version.rb +1 -1
  39. data/spec/acceptance/bootstrapping_spec.rb +1 -1
  40. data/spec/acceptance/client_resource_spec.rb +15 -37
  41. data/spec/acceptance/data_bag_item_resource_spec.rb +8 -14
  42. data/spec/acceptance/data_bag_resource_spec.rb +1 -1
  43. data/spec/acceptance/environment_resource_spec.rb +13 -22
  44. data/spec/acceptance/node_resource_spec.rb +10 -29
  45. data/spec/acceptance/role_resource_spec.rb +14 -13
  46. data/spec/acceptance/sandbox_resource_spec.rb +2 -2
  47. data/spec/support/shared_examples/ridley_resource.rb +2 -23
  48. data/spec/unit/ridley/bootstrap_bindings/unix_template_binding_spec.rb +3 -4
  49. data/spec/unit/ridley/bootstrap_bindings/windows_template_binding_spec.rb +3 -5
  50. data/spec/unit/ridley/bootstrapper/context_spec.rb +2 -3
  51. data/spec/unit/ridley/bootstrapper_spec.rb +1 -1
  52. data/spec/unit/ridley/chef_object_spec.rb +240 -0
  53. data/spec/unit/ridley/chef_objects/client_object_spec.rb +11 -0
  54. data/spec/unit/ridley/chef_objects/cookbook_object_spec.rb +93 -0
  55. data/spec/unit/ridley/chef_objects/data_bag_item_object_spec.rb +74 -0
  56. data/spec/unit/ridley/chef_objects/data_bag_object_spec.rb +9 -0
  57. data/spec/unit/ridley/chef_objects/environment_object_spec.rb +57 -0
  58. data/spec/unit/ridley/chef_objects/node_object_spec.rb +252 -0
  59. data/spec/unit/ridley/chef_objects/role_object_spec.rb +57 -0
  60. data/spec/unit/ridley/chef_objects/sandbox_object_spec.rb +66 -0
  61. data/spec/unit/ridley/client_spec.rb +51 -51
  62. data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +4 -4
  63. data/spec/unit/ridley/host_connector/ssh_spec.rb +26 -24
  64. data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +3 -4
  65. data/spec/unit/ridley/host_connector/winrm_spec.rb +4 -4
  66. data/spec/unit/ridley/host_connector_spec.rb +40 -3
  67. data/spec/unit/ridley/mixin/bootstrap_binding_spec.rb +1 -1
  68. data/spec/unit/ridley/resource_spec.rb +81 -109
  69. data/spec/unit/ridley/resources/client_resource_spec.rb +18 -33
  70. data/spec/unit/ridley/resources/cookbook_resource_spec.rb +56 -230
  71. data/spec/unit/ridley/resources/data_bag_item_resource_spec.rb +2 -57
  72. data/spec/unit/ridley/resources/data_bag_resource_spec.rb +12 -7
  73. data/spec/unit/ridley/resources/environment_resource_spec.rb +10 -118
  74. data/spec/unit/ridley/resources/node_resource_spec.rb +83 -394
  75. data/spec/unit/ridley/resources/role_resource_spec.rb +2 -56
  76. data/spec/unit/ridley/resources/sandbox_resource_spec.rb +139 -136
  77. data/spec/unit/ridley/resources/search_resource_spec.rb +234 -0
  78. data/spec/unit/ridley/sandbox_uploader_spec.rb +13 -58
  79. metadata +36 -17
  80. data/lib/ridley/chef/chefignore.rb +0 -76
  81. data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +0 -55
  82. data/lib/ridley/resources/search.rb +0 -101
  83. data/spec/fixtures/chefignore +0 -8
  84. data/spec/unit/ridley/chef/chefignore_spec.rb +0 -40
  85. data/spec/unit/ridley/resources/search_spec.rb +0 -221
@@ -7,7 +7,7 @@ describe Ridley::BootstrapBinding do
7
7
  server_url: "https://api.opscode.com/organizations/vialstudios",
8
8
  validator_client: "chef-validator",
9
9
  validator_path: fixtures_path.join("reset.pem").to_s,
10
- encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s,
10
+ encrypted_data_bag_secret: File.read(fixtures_path.join("reset.pem")),
11
11
  chef_version: "11.4.0"
12
12
  }
13
13
  end
@@ -1,33 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::Resource do
4
- let(:connection) { double('connection') }
5
-
6
- describe "ClassMethods" do
7
- subject do
8
- Class.new(Ridley::Resource)
4
+ let(:representation) do
5
+ Class.new(Ridley::ChefObject) do
6
+ set_chef_id "id"
7
+ set_chef_type "thing"
8
+ set_chef_json_class "Chef::Thing"
9
9
  end
10
+ end
10
11
 
11
- it_behaves_like "a Ridley Resource", Class.new(Ridley::Resource)
12
-
13
- describe "::initialize" do
14
- it "mass assigns the given attributes" do
15
- new_attrs = {
16
- name: "a name"
17
- }
18
-
19
- subject.any_instance.should_receive(:mass_assign).with(new_attrs)
20
- subject.new(connection, new_attrs)
21
- end
12
+ let(:resource_class) do
13
+ Class.new(Ridley::Resource) do
14
+ set_resource_path "rspecs"
22
15
  end
16
+ end
23
17
 
24
- describe "::set_chef_type" do
25
- it "sets the chef_type attr on the class" do
26
- subject.set_chef_type("environment")
27
-
28
- subject.chef_type.should eql("environment")
29
- end
30
- end
18
+ describe "ClassMethods" do
19
+ subject { resource_class }
31
20
 
32
21
  describe "::set_resource_path" do
33
22
  it "sets the resource_path attr on the class" do
@@ -37,126 +26,109 @@ describe Ridley::Resource do
37
26
  end
38
27
  end
39
28
 
40
- describe "::set_chef_json_class" do
41
- it "sets the chef_json_class attr on the class" do
42
- subject.set_chef_json_class("Chef::Environment")
43
-
44
- subject.chef_json_class.should eql("Chef::Environment")
45
- end
46
- end
47
-
48
- describe "::set_chef_id" do
49
- it "sets the chef_id attribute on the class" do
50
- subject.set_chef_id(:environment)
51
-
52
- subject.chef_id.should eql(:environment)
53
- end
54
- end
55
-
56
29
  describe "::resource_path" do
57
- it "returns the underscored and plural name of the including class if nothing is set" do
58
- subject.resource_path.should eql(subject.class.name.underscore.pluralize)
59
- end
60
- end
30
+ context "when not explicitly set" do
31
+ before { subject.set_resource_path(nil) }
61
32
 
62
- describe "::chef_type" do
63
- it "returns the underscored name of the including class if nothing is set" do
64
- subject.chef_type.should eql(subject.class.name.underscore)
33
+ it "returns the representation's chef type, pluralized" do
34
+ subject.resource_path.should eql(representation.chef_type.pluralize)
35
+ end
65
36
  end
66
- end
67
37
 
68
- describe "::chef_json_class" do
69
- it "returns the chef_json if nothing has been set" do
70
- subject.chef_json_class.should be_nil
71
- end
72
- end
38
+ context "when explicitly set" do
39
+ let(:set_path) { "hello" }
40
+ before { subject.set_resource_path(set_path) }
73
41
 
74
- describe "::chef_id" do
75
- it "returns nil if nothing is set" do
76
- subject.chef_id.should be_nil
42
+ it "returns the set value" do
43
+ subject.resource_path.should eql(set_path)
44
+ end
77
45
  end
78
46
  end
79
47
  end
80
48
 
81
- subject do
82
- Class.new(Ridley::Resource).new(connection)
49
+ let(:connection) { double('chef-connection') }
50
+ let(:response) { double('chef-response', body: Hash.new) }
51
+
52
+ subject { resource_class.new(double('registry')) }
53
+
54
+ before do
55
+ resource_class.stub(representation: representation)
56
+ subject.stub(connection: connection)
83
57
  end
84
58
 
85
- describe "comparable" do
86
- subject do
87
- Class.new(Ridley::Resource) do
88
- set_chef_id "name"
59
+ describe "::all" do
60
+ it "sends GET to /{resource_path}" do
61
+ connection.should_receive(:get).with(subject.class.resource_path).and_return(response)
89
62
 
90
- attribute "name"
91
- attribute "other_extra"
92
- attribute "extra"
93
- end
63
+ subject.all
94
64
  end
65
+ end
95
66
 
96
- let(:one) { subject.new(connection) }
97
- let(:two) { subject.new(connection) }
67
+ describe "::find" do
68
+ let(:id) { "some_id" }
98
69
 
99
- context "given two objects with the same value for their 'chef_id'" do
100
- before(:each) do
101
- one.mass_assign(name: "reset", other_extra: "stuff")
102
- two.mass_assign(name: "reset", extra: "stuff")
103
- end
70
+ it "sends GET to /{resource_path}/{id} where {id} is the given ID" do
71
+ connection.should_receive(:get).with("#{subject.class.resource_path}/#{id}").and_return(response)
104
72
 
105
- it "is equal" do
106
- one.should be_eql(two)
107
- end
73
+ subject.find(id)
108
74
  end
109
75
 
110
- context "given two objects with different values for their 'chef_id'" do
111
- before(:each) do
112
- one.mass_assign(name: "jamie", other_extra: "stuff")
113
- two.mass_assign(name: "winsor", extra: "stuff")
76
+ context "when the resource is not found" do
77
+ before do
78
+ connection.should_receive(:get).with("#{subject.class.resource_path}/#{id}").
79
+ and_raise(Ridley::Errors::HTTPNotFound.new({}))
114
80
  end
115
81
 
116
- it "is not equal" do
117
- one.should_not be_eql(two)
82
+ it "returns nil" do
83
+ subject.find(id).should be_nil
118
84
  end
119
85
  end
120
86
  end
121
87
 
122
- describe "uniqueness" do
123
- subject do
124
- Class.new(Ridley::Resource) do
125
- set_chef_id "name"
88
+ describe "::create" do
89
+ let(:attrs) do
90
+ {
91
+ first_name: "jamie",
92
+ last_name: "winsor"
93
+ }
94
+ end
126
95
 
127
- attribute "name"
128
- attribute "other_extra"
129
- attribute "extra"
130
- end
96
+ it "sends a post request to the given client using the includer's resource_path" do
97
+ connection.should_receive(:post).with(subject.class.resource_path, duck_type(:to_json)).and_return(response)
98
+
99
+ subject.create(attrs)
131
100
  end
101
+ end
132
102
 
133
- let(:one) { subject.new(connection) }
134
- let(:two) { subject.new(connection) }
103
+ describe "::delete" do
104
+ it "sends a delete request to the given client using the includer's resource_path for the given string" do
105
+ connection.should_receive(:delete).with("#{subject.class.resource_path}/ridley-test").and_return(response)
135
106
 
136
- context "given an array of objects with the same value for their 'chef_id'" do
137
- let(:nodes) do
138
- one.mass_assign(name: "reset", other_extra: "stuff")
139
- two.mass_assign(name: "reset", extra: "stuff")
107
+ subject.delete("ridley-test")
108
+ end
140
109
 
141
- [ one, two ]
142
- end
110
+ it "accepts an object that responds to 'chef_id'" do
111
+ object = double("obj")
112
+ object.stub(:chef_id) { "hello" }
113
+ connection.should_receive(:delete).with("#{subject.class.resource_path}/#{object.chef_id}").and_return(response)
143
114
 
144
- it "returns only one unique element" do
145
- nodes.uniq.should have(1).item
146
- end
115
+ subject.delete( object)
147
116
  end
117
+ end
148
118
 
149
- context "given an array of objects with different values for their 'chef_id'" do
150
- let(:nodes) do
151
- one.mass_assign(name: "jamie", other_extra: "stuff")
152
- two.mass_assign(name: "winsor", extra: "stuff")
119
+ describe "::delete_all" do
120
+ it "sends a delete request for every object in the collection" do
121
+ pending
122
+ end
123
+ end
153
124
 
154
- [ one, two ]
155
- end
125
+ describe "::update" do
126
+ it "sends a put request to the given client using the includer's resource_path with the given object" do
127
+ object = subject.new(name: "hello")
128
+ connection.should_receive(:put).
129
+ with("#{subject.class.resource_path}/#{object.chef_id}", duck_type(:to_json)).and_return(response)
156
130
 
157
- it "returns all of the elements" do
158
- nodes.uniq.should have(2).item
159
- end
131
+ subject.update(object)
160
132
  end
161
133
  end
162
134
  end
@@ -1,47 +1,32 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::ClientResource do
4
- it_behaves_like "a Ridley Resource", Ridley::ClientResource
4
+ subject { described_class.new(double('registry')) }
5
5
 
6
- let(:connection) { double('connection') }
7
-
8
- describe "ClassMethods" do
9
- subject { Ridley::ClientResource }
10
-
11
- describe "::regenerate_key" do
12
- let(:client) { double('client', name: "ridley-test") }
6
+ describe "#regenerate_key" do
7
+ let(:client_id) { "rspec-client" }
8
+ before { subject.stub(find: nil) }
13
9
 
14
- it "finds the given client and regenerates it's key" do
15
- client.should_receive(:regenerate_key)
16
- subject.should_receive(:find!).with(connection, "ridley-test").and_return(client)
17
-
18
- subject.regenerate_key(connection, "ridley-test")
19
- end
10
+ context "when a client with the given ID exists" do
11
+ let(:client) { double('chef-client') }
12
+ before { subject.should_receive(:find).with(client_id).and_return(client) }
20
13
 
21
- it "returns the updated client" do
22
- client.should_receive(:regenerate_key)
23
- subject.should_receive(:find!).with(connection, "ridley-test").and_return(client)
14
+ it "sets the private key to true and updates the client" do
15
+ client.should_receive(:private_key=).with(true)
16
+ subject.should_receive(:update).with(client)
24
17
 
25
- subject.regenerate_key(connection, "ridley-test").should eql(client)
18
+ subject.regenerate_key(client_id)
26
19
  end
27
20
  end
28
- end
29
-
30
- subject do
31
- Ridley::ClientResource.new(connection, name: "ridley-test", admin: false)
32
- end
33
-
34
- describe "#regenerate_key" do
35
- it "returns true if successful" do
36
- subject.should_receive(:save).and_return(true)
37
-
38
- subject.regenerate_key.should be_true
39
- end
40
21
 
41
- it "returns false if not successful" do
42
- subject.should_receive(:save).and_return(false)
22
+ context "when a client with the given ID does not exist" do
23
+ before { subject.should_receive(:find).with(client_id).and_return(nil) }
43
24
 
44
- subject.regenerate_key.should be_false
25
+ it "raises a ResourceNotFound error" do
26
+ expect {
27
+ subject.regenerate_key(client_id)
28
+ }.to raise_error(Ridley::Errors::ResourceNotFound)
29
+ end
45
30
  end
46
31
  end
47
32
  end
@@ -1,268 +1,94 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::CookbookResource do
4
- let(:client) { double('client', connection: double('connection')) }
4
+ let(:client_name) { "reset" }
5
+ let(:client_key) { fixtures_path.join('reset.pem') }
6
+ let(:connection) { double('connection') }
7
+ subject { described_class.new(double('registry'), client_name, client_key) }
8
+ before { subject.stub(connection: connection) }
5
9
 
6
- subject { described_class.new(client) }
7
-
8
- describe "ClassMethods" do
9
- subject { described_class }
10
- let(:server_url) { "https://api.opscode.com/organizations/vialstudios" }
11
- let(:client_name) { "reset" }
12
- let(:client_key) { fixtures_path.join("reset.pem") }
13
-
14
- let(:client) do
15
- Ridley.new(
16
- server_url: server_url,
17
- client_name: client_name,
18
- client_key: client_key
19
- )
20
- end
21
-
22
- describe "::all" do
23
- subject { described_class.all(client) }
24
-
25
- before(:each) do
26
- stub_request(:get, File.join(server_url, "cookbooks")).
27
- to_return(status: 200, body: {
28
- "ant" => {
29
- "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/ant",
30
- "versions" => [
31
- {
32
- "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/ant/0.10.1",
33
- "version" => "0.10.1"
34
- }
35
- ]
36
- },
37
- "apache2" => {
38
- "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/apache2",
39
- "versions" => [
40
- {
41
- "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/apache2/1.4.0",
42
- "version" => "1.4.0"
43
- }
44
- ]
45
- }
46
- }
47
- )
48
- end
49
-
50
- it "returns a Hash" do
51
- subject.should be_a(Hash)
52
- end
53
-
54
- it "contains a key for each cookbook" do
55
- subject.should include("ant")
56
- subject.should include("apache2")
57
- end
58
-
59
- it "contains an array of versions for each cookbook" do
60
- subject["ant"].should be_a(Array)
61
- subject["ant"].should have(1).item
62
- subject["ant"].should include("0.10.1")
63
- subject["apache2"].should be_a(Array)
64
- subject["apache2"].should have(1).item
65
- subject["apache2"].should include("1.4.0")
66
- end
67
- end
68
-
69
- describe "::delete" do
70
- let(:name) { "ant" }
71
- let(:version) { "1.0.0" }
72
-
73
- it "sends a DELETE to the cookbook version URL" do
74
- stub_request(:delete, File.join(server_url, "cookbooks", name, version)).
75
- to_return(status: 200, body: {})
76
-
77
- described_class.delete(client, name, version)
78
- end
79
-
80
- context "when :purge is true" do
81
- it "appends ?purge=true to the end of the URL" do
82
- stub_request(:delete, File.join(server_url, "cookbooks", name, "#{version}?purge=true")).
83
- to_return(status: 200, body: {})
84
-
85
- described_class.delete(client, name, version, purge: true)
86
- end
87
- end
88
- end
89
-
90
- describe "::delete_all" do
91
- let(:name) { "ant" }
92
- let(:versions) { ["1.0.0", "1.2.0", "2.0.0"] }
93
- let(:options) { Hash.new }
94
-
95
- subject { described_class }
96
-
97
- it "deletes each version of the cookbook" do
98
- subject.should_receive(:versions).with(client, name).and_return(versions)
10
+ describe "#download" do
11
+ pending
12
+ end
99
13
 
100
- versions.each do |version|
101
- subject.should_receive(:delete).with(client, name, version, options)
102
- end
14
+ describe "#latest_version" do
15
+ let(:name) { "ant" }
103
16
 
104
- subject.delete_all(client, name, options)
105
- end
17
+ before(:each) do
18
+ subject.should_receive(:versions).with(name).and_return(versions)
106
19
  end
107
20
 
108
- describe "::latest_version" do
109
- let(:name) { "ant" }
110
- subject { described_class }
111
-
112
- before(:each) do
113
- subject.should_receive(:versions).with(client, name).and_return(versions)
114
- end
115
-
116
- context "when the cookbook has no versions" do
117
- let(:versions) { Array.new }
118
-
119
- it "returns nil" do
120
- subject.latest_version(client, name).should be_nil
121
- end
122
- end
21
+ context "when the cookbook has no versions" do
22
+ let(:versions) { Array.new }
123
23
 
124
- context "when the cookbook has versions" do
125
- let(:versions) do
126
- [ "1.0.0", "1.2.0", "3.0.0", "1.4.1" ]
127
- end
128
-
129
- it "returns nil" do
130
- subject.latest_version(client, name).should eql("3.0.0")
131
- end
24
+ it "returns nil" do
25
+ subject.latest_version(name).should be_nil
132
26
  end
133
27
  end
134
28
 
135
- describe "::versions" do
136
- let(:cookbook) { "artifact" }
137
- subject { described_class.versions(client, cookbook) }
138
-
139
- before(:each) do
140
- stub_request(:get, File.join(server_url, "cookbooks", cookbook)).
141
- to_return(status: 200, body: {
142
- cookbook => {
143
- "versions" => [
144
- {
145
- "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.0.0",
146
- "version" => "1.0.0"
147
- },
148
- {
149
- "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.1.0",
150
- "version" => "1.1.0"
151
- },
152
- {
153
- "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.2.0",
154
- "version" => "1.2.0"
155
- }
156
- ],
157
- "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact"}
158
- }
159
- )
29
+ context "when the cookbook has versions" do
30
+ let(:versions) do
31
+ [ "1.0.0", "1.2.0", "3.0.0", "1.4.1" ]
160
32
  end
161
33
 
162
- it "returns an array" do
163
- subject.should be_a(Array)
164
- end
165
-
166
- it "contains a version string for each cookbook version available" do
167
- subject.should have(3).versions
168
- subject.should include("1.0.0")
169
- subject.should include("1.1.0")
170
- subject.should include("1.2.0")
34
+ it "returns nil" do
35
+ subject.latest_version(name).should eql("3.0.0")
171
36
  end
172
37
  end
173
-
174
- describe "::upload" do
175
- pending
176
- end
177
-
178
- describe "::update" do
179
- pending
180
- end
181
38
  end
182
39
 
183
- describe "#download" do
184
- it "downloads each file" do
185
- subject.stub(:manifest) do
186
- {
187
- resources: [],
188
- providers: [],
189
- recipes: [
40
+ describe "#versions" do
41
+ let(:cookbook) { "artifact" }
42
+ let(:versions_path) { "#{described_class.resource_path}/#{cookbook}" }
43
+ let(:response) do
44
+ double(body: {
45
+ cookbook => {
46
+ "versions" => [
190
47
  {
191
- checksum: "aa3505d3eb8ce328ea84a4333df05b07",
192
- name: "default.rb",
193
- path: "recipes/default.rb",
194
- specificity: "default",
195
- url: "https://chef.lax1.riotgames.com/organizations/reset/cookbooks/ohai/1.0.2/files/aa3505d3eb8ce328ea84a4333df05b07"
196
- }
197
- ],
198
- definitions: [],
199
- libraries: [],
200
- attributes: [],
201
- files: [
48
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.0.0",
49
+ "version" => "1.0.0"
50
+ },
51
+ {
52
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.1.0",
53
+ "version" => "1.1.0"
54
+ },
202
55
  {
203
- checksum: "85bc3bb921efade3f2566a668ab4b639",
204
- name: "README",
205
- path: "files/default/plugins/README",
206
- specificity: "plugins",
207
- url: "https://chef.lax1.riotgames.com/organizations/reset/cookbooks/ohai/1.0.2/files/85bc3bb921efade3f2566a668ab4b639"
56
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.2.0",
57
+ "version" => "1.2.0"
208
58
  }
209
59
  ],
210
- templates: [],
211
- root_files: []
60
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact"
212
61
  }
213
- end
214
-
215
- subject.should_receive(:download_file).with(:recipes, "recipes/default.rb", anything)
216
- subject.should_receive(:download_file).with(:files, "files/default/plugins/README", anything)
217
-
218
- subject.download
62
+ })
219
63
  end
220
- end
221
-
222
- describe "#download_file" do
223
- let(:destination) { tmp_path.join('fake.file').to_s }
224
64
 
225
65
  before(:each) do
226
- subject.stub(:root_files) { [ { path: 'metadata.rb', url: "http://test.it/file" } ] }
66
+ connection.should_receive(:get).with(versions_path).and_return(response)
227
67
  end
228
68
 
229
- it "downloads the file from the file's url" do
230
- client.connection.should_receive(:stream).with("http://test.it/file", destination)
231
-
232
- subject.download_file(:root_file, "metadata.rb", destination)
69
+ it "returns an array" do
70
+ subject.versions(cookbook).should be_a(Array)
233
71
  end
234
72
 
235
- context "when given an unknown filetype" do
236
- it "raises an UnknownCookbookFileType error" do
237
- expect {
238
- subject.download_file(:not_existant, "default.rb", destination)
239
- }.to raise_error(Ridley::Errors::UnknownCookbookFileType)
240
- end
241
- end
73
+ it "contains a version string for each cookbook version available" do
74
+ result = subject.versions(cookbook)
242
75
 
243
- context "when the cookbook doesn't have the specified file" do
244
- before(:each) do
245
- subject.stub(:root_files) { Array.new }
246
- end
247
-
248
- it "returns nil" do
249
- subject.download_file(:root_file, "metadata.rb", destination).should be_nil
250
- end
76
+ result.should have(3).versions
77
+ result.should include("1.0.0")
78
+ result.should include("1.1.0")
79
+ result.should include("1.2.0")
251
80
  end
252
81
  end
253
82
 
254
- describe "#manifest" do
255
- it "returns a Hash" do
256
- subject.manifest.should be_a(Hash)
257
- end
83
+ describe "#satisfy" do
84
+ pending
85
+ end
258
86
 
259
- it "has a key for each item in FILE_TYPES" do
260
- subject.manifest.keys.should =~ described_class::FILE_TYPES
261
- end
87
+ describe "#upload" do
88
+ pending
89
+ end
262
90
 
263
- it "contains an empty array for each key" do
264
- subject.manifest.should each be_a(Array)
265
- subject.manifest.values.should each be_empty
266
- end
91
+ describe "#update" do
92
+ pending
267
93
  end
268
94
  end