gliffy 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YzU3NGY4YjYxMzMzMTg4ZmUwMjBmYWE4Y2E5NWQ3MGUwMzgwNWU1Nw==
5
- data.tar.gz: !binary |-
6
- YzhkNzViNDI3ZWMyMWFlZWI0NzM5MjI5MjFkZjUzYjk5MzJkNzhmOQ==
2
+ SHA1:
3
+ metadata.gz: d08e7fc8875943cfbb8dc56185f6162cc3ea967b
4
+ data.tar.gz: df6d8c71405d5fc7ad14523bda869bd45ed20f5e
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YmU2NDFiMWYwZGZiMDRiMmU3YjZhNDE2MjY3OWI2MzYwOTVmMzE0NWI3MjYz
10
- YTEzM2NkYTgzY2E0ZDIwOWUwNGI5NjE3Nzk2NDIxMTA4ZTcyZDI0YzE0NTBk
11
- OTg2OTAwN2ZkNzVkMjM4ZmYyMmIzYzE2OTVmNzBjMTNlYTE1ZjM=
12
- data.tar.gz: !binary |-
13
- NTE2NDVlNzQ5MTBlNDVhYTA3ZTQ0ZGJkOTMyYTQ4Yzk0NmMxY2NiMjkzZDA3
14
- ZjNjYmJhZTA3ZmM2NGMwNDFlYjE2ZjJhMWE2OTVhY2M3ZmExYjAyYWJjNDQy
15
- Y2M2MGFlMjgxODViNzVhYmIzNDRkZWJjYWYyNzVhMzgzZGE2NWE=
6
+ metadata.gz: 2ca1cd73e086d17d17638300d2440d64c88b30035be88da258e803adcabaf084cf2c26d83bf51189ee3b85ee2f546256b714e8857babbe88003ee04ceab85f08
7
+ data.tar.gz: 6d204415352c176034d4c1a69ff7e5db4fef0b51a05058355d4919c95e46b9c69afd270fe95d423fac776ef97e3c23a1ec7726dcd145295941261c5e63400b86
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) [year] [fullname]
3
+ Copyright (c) 2013 Konstantin Burnaev
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -24,6 +24,9 @@ Basic usage
24
24
 
25
25
  doc.delete
26
26
 
27
+ doc.public?
28
+ doc.public = false
29
+
27
30
  #### Download document as PNG
28
31
 
29
32
  doc.png.full
@@ -47,3 +50,22 @@ Basic usage
47
50
  root.folders[1].path
48
51
 
49
52
  folder.delete
53
+
54
+ folder.users
55
+ folder.grant_access(user)
56
+ folder.revoke_access(user)
57
+
58
+ ### Users
59
+
60
+ account.users
61
+
62
+ account.users[0].username
63
+ account.users[1].email
64
+
65
+ account.create_user("john-smith")
66
+
67
+ user.email = "new-email@test.com"
68
+ user.password = "new-password"
69
+ user.admin = true
70
+
71
+ user.accessible_folders
data/lib/gliffy.rb CHANGED
@@ -11,6 +11,7 @@ require 'gliffy/document/presentation/png'
11
11
  require 'gliffy/document/presentation/svg'
12
12
  require 'gliffy/document/presentation/xml'
13
13
  require 'gliffy/folder'
14
+ require 'gliffy/user'
14
15
 
15
16
  require 'gliffy/oauth/helper'
16
17
 
@@ -24,6 +24,10 @@ module Gliffy
24
24
  @root ||= load_root
25
25
  end
26
26
 
27
+ def users
28
+ @users ||= load_users
29
+ end
30
+
27
31
  def document(document_id)
28
32
  response = api.get("/accounts/#{id}/documents/#{document_id}/meta-data.xml",
29
33
  :action => 'get')
@@ -34,6 +38,30 @@ module Gliffy
34
38
  )
35
39
  end
36
40
 
41
+ def create_user(username)
42
+ if username =~ /\s/ then
43
+ raise ArgumentError.new(username)
44
+ end
45
+
46
+ if users.select { |u| u.username == username }.length > 0 then
47
+ raise ArgumentError.new(username)
48
+ end
49
+
50
+ api.create_user(username)
51
+ users.select { |u| u.username == username }.first
52
+ end
53
+
54
+ # observer callback
55
+ def update(event, target)
56
+ case event
57
+ when :user_deleted
58
+ @users = @users.delete_if { |element| element == target }
59
+ target.delete_observer(self)
60
+ else
61
+ raise ArgumentError.new(event)
62
+ end
63
+ end
64
+
37
65
  private
38
66
 
39
67
  def initialize(api, params)
@@ -55,5 +83,15 @@ module Gliffy
55
83
  response.node("/g:response/g:folders/g:folder")
