-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package locker | ||
|
||
import ( | ||
"fmt" | ||
"github.com/bivas/rivi/bot" | ||
"github.com/bivas/rivi/util" | ||
"github.com/mitchellh/mapstructure" | ||
) | ||
|
||
type LockableEventData interface { | ||
Lock() | ||
Unlock() | ||
LockState() bool | ||
} | ||
|
||
type action struct { | ||
rule *rule | ||
err error | ||
} | ||
|
||
func (a *action) Apply(config bot.Configuration, meta bot.EventData) { | ||
lockable, ok := meta.(LockableEventData) | ||
if !ok { | ||
util.Logger.Warning("Event data does not support locking. Check your configurations") | ||
a.err = fmt.Errorf("Event data does not support locking") | ||
return | ||
} | ||
if lockable.LockState() { | ||
util.Logger.Debug("Issue is locked") | ||
if a.rule.State == "unlock" || a.rule.State == "change" { | ||
util.Logger.Debug("unlocking issue %d", meta.GetNumber()) | ||
lockable.Unlock() | ||
} else if a.rule.State == "lock" { | ||
util.Logger.Debug("Issue %d is already locked - nothing changed", meta.GetNumber()) | ||
} | ||
} else { | ||
util.Logger.Debug("Issue is unlocked") | ||
if a.rule.State == "lock" || a.rule.State == "change" { | ||
util.Logger.Debug("Locking issue %d", meta.GetNumber()) | ||
lockable.Lock() | ||
} else if a.rule.State == "lock" { | ||
util.Logger.Debug("Issue %d is already unlocked - nothing changed", meta.GetNumber()) | ||
} | ||
} | ||
} | ||
|
||
type factory struct { | ||
} | ||
|
||
func (*factory) BuildAction(config map[string]interface{}) bot.Action { | ||
item := rule{} | ||
if e := mapstructure.Decode(config, &item); e != nil { | ||
panic(e) | ||
} | ||
return &action{rule: &item} | ||
} | ||
|
||
func init() { | ||
bot.RegisterAction("locker", &factory{}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Locker | ||
|
||
## Goal | ||
|
||
Ability to lock/unlock an issue | ||
|
||
## Requirements | ||
|
||
None | ||
|
||
## Options | ||
|
||
- `state` (required) - sets the issue state. Can be `lock`, `unlock` or `change` | ||
|
||
## Example | ||
```yaml | ||
rules: | ||
example: | ||
locker: | ||
state: lock | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package locker | ||
|
||
import ( | ||
"github.com/bivas/rivi/bot/mock" | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
type mockLockableEventData struct { | ||
mock.MockEventData | ||
locked bool | ||
lockCalled, unlockCalled bool | ||
} | ||
|
||
func (m *mockLockableEventData) Lock() { | ||
m.locked = true | ||
m.lockCalled = true | ||
} | ||
|
||
func (m *mockLockableEventData) Unlock() { | ||
m.locked = false | ||
m.unlockCalled = true | ||
} | ||
|
||
func (m *mockLockableEventData) LockState() bool { | ||
return m.locked | ||
} | ||
|
||
func TestNotLockable(t *testing.T) { | ||
action := action{rule: &rule{}} | ||
meta := &mock.MockEventData{Labels: []string{}} | ||
config := &mock.MockConfiguration{} | ||
action.Apply(config, meta) | ||
assert.NotNil(t, action.err, "can't merge") | ||
} | ||
|
||
func TestLock(t *testing.T) { | ||
action := action{rule: &rule{State: "lock"}} | ||
meta := &mockLockableEventData{MockEventData: mock.MockEventData{}} | ||
config := &mock.MockConfiguration{} | ||
action.Apply(config, meta) | ||
assert.Nil(t, action.err, "shouldn't error") | ||
assert.True(t, meta.locked, "should be locked") | ||
assert.True(t, meta.lockCalled, "should be locked") | ||
} | ||
|
||
func TestLockWhenLocked(t *testing.T) { | ||
action := action{rule: &rule{State: "lock"}} | ||
meta := &mockLockableEventData{MockEventData: mock.MockEventData{}, locked: true} | ||
config := &mock.MockConfiguration{} | ||
action.Apply(config, meta) | ||
assert.Nil(t, action.err, "shouldn't error") | ||
assert.True(t, meta.locked, "should be locked") | ||
assert.False(t, meta.lockCalled, "no need to relock") | ||
} | ||
|
||
func TestUnlockWhenLocked(t *testing.T) { | ||
action := action{rule: &rule{State: "unlock"}} | ||
meta := &mockLockableEventData{MockEventData: mock.MockEventData{}, locked: true} | ||
config := &mock.MockConfiguration{} | ||
action.Apply(config, meta) | ||
assert.Nil(t, action.err, "shouldn't error") | ||
assert.False(t, meta.locked, "should be unlocked") | ||
assert.True(t, meta.unlockCalled, "should be unlocked") | ||
} | ||
|
||
func TestUnlockWhenUnlocked(t *testing.T) { | ||
action := action{rule: &rule{State: "unlock"}} | ||
meta := &mockLockableEventData{MockEventData: mock.MockEventData{}} | ||
config := &mock.MockConfiguration{} | ||
action.Apply(config, meta) | ||
assert.Nil(t, action.err, "shouldn't error") | ||
assert.False(t, meta.locked, "should be unlocked") | ||
assert.False(t, meta.unlockCalled, "no need to re-unlock") | ||
} | ||
|
||
func TestStateChangeFromUnlocked(t *testing.T) { | ||
action := action{rule: &rule{State: "change"}} | ||
meta := &mockLockableEventData{MockEventData: mock.MockEventData{}} | ||
config := &mock.MockConfiguration{} | ||
action.Apply(config, meta) | ||
assert.Nil(t, action.err, "shouldn't error") | ||
assert.True(t, meta.locked, "should be locked") | ||
assert.True(t, meta.lockCalled, "lock") | ||
} | ||
|
||
func TestStateChangeFromLocked(t *testing.T) { | ||
action := action{rule: &rule{State: "change"}} | ||
meta := &mockLockableEventData{MockEventData: mock.MockEventData{}, locked: true} | ||
config := &mock.MockConfiguration{} | ||
action.Apply(config, meta) | ||
assert.Nil(t, action.err, "shouldn't error") | ||
assert.False(t, meta.locked, "should be unlocked") | ||
assert.True(t, meta.unlockCalled, "unlock") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package locker | ||
|
||
type rule struct { | ||
State string `mapstructure:"state"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters