gliffy 0.0.8 → 0.0.9

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.
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