56
84
  )
57
85
  end
86
+
87
+ def load_users
88
+ api.get_users(id)
89
+ .nodes('//g:user')
90
+ .map { |n| load_user n }
91
+ end
92
+
93
+ def load_user(node)
94
+ Gliffy::User.load(self, node)
95
+ end
58
96
  end
59
97
  end
@@ -45,7 +45,36 @@ module Gliffy
45
45
 
46
46
  def get_folders(account_id)
47
47
  get("/accounts/#{account_id}/folders.xml",
48
- :action => 'get')
48
+ :action => "get")
49
+ end
50
+
51
+ def folders_accessible_to_user(username)
52
+ get("/accounts/#{account_id}/users/#{username}/folders.xml",
53
+ :action => "get")
54
+ end
55
+
56
+ def users_with_access_to_folder(path)
57
+ get("/accounts/#{account_id}/folders/#{escape_path path}/users.xml",
58
+ :action => "get")
59
+ end
60
+
61
+ def grant_access_to_folder(username, path)
62
+ post("/accounts/#{account_id}/folders/#{escape_path path}/users/#{username}.xml",
63
+ :action => "update",
64
+ :read => "true",
65
+ :write => "true")
66
+ end
67
+
68
+ def revoke_access_to_folder(username, path)
69
+ post("/accounts/#{account_id}/folders/#{escape_path path}/users/#{username}.xml",
70
+ :action => "update",
71
+ :read => "false",
72
+ :write => "false")
73
+ end
74
+
75
+ def get_users(account_id)
76
+ get("/accounts/#{account_id}/users.xml",
77
+ :action => "get")
49
78
  end
50
79
 
51
80
  def update_document_metadata(document_id, name, shared)
@@ -109,6 +138,38 @@ module Gliffy
109
138
  :action => "create")
110
139
  end
111
140
 
141
+ def create_user(username)
142
+ post("/accounts/#{account_id}/users.xml",
143
+ :action => "create",
144
+ :userName => username)
145
+ end
146
+
147
+ def update_user(username, email, password, is_admin)
148
+ params = {
149
+ :action => "update"
150
+ }
151
+
152
+ if not email.nil?
153
+ params[:email] = email
154
+ end
155
+
156
+ if not password.nil?
157
+ params[:password] = password
158
+ end
159
+
160
+ if not is_admin.nil?
161
+ params[:admin] = is_admin ? "true" : "false"
162
+ end
163
+
164
+ post("/accounts/#{account_id}/users/#{username}.xml",
165
+ params)
166
+ end
167
+
168
+ def delete_user(username)
169
+ post("/accounts/#{account_id}/users/#{username}.xml",
170
+ :action => "delete")
171
+ end
172
+
112
173
  private
113
174
 
114
175
  def handle_error(response)
@@ -88,6 +88,11 @@ module Gliffy
88
88
  is_public
89
89
  end
90
90
 
91
+ def public=(value)
92
+ api.update_document_metadata(id, nil, value)
93
+ @is_public = value
94
+ end
95
+
91
96
  def api
92
97
  owner.api
93
98
  end
data/lib/gliffy/folder.rb CHANGED
@@ -31,6 +31,20 @@ module Gliffy
31
31
  @is_deleted = false
32
32
  end
33
33
 
34
+ def users
35
+ api.users_with_access_to_folder(path)
36
+ .nodes("//g:user")
37
+ .map { |n| Gliffy::User.load(owner, n) }
38
+ end
39
+
40
+ def grant_access(user)
41
+ api.grant_access_to_folder(user.username, path)
42
+ end
43
+
44
+ def revoke_access(user)
45
+ api.revoke_access_to_folder(user.username, path)
46
+ end
47
+
34
48
  def parent=(parent)
35
49
  if path != parent.path + "/" + name then
36
50
  raise "Invalid parent"
