lita-locker 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 03119612570e96f75bb028de84abf384232d3706
4
- data.tar.gz: a05484fd65388045838e0bf6940162aff13ceb2f
3
+ metadata.gz: 228a4b3898980e9de630cee8152cd4ea8104c830
4
+ data.tar.gz: fd299284bef188f5d7fee52c79c925c91b979187
5
5
  SHA512:
6
- metadata.gz: 27704990d5d11504024266de0c058758eda2375f882cffa78f2377afe07f5ccc2328ed871ba0b3c963bd82abe46597244a376110059e2e59e02bf09bf1b97673
7
- data.tar.gz: b8a522feb8841916016981f8d81136ccd1eb51b619978f64d58ce3b23d0f498a6f0dfc35bfb1df2900816ccc7d2aeacd52439798f03d13a0c070e23b0ca90ec6
6
+ metadata.gz: 078690a522779d50e1f8f5f83d3635bf401d26027cd68496a29b2f4472af7c444367df91e5c368d1def23b02946ff4f30cef6c67d1743b90f7442ccd13d526bf
7
+ data.tar.gz: 05fa9b743fa6a22e6c68e44d6f445cf143cb345c91c09fdad7fb959effc79299c36f3e91721e0b8123ab9af969197ee8595f011135bac98a6e0538dd8b9d485f
@@ -5,7 +5,7 @@ ClassLength:
5
5
  Max: 500
6
6
 
7
7
  CyclomaticComplexity:
8
- Max: 10
8
+ Max: 8
9
9
 
10
10
  Documentation:
11
11
  Exclude:
@@ -17,3 +17,10 @@ FileName:
17
17
 
18
18
  MethodLength:
19
19
  Max: 200
20
+
21
+ LineLength:
22
+ Max: 85
23
+
24
+ GuardClause:
25
+ Exclude:
26
+ - lib/lita/handlers/locker.rb
data/README.md CHANGED
@@ -31,17 +31,16 @@ if all of the resources it uses are available.
31
31
  ### Examples
32
32
  ```
33
33
  lock web - Make something unavailable to others
34
- lock web 30m - Make something unavailable to others for 30 minutes
35
34
  unlock web - Make something available to others
36
- locker reserve web - Make yourself the next owner of something after it is unlocked
37
- locker status - Show what is and isn't available
35
+ steal web - Make yourself the owner of something locked by someone else
36
+ locker status web - Show the current state of web
38
37
  ```
39
38
 
40
39
  ### Locking, Unlocking, State
41
40
  ```
42
- lock <subject> - A basic reservation, with no time limit. <subject> can be a resource or a label.
43
- unlock <subject> - Remove a reservation. This can only be done by whomever made the request.
44
- unlock <subject> force - Force removal of a reservation. This can be done by anyone.
41
+ lock <label> - A basic reservation, with no time limit. Can have # comments afterwards.
42
+ unlock <label> - Remove a reservation. This can only be done by whomever made the request. Can have # comments afterwards.
43
+ steal <label> - Force removal of a reservation. This can be done by anyone. Can have # comments afterwards.
45
44
  ```
46
45
 
47
46
  ### Time-based locking - Not implemented yet!
data/Rakefile CHANGED
@@ -3,6 +3,6 @@ require 'rspec/core/rake_task'
3
3
  require 'rubocop/rake_task'
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
- Rubocop::RakeTask.new(:rubocop)
6
+ RuboCop::RakeTask.new(:rubocop)
7
7
 
8
8
  task default: [:spec, :rubocop]
data/TODO.md ADDED
@@ -0,0 +1,5 @@
1
+ Things to do:
2
+
3
+ * Better user management (meaning use the actual Lita user ID)
4
+ * User mentions in responses (if possible)
5
+ * Make emoji optional (since not all people use Hipchat)
@@ -4,63 +4,53 @@ module Lita
4
4
  http.get '/locker/label/:name', :http_label_show
5
5
  http.get '/locker/resource/:name', :http_resource_show
6
6
 
