droplet_kit 1.2.3 → 1.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/droplet_kit.gemspec +2 -2
  4. data/lib/droplet_kit.rb +20 -3
  5. data/lib/droplet_kit/client.rb +2 -0
  6. data/lib/droplet_kit/error_handling_resourcable.rb +19 -0
  7. data/lib/droplet_kit/mappings/domain_record_mapping.rb +6 -6
  8. data/lib/droplet_kit/mappings/floating_ip_mapping.rb +19 -0
  9. data/lib/droplet_kit/models/floating_ip.rb +10 -0
  10. data/lib/droplet_kit/paginated_resource.rb +1 -1
  11. data/lib/droplet_kit/resources/account_resource.rb +2 -0
  12. data/lib/droplet_kit/resources/action_resource.rb +2 -0
  13. data/lib/droplet_kit/resources/domain_record_resource.rb +2 -0
  14. data/lib/droplet_kit/resources/domain_resource.rb +2 -0
  15. data/lib/droplet_kit/resources/droplet_action_resource.rb +4 -0
  16. data/lib/droplet_kit/resources/droplet_resource.rb +3 -1
  17. data/lib/droplet_kit/resources/droplet_upgrade_resource.rb +2 -0
  18. data/lib/droplet_kit/resources/floating_ip_action_resource.rb +30 -0
  19. data/lib/droplet_kit/resources/floating_ip_resource.rb +29 -0
  20. data/lib/droplet_kit/resources/image_action_resource.rb +4 -0
  21. data/lib/droplet_kit/resources/image_resource.rb +2 -0
  22. data/lib/droplet_kit/resources/region_resource.rb +2 -0
  23. data/lib/droplet_kit/resources/size_resource.rb +2 -0
  24. data/lib/droplet_kit/resources/ssh_key_resource.rb +2 -0
  25. data/lib/droplet_kit/version.rb +1 -1
  26. data/spec/fixtures/droplet_actions/change_kernel.json +27 -0
  27. data/spec/fixtures/droplet_actions/disable_backups.json +27 -0
  28. data/spec/fixtures/droplet_actions/enable_ipv6.json +27 -0
  29. data/spec/fixtures/droplet_actions/enable_private_networking.json +27 -0
  30. data/spec/fixtures/droplet_actions/find.json +19 -0
  31. data/spec/fixtures/droplet_actions/password_reset.json +27 -0
  32. data/spec/fixtures/droplet_actions/power_cycle.json +27 -0
  33. data/spec/fixtures/droplet_actions/power_off.json +27 -0
  34. data/spec/fixtures/droplet_actions/power_on.json +27 -0
  35. data/spec/fixtures/droplet_actions/reboot.json +27 -0
  36. data/spec/fixtures/droplet_actions/rebuild.json +27 -0
  37. data/spec/fixtures/droplet_actions/rename.json +27 -0
  38. data/spec/fixtures/droplet_actions/resize.json +27 -0
  39. data/spec/fixtures/droplet_actions/restore.json +27 -0
  40. data/spec/fixtures/droplet_actions/shutdown.json +27 -0
  41. data/spec/fixtures/droplet_actions/snapshot.json +27 -0
  42. data/spec/fixtures/droplet_actions/upgrade.json +27 -0
  43. data/spec/fixtures/floating_ip_actions/all.json +41 -0
  44. data/spec/fixtures/floating_ip_actions/assign.json +27 -0
  45. data/spec/fixtures/floating_ip_actions/find.json +19 -0
  46. data/spec/fixtures/floating_ip_actions/unassign.json +27 -0
  47. data/spec/fixtures/floating_ips/all.json +186 -0
  48. data/spec/fixtures/floating_ips/all_empty.json +7 -0
  49. data/spec/fixtures/floating_ips/create.json +29 -0
  50. data/spec/fixtures/floating_ips/create_with_droplet.json +44 -0
  51. data/spec/fixtures/floating_ips/find.json +28 -0
  52. data/spec/fixtures/image_actions/convert.json +27 -0
  53. data/spec/fixtures/image_actions/transfer.json +27 -0
  54. data/spec/fixtures/images/private.json +31 -0
  55. data/spec/fixtures/images/type.json +31 -0
  56. data/spec/lib/droplet_kit/resources/account_resource_spec.rb +5 -0
  57. data/spec/lib/droplet_kit/resources/action_resource_spec.rb +7 -0
  58. data/spec/lib/droplet_kit/resources/domain_record_resource_spec.rb +13 -6
  59. data/spec/lib/droplet_kit/resources/domain_resource_spec.rb +10 -3
  60. data/spec/lib/droplet_kit/resources/droplet_action_resource_spec.rb +28 -34
  61. data/spec/lib/droplet_kit/resources/droplet_resource_spec.rb +36 -17
  62. data/spec/lib/droplet_kit/resources/droplet_upgrade_resource_spec.rb +6 -0
  63. data/spec/lib/droplet_kit/resources/floating_ip_action_resource_spec.rb +137 -0
  64. data/spec/lib/droplet_kit/resources/floating_ip_resource_spec.rb +91 -0
  65. data/spec/lib/droplet_kit/resources/image_action_resource_spec.rb +31 -28
  66. data/spec/lib/droplet_kit/resources/image_resource_spec.rb +11 -4
  67. data/spec/lib/droplet_kit/resources/region_resource_spec.rb +6 -0
  68. data/spec/lib/droplet_kit/resources/size_resource_spec.rb +6 -0
  69. data/spec/lib/droplet_kit/resources/ssh_key_resource_spec.rb +7 -0
  70. data/spec/support/request_stub_helpers.rb +1 -1
  71. data/spec/support/shared_examples/common_errors.rb +27 -0
  72. data/spec/support/shared_examples/paginated_endpoint.rb +2 -1
  73. data/spec/support/shared_examples/unsuccessful_create.rb +8 -0
  74. metadata +109 -38
  75. data/spec/support/null_hash_load.rb +0 -5