@@ -0,0 +1,57 @@
1
+ module Gliffy
2
+ class User
3
+ include Observable
4
+
5
+ attr_reader :username, :email
6
+
7
+ def self.load(owner, node)
8
+ Gliffy::User.new(
9
+ owner,
10
+ node.string('g:username'),
11
+ node.string('g:email'),
12
+ )
13
+ end
14
+
15
+ def initialize(owner, username, email)
16
+ @owner = owner
17
+ @username = username
18
+ @email = email
19
+ end
20
+
21
+ def accessible_folders
22
+ api.folders_accessible_to_user(username)
23
+ .nodes("//g:folders/g:folder")
24
+ .map { |n| Gliffy::Folder.load(owner, n) }
25
+ end
26
+
27
+ def delete
28
+ api.delete_user(username)
29
+
30
+ changed
31
+ notify_observers :user_deleted, self
32
+ end
33
+
34
+ def email=(email)
35
+ api.update_user(username, email, nil, nil)
36
+ @email = email
37
+ end
38
+
39
+ def password=(value)
40
+ api.update_user(username, nil, value, nil)
41
+ end
42
+
43
+ def admin=(value)
44
+ api.update_user(username, nil, nil, value)
45
+ end
46
+
47
+ private
48
+
49
+ def api
50
+ owner.api
51
+ end
52
+
53
+ def owner
54
+ @owner
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <response xmlns="http://www.gliffy.com" success="true">
3
+ <users>
4
+ <user id="209">
5
+ <username>barney</username>
6
+ <email>barney@BurnsODyne.apiuser.gliffy.com</email>
7
+ </user>
8
+ <user id="205">
9
+ <username>bart</username>
10
+ <email>bart@BurnsODyne.apiuser.gliffy.com</email>
11
+ </user>
12
+ <user id="210">
13
+ <username>discostu</username>
14
+ <email>discostu@BurnsODyne.apiuser.gliffy.com</email>
15
+ </user>
16
+ <user id="204">
17
+ <username>homer</username>
18
+ <email>homer@BurnsODyne.apiuser.gliffy.com</email>
19
+ </user>
20
+ </users>
21
+ </response>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <response xmlns="http://www.gliffy.com" success="true">
3
+ <folders>
4
+ <folder is-default="true">
5
+ <name>ROOT</name>
6
+ <path>ROOT</path>
7
+ <folder is-default="false">
8
+ <name>Tulacca Camp</name>
9
+ <path>ROOT/Tulacca Camp</path>
10
+ </folder>
11
+ <folder is-default="false">
12
+ <name>Simpsons Family</name>
13
+ <path>ROOT/Simpsons Family</path>
14
+ <folder is-default="false">
15
+ <name>Homer's Secrets</name>
16
+ <path>ROOT/Simpsons Family/Homer's Secrets</path>
17
+ </folder>
18
+ </folder>
19
+ </folder>
20
+ </folders>
21
+ </response>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <response xmlns="http://www.gliffy.com" success="true">
3
+ <users>
4
+ <user id="209">
5
+ <username>barney</username>
6
+ <email>barney@BurnsODyne.apiuser.gliffy.com</email>
7
+ </user>
8
+ <user id="205">
9
+ <username>bart</username>
10
+ <email>bart@BurnsODyne.apiuser.gliffy.com</email>
11
+ </user>
12
+ <user id="210">
13
+ <username>discostu</username>
14
+ <email>discostu@BurnsODyne.apiuser.gliffy.com</email>
15
+ </user>
16
+ <user id="204">
17
+ <username>homer</username>
18
+ <email>homer@BurnsODyne.apiuser.gliffy.com</email>
19
+ </user>
20
+ </users>
21
+ </response>
@@ -93,7 +93,7 @@ describe Gliffy::Account do
93
93
  subject(:root_folder) { account.root }
94
94
 
95
95
  it "is named ROOT" do
96
- expect(root_folder.name).to eq "ROOT"
96
+ expect(root_folder.name).to eq "ROOT"
97
97
  end
98
98
 
99
99
  it "has ROOT path" do
@@ -104,4 +104,116 @@ describe Gliffy::Account do
104
104
  expect(root_folder.owner).to be account
105
105
  end
106
106
  end