7
- LABEL_REGEX = /([\W\S_-]+)/
8
- RESOURCE_REGEX = /([\.a-zA-Z0-9_-]+)/
7
+ LABEL_REGEX = /([\.\w\s-]+)/
8
+ RESOURCE_REGEX = /([\.\w-]+)/
9
+ COMMENT_REGEX = /(\s\#.+)?/
9
10
 
10
11
  route(
11
- /^\(lock\)\s#{LABEL_REGEX}$/,
12
+ /^\(lock\)\s#{LABEL_REGEX}#{COMMENT_REGEX}$/,
12
13
  :lock
13
14
  )
14
15
 
15
16
  route(
16
- /^\(unlock\)\s#{LABEL_REGEX}$/,
17
+ /^(?:\(unlock\)|\(release\))\s#{LABEL_REGEX}#{COMMENT_REGEX}$/,
17
18
  :unlock
18
19
  )
19
20
 
20
21
  route(
21
- /^lock\s#{LABEL_REGEX}$/,
22
+ /^lock\s#{LABEL_REGEX}#{COMMENT_REGEX}$/,
22
23
  :lock,
23
24
  command: true,
24
- help: {
25
- t('help.lock_key') => t('help.lock_value')
26
- }
25
+ help: { t('help.lock.syntax') => t('help.lock.desc') }
27
26
  )
28
27
 
29
- # route(
30
- # /^lock\s([a-zA-Z0-9_-]+)\s(\d+)(s|m|h)$/,
31
- # :lock,
32
- # command: true,
33
- # help: {
34
- # t('help.lock_time_key') => t('help.lock_time_value')
35
- # }
36
- # )
37
-
38
28
  route(
39
- /^unlock\s#{LABEL_REGEX}$/,
29
+ /^unlock\s#{LABEL_REGEX}#{COMMENT_REGEX}$/,
40
30
  :unlock,
41
31
  command: true,
42
- help: {
43
- t('help.unlock_key') => t('help.unlock_value')
44
- }
32
+ help: { t('help.unlock.syntax') => t('help.unlock.desc') }
45
33
  )
46
34
 
47
35
  route(
48
- /^unlock\s#{LABEL_REGEX}\sforce$/,
49
- :unlock_force,
36
+ /^steal\s#{LABEL_REGEX}#{COMMENT_REGEX}$/,
37
+ :steal,
50
38
  command: true,
51
- help: {
52
- t('help.unlock_force_key') => t('help.unlock_force_value')
53
- }
39
+ help: { t('help.steal.syntax') => t('help.steal.desc') }
40
+ )
41
+
42
+ route(
43
+ /^locker\sstatus\s#{LABEL_REGEX}$/,
44
+ :status,
45
+ command: true,
46
+ help: { t('help.status.syntax') => t('help.status.desc') }
54
47
  )
55
48
 
56
49
  route(
57
50
  /^locker\sresource\slist$/,
58
51
  :resource_list,
59
52
  command: true,
60
- help: {
61
- t('help.resource_list_key') =>
62
- t('help.resource_list_value')
63
- }
53
+ help: { t('help.resource.list.syntax') => t('help.resource.list.desc') }
64
54
  )
65
55
 
66
56
  route(
@@ -69,8 +59,7 @@ module Lita
69
59
  command: true,
70
60
  restrict_to: [:locker_admins],
71
61
  help: {
72
- t('help.resource_create_key') =>
73
- t('help.resource_create_value')
62
+ t('help.resource.create.syntax') => t('help.resource.create.desc')
74
63
  }
75
64
  )
76
65
 
@@ -80,8 +69,7 @@ module Lita
80
69
  command: true,
81
70
  restrict_to: [:locker_admins],
82
71
  help: {
83
- t('help.resource_delete_key') =>
84
- t('help.resource_delete_value')
72
+ t('help.resource.delete.syntax') => t('help.resource.delete.desc')
85
73
  }
86
74
  )
87
75
 
@@ -89,178 +77,142 @@ module Lita
89
77
  /^locker\sresource\sshow\s#{RESOURCE_REGEX}$/,
90
78
  :resource_show,
91
79
  command: true,
92
- help: {
93
- t('help.resource_show_key') =>
94
- t('help.resource_show_value')
95
- }
80
+ help: { t('help.resource.show.syntax') => t('help.resource.show.desc') }
96
81
  )
97
82
 
98
83
  route(
99
84
  /^locker\slabel\slist$/,
100
85
  :label_list,
101
86
  command: true,
102
- help: {
103
- t('help.label_list_key') =>
104
- t('help.label_list_value')
105
- }
87
+ help: { t('help.label.list.syntax') => t('help.label.list.desc') }
106
88
  )
107
89
 
108
90
  route(
109
91
  /^locker\slabel\screate\s#{LABEL_REGEX}$/,
110
92
  :label_create,
111
93
  command: true,
112
- help: {
113
- t('help.label_create_key') =>
114
- t('help.label_create_value')
115
- }
94
+ help: { t('help.label.create.syntax') => t('help.label.create.desc') }
116
95
  )
117
96
 
118
97
  route(
119
98
  /^locker\slabel\sdelete\s#{LABEL_REGEX}$/,
120
99
  :label_delete,
121
100
  command: true,
122
- help: {
123
- t('help.label_delete_key') =>
124
- t('help.label_delete_value')
125
- }
101
+ help: { t('help.label.delete.syntax') => t('help.label.delete.desc') }
126
102
  )
127
103
 
128
104
  route(
129
105
  /^locker\slabel\sshow\s#{LABEL_REGEX}$/,
130
106
  :label_show,
131
107
  command: true,
132
- help: {
133
- t('help.label_show_key') =>
134
- t('help.label_show_value')
135
- }
108
+ help: { t('help.label.show.syntax') => t('help.label.show.desc') }
136
109
  )
137
110
 
138
111
  route(
139
112
  /^locker\slabel\sadd\s#{RESOURCE_REGEX}\sto\s#{LABEL_REGEX}$/,
140
113
  :label_add,
141
114
  command: true,
142
- help: {
143
- t('help.label_add_key') =>
144
- t('help.label_add_value')
145
- }
115
+ help: { t('help.label.add.syntax') => t('help.label.add.desc') }
146
116
  )
147
117
 
148
118
  route(
149
119
  /^locker\slabel\sremove\s#{RESOURCE_REGEX}\sfrom\s#{LABEL_REGEX}$/,
150
120
  :label_remove,
151
121
  command: true,
152
- help: {
153
- t('help.label_remove_key') =>
154
- t('help.label_remove_value')
155
- }
122
+ help: { t('help.label.remove.syntax') => t('help.label.remove.desc') }
156
123
  )
157
124
 
158
125
  def http_label_show(request, response)
159
126
  name = request.env['router.params'][:name]
160
127
  response.headers['Content-Type'] = 'application/json'
161
- result = label(name)
162
- response.write(result.to_json)
128
+ response.write(label(name).to_json)
163
129
  end
164
130
 
165
131
  def http_resource_show(request, response)
166
132
  name = request.env['router.params'][:name]
