lita-locker 1.0.1 → 1.0.2

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: 2815409ac4a6c9435d8bab8f79c9b5ac777c510c
4
- data.tar.gz: 9bd9b6aabf276f58148e05da2b4b82451ba0769c
3
+ metadata.gz: 05c37515e071dc49fb68a05ccefe0b708ef60bfd
4
+ data.tar.gz: 4fe6d90d4764be77216f11625c8c377d4a6aaabb
5
5
  SHA512:
6
- metadata.gz: ba2eb359c367608c8255e387c7393781f60d8872fbb8347d376fd8b6477db9bcc20546befc2ccf90d6a2bf8d4a1ab7effae3883b775313e8e57e3112e2e264e0
7
- data.tar.gz: bd74d58ac7ead4d092d194ff2e663fa645a2443019addd9283323a1de16fccdb4acd431ee1106ff40449c5f8588e41c239a89cceadb1a93553d00ef3136d85e4
6
+ metadata.gz: cb09f15584cd47ecbfbfbc6876fac0792d5708fd6e83012e4b7711578fe211770b9b1ba0ddcba4f62b252c00b421ad02bbf52dd1f25fc5a1d08f50b38136c128
7
+ data.tar.gz: 534cc1c533df5b591bf9a6f3e0baf8644efb69a3763e0892d931439b9018aa63d6a6f38057b78fe771f17cd50f0c85b2bc74adad65f02452619bd3efb1f074cf
@@ -41,13 +41,27 @@ module Lita
41
41
  help: { t('help.steal.syntax') => t('help.steal.desc') }
42
42
  )
43
43
 
44
+ route(
45
+ /^locker\sobserve\s#{LABEL_REGEX}#{COMMENT_REGEX}$/,
46
+ :observe,
47
+ command: true,
48
+ help: { t('help.observe.syntax') => t('help.observe.desc') }
49
+ )
50
+
51
+ route(
52
+ /^locker\sunobserve\s#{LABEL_REGEX}#{COMMENT_REGEX}$/,
53
+ :unobserve,
54
+ command: true,
55
+ help: { t('help.unobserve.syntax') => t('help.unobserve.desc') }
56
+ )
57
+
44
58
  def setup_redis(_payload)
45
59
  Label.redis = redis
46
60
  Resource.redis = redis
47
61
  end
48
62
 
49
63
  def lock(response)
50
- name = response.match_data['label']
64
+ name = response.match_data['label'].rstrip
51
65
 
52
66
  return response.reply(failed(t('label.does_not_exist', name: name))) unless Label.exists?(name)
53
67
  l = Label.new(name)
@@ -59,18 +73,48 @@ module Lita
59
73
  end
60
74
 
61
75
  def unlock(response)
62
- name = response.match_data['label']
76
+ name = response.match_data['label'].rstrip
77
+
63
78
  return response.reply(failed(t('subject.does_not_exist', name: name))) unless Label.exists?(name)
64
79
  l = Label.new(name)
65
80
  return response.reply(success(t('label.is_unlocked', name: name))) unless l.locked?
81
+
66
82
  response.reply(attempt_unlock(name, response.user))
83
+
84
+ return if l.locked?
85
+ mention_names = l.observers
86
+ .map { |observer| observer.mention_name ? "(@#{observer.mention_name})" : '' }
87
+ .reject { |mention| mention == '' }
88
+ .sort
89
+ .join(' ')
90
+ response.reply(t('label.unlocked_no_queue', name: name, mention: mention_names)) unless mention_names.empty?
67
91
  end
68
92
 
69
- def steal(response)
93
+ def observe(response)
70
94
  name = response.match_data['label']
95
+ return response.reply(failed(t('label.does_not_exist', name: name))) unless Label.exists?(name)
96
+ l = Label.new(name)
97
+ return response.reply(t('observe.already_observing', name: name)) if l.observer?(response.user.id)
98
+ l.add_observer!(response.user.id)
99
+ response.reply(t('observe.now_observing', name: name))
100
+ end
101
+
102
+ def unobserve(response)
103
+ name = response.match_data['label']
104
+ return response.reply(failed(t('label.does_not_exist', name: name))) unless Label.exists?(name)
105
+ l = Label.new(name)
106
+ return response.reply(t('observe.were_not_observing', name: name)) unless l.observer?(response.user.id)
107
+ l.remove_observer!(response.user.id)
108
+ response.reply(t('observe.stopped_observing', name: name))
109
+ end
110
+
111
+ def steal(response)
112
+ name = response.match_data['label'].rstrip
113
+
71
114
  return response.reply(failed(t('subject.does_not_exist', name: name))) unless Label.exists?(name)