107
+
108
+ it "has a list of users" do
109
+ api
110
+ .stub(:get_users)
111
+ .and_return(Gliffy::API::Response.new(fixture("user-list")))
112
+
113
+ expect(account).to respond_to :users
114
+ expect(account.users).to be_instance_of Array
115
+ expect(account.users.length).to eq 4
116
+
117
+ account.users.each do |u|
118
+ expect(u).to be_instance_of Gliffy::User
119
+ end
120
+ end
121
+
122
+ it "delegates the task of fetching user list to API" do
123
+ api
124
+ .stub(:get_users)
125
+ .and_return(Gliffy::API::Response.new(fixture("user-list")))
126
+
127
+ account.users
128
+
129
+ expect(api).to have_received(:get_users)
130
+ .with(account_id)
131
+ end
132
+
133
+ it "allows to create a new user" do
134
+ expect(account).to respond_to :create_user
135
+ end
136
+
137
+ context "when creating new user" do
138
+ let(:username) { "USER" }
139
+ let(:user1) { double(Gliffy::User, :username => "A") }
140
+ let(:user2) { double(Gliffy::User, :username => "B") }
141
+ let(:user) { double(Gliffy::User, :username => username) }
142
+
143
+ before :each do
144
+ api.stub(:create_user)
145
+
146
+ account.stub(:users)
147
+ .and_return([user1, user2],
148
+ [user1, user, user2])
149
+ end
150
+
151
+ it "calls REST API" do
152
+ account.create_user username
153
+
154
+ expect(api).to have_received(:create_user)
155
+ .with(username)
156
+ end
157
+
158
+ it "returns this user" do
159
+ new_user = account.create_user username
160
+ expect(new_user).to be user
161
+ end
162
+
163
+ context "when username contains a space" do
164
+ let(:username) { "US ER" }
165
+
166
+ it "throws an exception" do
167
+ expect { account.create_user username }.to raise_error
168
+ end
169
+ end
170
+
171
+ context "when username is already taken" do
172
+ let(:username) { "USER" }
173
+ let(:user) { double(Gliffy::User, { :username => username }) }
174
+
175
+ before :each do
176
+ account.stub(:users).and_return([user])
177
+ end
178
+
179
+ it "throws an exception" do
180
+ expect { account.create_user username }.to raise_error
181
+ end
182
+ end
183
+ end
184
+
185
+ context "when notified that user has been deleted" do
186
+ let(:user) do
187
+ api.stub(:get_users)
188
+ .and_return(Gliffy::API::Response.new(fixture("user-list")))
189
+
190
+ account.users[1]
191
+ end
192
+
193
+ before :each do
194
+ user.stub(:delete_observer).and_call_original
195
+ end
196
+
197
+ it "updates user list" do
198
+ original_length = account.users.length
199
+
200
+ account.update(:user_deleted, user)
201
+
202
+ expect(account.users.length).to eq original_length - 1
203
+ expect(account.users).to_not include user
204
+ end
205
+
206
+ it "stops listening to this user's' events" do
207
+ account.update(:user_deleted, user)
208
+
209
+ expect(user).to have_received(:delete_observer)
210
+ .with(account)
211
+ end
212
+ end
213
+
214
+ context "when receives an unknown event" do
215
+ it "throws an exception" do
216
+ expect { account.update(:unknown, double(Object)) }.to raise_error ArgumentError
217
+ end
218
+ end
107
219
  end
@@ -67,6 +67,44 @@ shared_examples_for "an API facade" do
67
67
  end
68
68
  end
69
69
 
70
+ it "allows to load a list of folders accessible to an user" do
71
+ expect(facade).to respond_to :folders_accessible_to_user
72
+ end
73
+
74
+ context "when loading list of folders accessible to an user" do
75
+ let(:username) { "USERNAME" }
76
+
77
+ before :each do
78
+ facade.stub(:get)
79
+ facade.folders_accessible_to_user username
80
+ end
81
+
82
+ it "sends GET request" do
83
+ expect(facade).to have_received(:get)
84
+ .with("/accounts/#{account_id}/users/#{username}/folders.xml",
85
+ hash_including(:action => "get"))
86
+ end
87
+ end
88
+
89
+ it "allows to load a list of users with access to a folder" do
90
+ expect(facade).to respond_to :users_with_access_to_folder
91
+ end
92
+
93
+ context "when loading list of users with access to a folder" do
94
+ let(:path) { "PATH" }
95
+
96
+ before :each do
97
+ facade.stub(:get)
98
+ facade.users_with_access_to_folder path
99
+ end
100
+
101
+ it "sends GET request" do
102
+ expect(facade).to have_received(:get)
103
+ .with("/accounts/#{account_id}/folders/#{path}/users.xml",
104
+ hash_including(:action => "get"))
105
+ end
106
+ end
107
+
70
108
  context "when loading a list of folders" do
71
109
  it "wraps own 'get' method" do
72
110
  account_id = 99
@@ -270,6 +308,128 @@ shared_examples_for "an API facade" do
270
308
  end
271
309
  end
272
310
 