@@ -18,7 +18,12 @@ RSpec.describe DropletKit::AccountResource do
18
18
  expect(account_info.email).to eq(parsed['account']['email'])
19
19
  expect(account_info.uuid).to eq(parsed['account']['uuid'])
20
20
  expect(account_info.email_verified).to eq(parsed['account']['email_verified'])
21
+ end
21
22
 
23
+ it_behaves_like 'resource that handles common errors' do
24
+ let(:path) { '/v2/account' }
25
+ let(:method) { :get }
26
+ let(:action) { :info }
22
27
  end
23
28
  end
24
29
  end
@@ -72,5 +72,12 @@ RSpec.describe DropletKit::ActionResource do
72
72
  expect(action.region.available).to be(true)
73
73
  expect(action.region.features).to include("virtio", "private_networking", "backups", "ipv6", "metadata")
74
74
  end
75
+
76
+ it_behaves_like 'resource that handles common errors' do
77
+ let(:path) { '/v2/actions/123' }
78
+ let(:method) { :get }
79
+ let(:action) { :find }
80
+ let(:arguments) { { id: 123 } }
81
+ end
75
82
  end
76
83
  end
@@ -31,10 +31,10 @@ RSpec.describe DropletKit::DomainRecordResource do
31
31
  name: 'www',
32
32
  data: '@'
33
33
  )
34
- as_hash = DropletKit::DomainRecordMapping.representation_for(:create, domain_record, NullHashLoad)
35
- expect(as_hash[:type]).to eq('CNAME')
36
- expect(as_hash[:name]).to eq('www')
37
- expect(as_hash[:data]).to eq('@')
34
+ as_hash = DropletKit::DomainRecordMapping.hash_for(:create, domain_record)
35
+ expect(as_hash['type']).to eq('CNAME')
36
+ expect(as_hash['name']).to eq('www')
37
+ expect(as_hash['data']).to eq('@')
38
38
 
39
39
  as_json = DropletKit::DomainRecordMapping.representation_for(:create, domain_record)
40
40
  stub_do_api('/v2/domains/example.com/records', :post).with(body: as_json).to_return(body: response, status: 201)
@@ -55,6 +55,13 @@ RSpec.describe DropletKit::DomainRecordResource do
55
55
  expected_record = DropletKit::DomainRecordMapping.extract_single(response, :read)
