squall 0.0.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +100 -0
- data/LICENSE +1 -1
- data/README.md +69 -0
- data/Rakefile +48 -42
- data/lib/squall/base.rb +96 -0
- data/lib/squall/config.rb +26 -0
- data/lib/squall/exception.rb +13 -0
- data/lib/squall/hypervisor.rb +46 -16
- data/lib/squall/ip_address.rb +13 -0
- data/lib/squall/network.rb +42 -0
- data/lib/squall/params.rb +50 -0
- data/lib/squall/role.rb +56 -0
- data/lib/squall/statistic.rb +10 -0
- data/lib/squall/template.rb +22 -0
- data/lib/squall/transaction.rb +16 -0
- data/lib/squall/user.rb +87 -0
- data/lib/squall/version.rb +3 -0
- data/lib/squall/virtual_machine.rb +169 -41
- data/lib/squall.rb +76 -20
- data/spec/params_spec.rb +195 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/squall/base_spec.rb +135 -0
- data/spec/squall/config_spec.rb +44 -0
- data/spec/squall/hypervisor_spec.rb +143 -0
- data/spec/squall/ip_address_spec.rb +32 -0
- data/spec/squall/network_spec.rb +121 -0
- data/spec/squall/role_spec.rb +123 -0
- data/spec/squall/statistic_spec.rb +23 -0
- data/spec/squall/template_spec.rb +59 -0
- data/spec/squall/transaction_spec.rb +42 -0
- data/spec/squall/user_spec.rb +195 -0
- data/spec/squall/virtual_machine_spec.rb +471 -0
- data/spec/squall_spec.rb +67 -0
- data/spec/vcr_cassettes/hypervisor/create.yml +77 -0
- data/spec/vcr_cassettes/hypervisor/delete.yml +77 -0
- data/spec/vcr_cassettes/hypervisor/edit.yml +79 -0
- data/spec/vcr_cassettes/hypervisor/list.yml +40 -0
- data/spec/vcr_cassettes/hypervisor/reboot.yml +77 -0
- data/spec/vcr_cassettes/hypervisor/show.yml +77 -0
- data/spec/vcr_cassettes/ipaddress/list.yml +77 -0
- data/spec/vcr_cassettes/network/create.yml +196 -0
- data/spec/vcr_cassettes/network/delete.yml +77 -0
- data/spec/vcr_cassettes/network/edit.yml +233 -0
- data/spec/vcr_cassettes/network/list.yml +40 -0
- data/spec/vcr_cassettes/role/create.yml +77 -0
- data/spec/vcr_cassettes/role/delete.yml +77 -0
- data/spec/vcr_cassettes/role/edit.yml +139 -0
- data/spec/vcr_cassettes/role/list.yml +40 -0
- data/spec/vcr_cassettes/role/permissions.yml +40 -0
- data/spec/vcr_cassettes/role/show.yml +77 -0
- data/spec/vcr_cassettes/statistic/usage_statistics.yml +40 -0
- data/spec/vcr_cassettes/template/download.yml +40 -0
- data/spec/vcr_cassettes/template/list.yml +40 -0
- data/spec/vcr_cassettes/template/make_public.yml +77 -0
- data/spec/vcr_cassettes/transaction/list.yml +40 -0
- data/spec/vcr_cassettes/transaction/show.yml +77 -0
- data/spec/vcr_cassettes/user/activate.yml +40 -0
- data/spec/vcr_cassettes/user/create.yml +116 -0
- data/spec/vcr_cassettes/user/delete.yml +77 -0
- data/spec/vcr_cassettes/user/edit_role.yml +116 -0
- data/spec/vcr_cassettes/user/generate_api_key.yml +40 -0
- data/spec/vcr_cassettes/user/list.yml +40 -0
- data/spec/vcr_cassettes/user/show.yml +77 -0
- data/spec/vcr_cassettes/user/stats.yml +40 -0
- data/spec/vcr_cassettes/user/suspend.yml +40 -0
- data/spec/vcr_cassettes/user/virtual_machines.yml +79 -0
- data/spec/vcr_cassettes/virtual_machine/build.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/change_owner.yml +108 -0
- data/spec/vcr_cassettes/virtual_machine/change_password.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/create.yml +40 -0
- data/spec/vcr_cassettes/virtual_machine/delete.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/edit.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/list.yml +40 -0
- data/spec/vcr_cassettes/virtual_machine/migrate.yml +116 -0
- data/spec/vcr_cassettes/virtual_machine/reboot.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/resize.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/show.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/shutdown.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/startup.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/stop.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/suspend.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/unlock.yml +77 -0
- data/spec/vcr_cassettes/virtual_machine/unsuspend.yml +77 -0
- data/squall.gemspec +25 -62
- metadata +224 -42
- data/.document +0 -5
- data/README.rdoc +0 -17
- data/VERSION.yml +0 -5
- data/lib/squall/client.rb +0 -87
- data/test/fixtures/virtual_machines.json +0 -1
- data/test/fixtures/virtual_machines_1.json +0 -1
- data/test/helper.rb +0 -31
- data/test/test_client.rb +0 -152
- data/test/test_squall.rb +0 -12
- data/test/test_virtual_machine.rb +0 -98
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rspec'
|
3
|
+
require 'vcr'
|
4
|
+
require 'squall'
|
5
|
+
|
6
|
+
VCR.config do |c|
|
7
|
+
c.cassette_library_dir = 'spec/vcr_cassettes'
|
8
|
+
c.stub_with :fakeweb
|
9
|
+
c.default_cassette_options = {:record => :new_episodes}
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.configure do |c|
|
13
|
+
c.extend VCR::RSpec::Macros
|
14
|
+
c.after(:each) do
|
15
|
+
Squall.reset_config
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_config
|
20
|
+
yaml = File.join(ENV['HOME'], '.squall.yml')
|
21
|
+
if ENV['SQUALL_LIVE'] && File.exists?(yaml)
|
22
|
+
config = YAML::load_file(yaml)
|
23
|
+
uri = config['base_uri']
|
24
|
+
user = config['username']
|
25
|
+
pass = config['password']
|
26
|
+
else
|
27
|
+
uri = 'http://www.example.com'
|
28
|
+
user = 'user'
|
29
|
+
pass = 'pass'
|
30
|
+
end
|
31
|
+
Squall.config do |c|
|
32
|
+
c.base_uri uri
|
33
|
+
c.username user
|
34
|
+
c.password pass
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def requires_attr(attr, &block)
|
39
|
+
expect { block.call }.to raise_error(ArgumentError, /Missing required params: #{attr}/i)
|
40
|
+
end
|
41
|
+
|
42
|
+
def mock_request(meth, path, options = {})
|
43
|
+
config = Squall.config
|
44
|
+
uri = URI.parse(Squall.config[:base_uri])
|
45
|
+
url = "#{uri.scheme}://#{config[:username]}:#{config[:password]}@#{uri.host}:#{uri.port}#{path}"
|
46
|
+
FakeWeb.register_uri(meth, url, {:content_type => 'application/json'}.merge(options))
|
47
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class CamelTest < Squall::Base;end;
|
4
|
+
class Nocamel < Squall::Base;end;
|
5
|
+
module Subclass
|
6
|
+
class Test < Squall::Base;end;
|
7
|
+
class CamelTest < Squall::Base;end;
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Squall::Base do
|
11
|
+
before(:each) do
|
12
|
+
default_config
|
13
|
+
@base = Squall::Base.new
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#initialize" do
|
17
|
+
it "sets the base_uri" do
|
18
|
+
@base.class.base_uri.should == 'http://www.example.com'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sets credentials" do
|
22
|
+
@base.class.default_options[:basic_auth].should include(:username => 'user', :password => 'pass')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "uses JSON" do
|
26
|
+
@base.class.default_options[:format].should == :json
|
27
|
+
end
|
28
|
+
|
29
|
+
it "sets JSON headers" do
|
30
|
+
@base.class.default_options[:headers].should include('Content-Type' => 'application/json')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#request" do
|
35
|
+
it "200-207 returns success" do
|
36
|
+
(200..207).each do |i|
|
37
|
+
mock_request(:get, "/#{i}", :status => [i, "OK"])
|
38
|
+
base = Squall::Base.new
|
39
|
+
base.request(:get, "/#{i}")
|
40
|
+
base.success.should be_true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises NotFound for 404s" do
|
45
|
+
mock_request(:get, '/404', :status => [404, "NotFound"])
|
46
|
+
expect { @base.request(:get, '/404') }.to raise_error(Squall::NotFound)
|
47
|
+
@base.success.should be_false
|
48
|
+
end
|
49
|
+
|
50
|
+
it "raises ServerError on errors" do
|
51
|
+
mock_request(:get, '/500', :status => [500, "Internal Server Error"])
|
52
|
+
expect { @base.request(:get, '/500') }.to raise_error(Squall::ServerError)
|
53
|
+
@base.success.should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
it "raises RequestError on errors" do
|
57
|
+
mock_request(:get, '/422', :status => [422, "Unprocessable"])
|
58
|
+
expect { @base.request(:get, '/422') }.to raise_error(Squall::RequestError)
|
59
|
+
@base.success.should be_false
|
60
|
+
end
|
61
|
+
|
62
|
+
it "is a sad panda when the config hasn't been specified" do
|
63
|
+
Squall.reset_config
|
64
|
+
expect { @base.request(:get, '/money') }.to raise_error(Squall::NoConfig, "Squall.config must be specified")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#errors" do
|
69
|
+
it "is empty on success" do
|
70
|
+
mock_request(:get, '/200_errors', :status => [200, "OK"], :body => '"{\"something\":[\"OK\"]}"')
|
71
|
+
@base.request(:get, '/200_errors')
|
72
|
+
@base.errors.should be_empty
|
73
|
+
end
|
74
|
+
|
75
|
+
it "returns an error hash" do
|
76
|
+
mock_request(:get, '/500_errors', :status => [500, "Internal Server Error"], :body => '"{\"something\":[\"errors\"]}"')
|
77
|
+
expect { @base.request(:get, '/500_errors') }.to raise_error(Squall::ServerError)
|
78
|
+
@base.errors.should_not be_empty
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#params" do
|
83
|
+
it "returns Params.new" do
|
84
|
+
@base.params.should be_a(Squall::Params)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#default_params" do
|
89
|
+
it "sets the default options" do
|
90
|
+
@base.default_params.should == {}
|
91
|
+
end
|
92
|
+
|
93
|
+
it "merges the query in" do
|
94
|
+
expected = {
|
95
|
+
:query => {
|
96
|
+
:base => {:one => 1, :two => 2}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
@base.default_params(:one => 1, :two => 2).should include(expected)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "uses the subclass name as the key" do
|
103
|
+
base_test = CamelTest.new
|
104
|
+
base_test.default_params.should == {}
|
105
|
+
expected = {
|
106
|
+
:query => {
|
107
|
+
:camel_test => {:one => 1, :two => 2}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
base_test.default_params(:one => 1, :two => 2).should include(expected)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#key_for_class" do
|
115
|
+
it "converts CamelTest to :camel_test" do
|
116
|
+
camel_test = CamelTest.new
|
117
|
+
camel_test.key_for_class.should == :camel_test
|
118
|
+
end
|
119
|
+
|
120
|
+
it "converts Nocamel to :nocamel" do
|
121
|
+
nocamel = Nocamel.new
|
122
|
+
nocamel.key_for_class.should == :nocamel
|
123
|
+
end
|
124
|
+
|
125
|
+
it "converts Subclass::Test to :test" do
|
126
|
+
sub_class = Subclass::Test.new
|
127
|
+
sub_class.key_for_class.should == :test
|
128
|
+
end
|
129
|
+
|
130
|
+
it "converts Subclass::CamelTest to :camel_test" do
|
131
|
+
camel_test = Subclass::CamelTest.new
|
132
|
+
camel_test.key_for_class.should == :camel_test
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Squall::Config do
|
4
|
+
before(:each) do
|
5
|
+
@config = Squall::Config.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#new" do
|
9
|
+
it "sets up the @config hash" do
|
10
|
+
@config.config.should == {}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#[]" do
|
15
|
+
it "behaves like an array" do
|
16
|
+
@config.config[:something] = 1
|
17
|
+
@config[:something].should == 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#base_uri" do
|
22
|
+
it "sets the base_uri" do
|
23
|
+
@config.config[:base_uri].should be_nil
|
24
|
+
@config.base_uri 'url'
|
25
|
+
@config.config[:base_uri].should == 'url'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#username" do
|
30
|
+
it "sets the username" do
|
31
|
+
@config.config[:username].should be_nil
|
32
|
+
@config.username 'user'
|
33
|
+
@config.config[:username].should == 'user'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#password" do
|
38
|
+
it "sets the password" do
|
39
|
+
@config.config[:password].should be_nil
|
40
|
+
@config.password 'pass'
|
41
|
+
@config.config[:password].should == 'pass'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Squall::Hypervisor do
|
4
|
+
before(:each) do
|
5
|
+
default_config
|
6
|
+
@hv = Squall::Hypervisor.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#list" do
|
10
|
+
use_vcr_cassette 'hypervisor/list'
|
11
|
+
it "returns hypervisors" do
|
12
|
+
hvs = @hv.list
|
13
|
+
hvs.size.should be(2)
|
14
|
+
|
15
|
+
keys = ["label", "called_in_at", "spare", "created_at", "hypervisor_type",
|
16
|
+
"updated_at", "xen_info", "id", "hypervisor_group_id", "enabled", "health",
|
17
|
+
"failure_count", "memory_overhead", "online", "locked", "ip_address"]
|
18
|
+
first = hvs.first
|
19
|
+
first.keys.should include(*keys)
|
20
|
+
first['label'].should == 'Testing'
|
21
|
+
first['hypervisor_type'].should == 'xen'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#show" do
|
26
|
+
use_vcr_cassette "hypervisor/show"
|
27
|
+
it "requires an id" do
|
28
|
+
expect { @hv.show }.to raise_error(ArgumentError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns not found for invalid hvs" do
|
32
|
+
expect { @hv.show(5) }.to raise_error(Squall::NotFound)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns a hv" do
|
36
|
+
hv = @hv.show(1)
|
37
|
+
hv['label'].should == 'Testing'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#create" do
|
42
|
+
use_vcr_cassette "hypervisor/create"
|
43
|
+
it "requires label" do
|
44
|
+
requires_attr(:label) { @hv.create }
|
45
|
+
@hv.success.should be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "requires ip_address" do
|
49
|
+
requires_attr(:ip_address) { @hv.create(:label => 'Brand New') }
|
50
|
+
@hv.success.should be_false
|
51
|
+
end
|
52
|
+
|
53
|
+
it "requires hypervisor_type" do
|
54
|
+
requires_attr(:hypervisor_type) { @hv.create(:label => 'Brand New', :ip_address => '222.222.222.222') }
|
55
|
+
@hv.success.should be_false
|
56
|
+
end
|
57
|
+
|
58
|
+
# The API allows you to commit this value but subsequent
|
59
|
+
# saves do not work because of this missing value.
|
60
|
+
it "requires memory_overhead" do
|
61
|
+
pending "Broken in OnApp"
|
62
|
+
requires_attr(:memory_overhead) { @hv.create(:label => 'Brand New', :ip_address => '222.222.222.222', :hypervisor_type => 'xen') }
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises error on duplicate account" do
|
66
|
+
expect {
|
67
|
+
@hv.create(:label => 'Testing', :ip_address => '123.123.123.123', :hypervisor_type => 'xen')
|
68
|
+
}.to raise_error(Squall::RequestError)
|
69
|
+
@hv.errors['label'].should include("has already been taken")
|
70
|
+
@hv.errors['ip_address'].should include("has already been taken")
|
71
|
+
@hv.success.should be_false
|
72
|
+
end
|
73
|
+
|
74
|
+
it "creates a hypervisor" do
|
75
|
+
create = @hv.create(:label => 'Brand new', :ip_address => '126.126.126.126', :hypervisor_type => 'xen')
|
76
|
+
@hv.success.should be_true
|
77
|
+
|
78
|
+
create['label'].should == 'Brand new'
|
79
|
+
create['ip_address'].should == '126.126.126.126'
|
80
|
+
create['hypervisor_type'].should == 'xen'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#edit" do
|
85
|
+
use_vcr_cassette 'hypervisor/edit'
|
86
|
+
it "requires an id" do
|
87
|
+
expect { @hv.edit }.to raise_error(ArgumentError)
|
88
|
+
@hv.success.should be_false
|
89
|
+
end
|
90
|
+
|
91
|
+
it "raises an error with unknown param " do
|
92
|
+
expect { @hv.edit(3, :blah => 1)}.to raise_error(ArgumentError)
|
93
|
+
@hv.success.should be_false
|
94
|
+
end
|
95
|
+
|
96
|
+
it "edits the label" do
|
97
|
+
edit = @hv.edit(3, :label => 'Old Gregg')
|
98
|
+
@hv.success.should be_true
|
99
|
+
end
|
100
|
+
|
101
|
+
it "edits the ip_address" do
|
102
|
+
edit = @hv.edit(3, :ip_address => '120.120.120.120')
|
103
|
+
@hv.success.should be_true
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#reboot" do
|
108
|
+
use_vcr_cassette 'hypervisor/reboot'
|
109
|
+
it "requires an id" do
|
110
|
+
expect { @hv.reboot }.to raise_error(ArgumentError)
|
111
|
+
@hv.success.should be_false
|
112
|
+
end
|
113
|
+
|
114
|
+
it "404s on not found" do
|
115
|
+
expect { @hv.reboot(404) }.to raise_error(Squall::NotFound)
|
116
|
+
@hv.success.should be_false
|
117
|
+
end
|
118
|
+
|
119
|
+
it "reboots the hypervisor" do
|
120
|
+
reboot = @hv.reboot(1)
|
121
|
+
@hv.success.should be_true
|
122
|
+
|
123
|
+
reboot['label'].should == 'Testing'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#delete" do
|
128
|
+
use_vcr_cassette "hypervisor/delete"
|
129
|
+
it "requires an id" do
|
130
|
+
expect { @hv.delete }.to raise_error(ArgumentError)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "404s on not found" do
|
134
|
+
expect { @hv.delete(404) }.to raise_error(Squall::NotFound)
|
135
|
+
@hv.success.should be_false
|
136
|
+
end
|
137
|
+
|
138
|
+
it "returns a hv" do
|
139
|
+
@hv.delete(3)
|
140
|
+
@hv.success.should be_true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Squall::IpAddress do
|
4
|
+
before(:each) do
|
5
|
+
default_config
|
6
|
+
@ip = Squall::IpAddress.new
|
7
|
+
@keys = ["netmask", "disallowed_primary", "address", "created_at", "updated_at", "network_id",
|
8
|
+
"network_address", "broadcast", "id", "gateway"]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#list" do
|
12
|
+
use_vcr_cassette 'ipaddress/list'
|
13
|
+
|
14
|
+
it "requires network_id" do
|
15
|
+
expect { @ip.list }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "404s on invalid network" do
|
19
|
+
expect { @ip.list(404) }.to raise_error(Squall::NotFound)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns ip_addresses" do
|
23
|
+
ips = @ip.list(1)
|
24
|
+
ips.size.should be(2)
|
25
|
+
|
26
|
+
first = ips.first
|
27
|
+
first.keys.should include(*@keys)
|
28
|
+
first['netmask'].should == '255.255.255.0'
|
29
|
+
first['address'].should == '127.2.2.2'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Squall::Network do
|
4
|
+
before(:each) do
|
5
|
+
default_config
|
6
|
+
@network = Squall::Network.new
|
7
|
+
@keys = ["label", "created_at", "updated_at", "network_group_id", "vlan", "id", "identifier"]
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#list" do
|
11
|
+
use_vcr_cassette "network/list"
|
12
|
+
it "returns a network list" do
|
13
|
+
networks = @network.list
|
14
|
+
networks.size.should be(2)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "contains first networks data" do
|
18
|
+
network = @network.list.first
|
19
|
+
network.keys.should include(*@keys)
|
20
|
+
network['label'].should == 'Test'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#edit" do
|
25
|
+
use_vcr_cassette 'network/edit'
|
26
|
+
it "requires an id" do
|
27
|
+
expect { @network.edit }.to raise_error(ArgumentError)
|
28
|
+
@network.success.should be_false
|
29
|
+
end
|
30
|
+
|
31
|
+
it "errors on invalid params" do
|
32
|
+
expect { @network.edit(1, :what => 1) }.to raise_error(ArgumentError, 'Unknown params: what')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "accepts valid params" do
|
36
|
+
@network.edit(1, :label => 'one')
|
37
|
+
@network.success.should be_true
|
38
|
+
|
39
|
+
@network.edit(1, :network_group_id => 1)
|
40
|
+
@network.success.should be_true
|
41
|
+
|
42
|
+
@network.edit(1, :identifier => 'lolzsdfds')
|
43
|
+
@network.success.should be_true
|
44
|
+
|
45
|
+
@network.edit(1, :vlan => 1)
|
46
|
+
@network.success.should be_true
|
47
|
+
|
48
|
+
@network.edit(1, :label => 'two', :vlan => 2, :identifier => 'woah')
|
49
|
+
@network.success.should be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "404s on not found" do
|
53
|
+
expect { @network.edit(404) }.to raise_error(Squall::NotFound)
|
54
|
+
@network.success.should be_false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#create" do
|
59
|
+
use_vcr_cassette "network/create"
|
60
|
+
it "requires label" do
|
61
|
+
requires_attr(:label) { @network.create }
|
62
|
+
end
|
63
|
+
|
64
|
+
it "raises error on duplicate account" do
|
65
|
+
pending "Broken in OnApp" do
|
66
|
+
expect {
|
67
|
+
@network.create(:label => 'networktaken')
|
68
|
+
}.to raise_error(Squall::RequestError)
|
69
|
+
@network.errors['label'].should include("has already been taken")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it "raises error on invalid params" do
|
74
|
+
expect {
|
75
|
+
@network.create(:what => 'networktaken', :label => 'wut')
|
76
|
+
}.to raise_error(ArgumentError, 'Unknown params: what')
|
77
|
+
end
|
78
|
+
|
79
|
+
it "creates a network" do
|
80
|
+
network = @network.create(:label => 'newnetwork', :vlan => 1, :identifier => 'newnetworkid')
|
81
|
+
@network.success.should be_true
|
82
|
+
|
83
|
+
network['label'].should == 'newnetwork'
|
84
|
+
network['vlan'].should == 1
|
85
|
+
network['identifier'].should == 'newnetworkid'
|
86
|
+
|
87
|
+
network = @network.create(:label => 'newnetwork')
|
88
|
+
network['label'].should == 'newnetwork'
|
89
|
+
network['vlan'].should be_nil
|
90
|
+
@network.success.should be_true
|
91
|
+
|
92
|
+
network = @network.create(:label => 'newnetwork', :vlan => 2)
|
93
|
+
network['label'].should == 'newnetwork'
|
94
|
+
network['vlan'].should == 2
|
95
|
+
@network.success.should be_true
|
96
|
+
|
97
|
+
network = @network.create(:label => 'newnetwork', :identifier => 'something')
|
98
|
+
network['label'].should == 'newnetwork'
|
99
|
+
network['identifier'].should == 'something'
|
100
|
+
@network.success.should be_true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#delete" do
|
105
|
+
use_vcr_cassette 'network/delete'
|
106
|
+
it "requires an id" do
|
107
|
+
expect { @network.delete }.to raise_error(ArgumentError)
|
108
|
+
@network.success.should be_false
|
109
|
+
end
|
110
|
+
|
111
|
+
it "404s on not found" do
|
112
|
+
expect { @network.delete(404) }.to raise_error(Squall::NotFound)
|
113
|
+
@network.success.should be_false
|
114
|
+
end
|
115
|
+
|
116
|
+
it "deletes the network" do
|
117
|
+
delete = @network.delete(16)
|
118
|
+
@network.success.should be_true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Squall::Role do
|
4
|
+
before(:each) do
|
5
|
+
default_config
|
6
|
+
@role = Squall::Role.new
|
7
|
+
@keys = ["label", "created_at", "updated_at", "id", "permissions", "identifier"]
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#list" do
|
11
|
+
use_vcr_cassette "role/list"
|
12
|
+
it "returns roles" do
|
13
|
+
roles = @role.list
|
14
|
+
roles.size.should be(2)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "contains the role of a user" do
|
18
|
+
role = @role.list.first
|
19
|
+
role.keys.should include(*@keys)
|
20
|
+
role['label'].should == "Administrator"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#show" do
|
25
|
+
use_vcr_cassette "role/show"
|
26
|
+
it "requires an id" do
|
27
|
+
expect { @role.show }.to raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns not found for invalid user" do
|
31
|
+
expect { @role.show(5) }.to raise_error(Squall::NotFound)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns a role" do
|
35
|
+
role = @role.show(1)
|
36
|
+
role.keys.should include(*@keys)
|
37
|
+
role['label'].should == "Administrator"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#edit" do
|
42
|
+
use_vcr_cassette "role/edit"
|
43
|
+
it "requires an id" do
|
44
|
+
expect { @role.edit }.to raise_error(ArgumentError)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns not found for invalid user" do
|
48
|
+
expect { @role.edit(5) }.to raise_error(Squall::NotFound)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "allows :label and/or :permission" do
|
52
|
+
expect { @role.edit(3, :missing => 1) }.to raise_error(ArgumentError, /Unknown.*missing/)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "updates the role" do
|
56
|
+
pending "OnApp is returning an empty response" do
|
57
|
+
old_role = @role.show(3)
|
58
|
+
old_role['label'].should == "Other"
|
59
|
+
|
60
|
+
new_role = @role.edit(3, :label => 'New')
|
61
|
+
new_role['label'].should == 'New'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#delete" do
|
67
|
+
use_vcr_cassette "role/delete"
|
68
|
+
it "requires an id" do
|
69
|
+
expect { @role.delete }.to raise_error(ArgumentError)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns not found for invalid user" do
|
73
|
+
expect { @role.delete(5) }.to raise_error(Squall::NotFound)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns a role" do
|
77
|
+
role = @role.delete(3)
|
78
|
+
@role.success.should be_true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#permissions" do
|
83
|
+
use_vcr_cassette "role/permissions"
|
84
|
+
it "returns permissions" do
|
85
|
+
permissions = @role.permissions
|
86
|
+
permissions.size.should be(229)
|
87
|
+
|
88
|
+
keys = ["label", "created_at", "updated_at", "id", "identifier"]
|
89
|
+
first = permissions.first
|
90
|
+
first.keys.should include(*keys)
|
91
|
+
|
92
|
+
keys.each do |key|
|
93
|
+
first[key].should_not be_nil
|
94
|
+
first[key].to_s.size.should be >= 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#create" do
|
100
|
+
use_vcr_cassette "role/create"
|
101
|
+
it "requires login" do
|
102
|
+
requires_attr(:label) { @role.create }
|
103
|
+
end
|
104
|
+
|
105
|
+
it "requires label" do
|
106
|
+
requires_attr(:identifier) { @role.create(:label => 'my-label') }
|
107
|
+
end
|
108
|
+
|
109
|
+
it "raises error on duplicate" do
|
110
|
+
expect {
|
111
|
+
@role.create(:label => 'Test', :identifier => 'testing')
|
112
|
+
}.to raise_error(Squall::RequestError)
|
113
|
+
@role.errors['identifier'].should include("has already been taken")
|
114
|
+
end
|
115
|
+
|
116
|
+
it "creates a role" do
|
117
|
+
value = {:label => 'Test Create', :identifier => 'testing-create'}
|
118
|
+
role = @role.create(value)
|
119
|
+
role['label'].should == value[:label]
|
120
|
+
role['identifier'].should == value[:identifier]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Squall::Statistic do
|
4
|
+
before(:each) do
|
5
|
+
default_config
|
6
|
+
@statistic = Squall::Statistic.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#usage_statistic" do
|
10
|
+
use_vcr_cassette "statistic/usage_statistics"
|
11
|
+
|
12
|
+
it "requires an id" do
|
13
|
+
expect { @statistic.daily_stats }.to raise_error(ArgumentError)
|
14
|
+
@statistic.success.should be_false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns the daily statistics" do
|
18
|
+
result = @statistic.daily_stats(1)
|
19
|
+
result['id'].to_i.should == 1
|
20
|
+
result['cost'].to_f.should == 0.0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|