311
+ it "has provides access to folder list" do
312
+ expect(facade).to respond_to :get_users
313
+ end
314
+
315
+ context "when loading user list" do
316
+ let(:response) { double(Gliffy::API::Response) }
317
+
318
+ it "sends GET request and returns its result" do
319
+ facade.stub(:get).and_return(response)
320
+
321
+ expect(facade.get_users(account_id)).to be response
322
+
323
+ expect(facade).to have_received(:get)
324
+ .with("/accounts/#{account_id}/users.xml",
325
+ hash_including(:action => "get"))
326
+ end
327
+ end
328
+
329
+ it "allows to create a new user" do
330
+ expect(facade).to respond_to :create_user
331
+ end
332
+
333
+ context "when creating user" do
334
+ let(:username) { "USER" }
335
+ let(:email) { "test@test.com" }
336
+
337
+ before :each do
338
+ facade.stub(:post)
339
+ end
340
+
341
+ it "sends POST request to API" do
342
+ facade.create_user username
343
+
344
+ expect(facade).to have_received(:post)
345
+ .with("/accounts/#{account_id}/users.xml",
346
+ hash_including(:action => "create" ))
347
+ end
348
+ end
349
+
350
+ it "allows to delete existing user" do
351
+ expect(facade).to respond_to :delete_user
352
+ end
353
+
354
+ context "when deleting user" do
355
+ let(:username) { "USER" }
356
+
357
+ before :each do
358
+ facade.stub(:post)
359
+ end
360
+
361
+ it "sends POST request to API" do
362
+ facade.delete_user username
363
+
364
+ expect(facade).to have_received(:post)
365
+ .with("/accounts/#{account_id}/users/#{username}.xml",
366
+ hash_including(:action => "delete"))
367
+ end
368
+ end
369
+
370
+ it "allows to update existing user" do
371
+ expect(facade).to respond_to :update_user
372
+ end
373
+
374
+ context "when updating user" do
375
+ let(:username) { "testuser" }
376
+ let(:new_email) { "new-email@test.com" }
377
+ let(:new_password) { "password" }
378
+ let(:new_admin) { true }
379
+
380
+ before :each do
381
+ facade.stub(:post)
382
+
383
+ facade.update_user(username, new_email, new_password, new_admin)
384
+ end
385
+
386
+ it "sends POST request to API" do
387
+ expect(facade).to have_received(:post)
388
+ .with("/accounts/#{account_id}/users/#{username}.xml",
389
+ hash_including(:action => "update"))
390
+ end
391
+
392
+ context "when all data is given" do
393
+ it "updates all fields" do
394
+ expect(facade).to have_received(:post)
395
+ .with(anything(),
396
+ hash_including(:email => new_email,
397
+ :password => new_password,
398
+ :admin => new_admin ? "true" : "false"))
399
+ end
400
+ end
401
+
402
+ context "when no email is given" do
403
+ let(:new_email) { nil }
404
+
405
+ it "doesnt try to update email" do
406
+ expect(facade).to have_received(:post)
407
+ .with(anything(),
408
+ hash_not_including(:email))
409
+ end
410
+ end
411
+
412
+ context "when no password is given" do
413
+ let(:new_password) { nil }
414
+
415
+ it "doesnt try to update password" do
416
+ expect(facade).to have_received(:post)
417
+ .with(anything(),
418
+ hash_not_including(:password))
419
+ end
420
+ end
421
+
422
+ context "when no admin flag is given" do
423
+ let(:new_admin) { nil }
424
+
425
+ it "doesnt try to update admin flag" do
426
+ expect(facade).to have_received(:post)
427
+ .with(anything(),
428
+ hash_not_including(:admin))
429
+ end
430
+ end
431
+ end
432
+
273
433
  context "when POST request returns an error" do
274
434
  let(:response) { Gliffy::API::Response.new(fixture("error-401")) }
275
435
 
@@ -301,6 +461,50 @@ shared_examples_for "an API facade" do
301
461
  expect { facade.get("/random_url", {}) }.to raise_error(Gliffy::API::Error)
302
462
  end
303
463
  end
464
+
465
+ it "allows to grant user access to folder" do
466
+ expect(facade).to respond_to :grant_access_to_folder
467
+ end
468
+
469
+ context "when user access is granted" do
470
+ let(:username) { "USERNAME" }
471
+ let(:path) { "ROOT/FOLDER/SUB" }
472
+
473
+ before :each do
474
+ facade.stub(:post)
475
+ facade.grant_access_to_folder(username, path)
476
+ end
477
+
478
+ it "sends POST request" do
479
+ expect(facade).to have_received(:post)
480
+ .with("/accounts/#{account_id}/folders/#{path}/users/#{username}.xml",
481
+ hash_including(:action => "update",
482
+ :read => "true",
483
+ :write => "true"))
484
+ end
485
+ end
486
+
487
+ it "allows to revoke user access to folder" do
488
+ expect(facade).to respond_to :revoke_access_to_folder
489
+ end
490
+
491
+ context "when user access is revoked" do
492
+ let(:username) { "USERNAME" }
493
+ let(:path) { "ROOT/FOLDER/SUB" }
494
+
495
+ before :each do
496
+ facade.stub(:post)
497
+ facade.revoke_access_to_folder(username, path)
498
+ end
499
+
500
+ it "sends POST request" do
501
+ expect(facade).to have_received(:post)
502
+ .with("/accounts/#{account_id}/folders/#{path}/users/#{username}.xml",
503
+ hash_including(:action => "update",
504
+ :read => "false",
505
+ :write => "false"))
506
+ end
507
+ end
304
508
  end
305
509
 
306
510
  describe Gliffy::API::Facade do
