shelly 0.1.34 → 0.1.35

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.
@@ -0,0 +1,44 @@
1
+ require "spec_helper"
2
+ require "shelly/cli/organization"
3
+
4
+ describe Shelly::CLI::Organization do
5
+ before do
6
+ FileUtils.stub(:chmod)
7
+ @organization = Shelly::CLI::Organization.new
8
+ Shelly::CLI::Organization.stub(:new).and_return(@organization)
9
+ @client = mock
10
+ Shelly::Client.stub(:new).and_return(@client)
11
+ $stdout.stub(:puts)
12
+ $stdout.stub(:print)
13
+ @client.stub(:token).and_return("abc")
14
+ FileUtils.mkdir_p("/projects/foo")
15
+ Dir.chdir("/projects/foo")
16
+ end
17
+
18
+ describe "#list" do
19
+ before do
20
+ @client.stub(:token).and_return("abc")
21
+ @client.stub(:organizations).and_return([
22
+ {"name" => "aaa", "app_code_names" => ["app1"]},
23
+ {"name" => "ccc", "app_code_names" => ["app2", "app3"]}
24
+ ])
25
+ @client.stub(:app).with("app1").and_return("state" => "running")
26
+ @client.stub(:app).with("app2").and_return("state" => "turned_off")
27
+ @client.stub(:app).with("app3").and_return("state" => "no_code")
28
+ end
29
+
30
+ it "should ensure user has logged in" do
31
+ hooks(@organization, :list).should include(:logged_in?)
32
+ end
33
+
34
+ it "should print out all organizations with apps" do
35
+ $stdout.should_receive(:puts).with(green("You have access to the following organizations and clouds:"))
36
+ $stdout.should_receive(:puts).with(green("aaa"))
37
+ $stdout.should_receive(:puts).with(/app1 \s+ | running/)
38
+ $stdout.should_receive(:puts).with(green("ccc"))
39
+ $stdout.should_receive(:puts).with(/app2 \s+ | turned off/)
40
+ $stdout.should_receive(:puts).with(/app3 \s+ | no code/)
41
+ invoke(@organization, :list)
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,6 @@
1
1
  require "spec_helper"
2
2
  require "shelly/cli/user"
3
+ require "shelly/cli/organization"
3
4
 
4
5
  describe Shelly::CLI::User do
5
6
  before do
@@ -15,40 +16,45 @@ describe Shelly::CLI::User do
15
16
  Dir.chdir("/projects/foo")
16
17
  @app = Shelly::App.new("foo-staging")
17
18
  File.open("Cloudfile", 'w') {|f| f.write("foo-staging:\n") }
19
+
20
+ @client.stub(:members).and_return({})
18
21
  end
19
22
 
20
23
  describe "#help" do
21
24
  it "should show help" do
22
25
  $stdout.should_receive(:puts).with("Tasks:")
