droplet_kit 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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