167
133
  response.headers['Content-Type'] = 'application/json'
168
- result = resource(name)
169
- response.write(result.to_json)
134
+ response.write(resource(name).to_json)
170
135
  end
171
136
 
172
137
  def lock(response)
173
138
  name = response.matches[0][0]
174
- timeamt = response.matches[0][1]
175
- timeunit = response.matches[0][2]
176
- case timeunit
177
- when 's'
178
- time_until = Time.now.utc + timeamt.to_i
179
- when 'm'
180
- time_until = Time.now.utc + (timeamt.to_i * 60)
181
- when 'h'
182
- time_until = Time.now.utc + (timeamt.to_i * 3600)
183
- else
184
- time_until = nil
185
- end
186
139
 
187
- if resource_exists?(name)
188
- if lock_resource!(name, response.user, time_until)
189
- response.reply(t('resource.lock', name: name))
190
- else
191
- response.reply(t('resource.is_locked', name: name))
192
- end
193
- elsif label_exists?(name)
140
+ if label_exists?(name)
194
141
  m = label_membership(name)
195
142
  if m.count > 0
196
- if lock_label!(name, response.user, time_until)
197
- response.reply(t('label.lock', name: name))
143
+ if lock_label!(name, response.user, nil)
144
+ response.reply('(successful) ' + t('label.lock', name: name))
198
145
  else
199
- response.reply(t('label.unable_to_lock', name: name))
146
+ l = label(name)
147
+ if l['state'] == 'locked'
148
+ response.reply('(failed) ' + t('label.owned',
149
+ name: name,
150
+ owner_name: l['owner_name'],
151
+ owner_mention: l['owner_mention']))
152
+ else
153
+ response.reply('(failed) ' + t('label.dependency'))
154
+ end
200
155
  end
201
156
  else
202
- response.reply(t('label.no_resources', name: name))
157
+ response.reply('(failed) ' + t('label.no_resources', name: name))
203
158
  end
204
159
  else
205
- response.reply(t('subject.does_not_exist', name: name))
160
+ response.reply('(failed) ' + t('label.does_not_exist', name: name))
206
161
  end
207
162
  end
208
163
 
209
164
  def unlock(response)
210
165
  name = response.matches[0][0]
211
- if resource_exists?(name)
212
- res = resource(name)
213
- if res['state'] == 'unlocked'
214
- response.reply(t('resource.is_unlocked', name: name))
215
- else
216
- # FIXME: NOT SECURE
217
- if response.user.name == res['owner']
218
- unlock_resource!(name)
219
- response.reply(t('resource.unlock', name: name))
220
- # FIXME: Handle the case where things can't be unlocked?
221
- else
222
- response.reply(t('resource.owned', name: name,
223
- owner: res['owner']))
224
- end
225
- end
226
- elsif label_exists?(name)
166
+ if label_exists?(name)
227
167
  l = label(name)
228
168
  if l['state'] == 'unlocked'
229
- response.reply(t('label.is_unlocked', name: name))
169
+ response.reply('(successful) ' + t('label.is_unlocked',
170
+ name: name))
230
171
  else
231
- # FIXME: NOT SECURE
232
- if response.user.name == l['owner']
172
+ if response.user.id == l['owner_id']
233
173
  unlock_label!(name)
234
- response.reply(t('label.unlock', name: name))
235
- # FIXME: Handle the case where things can't be unlocked?
174
+ response.reply('(successful) ' + t('label.unlock', name: name))
236
175
  else
237
- response.reply(t('label.owned', name: name,
238
- owner: l['owner']))
176
+ response.reply('(failed) ' + t('label.owned',
177
+ name: name,
178
+ owner_name: l['owner_name'],
179
+ owner_mention: l['owner_mention']))
239
180
  end
240
181
  end
241
182
  else
242
- response.reply(t('subject.does_not_exist', name: name))
183
+ response.reply('(failed) ' + t('subject.does_not_exist', name: name))
243
184
  end
244
185
  end
245
186
 
246
- def unlock_force(response)
187
+ def steal(response)
247
188
  name = response.matches[0][0]
248
- if resource_exists?(name)
249
- unlock_resource!(name)
250
- response.reply(t('resource.unlock', name: name))
251
- # FIXME: Handle the case where things can't be unlocked?
252
- elsif label_exists?(name)
189
+ if label_exists?(name)
253
190
  unlock_label!(name)
254
- response.reply(t('label.unlock', name: name))
191
+ response.reply('(successful) ' + t('label.unlock', name: name))
255
192
  # FIXME: Handle the case where things can't be unlocked?
193
+ else
194
+ response.reply('(failed) ' + t('subject.does_not_exist', name: name))
195
+ end
196
+ end
197
+
198
+ def status(response)
199
+ name = response.matches[0][0]
200
+ if label_exists?(name)
201
+ l = label(name)
202
+ response.reply(t('label.desc', name: name, state: l['state']))
203
+ elsif resource_exists?(name)
204
+ r = resource(name)
205
+ response.reply(t('resource.desc', name: name, state: r['state']))
256
206
  else
257
207
  response.reply(t('subject.does_not_exist', name: name))
258
208
  end
259
209
  end
260
210
 
261
211
  def label_list(response)
262
- labels.each do |l|
263
- response.reply(t('label.desc', name: l.sub('label_', '')))
212
+ labels.each do |n|
213
+ name = n.sub('label_', '')
214
+ l = label(name)
215
+ response.reply(t('label.desc', name: name, state: l['state']))
264
216
  end
265
217
  end
266
218
 
@@ -336,11 +288,13 @@ module Lita
336
288
  end