@@ -121,7 +121,7 @@ describe Gliffy::Document do
121
121
  end
122
122
 
123
123
  context "when renamed" do
124
- let (:new_name) { "NEW DOCUMENT NAME" }
124
+ let(:new_name) { "NEW DOCUMENT NAME" }
125
125
  before :each do
126
126
  api.stub(:update_document_metadata)
127
127
  document.rename new_name
@@ -137,6 +137,29 @@ describe Gliffy::Document do
137
137
  end
138
138
  end
139
139
 
140
+ it "can be made public or private" do
141
+ expect(document).to respond_to :public=
142
+ end
143
+
144
+ context "when public state changes" do
145
+ let(:new_shared) { false }
146
+
147
+ before :each do
148
+ api.stub(:update_document_metadata)
149
+
150
+ document.public = new_shared
151
+ end
152
+
153
+ it "calls REST API" do
154
+ expect(api).to have_received(:update_document_metadata)
155
+ .with(document_id, nil, new_shared)
156
+ end
157
+
158
+ it "updates local object" do
159
+ expect(document.public?).to eq new_shared
160
+ end
161
+ end
162
+
140
163
  it "can be moved" do
141
164
  expect(document).to respond_to :move
142
165
  end
@@ -29,6 +29,32 @@ describe Gliffy::Folder do
29
29
  expect(folder).to respond_to :documents
30
30
  end
31
31
 
32
+ it "has a list of users with access to this folder" do
33
+ expect(folder).to respond_to :users
34
+ end
35
+
36
+ describe "user list" do
37
+ before :each do
38
+ api.stub(:users_with_access_to_folder)
39
+ .and_return(Gliffy::API::Response.new(fixture("folder-users")))
40
+ end
41
+
42
+ subject(:users) { folder.users }
43
+
44
+ it "is an array" do
45
+ expect(users).to be_instance_of Array
46
+ end
47
+
48
+ it "has correct length" do
49
+ expect(users.length).to eq 4
50
+ end
51
+
52
+ it "contains correct user objects" do
53
+ expect(users[0].username).to eq "barney"
54
+ expect(users[3].username).to eq "homer"
55
+ end
56
+ end
57
+
32
58
  describe "root folder" do
33
59
  it "knows it is root" do
34
60
  expect(folder.root?).to be_true
@@ -86,7 +112,7 @@ describe Gliffy::Folder do
86
112
 
87
113
  it { should respond_to :length }
88
114
  it { should respond_to :[] }
89
- it "has corrent length" do
115
+ it "has corrent length" do
90
116
  expect(children.length).to eq 4
91
117
  end
92
118
  end
@@ -217,7 +243,7 @@ describe Gliffy::Folder do
217
243
  .with(folder.path + "/" + folder_name)
218
244
  end
219
245
 
220
- it "returns a new folder" do
246
+ it "returns new folder" do
221
247
  new_folder = folder.create_folder(folder_name)
222
248
  expect(new_folder).to be_instance_of Gliffy::Folder
223
249
  end
@@ -392,4 +418,41 @@ describe Gliffy::Folder do
392
418
  expect(folder.deleted?).to be_true
393
419
  end
394
420
  end
421
+
422
+ describe "access rights" do
423
+ let(:username) { "USERNAME" }
424
+ let(:user) { double(Gliffy::User, :username => username ) }
425
+
426
+ it "can be granted" do
427
+ expect(folder).to respond_to :grant_access
428
+ end
429
+
430
+ context "when granting" do
431
+ before :each do
432
+ api.stub(:grant_access_to_folder)
433
+ folder.grant_access(user)
434
+ end
435
+
436
+ it "calls API" do
437
+ expect(api).to have_received(:grant_access_to_folder)
438
+ .with(username, folder.path)
439
+ end
440
+ end
441
+
442
+ it "can be revoked" do
443
+ expect(folder).to respond_to :revoke_access
444
+ end
445
+
446
+ context "when revoking" do
447
+ before :each do
448
+ api.stub(:revoke_access_to_folder)
449
+ folder.revoke_access(user)
450
+ end
451
+
452
+ it "calls API" do
453
+ expect(api).to have_received(:revoke_access_to_folder)
454
+ .with(username, folder.path)
455
+ end
456
+ end
457
+ end
395
458
  end