56
56
  expect(resource.find(id: 12, for_domain: 'example.com')).to eq(expected_record)
57
57
  end
58
+
59
+ it_behaves_like 'resource that handles common errors' do
60
+ let(:path) { '/v2/domains/example.com/records/12' }
61
+ let(:method) { :get }
62
+ let(:action) { :find }
63
+ let(:arguments) { { for_domain: 'example.com', id: 123 } }
64
+ end
58
65
  end
59
66
 
60
67
  describe '#delete' do
@@ -71,8 +78,8 @@ RSpec.describe DropletKit::DomainRecordResource do
71
78
  response = api_fixture('domain_records/update')
72
79
 
73
80
  domain_record = DropletKit::DomainRecord.new(name: 'lol')
74
- as_hash = DropletKit::DomainRecordMapping.representation_for(:update, domain_record, NullHashLoad)
75
- expect(as_hash[:name]).to eq('lol')
81
+ as_hash = DropletKit::DomainRecordMapping.hash_for(:update, domain_record)
82
+ expect(as_hash['name']).to eq('lol')
76
83
 
77
84
  as_json = DropletKit::DomainRecordMapping.representation_for(:update, domain_record)
78
85
  request = stub_do_api('/v2/domains/example.com/records/1066', :put).with(body: as_json).to_return(body: response, status: 200)
@@ -24,9 +24,9 @@ RSpec.describe DropletKit::DomainResource do
24
24
  response = api_fixture('domains/create')
25
25
 
26
26
  domain = DropletKit::Domain.new(ip_address: '1.1.1.1', name: 'example.com')
27
- as_hash = DropletKit::DomainMapping.representation_for(:create, domain, NullHashLoad)
28
- expect(as_hash[:ip_address]).to eq('1.1.1.1')
29
- expect(as_hash[:name]).to eq('example.com')
27
+ as_hash = DropletKit::DomainMapping.hash_for(:create, domain)
28
+ expect(as_hash['ip_address']).to eq('1.1.1.1')
29
+ expect(as_hash['name']).to eq('example.com')
30
30
 
31
31
  as_json = DropletKit::DomainMapping.representation_for(:create, domain)
32
32
  stub_do_api('/v2/domains', :post).with(body: as_json).to_return(body: response, status: 201)
@@ -46,6 +46,13 @@ RSpec.describe DropletKit::DomainResource do
46
46
 
47
47
  expect(resource.find(name: 'example.com')).to eq(expected_domain)
48
48
  end
49
+
50
+ it_behaves_like 'resource that handles common errors' do
51
+ let(:path) { '/v2/domains/example.com' }
52
+ let(:method) { :get }
53
+ let(:action) { :find }
54
+ let(:arguments) { { name: 'example.com' } }
55
+ end
49
56
  end
50
57
 
51
58
  describe '#delete' do
@@ -3,27 +3,8 @@ require 'spec_helper'
3
3
  RSpec.describe DropletKit::DropletActionResource do
4
4
  subject(:resource) { described_class.new(connection: connection) }
5
5
  let(:droplet_id) { 1066 }
6
- def json
7
- {
8
- "action" => {
9
- "id" => 2,
10
- "status" => "in-progress",
11
- "type" => action,
12
- "started_at" => "2014-07-29T14:35:27Z",
13
- "completed_at" => nil,
14
- "resource_id" => 12,
15
- "resource_type" => "droplet",
16
- "region_slug" => "nyc1",
17
- "region" => {
18
- "name" => "New York",
19
- "slug" => "nyc1",
20
- "available" => true,
21
- "sizes" => ["512mb"],
22
- "features" => ["virtio", "private_networking", "backups", "ipv6", "metadata"]
23
- }
24
- }
25
- }.to_json
26
- end
6
+
7
+ let(:fixture) { api_fixture("droplet_actions/#{action}") }
27
8
 
28
9
  include_context 'resources'
29
10
 
@@ -34,16 +15,22 @@ RSpec.describe DropletKit::DropletActionResource do
34
15
  ACTIONS_WITHOUT_INPUT.each do |action_name|
35
16
  describe "Action #{action_name}" do