23
- $stdout.should_receive(:puts).with(/add \[EMAIL\]\s+# Add new developer to clouds defined in Cloudfile/)
24
- $stdout.should_receive(:puts).with(/list\s+# List users with access to clouds defined in Cloudfile/)
26
+ $stdout.should_receive(:puts).with(/add \[EMAIL\]\s+# Add new developer to organization/)
27
+ $stdout.should_receive(:puts).with(/list\s+# List users with access to organizations/)
28
+ $stdout.should_receive(:puts).with(/delete \[EMAIL\]\s+# Remove developer from organization/)
25
29
  invoke(@cli_user, :help)
26
30
  end
27
31
  end
28
32
 
29
33
  describe "#list" do
34
+ let(:organizations){
35
+ [{"name" => "org1"}]
36
+ }
37
+
30
38
  let(:response) {
31
- [{'email' => 'user@example.com', 'active' => true},
32
- {'email' => 'auser2@example2.com', 'active' => false}]
39
+ [{'email' => 'user@example.com', 'active' => true, "owner" => true},
40
+ {'email' => 'user2@example2.com', 'active' => true, "owner" => false},
41
+ {'email' => 'user3@example3.com', 'active' => false, "owner" => true}]
33
42
  }
34
43
 
35
44
  it "should ensure user has logged in" do
36
45
  hooks(@cli_user, :list).should include(:logged_in?)
37
46
  end
38
47
 
39
- # multiple_clouds is tested in main_spec.rb in describe "#start" block
40
- it "should ensure multiple_clouds check" do
41
- @client.stub(:collaborations).and_return(response)
42
- @cli_user.should_receive(:multiple_clouds).and_return(@app)
43
- invoke(@cli_user, :list)
44
- end
45
-
46
48
  context "on success" do
47
- it "should display clouds and users" do
48
- @client.stub(:collaborations).and_return(response)
49
- $stdout.should_receive(:puts).with("Cloud foo-staging:")
50
- $stdout.should_receive(:puts).with(" user@example.com")
51
- $stdout.should_receive(:puts).with(" auser2@example2.com (invited)")
49
+ it "should display organization's users" do
50
+ @cli_user.options = {:organization => "foo-org"}
51
+ @client.stub(:organizations).and_return(organizations)
52
+ @client.stub(:members).and_return(response)
53
+ $stdout.should_receive(:puts).with("Organizations with users:")
54
+ $stdout.should_receive(:puts).with(green " org1")
55
+ $stdout.should_receive(:puts).with(/user@example.com\s+ \| owner/)
56
+ $stdout.should_receive(:puts).with(/user2@example2.com\s+ \| member/)
57
+ $stdout.should_receive(:puts).with(/user3@example3.com \(invited\)\s+ \| owner/)
52
58
  invoke(@cli_user, :list)
53
59
  end
54
60
  end
@@ -56,78 +62,108 @@ describe Shelly::CLI::User do
56
62
 
57
63
  describe "#add" do
58
64
  before do
59
- @user = Shelly::User.new
60
- @client.stub(:apps).and_return([{"code_name" => "abc"}, {"code_name" => "fooo"}])
61
- Shelly::User.stub(:new).and_return(@user)
65
+ @organization = Shelly::Organization.new("name" => "foo-org")
66
+ Shelly::Organization.stub(:new).and_return(@organization)
67
+ @cli_user.options = {:organization => "foo-org"}
62
68
  end
63
69
 
64
70
  it "should ensure user has logged in" do
65
71
  hooks(@cli_user, :add).should include(:logged_in?)
66
72
  end
67
73
 
68
-
69
74
  context "on success" do
70
75
  before do
71
- @client.should_receive(:send_invitation).with("foo-staging", "megan@example.com")
72
- end
73
-
74
- # multiple_clouds is tested in main_spec.rb in describe "#start" block
75
- it "should ensure multiple_clouds check" do
76
- @cli_user.should_receive(:multiple_clouds).and_return(@app)
77
- invoke(@cli_user, :add, "megan@example.com")
76
+ @client.should_receive(:send_invitation).with("foo-org", "megan@example.com", true)
78
77
  end
79
78
 
80
79
  it "should ask about email" do
81
- fake_stdin(["megan@example.com"]) do
80
+ $stdout.should_receive(:puts).with(green "Sending invitation to megan@example.com to work on foo-org organization")
81
+ fake_stdin(["megan@example.com", "yes"]) do
82
82
  invoke(@cli_user, :add)
83
83
  end
84
84
  end
85
85
 
86
- it "should receive clouds from the Cloudfile" do
87
- invoke(@cli_user, :add, "megan@example.com")
86
+ it "should use email from argument" do
87
+ $stdout.should_receive(:puts).with(green "Sending invitation to megan@example.com to work on foo-org organization")
88
+ fake_stdin(["yes"]) do
89
+ invoke(@cli_user, :add, "megan@example.com")
90
+ end
91
+ end
92
+ end
93
+
94
+ context "on failure" do
95
+ it "should list all user's organizations" do
96
+ @cli_user.options = {}
97
+ $stdout.should_receive(:puts).with(red "You have to specify organization")
98
+ $stdout.should_receive(:puts).with("Select organization using `shelly user add [EMAIL] --organization ORGANIZATION_NAME`")
99
+ Shelly::CLI::Organization.stub_chain(:new, :list)
100
+ lambda do
101
+ invoke(@cli_user, :add, "megan@example.com")
102
+ end.should raise_error(SystemExit)
103
+ end
104
+
105
+ it "should display forbidden exception" do
106
+ exception = Shelly::Client::ForbiddenException.new({})
107
+ @client.stub(:send_invitation).and_raise(exception)
108
+ $stdout.should_receive(:puts).with(red "You have to be organization's owner to add new members")
109
+
110
+ lambda do
111
+ fake_stdin(["yes"]) { invoke(@cli_user, :add, "megan@example.com") }
112
+ end.should raise_error(SystemExit)
113
+ end
114
+
115
+ it "should display not found" do
116
+ response = {"resource" => "organization"}
117
+ exception = Shelly::Client::NotFoundException.new(response)
118
+ @client.stub(:send_invitation).and_raise(exception)
119
+
120
+ $stdout.should_receive(:puts).with(red "Organization 'foo-org' not found")
121
+ $stdout.should_receive(:puts).with(red "You can list organizations you have access to with `shelly organization list`")
122
+ lambda do
123
+ fake_stdin(["yes"]) { invoke(@cli_user, :add, "megan@example.com") }
124
+ end.should raise_error(SystemExit)
88
125
  end
89
126
 
90
- it "should receive clouds from the Cloudfile" do
91
- $stdout.should_receive(:puts).with("\e[32mSending invitation to megan@example.com to work on foo-staging\e[0m")
92
- invoke(@cli_user, :add, "megan@example.com")
127
+ it "should display validation exception" do
128
+ body = {"message" => "Validation Failed", "errors" => [["email", "megan@example.com has been already taken"]]}
129
+ exception = Shelly::Client::ValidationException.new(body)
130
+ @client.stub(:send_invitation).and_raise(exception)
131
+ $stdout.should_receive(:puts).with(red "User megan@example.com is already in the organization foo-org")
132
+
133
+ lambda do
134
+ fake_stdin(["yes"]) { invoke(@cli_user, :add, "megan@example.com") }
135
+ end.should raise_error(SystemExit)
93
136
  end
94
137
  end
95
138
  end
96
139
 
97
140
  describe "#delete" do
98
141
  before do
99
- @user = Shelly::User.new
100
- @client.stub(:apps).and_return([{"code_name" => "abc"}, {"code_name" => "fooo"}])
101
- Shelly::User.stub(:new).and_return(@user)
142
+ @organization = Shelly::Organization.new("name" => "foo-org")
143
+ Shelly::Organization.stub(:new).and_return(@organization)
144
+ @cli_user.options = {:organization => "foo-org"}
102
145
  end
103
146
 
104
147
  it "should ensure user has logged in" do
105
148
  hooks(@cli_user, :delete).should include(:logged_in?)
106
149
  end
107
150
 
108
- # multiple_clouds is tested in main_spec.rb in describe "#start" block
109
- it "should ensure multiple_clouds check" do
110
- @client.should_receive(:delete_collaboration).with("foo-staging", "megan@example.com")
111
- @cli_user.should_receive(:multiple_clouds).and_return(@app)
112
- invoke(@cli_user, :delete, "megan@example.com")
113
- end
114
-
115
151
  context "on success" do
116
152
  it "should ask about email" do
117
- @client.should_receive(:delete_collaboration).with("foo-staging", "megan@example.com")
153
+ @client.should_receive(:delete_member).with("foo-org", "megan@example.com")
118
154
  fake_stdin(["megan@example.com"]) do
119
155
  invoke(@cli_user, :delete)
120
156
  end
121
157
  end
122
158
 
123
159
  it "should receive email from param" do
124
- @client.should_receive(:delete_collaboration).with("foo-staging", "megan@example.com")
160
+ @client.should_receive(:delete_member).with("foo-org", "megan@example.com")
125
161
  invoke(@cli_user, :delete, "megan@example.com")
126
162
  end
127
163
 
128
164
  it "should show that user was removed" do
129
- @client.stub(:delete_collaboration)
130
- $stdout.should_receive(:puts).with("User megan@example.com deleted from cloud foo-staging")
165
+ @client.stub(:delete_member)
166
+ $stdout.should_receive(:puts).with("User megan@example.com deleted from organization foo-org")
131
167
  invoke(@cli_user, :delete, "megan@example.com")
132
168
  end
133
169
  end
@@ -135,7 +171,7 @@ describe Shelly::CLI::User do
135
171
  context "on failure" do
136
172
  it "should show that user wasn't found" do
137
173
  exception = Shelly::Client::NotFoundException.new("resource" => "user")
138
- @client.stub(:delete_collaboration).and_raise(exception)
174
+ @client.stub(:delete_member).and_raise(exception)
139
175
  $stdout.should_receive(:puts).with(red "User 'megan@example.com' not found")
140
176
  $stdout.should_receive(:puts).with(red "You can list users with `shelly user list`")
141
177
  lambda {
@@ -143,15 +179,35 @@ describe Shelly::CLI::User do
143
179
  }.should raise_error(SystemExit)
144
180
  end
145
181
 
182
+ it "should show that organization wasn't found" do
183
+ exception = Shelly::Client::NotFoundException.new("resource" => "organization")
184
+ @client.stub(:delete_member).and_raise(exception)
185
+ $stdout.should_receive(:puts).with(red "Organization 'foo-org' not found")
186
+ $stdout.should_receive(:puts).with(red "You can list organizations you have access to with `shelly organization list`")
187
+ lambda {
188
+ invoke(@cli_user, :delete, "megan@example.com")
189
+ }.should raise_error(SystemExit)
190
+ end
191
+
146
192
  it "should show that user can't delete own collaboration" do
147
193
  exception = Shelly::Client::ConflictException.new("message" =>
148
194
  "Can't remove own collaboration")
149
- @client.stub(:delete_collaboration).and_raise(exception)
195
+ @client.stub(:delete_member).and_raise(exception)
150
196
  $stdout.should_receive(:puts).with(red "Can't remove own collaboration")
151
197
  lambda {
152
198
  invoke(@cli_user, :delete, "megan@example.com")
153
199
  }.should raise_error(SystemExit)
154
200
  end
201
+
202
+ it "should show forbidden exception" do
203
+ exception = Shelly::Client::ForbiddenException.new({})
204
+ @client.stub(:delete_member).and_raise(exception)
205
+ $stdout.should_receive(:puts).with(red "You have to be organization's owner to remove members")
206
+
207
+ lambda {
208
+ invoke(@cli_user, :delete, "megan@example.com")
209
+ }.should raise_error(SystemExit)
210
+ end
155
211
  end
156
212
  end
157
213
  end
@@ -165,17 +165,43 @@ describe Shelly::Client do
165
165
 
166
166
  describe "#create_app" do
167
167
  it "should send post with app's attributes" do
168
- @client.should_receive(:post).with("/apps", :app => {:code_name => "foo", :ruby_version => "1.9.2"})
168
+ @client.should_receive(:post).with("/apps", :app => {:code_name => "foo", :ruby_version => "1.9.2"}, :organization_name => nil)
169
169
  @client.create_app(:code_name => "foo", :ruby_version => "1.9.2")
170
170
  end
171
+
172
+ it "should send post with app's attributes and organization name" do
173
+ @client.should_receive(:post).with("/apps", :app => {:code_name => "foo", :ruby_version => "1.9.2"}, :organization_name => "foo")
174
+ @client.create_app(:code_name => "foo", :ruby_version => "1.9.2", :organization_name => "foo")
175
+ end
176
+
177
+ end
178
+
179
+ describe "#organizations" do
180
+ it "should fetch organizations from API" do
181
+ FakeWeb.register_uri(:get, api_url("organizations"),
182
+ :body => [{:name => "org1", :app_code_names => ["app1"]},
183
+ {:name => "org2", :app_code_names => ["app2"]}].to_json)
184
+ response = @client.organizations
185
+ response.should == [{"name" => "org1", "app_code_names" => ["app1"]},
186
+ {"name" => "org2", "app_code_names" => ["app2"]}]
187
+ end
188
+ end
189
+
190
+ describe "#organization" do
191
+ it "should fetch organization from API" do
192
+ FakeWeb.register_uri(:get, api_url("organizations/foo-org"),
193
+ :body => {:name => "org1", :app_code_names => ["app1"]}.to_json)
194
+ response = @client.organization("foo-org")
195
+ response.should == {"name" => "org1", "app_code_names" => ["app1"]}
196
+ end
171
197
  end
172
198
 
173
- describe "#collaborations" do
199
+ describe "#members" do
174
200
  it "should send get request with app code_names" do
175
- FakeWeb.register_uri(:get, api_url("apps/staging-foo/collaborations"),
201
+ FakeWeb.register_uri(:get, api_url("organizations/staging-foo/memberships"),
176
202
  :body => [{:email => "test@example.com", :active => true},
177
203
  {:email => "test2@example.com", :active => false}].to_json)
178
- response = @client.collaborations("staging-foo")
204
+ response = @client.members("staging-foo")
179
205
  response.should == [{"email" => "test@example.com", 'active' => true},
180
206
  {"email" => "test2@example.com", 'active' => false}]
181
207
  end
@@ -229,7 +255,7 @@ describe Shelly::Client do
229
255
 
230
256
  describe "#send_invitation" do
231
257
  it "should send post with developer's email" do
232
- FakeWeb.register_uri(:post, api_url("apps/staging-foo/collaborations"), :body => {}.to_json)
258
+ FakeWeb.register_uri(:post, api_url("organizations/staging-foo/memberships"), :body => {}.to_json)
233
259
  response = @client.send_invitation("staging-foo", "megan@example.com")
234
260
  response.should == {}
235
261
  end
@@ -237,8 +263,8 @@ describe Shelly::Client do
237
263
 
238
264
  describe "#delete_collaboration" do
239
265
  it "should send delete with developer's email in url" do
240
- FakeWeb.register_uri(:delete, api_url("apps/staging-foo/collaborations/megan@example.com"), :body => {}.to_json)
241
- @client.delete_collaboration("staging-foo", "megan@example.com")
266
+ FakeWeb.register_uri(:delete, api_url("organizations/staging-foo/memberships/megan@example.com"), :body => {}.to_json)
267
+ @client.delete_member("staging-foo", "megan@example.com")
242
268
  end
243
269
  end
244
270
 
@@ -0,0 +1,78 @@
1
+ require "spec_helper"
2
+ require "shelly/organization"
3
+
4
+ describe Shelly::Organization do
5
+ before do
6
+ @client = mock
7
+ Shelly::Client.stub(:new).and_return(@client)
8
+ @organization = Shelly::Organization.new({"name" => "foo-org",
9
+ "app_code_names" => ['foo-staging']})
10
+ end
11
+
12
+ describe "#apps" do
13
+ it "should initialize App objects" do
14
+ Shelly::App.should_receive(:new).with('foo-staging')
15
+ @organization.apps
16
+ end
17
+ end
18
+
19
+ describe "#memberships" do
20
+ before do
21
+ response = [{"email" => "bb@example.com", "active" => true, "owner" => true},
22
+ {"email" => "aa@example.com", "active" => true, "owner" => false},
23
+ {"email" => "cc@example.com", "active" => false, "owner" => true},
24
+ {"email" => "dd@example.com", "active" => false, "owner" => false}]
25
+ @client.stub(:members).with("foo-org").and_return(response)
26
+ end
27
+
28
+ it "should fetch organization's users" do
29
+ @client.should_receive(:members).with("foo-org")
30
+ @organization.memberships
31
+ end
32
+
33
+ it "should sort members by email" do
34
+ members = @organization.memberships
35
+ members.should == [{"email"=>"aa@example.com", "active"=>true, "owner"=>false},
36
+ {"email"=>"bb@example.com", "active"=>true, "owner"=>true},
37
+ {"email"=>"cc@example.com", "active"=>false, "owner"=>true},
38
+ {"email"=>"dd@example.com", "active"=>false, "owner"=>false}]
39
+ end
40
+
41
+
42
+ context "owners" do
43
+ it "should return only owners without inactive members" do
44
+ owners = @organization.owners
45
+ owners.should == [{"email"=>"bb@example.com", "active"=>true, "owner"=>true}]
46
+ end
47
+ end
48
+
49
+ context "members" do
50
+ it "should return only members without inactive members" do
51
+ members = @organization.members
52
+ members.should == [{"email"=>"aa@example.com", "active"=>true, "owner"=>false}]
53
+ end
54
+ end
55
+
56
+ context "inactive_members" do
57
+ it "should return only inactive members" do
58
+ inactive = @organization.inactive_members
59
+ inactive.should == [{"email"=>"cc@example.com", "active"=>false, "owner"=>true},
60
+ {"email"=>"dd@example.com", "active"=>false, "owner"=>false}]
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "#send_invitation" do
66
+ it "should send invitation" do
67
+ @client.should_receive(:send_invitation).with("foo-org", "megan@example.com", true)
68
+ @organization.send_invitation("megan@example.com", true)
69
+ end
70
+ end
71
+
72
+ describe "#delete_member" do
73
+ it "should delete collaboration" do
74
+ @client.should_receive(:delete_member).with("foo-org", "megan@example.com")
75
+ @organization.delete_member("megan@example.com")
76
+ end
77
+ end
78
+ end
@@ -104,20 +104,6 @@ describe Shelly::User do
104
104
  end
105
105
  end
106
106
 
107
- describe "#send_invitation" do
108
- it "should send invitation" do
109
- @client.should_receive(:send_invitation).with("foo-staging", "megan@example.com")
110
- @user.send_invitation("foo-staging", "megan@example.com")
111
- end
112
- end
113
-
114
- describe "#delete_collaboration" do
115
- it "should delete collaboration" do
116
- @client.should_receive(:delete_collaboration).with("foo-staging", "megan@example.com")
117
- @user.delete_collaboration("foo-staging", "megan@example.com")
118
- end
119
- end
120
-
121
107
  describe "#ssh_key_path" do
122
108
  it "should return path to public dsa key file in the first place" do
123
109
  @user.ssh_key_path.should == File.expand_path("~/.ssh/id_dsa.pub")
@@ -195,5 +181,13 @@ describe Shelly::User do
195
181
  @user.apps
196
182
  end
197
183
  end
198
- end
199
184
 
185
+ describe "#organizations" do
186
+ it "should initialaize organizations objects" do
187
+ organizations = [{"name" => "org1"}]
188
+ @client.should_receive(:organizations).and_return(organizations)
189
+ Shelly::Organization.should_receive(:new).with({"name" => "org1"})
190
+ @user.organizations
191
+ end
192
+ end
193
+ end