@@ -0,0 +1,144 @@
1
+ # -*- coding: utf-8-unix -*-
2
+ require 'spec_helper'
3
+
4
+ describe Gliffy::User do
5
+ let(:account_id) { 100 }
6
+ let(:api) { double(Gliffy::API::Facade) }
7
+ let(:account) { double(Gliffy::Account, :api => api, :id => account_id) }
8
+
9
+ subject(:user) do
10
+ Gliffy::User.load(
11
+ account,
12
+ Gliffy::API::Response.new(
13
+ fixture('user-list')
14
+ ).node("//g:users/g:user[1]")
15
+ )
16
+ end
17
+
18
+ it "has a username" do
19
+ expect(user).to respond_to :username
20
+ expect(user.username).to eq "barney"
21
+ end
22
+
23
+ it "has an email" do
24
+ expect(user).to respond_to :email
25
+ expect(user.email).to eq "barney@BurnsODyne.apiuser.gliffy.com"
26
+ end
27
+
28
+ it "has a list of folders accessible to it" do
29
+ expect(user).to respond_to :accessible_folders
30
+ end
31
+
32
+ describe "list of accessible folders" do
33
+ before :each do
34
+ api.stub(:folders_accessible_to_user)
35
+ .and_return(Gliffy::API::Response.new(fixture("user-folders")))
36
+ end
37
+
38
+ it "is a list of folder objects" do
39
+ expect(user.accessible_folders).to be_instance_of Array
40
+ expect(user.accessible_folders.length).to eq 1
41
+ expect(user.accessible_folders[0].name).to eq "ROOT"
42
+ expect(user.accessible_folders[0].folders.length).to eq 2
43
+ end
44
+
45
+ context "when list of accessible is loaded" do
46
+ before :each do
47
+ user.accessible_folders
48
+ end
49
+
50
+ it "is fetched from API" do
51
+ expect(api).to have_received(:folders_accessible_to_user)
52
+ .with(user.username)
53
+ end
54
+ end
55
+ end
56
+
57
+ it "can be deleted" do
58
+ expect(user).to respond_to :delete
59
+ end
60
+
61
+ context "when being deleted" do
62
+ let(:observer) { double(Object) }
63
+
64
+ before :each do
65
+ api.stub(:delete_user)
66
+
67
+ observer.stub(:update)
68
+ user.add_observer(observer)
69
+
70
+ user.delete
71
+ end
72
+
73
+ it "calls API" do
74
+ expect(api).to have_received(:delete_user)
75
+ .with(user.username)
76
+ end
77
+
78
+ it "notifies observers" do
79
+ expect(observer).to have_received(:update)
80
+ .with(:user_deleted, user)
81
+ end
82
+ end
83
+
84
+ it "allows to update email" do
85
+ expect(user).to respond_to :email=
86
+ end
87
+
88
+ context "when email is updated" do
89
+ let(:new_email) { "new-email@test.com" }
90
+
91
+ before :each do
92
+ api.stub(:update_user)
93
+
94
+ user.email = new_email
95
+ end
96
+
97
+ it "sends a request to API" do
98
+ expect(api).to have_received(:update_user)
99
+ .with(user.username, new_email, nil, nil)
100
+ end
101
+
102
+ it "updates local email value" do
103
+ expect(user.email).to eq new_email
104
+ end
105
+ end
106
+
107
+ it "allows to update password" do
108
+ expect(user).to respond_to :password=
109
+ end
110
+
111
+ context "when password is updated" do
112
+ let(:new_password) { "new-password" }
113
+
114
+ before :each do
115
+ api.stub(:update_user)
116
+
117
+ user.password = new_password
118
+ end
119
+
120
+ it "sends a request to API" do
121
+ expect(api).to have_received(:update_user)
122
+ .with(user.username, nil, new_password, nil)
123
+ end
124
+ end
125
+
126
+ it "allows to grant or revoke admin priviletes" do
127
+ expect(user).to respond_to :admin=
128
+ end
129
+
130
+ context "when admin flag is updated" do
131
+ let(:new_admin) { true }
132
+
133
+ before :each do
134
+ api.stub(:update_user)
135
+
136
+ user.admin = new_admin
137
+ end
138
+
139
+ it "sends a request to API" do
140
+ expect(api).to have_received(:update_user)
141
+ .with(user.username, nil, nil, new_admin)
142
+ end
143
+ end
144
+ end
data/spec/spec_helper.rb CHANGED
@@ -6,7 +6,7 @@ SimpleCov.command_name "test:units"
6
6
  SimpleCov.start do
7
7
  add_filter '/spec/'
8
8
  add_filter '/lib/gliffy/oauth/'
9
- coverage_dir '/reports/coverage'
9
+ coverage_dir './reports/coverage'
10
10
  minimum_coverage 100
11
11
  refuse_coverage_drop
12
12
  end
metadata CHANGED
@@ -1,125 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gliffy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Burnaev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-13 00:00:00.000000000 Z
11
+ date: 2013-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oauth
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '2.14'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.14'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: simplecov
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: http_logger
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: guard
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ! '>='
87
+ - - '>='
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ! '>='
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rb-readline
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: guard-rspec
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - ! '>='
115
+ - - '>='
102
116
  - !ruby/object:Gem::Version