337
289
 
338
290
  def resource_list(response)
291
+ output = ''
339
292
  resources.each do |r|
340
293
  r_name = r.sub('resource_', '')
341
294
  res = resource(r_name)
342
- response.reply(t('resource.desc', name: r_name, state: res['state']))
295
+ output += t('resource.desc', name: r_name, state: res['state'])
343
296
  end
297
+ response.reply(output)
344
298
  end
345
299
 
346
300
  def resource_create(response)
@@ -425,9 +379,10 @@ module Lita
425
379
  value = redis.hget(resource_key, 'state')
426
380
  if value == 'unlocked'
427
381
  # FIXME: Race condition!
428
- # FIXME: Store something better than name
429
382
  redis.hset(resource_key, 'state', 'locked')
430
- redis.hset(resource_key, 'owner', owner.name)
383
+ redis.hset(resource_key, 'owner_id', owner.id)
384
+ redis.hset(resource_key, 'owner_name', owner.name)
385
+ redis.hset(resource_key, 'owner_mention', owner.mention_name)
431
386
  redis.hset(resource_key, 'until', time_until)
432
387
  true
433
388
  else
@@ -443,15 +398,12 @@ module Lita
443
398
  key = "label_#{name}"
444
399
  members = label_membership(name)
445
400
  members.each do |m|
446
- r = resource(m)
447
- return false if r['state'] == 'locked'
448
- end
449
- # FIXME: No, really, race condition.
450
- members.each do |m|
451
- lock_resource!(m, owner, time_until)
401
+ return false unless lock_resource!(m, owner, time_until)
452
402
  end
453
403
  redis.hset(key, 'state', 'locked')
454
- redis.hset(key, 'owner', owner.name)
404
+ redis.hset(key, 'owner_id', owner.id)
405
+ redis.hset(key, 'owner_name', owner.name)
406
+ redis.hset(key, 'owner_mention', owner.mention_name)
455
407
  redis.hset(key, 'until', time_until)
456
408
  true
457
409
  else
@@ -461,10 +413,11 @@ module Lita
461
413
 
462
414
  def unlock_resource!(name)
463
415
  if resource_exists?(name)
464
- # FIXME: Tracking here?
465
416
  key = "resource_#{name}"
466
417
  redis.hset(key, 'state', 'unlocked')
467
- redis.hset(key, 'owner', '')
418
+ redis.hset(key, 'owner_name', '')
419
+ redis.hset(key, 'owner_mention', '')
420
+ redis.hset(key, 'owner_id', '')
468
421
  else
469
422
  false
470
423
  end
@@ -478,7 +431,9 @@ module Lita
478
431
  unlock_resource!(m)
479
432
  end
480
433
  redis.hset(key, 'state', 'unlocked')
481
- redis.hset(key, 'owner', '')
434
+ redis.hset(key, 'owner_name', '')
435
+ redis.hset(key, 'owner_mention', '')
436
+ redis.hset(key, 'owner_id', '')
482
437
  true
483
438
  else
484
439
  false
@@ -1,10 +1,10 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'lita-locker'
3
- spec.version = '0.4.0'
3
+ spec.version = '0.5.0'
4
4
  spec.authors = ['Eric Sigler']
5
5
  spec.email = ['me@esigler.com']
6
- spec.description = %q("lock" and "unlock" arbitrary subjects)
7
- spec.summary = %q("lock" and "unlock" arbitrary subjects)
6
+ spec.description = '"lock" and "unlock" arbitrary subjects'
7
+ spec.summary = '"lock" and "unlock" arbitrary subjects'
8
8
  spec.homepage = 'https://github.com/esigler/lita-locker'
9
9
  spec.license = 'MIT'
10
10
  spec.metadata = { 'lita_plugin_type' => 'handler' }
@@ -3,32 +3,50 @@ en:
3
3
  handlers:
4
4
  locker:
5
5
  help:
6
- lock_key: lock <subject>
7
- lock_value: Make something unavailable to others
8
- unlock_key: unlock <subject>
9
- unlock_value: Make something available to others
10
- unlock_force_key: unlock <subject> force
11
- unlock_force_value: Force removal of a reservation.
12
- resource_list_key: locker resource list
13
- resource_list_value: List all resources
14
- resource_create_key: locker resource create <name>
15
- resource_create_value: Create a resource with <name>
16
- resource_delete_key: locker resource delete <name>
17
- resource_delete_value: Delete the resource with <name>
18
- resource_show_key: locker resource show <name>
19
- resource_show_value: Show the state of <name>
20
- label_list_key: locker label list
21
- label_list_value: List all labels
22
- label_create_key: locker label create <name>
23
- label_create_value: Create a label with <name>
24
- label_delete_key: locker label delete <name>
25
- label_delete_value: Delete the label with <name>
26
- label_show_key: locker label show <name>
27
- label_show_value: Show all resources for <name>
28
- label_add_key: locker label add <resource> to <name>
29
- label_add_value: Adds <resource> to the list of things to lock/unlock for <name>
30
- label_remove_key: locker label remove <resource> from <name>
31
- label_remove_value: Removes <resource> from <name>
6
+ lock:
7
+ syntax: lock <subject>
8
+ desc: Make something unavailable to others. Can have # comments afterwards.
9
+ unlock:
10
+ syntax: unlock <subject>
11
+ desc: Make something available to others. Can have # comments afterwards.
12
+ steal:
13
+ syntax: steal <subject>
14
+ desc: Force removal of a reservation. Can have # comments afterwards.
15
+ status:
16
+ syntax: locker status <label or resource>
17
+ desc: Show the current state of <label or resource>
18
+ resource:
19
+ list:
20
+ syntax: locker resource list
21
+ desc: List all resources
22
+ create:
23
+ syntax: locker resource create <name>
24
+ desc: Create a resource with <name>
25
+ delete:
26
+ syntax: locker resource delete <name>
27
+ desc: Delete the resource with <name>
28
+ show:
29
+ syntax: locker resource show <name>
30
+ desc: Show the state of <name>
31
+ label:
32
+ list:
33
+ syntax: locker label list
34
+ desc: List all labels
35
+ create:
36
+ syntax: locker label create <name>
37
+ desc: Create a label with <name>
38
+ delete:
39
+ syntax: locker label delete <name>
40
+ desc: Delete the label with <name>
41
+ show:
42
+ syntax: locker label show <name>
43
+ desc: Show all resources for <name>
44
+ add:
45
+ syntax: locker label add <resource> to <name>
46
+ desc: Adds <resource> to the list of things to lock/unlock for <name>
47
+ remove:
48
+ syntax: locker label remove <resource> from <name>
49
+ desc: Removes <resource> from <name>
32
50
  resource:
33
51
  created: "Resource %{name} created"
34
52
  desc: "Resource: %{name}, state: %{state}"
@@ -39,23 +57,24 @@ en:
39
57
  is_locked: "%{name} is locked"
40
58
  unlock: "%{name} unlocked"
41
59
  is_unlocked: "%{name} is unlocked"
42
- owned: "%{name} is locked by %{owner}"
60
+ owned: "%{name} is locked by %{owner_name} %{owner_mention}"
43
61
  subject:
44
- does_not_exist: "%{name} does not exist"
62
+ does_not_exist: "Sorry, that does not exist"
45
63
  label:
46
64
  unlock: "%{name} unlocked"
47
- owned: "%{name} is locked by %{owner}"
65
+ owned: "%{name} is locked by %{owner_name} %{owner_mention}"
48
66
  is_unlocked: "%{name} is unlocked"
49
67
  unable_to_lock: "%{name} unable to be locked"
50
68
  lock: "%{name} locked"
51
- desc: "Label: %{name}"
69
+ desc: "Label: %{name}, state: %{state}"
52
70
  created: "Label %{name} created"
53
71
  exists: "%{name} already exists"
54
72
  deleted: "Label %{name} deleted"
55
- does_not_exist: "Label %{name} does not exist"
73
+ does_not_exist: "Label %{name} does not exist. To create it: \"!locker label create %{name}\""
56
74
  has_no_resources: "Label %{name} has no resources"
57
75
  resource_added: "Resource %{resource} has been added to %{label}"
58
76
  resource_removed: "Resource %{resource} has been removed from %{label}"
59
77
  resources: "Label %{name} has: %{resources}"
60
78
  does_not_have_resource: "Label %{label} does not have Resource %{resource}"
61
79
  no_resources: "%{name} has no resources, so it cannot be locked"
80
+ dependency: 'Label unable to be locked, blocked on a dependency'
@@ -1,35 +1,51 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Lita::Handlers::Locker, lita_handler: true do
4
- it { routes('(lock) foobar').to(:lock) }
5
- it { routes('(unlock) foobar').to(:unlock) }
4
+ label_examples = ['foobar', 'foo bar', 'foo-bar', 'foo_bar']
5
+ resource_examples = ['foobar', 'foo.bar', 'foo-bar', 'foo_bar']
6
+
7
+ label_examples.each do |l|
8
+ it { routes("(lock) #{l}").to(:lock) }
9
+ it { routes("(unlock) #{l}").to(:unlock) }
10
+ it { routes("(release) #{l}").to(:unlock) }
11
+
12
+ it { routes("(lock) #{l} #this is a comment").to(:lock) }
13
+ it { routes("(unlock) #{l} #this is a comment").to(:unlock) }
14
+ it { routes("(release) #{l} #this is a comment").to(:unlock) }
15
+
16
+ it { routes_command("lock #{l}").to(:lock) }
17
+ it { routes_command("lock #{l} #this is a comment").to(:lock) }
18
+ it { routes_command("unlock #{l}").to(:unlock) }
19
+ it { routes_command("unlock #{l} #this is a comment").to(:unlock) }
20
+ it { routes_command("steal #{l}").to(:steal) }
21
+ it { routes_command("steal #{l} #this is a comment").to(:steal) }
22
+ end
6
23
 
7
- it { routes_command('lock foobar').to(:lock) }
8
- it { routes_command('lock foo bar').to(:lock) }
9
- it { routes_command('lock foo-bar').to(:lock) }
10
- it { routes_command('lock foo_bar').to(:lock) }
11
- # it { routes_command('lock foobar 30m').to(:lock) }
24
+ label_examples.each do |l|
25
+ it { routes_command("locker status #{l}").to(:status) }
26
+ end
12
27
 
13
- it { routes_command('unlock foobar').to(:unlock) }
14
- it { routes_command('unlock foo bar').to(:unlock) }
15
- it { routes_command('unlock foo-bar').to(:unlock) }
16
- it { routes_command('unlock foo_bar').to(:unlock) }
17
- it { routes_command('unlock foobar force').to(:unlock_force) }
28
+ resource_examples.each do |r|
29
+ it { routes_command("locker status #{r}").to(:status) }
30
+ end
18
31
 
19
32
  it { routes_command('locker resource list').to(:resource_list) }