36
17
  let(:action) { action_name }
18
+ let(:path) { "/v2/droplets/#{droplet_id}/actions" }
37
19
 
38
20
  it 'performs the action' do
39
- request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
40
- body: { type: action_name }.to_json
41
- ).to_return(body: json, status: 201)
21
+ request = stub_do_api(path, :post).with(
22
+ body: { type: action }.to_json
23
+ ).to_return(body: fixture, status: 201)
42
24
 
43
- returned_action = resource.send(action_name, droplet_id: droplet_id)
25
+ returned_action = resource.send(action, droplet_id: droplet_id)
44
26
 
45
27
  expect(request).to have_been_made
46
- expect(returned_action.type).to eq(action_name)
28
+ expect(returned_action.type).to eq(action)
29
+ end
30
+
31
+ it_behaves_like 'an action that handles invalid parameters' do
32
+ let(:object) { DropletKit::Droplet.new }
33
+ let(:arguments) { { droplet_id: droplet_id } }
47
34
  end
48
35
  end
49
36
  end
@@ -54,7 +41,7 @@ RSpec.describe DropletKit::DropletActionResource do
54
41
  it 'performs the action' do
55
42
  request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
56
43
  body: { type: action, name: 'Dwight' }.to_json
57
- ).to_return(body: json, status: 201)
44
+ ).to_return(body: fixture, status: 201)
58
45
 
59
46
  returned_action = resource.send(action, droplet_id: droplet_id, name: 'Dwight')
60
47
 
@@ -69,7 +56,7 @@ RSpec.describe DropletKit::DropletActionResource do
69
56
  it 'performs the action' do
70
57
  request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
71
58
  body: { type: action, kernel: 1556 }.to_json
72
- ).to_return(body: json, status: 201)
59
+ ).to_return(body: fixture, status: 201)
73
60
 
74
61
  returned_action = resource.send(action, droplet_id: droplet_id, kernel: 1556)
75
62
 
@@ -84,7 +71,7 @@ RSpec.describe DropletKit::DropletActionResource do
84
71
  it 'performs the action' do
85
72
  request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
86
73
  body: { type: action, name: 'newname.com' }.to_json
87
- ).to_return(body: json, status: 201)
74
+ ).to_return(body: fixture, status: 201)
88
75
 
89
76
  returned_action = resource.send(action, droplet_id: droplet_id, name: 'newname.com')
90
77
 
@@ -99,7 +86,7 @@ RSpec.describe DropletKit::DropletActionResource do
99
86
  it 'performs the action' do
100
87
  request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
101
88
  body: { type: action, image: 'ubuntu-14-04-x86' }.to_json
102
- ).to_return(body: json, status: 201)
89
+ ).to_return(body: fixture, status: 201)
103
90
 
104
91
  returned_action = resource.send(action, droplet_id: droplet_id, image: 'ubuntu-14-04-x86')
105
92
 
@@ -114,7 +101,7 @@ RSpec.describe DropletKit::DropletActionResource do
114
101
  it 'performs the action' do
115
102
  request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
116
103
  body: { type: action, image: 'ubuntu-14-04-x86' }.to_json
117
- ).to_return(body: json, status: 201)
104
+ ).to_return(body: fixture, status: 201)
118
105
 
119
106
  returned_action = resource.send(action, droplet_id: droplet_id, image: 'ubuntu-14-04-x86')
120
107
 
@@ -129,7 +116,7 @@ RSpec.describe DropletKit::DropletActionResource do
129
116
  it 'performs the action' do
130
117
  request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
131
118
  body: { type: action, size: '1gb', disk: nil }.to_json
132
- ).to_return(body: json, status: 201)
119
+ ).to_return(body: fixture, status: 201)
133
120
 
134
121
  returned_action = resource.send(action, droplet_id: droplet_id, size: '1gb')
135
122
 
@@ -144,7 +131,7 @@ RSpec.describe DropletKit::DropletActionResource do
144
131
  it 'performs the action' do
145
132
  request = stub_do_api("/v2/droplets/#{droplet_id}/actions", :post).with(
146
133
  body: { type: action, size: '1gb', disk: true }.to_json
147
- ).to_return(body: json, status: 201)
134
+ ).to_return(body: fixture, status: 201)
148
135
 