72
115
  l = Label.new(name)
73
116
  return response.reply(t('steal.already_unlocked', label: name)) unless l.locked?
117
+
74
118
  response.reply(attempt_steal(name, response.user))
75
119
  end
76
120
 
@@ -24,7 +24,7 @@ module Lita
24
24
  )
25
25
 
26
26
  route(
27
- /^locker\sdequeue\s#{LABEL_REGEX}$/,
27
+ /^locker\s(dq|dequeue)\s#{LABEL_REGEX}$/,
28
28
  :dequeue,
29
29
  command: true,
30
30
  help: { t('help.dequeue.syntax') => t('help.dequeue.desc') }
@@ -11,6 +11,7 @@ module Locker
11
11
  value :taken_at
12
12
 
13
13
  set :membership
14
+ set :observer_ids
14
15
  list :wait_queue
15
16
  list :journal
16
17
 
@@ -39,7 +40,7 @@ module Locker
39
40
 
40
41
  def self.delete(key)
41
42
  fail 'Unknown label key' unless Label.exists?(key)
42
- %w(state, owner_id, membership, wait_queue, journal).each do |item|
43
+ %w(state, owner_id, membership, wait_queue, journal, observer_ids).each do |item|
43
44
  redis.del("label:#{key}:#{item}")
44
45
  end
45
46
  redis.srem('label-list', Label.normalize(key))
@@ -105,10 +106,28 @@ module Locker
105
106
  self.unlock!
106
107
  end
107
108
 
109
+ def add_observer!(observer_id)
110
+ observer_ids.add(observer_id)
111
+ end
112
+
113
+ def remove_observer!(observer_id)
114
+ observer_ids.delete(observer_id)
115
+ end
116
+
117
+ def observer?(observer_id)
118
+ observer_ids.member?(observer_id)
119
+ end
120
+
108
121
  def locked?
109
122
  (state == 'locked')
110
123
  end
111
124
 
125
+ def observers
126
+ observer_ids.map do |observer_id|
127
+ Lita::User.find_by_id(observer_id)
128
+ end
129
+ end
130
+
112
131
  def add_resource(resource)
113
132
  log("Resource #{resource.id} added")
114
133
  resource.labels << id
@@ -153,8 +172,17 @@ module Locker
153
172
  def label_ownership(name)
154
173
  l = Label.new(name)
155
174
  return label_dependencies(name) unless l.locked?
175
+ queue = []
176
+ l.wait_queue.each do |u|
177
+ usr = Lita::User.find_by_id(u)
178
+ queue.push(usr.name)
179
+ end
156
180
  mention = l.owner.mention_name ? "(@#{l.owner.mention_name})" : ''
157
- failed(t('label.owned_lock', name: name, owner_name: l.owner.name, mention: mention, time: l.held_for))
181
+ failed(t('label.owned_lock', name: name,
182
+ owner_name: l.owner.name,
183
+ mention: mention,
184
+ time: l.held_for,
185
+ queue: queue.join(', ')))
158
186
  end
159
187
 
160
188
  def label_dependencies(name)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'lita-locker'
3
- spec.version = '1.0.1'
3
+ spec.version = '1.0.2'
4
4
  spec.authors = ['Eric Sigler']
5
5
  spec.email = ['me@esigler.com']
6
6
  spec.description = '"lock" and "unlock" arbitrary subjects'
@@ -6,6 +6,11 @@ en:
6
6
  stolen: "%{label} stolen from %{old_owner} %{mention}"
7
7
  already_unlocked: "%{label} was already unlocked"
8
8
  self: Why are you stealing the lock from yourself?
9
+ observe:
10
+ now_observing: "Now observing %{name}"
11
+ already_observing: "You are already observing %{name}"
12
+ stopped_observing: "You have stopped observing %{name}"
13
+ were_not_observing: "You were not observing %{name} originally"
9
14
  help:
10
15
  log:
11
16
  syntax: locker log <label>
@@ -19,6 +24,12 @@ en:
19
24
  unlock:
20
25
  syntax: unlock <subject>
21
26
  desc: Make something available to others. Can have # comments afterwards.
27
+ observe:
28
+ syntax: locker observe <subject>
29
+ desc: Get a notification when something becomes available. Can have # comments afterwards
30
+ unobserve:
31
+ syntax: locker unobserve <subject>
32
+ desc: Stop getting notifications when something becomes available. Can have # comments afterwards
22
33
  steal:
23
34
  syntax: steal <subject>
24
35
  desc: Force removal of a reservation. Can have # comments afterwards.
@@ -78,9 +89,10 @@ en:
78
89
  log_entry: "%{entry}"
79
90
  self_lock: "You already have the lock on %{name}"
80
91
  unlock: "%{name} unlocked"
81
- owned_lock: "%{name} is locked by %{owner_name} %{mention} (taken %{time}), you have been added to the queue, type 'locker dequeue %{name}' to be removed"
92
+ owned_lock: "%{name} is locked by %{owner_name} %{mention} (taken %{time}), you have been added to the queue (currently: %{queue}), type 'locker dequeue %{name}' to be removed"
82
93
  owned_unlock: "%{name} is locked by %{owner_name} %{mention} (taken %{time})"
83
94
  is_unlocked: "%{name} is unlocked"
95
+ unlocked_no_queue: "%{name} is unlocked and no one is next up %{mention}"
84
96
  unable_to_lock: "%{name} unable to be locked"
85
97
  lock: "%{name} locked"
86
98
  desc: "%{name} is unlocked"
@@ -26,6 +26,11 @@ describe Lita::Handlers::LockerMisc, lita_handler: true do
26
26
  is_expected.to route_command('locker log something').to(:log)
27
27
  end
28
28
 
29
+ it do
30
+ is_expected.to route_command('locker dequeue something something').to(:dequeue)
31
+ is_expected.to route_command('locker dq something something').to(:dequeue)
32
+ end
33
+
29
34
  let(:alice) do
30
35
  Lita::User.create('9001@hipchat', name: 'Alice', mention_name: 'alice')
31
36
  end
@@ -22,11 +22,18 @@ describe Lita::Handlers::Locker, lita_handler: true do
22
22
  is_expected.to route("(release) #{l} #this is a comment").to(:unlock)
23
23
 
24
24
  is_expected.to route_command("lock #{l}").to(:lock)
25
+ is_expected.to route_command("lock #{l} ").to(:lock)
25
26
  is_expected.to route_command("lock #{l} #this is a comment").to(:lock)
26
27
  is_expected.to route_command("unlock #{l}").to(:unlock)
28
+ is_expected.to route_command("unlock #{l} ").to(:unlock)
27
29
  is_expected.to route_command("unlock #{l} #this is a comment").to(:unlock)
28
30
  is_expected.to route_command("steal #{l}").to(:steal)
31
+ is_expected.to route_command("steal #{l} ").to(:steal)
29
32
  is_expected.to route_command("steal #{l} #this is a comment").to(:steal)
33
+ is_expected.to route_command("locker observe #{l}").to(:observe)
34
+ is_expected.to route_command("locker observe #{l} #this is a comment").to(:observe)
35
+ is_expected.to route_command("locker unobserve #{l}").to(:unobserve)
36
+ is_expected.to route_command("locker unobserve #{l} #this is a comment").to(:unobserve)
30
37
  end
31
38
  end
32
39
 
@@ -58,7 +65,7 @@ describe Lita::Handlers::Locker, lita_handler: true do
58
65
  send_command('locker label create bazbat')
59
66
  send_command('locker label add foobar to bazbat')
60
67
  send_command('lock bazbat ')
61
- expect(replies.last).to eq('bazbat locked')
68
+ expect(replies.last).to eq('bazbat locked')
62
69
  end
63
70
 
64
71
  it 'does not enqueue the user that currently has a lock' do
@@ -119,7 +126,7 @@ describe Lita::Handlers::Locker, lita_handler: true do
119
126
  send_command('lock bazbat', as: alice)
120
127
  send_command('lock bazbat', as: bob)
121
128
  expect(replies.last).to eq('bazbat is locked by Alice (@alice) (taken 1 second ago), you have been ' \
122
- 'added to the queue, type \'locker dequeue bazbat\' to be removed')
129
+ 'added to the queue (currently: Bob), type \'locker dequeue bazbat\' to be removed')
123
130
  end
