lita-locker 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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