squall 0.0.3 → 1.0.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 (100) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +100 -0
  7. data/LICENSE +1 -1
  8. data/README.md +69 -0
  9. data/Rakefile +48 -42
  10. data/lib/squall/base.rb +96 -0
  11. data/lib/squall/config.rb +26 -0
  12. data/lib/squall/exception.rb +13 -0
  13. data/lib/squall/hypervisor.rb +46 -16
  14. data/lib/squall/ip_address.rb +13 -0
  15. data/lib/squall/network.rb +42 -0
  16. data/lib/squall/params.rb +50 -0
  17. data/lib/squall/role.rb +56 -0
  18. data/lib/squall/statistic.rb +10 -0
  19. data/lib/squall/template.rb +22 -0
  20. data/lib/squall/transaction.rb +16 -0
  21. data/lib/squall/user.rb +87 -0
  22. data/lib/squall/version.rb +3 -0
  23. data/lib/squall/virtual_machine.rb +169 -41
  24. data/lib/squall.rb +76 -20
  25. data/spec/params_spec.rb +195 -0
  26. data/spec/spec_helper.rb +47 -0
  27. data/spec/squall/base_spec.rb +135 -0
  28. data/spec/squall/config_spec.rb +44 -0
  29. data/spec/squall/hypervisor_spec.rb +143 -0
  30. data/spec/squall/ip_address_spec.rb +32 -0
  31. data/spec/squall/network_spec.rb +121 -0
  32. data/spec/squall/role_spec.rb +123 -0
  33. data/spec/squall/statistic_spec.rb +23 -0
  34. data/spec/squall/template_spec.rb +59 -0
  35. data/spec/squall/transaction_spec.rb +42 -0
  36. data/spec/squall/user_spec.rb +195 -0
  37. data/spec/squall/virtual_machine_spec.rb +471 -0
  38. data/spec/squall_spec.rb +67 -0
  39. data/spec/vcr_cassettes/hypervisor/create.yml +77 -0
  40. data/spec/vcr_cassettes/hypervisor/delete.yml +77 -0
  41. data/spec/vcr_cassettes/hypervisor/edit.yml +79 -0
  42. data/spec/vcr_cassettes/hypervisor/list.yml +40 -0
  43. data/spec/vcr_cassettes/hypervisor/reboot.yml +77 -0
  44. data/spec/vcr_cassettes/hypervisor/show.yml +77 -0
  45. data/spec/vcr_cassettes/ipaddress/list.yml +77 -0
  46. data/spec/vcr_cassettes/network/create.yml +196 -0
  47. data/spec/vcr_cassettes/network/delete.yml +77 -0
  48. data/spec/vcr_cassettes/network/edit.yml +233 -0
  49. data/spec/vcr_cassettes/network/list.yml +40 -0
  50. data/spec/vcr_cassettes/role/create.yml +77 -0
  51. data/spec/vcr_cassettes/role/delete.yml +77 -0
  52. data/spec/vcr_cassettes/role/edit.yml +139 -0
  53. data/spec/vcr_cassettes/role/list.yml +40 -0
  54. data/spec/vcr_cassettes/role/permissions.yml +40 -0
  55. data/spec/vcr_cassettes/role/show.yml +77 -0
  56. data/spec/vcr_cassettes/statistic/usage_statistics.yml +40 -0
  57. data/spec/vcr_cassettes/template/download.yml +40 -0
  58. data/spec/vcr_cassettes/template/list.yml +40 -0
  59. data/spec/vcr_cassettes/template/make_public.yml +77 -0
  60. data/spec/vcr_cassettes/transaction/list.yml +40 -0
  61. data/spec/vcr_cassettes/transaction/show.yml +77 -0
  62. data/spec/vcr_cassettes/user/activate.yml +40 -0
  63. data/spec/vcr_cassettes/user/create.yml +116 -0
  64. data/spec/vcr_cassettes/user/delete.yml +77 -0
  65. data/spec/vcr_cassettes/user/edit_role.yml +116 -0
  66. data/spec/vcr_cassettes/user/generate_api_key.yml +40 -0
  67. data/spec/vcr_cassettes/user/list.yml +40 -0
  68. data/spec/vcr_cassettes/user/show.yml +77 -0
  69. data/spec/vcr_cassettes/user/stats.yml +40 -0
  70. data/spec/vcr_cassettes/user/suspend.yml +40 -0
  71. data/spec/vcr_cassettes/user/virtual_machines.yml +79 -0
  72. data/spec/vcr_cassettes/virtual_machine/build.yml +77 -0
  73. data/spec/vcr_cassettes/virtual_machine/change_owner.yml +108 -0
  74. data/spec/vcr_cassettes/virtual_machine/change_password.yml +77 -0
  75. data/spec/vcr_cassettes/virtual_machine/create.yml +40 -0
  76. data/spec/vcr_cassettes/virtual_machine/delete.yml +77 -0
  77. data/spec/vcr_cassettes/virtual_machine/edit.yml +77 -0
  78. data/spec/vcr_cassettes/virtual_machine/list.yml +40 -0
  79. data/spec/vcr_cassettes/virtual_machine/migrate.yml +116 -0
  80. data/spec/vcr_cassettes/virtual_machine/reboot.yml +77 -0
  81. data/spec/vcr_cassettes/virtual_machine/resize.yml +77 -0
  82. data/spec/vcr_cassettes/virtual_machine/show.yml +77 -0
  83. data/spec/vcr_cassettes/virtual_machine/shutdown.yml +77 -0
  84. data/spec/vcr_cassettes/virtual_machine/startup.yml +77 -0
  85. data/spec/vcr_cassettes/virtual_machine/stop.yml +77 -0
  86. data/spec/vcr_cassettes/virtual_machine/suspend.yml +77 -0
  87. data/spec/vcr_cassettes/virtual_machine/unlock.yml +77 -0
  88. data/spec/vcr_cassettes/virtual_machine/unsuspend.yml +77 -0
  89. data/squall.gemspec +25 -62
  90. metadata +224 -42
  91. data/.document +0 -5
  92. data/README.rdoc +0 -17
  93. data/VERSION.yml +0 -5
  94. data/lib/squall/client.rb +0 -87
  95. data/test/fixtures/virtual_machines.json +0 -1
  96. data/test/fixtures/virtual_machines_1.json +0 -1
  97. data/test/helper.rb +0 -31
  98. data/test/test_client.rb +0 -152
  99. data/test/test_squall.rb +0 -12
  100. data/test/test_virtual_machine.rb +0 -98
@@ -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