124
131
 
125
132
  it 'shows an error when a label does not exist' do
@@ -148,6 +155,53 @@ describe Lita::Handlers::Locker, lita_handler: true do
148
155
  expect(replies.last).to eq('bazbat now locked by Bob (@bob)')
149
156
  end
150
157
 
158
+ it 'unlocks a label and alerts observers' do
159
+ send_command('locker resource create foobar')
160
+ send_command('locker label create bazbat')
161
+ send_command('locker label add foobar to bazbat')
162
+ send_command('locker observe bazbat', as: alice)
163
+ send_command('lock bazbat', as: bob)
164
+ send_command('locker observe bazbat', as: charlie)
165
+ send_command('unlock bazbat # with a comment', as: bob)
166
+ expect(replies).to include('bazbat is unlocked and no one is next up (@alice) (@charlie)')
167
+ expect(replies).to include('bazbat unlocked')
168
+ end
169
+
170
+ it 'does not alert observers if there is a queued person' do
171
+ send_command('locker resource create foobar')
172
+ send_command('locker label create bazbat')
173
+ send_command('locker label add foobar to bazbat')
174
+ send_command('locker observe bazbat', as: alice)
175
+ send_command('lock bazbat', as: bob)
176
+ send_command('lock bazbat', as: charlie)
177
+ send_command('unlock bazbat # with a comment', as: bob)
178
+ expect(replies).not_to include('bazbat is unlocked and no one is next up (@alice)')
179
+ end
180
+
181
+ it 'unlocks a label and alerts only observers' do
182
+ send_command('locker resource create foobar')
183
+ send_command('locker label create bazbat')
184
+ send_command('locker label add foobar to bazbat')
185
+ send_command('locker observe bazbat', as: alice)
186
+ send_command('lock bazbat', as: bob)
187
+ send_command('locker observe bazbat', as: charlie)
188
+ send_command('locker unobserve bazbat', as: alice)
189
+ send_command('unlock bazbat # with a comment', as: bob)
190
+ expect(replies).to include('bazbat is unlocked and no one is next up (@charlie)')
191
+ expect(replies).to include('bazbat unlocked')
192
+ end
193
+
194
+ it 'unlocks a label and does not alert anyone if there are no observers' do
195
+ send_command('locker resource create foobar')
196
+ send_command('locker label create bazbat')
197
+ send_command('locker label add foobar to bazbat')
198
+ send_command('locker observe bazbat', as: alice)
199
+ send_command('lock bazbat', as: bob)
200
+ send_command('locker unobserve bazbat', as: alice)
201
+ send_command('unlock bazbat # with a comment', as: bob)
202
+ expect(replies.last).to eq('bazbat unlocked')
203
+ end
204
+
151
205
  it 'does not unlock a label when someone else locked it' do