20
- it { routes_command('locker resource create foobar').to(:resource_create) }
21
- it { routes_command('locker resource create foo.bar').to(:resource_create) }
22
- it { routes_command('locker resource create foo-bar').to(:resource_create) }
23
- it { routes_command('locker resource create foo_bar').to(:resource_create) }
24
- it { routes_command('locker resource delete foobar').to(:resource_delete) }
25
- it { routes_command('locker resource show foobar').to(:resource_show) }
33
+
34
+ resource_examples.each do |r|
35
+ it { routes_command("locker resource create #{r}").to(:resource_create) }
36
+ it { routes_command("locker resource delete #{r}").to(:resource_delete) }
37
+ it { routes_command("locker resource show #{r}").to(:resource_show) }
38
+ end
26
39
 
27
40
  it { routes_command('locker label list').to(:label_list) }
28
- it { routes_command('locker label create foobar').to(:label_create) }
29
- it { routes_command('locker label delete foobar').to(:label_delete) }
30
- it { routes_command('locker label show foobar').to(:label_show) }
31
- it { routes_command('locker label add foo to bar').to(:label_add) }
32
- it { routes_command('locker label remove foo from bar').to(:label_remove) }
41
+
42
+ label_examples.each do |l|
43
+ it { routes_command("locker label create #{l}").to(:label_create) }
44
+ it { routes_command("locker label delete #{l}").to(:label_delete) }
45
+ it { routes_command("locker label show #{l}").to(:label_show) }
46
+ it { routes_command("locker label add resource to #{l}").to(:label_add) }
47
+ it { routes_command("locker label remove resource from #{l}").to(:label_remove) }
48
+ end
33
49
 
34
50
  it { routes_http(:get, '/locker/label/foobar').to(:http_label_show) }
35
51
  it { routes_http(:get, '/locker/resource/foobar').to(:http_resource_show) }
@@ -41,19 +57,21 @@ describe Lita::Handlers::Locker, lita_handler: true do
41
57
  ).and_return(true)
42
58
  end
43
59
 
44
- describe '#lock' do
45
- it 'locks a resource when it is available' do
46
- send_command('locker resource create foobar')
47
- send_command('lock foobar')
48
- expect(replies.last).to eq('foobar locked')
49
- end
60
+ let(:alice) do
61
+ Lita::User.create('9001@hipchat', name: 'Alice', mention_name: '@alice')
62
+ end
50
63
 
64
+ let(:bob) do
65
+ Lita::User.create('9002@hipchat', name: 'Bob', mention_name: '@bob')
66
+ end
67
+
68
+ describe '#lock' do
51
69
  it 'locks a label when it is available and has resources' do
52
70
  send_command('locker resource create foobar')
53
71
  send_command('locker label create bazbat')
54
72
  send_command('locker label add foobar to bazbat')
55
- send_command('lock bazbat')
56
- expect(replies.last).to eq('bazbat locked')
73
+ send_command('lock bazbat # with a comment')
74
+ expect(replies.last).to eq('(successful) bazbat locked')
57
75
  send_command('locker resource show foobar')
58
76
  expect(replies.last).to eq('Resource: foobar, state: locked')
59
77
  end
@@ -61,87 +79,69 @@ describe Lita::Handlers::Locker, lita_handler: true do
61
79
  it 'shows a warning when a label has no resources' do
62
80
  send_command('locker label create foobar')
63
81
  send_command('lock foobar')