149
136
  returned_action = resource.send(action, droplet_id: droplet_id, size: '1gb', disk: true)
150
137
 
@@ -156,7 +143,7 @@ RSpec.describe DropletKit::DropletActionResource do
156
143
  describe '#find' do
157
144
  it 'returns an action' do
158
145
  request = stub_do_api("/v2/droplets/1066/actions/123", :get).to_return(
159
- body: api_fixture('actions/find')
146
+ body: api_fixture('droplet_actions/find')
160
147
  )
161
148
 
162
149
  returned_action = resource.find(droplet_id: 1066, id: 123)
@@ -176,5 +163,12 @@ RSpec.describe DropletKit::DropletActionResource do
176
163
  expect(returned_action.region.available).to be(true)
177
164
  expect(returned_action.region.features).to include("virtio", "private_networking", "backups", "ipv6", "metadata")
178
165
  end
166
+
167
+ it_behaves_like 'resource that handles common errors' do
168
+ let(:path) { '/v2/droplets/1066/actions/123' }
169
+ let(:method) { :get }
170
+ let(:action) { :find }
171
+ let(:arguments) { { droplet_id: 1066, id: 123 } }
172
+ end
179
173
  end
180
174
  end
@@ -89,9 +89,18 @@ RSpec.describe DropletKit::DropletResource do
89
89
  expect(droplet).to be_kind_of(DropletKit::Droplet)
90
90
  check_droplet(droplet)
91
91
  end
92
+
93
+ it_behaves_like 'resource that handles common errors' do
94
+ let(:path) { '/v2/droplets/123' }
95
+ let(:method) { :get }
96
+ let(:action) { :find }
97
+ let(:arguments) { { id: 123 } }
98
+ end
92
99
  end
93
100
 
94
101
  describe '#create' do
102
+ let(:path) { '/v2/droplets' }
103
+
95
104
  context 'for a successful create' do
96
105
  it 'returns the created droplet' do
97
106
  droplet = DropletKit::Droplet.new(
@@ -106,32 +115,42 @@ RSpec.describe DropletKit::DropletResource do
106
115
  user_data: "#cloud-config\nruncmd\n\t- echo 'Hello!'"
107
116
  )
108
117
 
109
- as_hash = DropletKit::DropletMapping.representation_for(:create, droplet, NullHashLoad)
110
- expect(as_hash[:name]).to eq(droplet.name)
111
- expect(as_hash[:region]).to eq(droplet.region)
112
- expect(as_hash[:size]).to eq(droplet.size)
113
- expect(as_hash[:image]).to eq(droplet.image)
114
- expect(as_hash[:ssh_keys]).to eq(droplet.ssh_keys)
115
- expect(as_hash[:backups]).to eq(droplet.backups)
116
- expect(as_hash[:ipv6]).to eq(droplet.ipv6)
117
- expect(as_hash[:private_networking]).to eq(droplet.private_networking)
118
- expect(as_hash[:user_data]).to eq(droplet.user_data)
118
+ as_hash = DropletKit::DropletMapping.hash_for(:create, droplet)
119
+ expect(as_hash['name']).to eq(droplet.name)
120
+ expect(as_hash['region']).to eq(droplet.region)
121
+ expect(as_hash['size']).to eq(droplet.size)
122
+ expect(as_hash['image']).to eq(droplet.image)
123
+ expect(as_hash['ssh_keys']).to eq(droplet.ssh_keys)
124
+ expect(as_hash['backups']).to eq(droplet.backups)
125
+ expect(as_hash['ipv6']).to eq(droplet.ipv6)
126
+ expect(as_hash['private_networking']).to eq(droplet.private_networking)
127
+ expect(as_hash['user_data']).to eq(droplet.user_data)
119
128
 
120
129
  as_string = DropletKit::DropletMapping.representation_for(:create, droplet)
121
- stub_do_api('/v2/droplets', :post).with(body: as_string).to_return(body: api_fixture('droplets/create'), status: 202)
130
+ stub_do_api(path, :post).with(body: as_string).to_return(body: api_fixture('droplets/create'), status: 202)
122
131
  created_droplet = resource.create(droplet)