152
206
  send_command('locker resource create foobar')
153
207
  send_command('locker label create bazbat')
@@ -215,4 +269,44 @@ describe Lita::Handlers::Locker, lita_handler: true do
215
269
  expect(replies.last).to eq('Sorry, that does not exist')
216
270
  end
217
271
  end
272
+
273
+ describe '#observe' do
274
+ it 'adds a user as observer of a label' do
275
+ send_command('locker resource create foobar')
276
+ send_command('locker label create bazbat')
277
+ send_command('locker label add foobar to bazbat')
278
+ send_command('locker observe bazbat', as: alice)
279
+ expect(replies.last).to eq('Now observing bazbat')
280
+ end
281
+
282
+ it 'warns user if already observing label' do
283
+ send_command('locker resource create foobar')
284
+ send_command('locker label create bazbat')
285
+ send_command('locker label add foobar to bazbat')
286
+ send_command('locker observe bazbat', as: alice)
287
+ send_command('locker observe bazbat', as: alice)
288
+ expect(replies.last).to eq('You are already observing bazbat')
289
+ end
290
+ end
291
+
292
+ describe '#unobserve' do
293
+ it 'removes user from observer list for a label' do
294
+ send_command('locker resource create foobar')
295
+ send_command('locker label create bazbat')
296
+ send_command('locker label add foobar to bazbat')
297
+ send_command('locker observe bazbat', as: alice)
298
+ send_command('locker unobserve bazbat', as: alice)
299
+ expect(replies.last).to eq('You have stopped observing bazbat')
300
+ end
301
+
302
+ it 'warns user if already not observing label' do
303
+ send_command('locker resource create foobar')
304
+ send_command('locker label create bazbat')
305
+ send_command('locker label add foobar to bazbat')
306
+ send_command('locker observe bazbat', as: alice)
307
+ send_command('locker unobserve bazbat', as: alice)
308
+ send_command('locker unobserve bazbat', as: alice)
309
+ expect(replies.last).to eq('You were not observing bazbat originally')
310
+ end
311
+ end
218
312
  end
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: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Sigler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-20 00:00:00.000000000 Z
11
+ date: 2015-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lita