64
- expect(replies.last).to eq('foobar has no resources, ' \
82
+ expect(replies.last).to eq('(failed) foobar has no resources, ' \
65
83
  'so it cannot be locked')
66
84
  end
67
85
 
68
- it 'shows a warning when a resource is unavailable' do
69
- send_command('locker resource create foobar')
70
- send_command('lock foobar')
71
- send_command('lock foobar')
72
- expect(replies.last).to eq('foobar is locked')
73
- end
74
-
75
86
  it 'shows a warning when a label is unavailable' do
87
+ send_command('locker resource create r1')
88
+ send_command('locker label create l1')
89
+ send_command('locker label create l2')
90
+ send_command('locker label add r1 to l1')
91
+ send_command('locker label add r1 to l2')
92
+ send_command('lock l1', as: alice)
93
+ send_command('lock l2', as: alice)
94
+ expect(replies.last).to eq('(failed) Label unable to be locked, ' \
95
+ 'blocked on a dependency')
96
+ end
97
+
98
+ it 'shows a warning when a label is taken by someone else' do
76
99
  send_command('locker resource create foobar')
77
100
  send_command('locker label create bazbat')
78
101
  send_command('locker label add foobar to bazbat')
79
- send_command('lock foobar')
80
- send_command('lock bazbat')
81
- expect(replies.last).to eq('bazbat unable to be locked')
102
+ send_command('lock bazbat', as: alice)
103
+ send_command('lock bazbat', as: bob)
104
+ expect(replies.last).to eq('(failed) bazbat is locked by Alice @alice')
82
105
  end
83
106
 
84
- it 'shows an error when a <subject> does not exist' do
107
+ it 'shows an error when a label does not exist' do
85
108
  send_command('lock foobar')
86
- expect(replies.last).to eq('foobar does not exist')
87
- end
88
-
89
- # it 'locks a resource when it is available for a period of time' do
90
- # send_command('locker resource create foobar')
91
- # send_command('lock foobar 17m')
92
- # expect(replies.last).to eq('foobar locked for 17 minutes')
93
- # send_command('locker resource show foobar')
94
- # expect(replies.last).to eq('Resource: foobar, state: locked')
95
- # send_command('unlock foobar')
96
- # send_command('lock foobar 12s')
97
- # expect(replies.last).to eq('foobar locked for 17 seconds')
98
- # send_command('unlock foobar')
99
- # send_command('lock foobar 14h')
100
- # expect(replies.last).to eq('foobar locked for 14 hours')
101
- # end
109
+ expect(replies.last).to eq('(failed) Label foobar does not exist. To ' \
110
+ 'create it: "!locker label create foobar"')
111
+ end
112
+
113
+ # it 'locks a resource when it is available for a period of time' do
114
+ # send_command('locker resource create foobar')
115
+ # send_command('lock foobar 17m')
116
+ # expect(replies.last).to eq('foobar locked for 17 minutes')
117
+ # send_command('locker resource show foobar')
118
+ # expect(replies.last).to eq('Resource: foobar, state: locked')
119
+ # send_command('unlock foobar')
120
+ # send_command('lock foobar 12s')
121
+ # expect(replies.last).to eq('foobar locked for 17 seconds')
122
+ # send_command('unlock foobar')
123
+ # send_command('lock foobar 14h')
124
+ # expect(replies.last).to eq('foobar locked for 14 hours')
125
+ # end
102
126
  end
103
127
 
104
128
  describe '#unlock' do
105
- it 'unlocks a resource when it is available' do
106
- send_command('locker resource create foobar')
107
- send_command('lock foobar')
108
- send_command('unlock foobar')
109
- expect(replies.last).to eq('foobar unlocked')
110
- end
111
-
112
- it 'does not unlock a resource when someone else locked it' do
113
- alice = Lita::User.create(1, name: 'Alice')
114
- bob = Lita::User.create(2, name: 'Bob')
115
- send_command('locker resource create foobar')
116
- send_command('lock foobar', as: alice)
117
- send_command('unlock foobar', as: bob)
118
- expect(replies.last).to eq('foobar is locked by Alice')
119
- end
120
-
121
129
  it 'unlocks a label when it is available' do
122
130
  send_command('locker resource create foobar')
123
131
  send_command('locker label create bazbat')
124
132
  send_command('locker label add foobar to bazbat')
125
133
  send_command('lock bazbat')
126
- send_command('unlock bazbat')
127
- expect(replies.last).to eq('bazbat unlocked')
134
+ send_command('unlock bazbat # with a comment')
135
+ expect(replies.last).to eq('(successful) bazbat unlocked')
128
136
  end
129
137
 
130
138
  it 'does not unlock a label when someone else locked it' do
131
- alice = Lita::User.create(1, name: 'Alice')
132
- bob = Lita::User.create(2, name: 'Bob')
133
139
  send_command('locker resource create foobar')
134
140
  send_command('locker label create bazbat')
135
141
  send_command('locker label add foobar to bazbat')
136
142
  send_command('lock bazbat', as: alice)
137
143
  send_command('unlock bazbat', as: bob)
138
- expect(replies.last).to eq('bazbat is locked by Alice')
139
- end
140
-
141
- it 'shows a warning when a resource is already unlocked' do
142
- send_command('locker resource create foobar')
143
- send_command('unlock foobar')
144
- expect(replies.last).to eq('foobar is unlocked')
144
+ expect(replies.last).to eq('(failed) bazbat is locked by Alice @alice')
145
145
  end
146
146
 
147
147
  it 'shows a warning when a label is already unlocked' do
@@ -150,39 +150,57 @@ describe Lita::Handlers::Locker, lita_handler: true do
150
150
  send_command('locker label add foobar to bazbat')
151
151
  send_command('unlock bazbat')
152
152
  send_command('unlock bazbat')
153
- expect(replies.last).to eq('bazbat is unlocked')
153
+ expect(replies.last).to eq('(successful) bazbat is unlocked')
154
154
  end
155
155
 
156
156
  it 'shows an error when a <subject> does not exist' do
157
157
  send_command('unlock foobar')
158
- expect(replies.last).to eq('foobar does not exist')
158
+ expect(replies.last).to eq('(failed) Sorry, that does not exist')
159
159
  end
160
160
  end
161
161
 
162
- describe '#unlock_force' do
163
- it 'unlocks a resource from someone else when it is available' do
164
- alice = Lita::User.create(1, name: 'Alice')
165
- bob = Lita::User.create(2, name: 'Bob')
166
- send_command('locker resource create foobar')
167
- send_command('lock foobar', as: alice)
168
- send_command('unlock foobar force', as: bob)
169
- expect(replies.last).to eq('foobar unlocked')
170
- end
171
-
162
+ describe '#steal' do
172
163
  it 'unlocks a label from someone else when it is available' do
173
- alice = Lita::User.create(1, name: 'Alice')
174
- bob = Lita::User.create(2, name: 'Bob')
175
164
  send_command('locker resource create foobar')
176
165
  send_command('locker label create bazbat')
177
166
  send_command('locker label add foobar to bazbat')
178
167
  send_command('lock bazbat', as: alice)
179
- send_command('unlock bazbat force', as: bob)
180
- expect(replies.last).to eq('bazbat unlocked')
168
+ send_command('steal bazbat # with a comment', as: bob)
169
+ expect(replies.last).to eq('(successful) bazbat unlocked')
181
170
  end
182
171
 
183
172
  it 'shows an error when a <subject> does not exist' do
184
- send_command('unlock foobar force')
185
- expect(replies.last).to eq('foobar does not exist')
173
+ send_command('steal foobar')
174
+ expect(replies.last).to eq('(failed) Sorry, that does not exist')
175
+ end
176
+ end
177
+
178
+ describe '#status' do
179
+ it 'shows the status of a label' do
180
+ send_command('locker resource create bar')
181
+ send_command('locker label create foo')
182
+ send_command('locker label add bar to foo')
183
+ send_command('locker status foo')
184
+ expect(replies.last).to eq('Label: foo, state: unlocked')
185
+ send_command('lock foo')
186
+ send_command('locker status foo')
187
+ expect(replies.last).to eq('Label: foo, state: locked')
188
+ end
189
+
190
+ it 'shows the status of a resource' do
191
+ send_command('locker resource create bar')
192
+ send_command('locker label create foo')
193
+ send_command('locker label add bar to foo')
194
+ send_command('locker status bar')
195
+ expect(replies.last).to eq('Resource: bar, state: unlocked')
196
+ send_command('lock foo')
197
+ send_command('locker status bar')
198
+ expect(replies.last).to eq('Resource: bar, state: locked')
199
+ end
200
+
201
+ it 'shows an error if nothing exists with that name' do
202
+ send_command('locker status foo')
203
+ expect(replies.last).to eq('Sorry, that does not exist')
186
204
  end
187
205
  end
188
206
 
@@ -191,8 +209,8 @@ describe Lita::Handlers::Locker, lita_handler: true do
191
209
  send_command('locker label create foobar')
192
210
  send_command('locker label create bazbat')
193
211
  send_command('locker label list')
194
- expect(replies.include?('Label: foobar')).to eq(true)
195
- expect(replies.include?('Label: bazbat')).to eq(true)
212
+ expect(replies.include?('Label: foobar, state: unlocked')).to eq(true)
213
+ expect(replies.include?('Label: bazbat, state: unlocked')).to eq(true)
196
214
  end
197
215
  end
198
216
 
@@ -224,7 +242,8 @@ describe Lita::Handlers::Locker, lita_handler: true do
224
242
 
225
243
  it 'shows a warning when <name> does not exist' do
226
244
  send_command('locker label delete foobar')
227
- expect(replies.last).to eq('Label foobar does not exist')
245
+ expect(replies.last).to eq('Label foobar does not exist. To create ' \
246
+ 'it: "!locker label create foobar"')
228
247
  end
229
248
  end
230
249
 
@@ -245,7 +264,8 @@ describe Lita::Handlers::Locker, lita_handler: true do
245
264
 
246
265
  it 'shows an error if the label does not exist' do
247
266
  send_command('locker label show foobar')
248
- expect(replies.last).to eq('Label foobar does not exist')
267
+ expect(replies.last).to eq('Label foobar does not exist. To create ' \
268
+ 'it: "!locker label create foobar"')
249
269
  end
250
270
  end
251
271
 
@@ -266,12 +286,13 @@ describe Lita::Handlers::Locker, lita_handler: true do
266
286
  send_command('locker label add foo to bar')
267
287
  send_command('locker label add baz to bar')
268
288
  send_command('locker label show bar')
269
- expect(replies.last).to eq('Label bar has: baz, foo')
289
+ expect(replies.last).to eq('Label bar has: foo, baz')
270
290
  end
271
291
 
272
292
  it 'shows an error if the label does not exist' do
273
293
  send_command('locker label add foo to bar')
274
- expect(replies.last).to eq('Label bar does not exist')
294
+ expect(replies.last).to eq('Label bar does not exist. To create ' \
295
+ 'it: "!locker label create bar"')
275
296
  end
276
297
 
277
298
  it 'shows an error if the resource does not exist' do
@@ -300,7 +321,8 @@ describe Lita::Handlers::Locker, lita_handler: true do
300
321
 
301
322
  it 'shows an error if the label does not exist' do
302
323
  send_command('locker label add foo to bar')
303
- expect(replies.last).to eq('Label bar does not exist')
324
+ expect(replies.last).to eq('Label bar does not exist. To create ' \
325
+ 'it: "!locker label create bar"')
304
326
  end
305
327
 
306
328
  it 'shows an error if the resource does not exist' do
@@ -315,8 +337,8 @@ describe Lita::Handlers::Locker, lita_handler: true do
315
337
  send_command('locker resource create foobar')
316
338
  send_command('locker resource create bazbat')
317
339
  send_command('locker resource list')
318
- expect(replies.include?('Resource: foobar, state: unlocked')).to eq(true)
319
- expect(replies.include?('Resource: bazbat, state: unlocked')).to eq(true)
340
+ expect(replies.last).to match(/Resource: foobar, state: unlocked/)
341
+ expect(replies.last).to match(/Resource: bazbat, state: unlocked/)
320
342
  end
321
343
  end
322
344
 
@@ -357,9 +379,6 @@ describe Lita::Handlers::Locker, lita_handler: true do
357
379
  send_command('locker resource create foobar')
358
380
  send_command('locker resource show foobar')
359
381
  expect(replies.last).to eq('Resource: foobar, state: unlocked')
360
- send_command('lock foobar')
361
- send_command('locker resource show foobar')
362
- expect(replies.last).to eq('Resource: foobar, state: locked')
363
382
  end
364
383
 
365
384
  it 'shows a warning when <name> does not exist' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita-locker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Sigler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-16 00:00:00.000000000 Z
11
+ date: 2014-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lita
@@ -122,6 +122,7 @@ files:
122
122
  - LICENSE
123
123
  - README.md
124
124
  - Rakefile
125
+ - TODO.md
125
126
  - lib/lita-locker.rb
126
127
  - lib/lita/handlers/locker.rb
127
128
  - lita-locker.gemspec