123
132
  check_droplet(created_droplet)
124
133
  end
125
- end
126
134
 
127
- context 'for an unsuccessful create' do
128
- it 'raises a FailedCreate exception with the message attached' do
129
- response_body = { id: :unprocessable_entity, message: 'Something is not right' }
130
- stub_do_api('/v2/droplets', :post).to_return(body: response_body.to_json, status: 422)
135
+ it 'reuses the same object' do
136
+ droplet = DropletKit::Droplet.new(
137
+ name: 'test.example.com',
138
+ region: 'nyc1',
139
+ size: '512mb',
140
+ image: 'ubuntu-14-04-x86'
141
+ )
131
142
 
132
- expect { resource.create(DropletKit::Droplet.new) }.to raise_exception(DropletKit::FailedCreate).with_message(response_body[:message])
143
+ json = DropletKit::DropletMapping.representation_for(:create, droplet)
144
+ stub_do_api(path, :post).with(body: json).to_return(body: api_fixture('droplets/create'), status: 202)
145
+ created_droplet = resource.create(droplet)
146
+ expect(created_droplet).to be droplet
133
147
  end
134
148
  end
149
+
150
+ it_behaves_like 'an action that handles invalid parameters' do
151
+ let(:action) { 'create' }
152
+ let(:arguments) { DropletKit::Droplet.new }
153
+ end
135
154
  end
136
155
 
137
156
  describe '#kernels' do
@@ -12,5 +12,11 @@ RSpec.describe DropletKit::DropletUpgradeResource do
12
12
 
13
13
  expect(resource.all).to eq(expected)
14
14
  end
15
+
16
+ it_behaves_like 'resource that handles common errors' do
17
+ let(:path) { '/v2/droplet_upgrades' }
18
+ let(:method) { :get }
19
+ let(:action) { :all }
20
+ end
15
21
  end
16
22
  end