103
117
  version: '0'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - ! '>='
122
+ - - '>='
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: ci_reporter
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - ! '>='
129
+ - - '>='
116
130
  - !ruby/object:Gem::Version
117
131
  version: '0'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - ! '>='
136
+ - - '>='
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  description: A simple Gliffy REST API wrapper.
@@ -128,40 +142,45 @@ executables: []
128
142
  extensions: []
129
143
  extra_rdoc_files: []
130
144
  files:
131
- - lib/gliffy/api/error.rb
132
- - lib/gliffy/api/facade.rb
133
- - lib/gliffy/api/response.rb
145
+ - lib/gliffy/folder.rb
134
146
  - lib/gliffy/document/presentation.rb
135
- - lib/gliffy/document/presentation/xml.rb
136
147
  - lib/gliffy/document/presentation/png.rb
148
+ - lib/gliffy/document/presentation/xml.rb
137
149
  - lib/gliffy/document/presentation/svg.rb
138
- - lib/gliffy/oauth/helper.rb
150
+ - lib/gliffy/api/error.rb
151
+ - lib/gliffy/api/facade.rb
152
+ - lib/gliffy/api/response.rb
153
+ - lib/gliffy/account.rb
139
154
  - lib/gliffy/api.rb
140
- - lib/gliffy/folder.rb
155
+ - lib/gliffy/user.rb
141
156
  - lib/gliffy/document.rb
142
- - lib/gliffy/account.rb
157
+ - lib/gliffy/oauth/helper.rb
143
158
  - lib/gliffy.rb
144
159
  - spec/support/document_presentation_shared_examples.rb
160
+ - spec/fixtures/documents-empty.xml
161
+ - spec/fixtures/token.xml
145
162
  - spec/fixtures/folder.xml
146
- - spec/fixtures/document.xml
147
- - spec/fixtures/account.xml
148
163
  - spec/fixtures/error-401.xml
164
+ - spec/fixtures/account.xml
165
+ - spec/fixtures/document.xml
166
+ - spec/fixtures/user-list.xml
167
+ - spec/fixtures/user-folders.xml
168
+ - spec/fixtures/folder-users.xml
149
169
  - spec/fixtures/documents.xml
150
- - spec/fixtures/documents-empty.xml
151
- - spec/fixtures/token.xml
152
- - spec/lib/gliffy/account_spec.rb
153
- - spec/lib/gliffy/api/facade_spec.rb
154
- - spec/lib/gliffy/api/response_spec.rb
155
- - spec/lib/gliffy/api/error_spec.rb
170
+ - spec/spec_helper.rb
171
+ - spec/lib/gliffy/user_spec.rb
172
+ - spec/lib/gliffy/api_spec.rb
156
173
  - spec/lib/gliffy/document/presentation_spec.rb
157
174
  - spec/lib/gliffy/document/presentation/xml_spec.rb
158
- - spec/lib/gliffy/document/presentation/svg_spec.rb
159
175
  - spec/lib/gliffy/document/presentation/png_spec.rb
160
- - spec/lib/gliffy/folder_spec.rb
176
+ - spec/lib/gliffy/document/presentation/svg_spec.rb
177
+ - spec/lib/gliffy/api/response_spec.rb
178
+ - spec/lib/gliffy/api/facade_spec.rb
179
+ - spec/lib/gliffy/api/error_spec.rb
161
180
  - spec/lib/gliffy/document_spec.rb
162
- - spec/lib/gliffy/api_spec.rb
181
+ - spec/lib/gliffy/account_spec.rb
182
+ - spec/lib/gliffy/folder_spec.rb
163
183
  - spec/lib/gliffy_spec.rb
164
- - spec/spec_helper.rb
165
184
  - README.md
166
185
  - LICENSE
167
186
  homepage: https://github.com/bkon/gliffy
@@ -174,17 +193,17 @@ require_paths:
174
193
  - lib
175
194
  required_ruby_version: !ruby/object:Gem::Requirement
176
195
  requirements:
177
- - - ! '>='
196
+ - - '>='
178
197
  - !ruby/object:Gem::Version
179
198
  version: '0'
180
199
  required_rubygems_version: !ruby/object:Gem::Requirement
181
200
  requirements:
182
- - - ! '>='
201
+ - - '>='
183
202
  - !ruby/object:Gem::Version
184
203
  version: '0'
185
204
  requirements: []
186
205
  rubyforge_project:
187
- rubygems_version: 2.1.5
206
+ rubygems_version: 2.1.11
188
207
  signing_key:
189
208
  specification_version: 4
190
209
  summary: Gliffy API client