@@ -0,0 +1,137 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe DropletKit::FloatingIpActionResource do
4
+ subject(:resource) { described_class.new(connection: connection) }
5
+ include_context 'resources'
6
+
7
+ describe '#assign' do
8
+ let(:ip) { '127.0.0.1' }
9
+ let(:droplet_id) { 123 }
10
+ let(:path) { "/v2/floating_ips/#{ip}/actions" }
11
+ let(:action) { 'assign' }
12
+ let(:fixture) { api_fixture("floating_ip_actions/#{action}") }
13
+
14
+ it 'sends an assign request for a floating ip' do
15
+ request = stub_do_api(path).with(
16
+ body: { type: action, droplet_id: droplet_id }.to_json
17
+ ).to_return(body: fixture, status: 201)
18
+
19
+ action = resource.assign(ip: ip, droplet_id: droplet_id)
20
+
21
+ expect(request).to have_been_made
22
+
23
+ expect(action).to be_kind_of(DropletKit::Action)
24
+ expect(action.id).to eq(2)
25
+ expect(action.status).to eq("in-progress")
26
+ expect(action.type).to eq("assign")
27
+ expect(action.started_at).to eq("2014-08-05T15:15:28Z")
28
+ expect(action.completed_at).to eq(nil)
29
+ expect(action.resource_id).to eq(12)
30
+ expect(action.resource_type).to eq("floating_ip")
31
+ expect(action.region_slug).to eq("nyc1")
32
+
33
+ expect(action.region).to be_kind_of(DropletKit::Region)
34
+ expect(action.region.slug).to eq('nyc1')
35
+ expect(action.region.name).to eq('New York')
36
+ expect(action.region.sizes).to include('512mb')
37
+ expect(action.region.available).to be(true)
38
+ expect(action.region.features).to include("virtio", "private_networking", "backups", "ipv6", "metadata")
39
+ end
40
+
41
+ it_behaves_like 'an action that handles invalid parameters' do
42
+ let(:arguments) { { ip: ip, droplet_id: droplet_id } }
43
+ end
44
+ end
45
+
46
+ describe '#unassign' do
47
+ let(:ip) { '127.0.0.1' }
48
+ let(:path) { "/v2/floating_ips/#{ip}/actions" }
49
+ let(:action) { 'unassign' }
50
+ let(:fixture) { api_fixture("floating_ip_actions/#{action}") }
51
+
52
+ it 'sends an unassign request for a floating ip' do
53
+ request = stub_do_api(path).with(
54
+ body: { type: action }.to_json
55
+ ).to_return(body: fixture, status: 201)
56
+
57
+ action = resource.unassign(ip: ip)
58
+
59
+ expect(request).to have_been_made
60
+
61
+ expect(action).to be_kind_of(DropletKit::Action)
62
+ expect(action.id).to eq(2)
63
+ expect(action.status).to eq("in-progress")
64
+ expect(action.type).to eq("unassign")
65
+ expect(action.started_at).to eq("2014-08-05T15:15:28Z")
66
+ expect(action.completed_at).to eq(nil)
67
+ expect(action.resource_id).to eq(12)
68
+ expect(action.resource_type).to eq("floating_ip")
69
+ expect(action.region_slug).to eq("nyc1")
70
+
71
+ expect(action.region).to be_kind_of(DropletKit::Region)
72
+ expect(action.region.slug).to eq('nyc1')
73
+ expect(action.region.name).to eq('New York')
74
+ expect(action.region.sizes).to include('512mb')
75
+ expect(action.region.available).to be(true)
76
+ expect(action.region.features).to include("virtio", "private_networking", "backups", "ipv6", "metadata")
77
+ end
78
+
79
+ it_behaves_like 'an action that handles invalid parameters' do
80
+ let(:arguments) { { ip: ip } }
81
+ end
82
+ end
83
+
84
+ describe '#all' do
85
+ let(:ip) { '127.0.0.1' }
86
+
87
+ it 'returns all of the floating ip actions via a paginated resources' do
88
+ request = stub_do_api("/v2/floating_ips/#{ip}/actions", :get).to_return(
89
+ body: api_fixture('floating_ip_actions/all'),
90
+ status: 200
91
+ )
92
+
93
+ actions = resource.all(ip: ip).take(20)
94
+
95
+ expect(request).to have_been_made
96
+
97
+ expect(actions.size).to be(2)
98
+
99
+ action = actions.first
100
+
101
+ expect(action.id).to eq(19)
102
+ expect(action.status).to eq("completed")
103
+ expect(action.type).to eq("assign_ip")
104
+ expect(action.started_at).to eq("2014-10-28T17:11:05Z")
105
+ expect(action.completed_at).to eq("2014-10-28T17:11:06Z")
106
+ expect(action.resource_id).to eq(45646587)
107
+ expect(action.resource_type).to eq("floating_ip")
108
+ expect(action.region).to be_kind_of(DropletKit::Region)
109
+ expect(action.region_slug).to eq("nyc1")
110
+ end
111
+
112
+ it_behaves_like 'a paginated index' do
113
+ let(:fixture_path) { 'floating_ip_actions/all' }
114
+ let(:api_path) { "/v2/floating_ips/#{ip}/actions" }
115
+ let(:parameters) { { ip: ip } }
116
+ end
117
+ end
118
+
119
+ describe '#find' do
120
+ let(:ip) { '127.0.0.1' }
121
+
122
+ it 'returns a single action' do
123
+ stub_do_api("/v2/floating_ips/#{ip}/actions/23", :get).to_return(body: api_fixture('floating_ip_actions/find'))
124
+ action = resource.find(ip: ip, id: 23)
125
+
126
+ expect(action.id).to eq(19)
127
+ expect(action.status).to eq("completed")
128
+ expect(action.type).to eq("assign_ip")
129
+ expect(action.started_at).to eq("2014-10-28T17:11:05Z")
130
+ expect(action.completed_at).to eq("2014-10-28T17:11:06Z")
131
+ expect(action.resource_id).to eq(45646587)
132
+ expect(action.resource_type).to eq("floating_ip")
133
+ expect(action.region).to be_kind_of(DropletKit::Region)
134
+ expect(action.region_slug).to eq("nyc1")
135
+ end
136
+ end
137
+ end