From aec3b8d204dd8b4f9308f536e9b5eefcf966f86e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 2 May 2018 22:30:43 +0300 Subject: [PATCH] Add tests for PushRule.Match and fork glob to make it compatible with the spec --- Gopkg.lock | 10 +- Gopkg.toml | 4 - .../github.com/zyedidia => lib}/glob/LICENSE | 0 .../zyedidia => lib}/glob/README.md | 0 .../github.com/zyedidia => lib}/glob/glob.go | 16 +- matrix/pushrules/condition.go | 7 +- matrix/pushrules/condition_eventmatch_test.go | 6 + matrix/pushrules/rule.go | 2 +- matrix/pushrules/rule_test.go | 166 ++++++++++++++++++ 9 files changed, 195 insertions(+), 16 deletions(-) rename {vendor/github.com/zyedidia => lib}/glob/LICENSE (100%) rename {vendor/github.com/zyedidia => lib}/glob/README.md (100%) rename {vendor/github.com/zyedidia => lib}/glob/glob.go (83%) diff --git a/Gopkg.lock b/Gopkg.lock index b78c6ef..44e4ee4 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -61,12 +61,6 @@ packages = ["."] revision = "4611e809d8b1a3051c11d11f4b610c44df73fa38" -[[projects]] - branch = "master" - name = "github.com/zyedidia/glob" - packages = ["."] - revision = "dd4023a66dc351ae26e592d21cd133b5b143f3d8" - [[projects]] branch = "master" name = "golang.org/x/image" @@ -88,7 +82,7 @@ "html", "html/atom" ] - revision = "5f9ae10d9af5b1c89ae6904293b14b064d4ada23" + revision = "640f4622ab692b87c2f3a94265e6f579fe38263d" [[projects]] name = "golang.org/x/text" @@ -144,6 +138,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "ea0f742be221116a10b3fb332aee126fd8f4b3392b65a8e38a7c26e8c45faf8f" + inputs-digest = "375d42f271992a59ae0bcf25e2401aae2f4d8adb7b63605c4ffef577c5154025" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 312c8a1..ab8782e 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -41,10 +41,6 @@ branch = "master" name = "github.com/zyedidia/clipboard" -[[constraint]] - branch = "master" - name = "github.com/zyedidia/glob" - [[constraint]] branch = "master" name = "golang.org/x/image" diff --git a/vendor/github.com/zyedidia/glob/LICENSE b/lib/glob/LICENSE similarity index 100% rename from vendor/github.com/zyedidia/glob/LICENSE rename to lib/glob/LICENSE diff --git a/vendor/github.com/zyedidia/glob/README.md b/lib/glob/README.md similarity index 100% rename from vendor/github.com/zyedidia/glob/README.md rename to lib/glob/README.md diff --git a/vendor/github.com/zyedidia/glob/glob.go b/lib/glob/glob.go similarity index 83% rename from vendor/github.com/zyedidia/glob/glob.go rename to lib/glob/glob.go index 10c9b5d..c270dbc 100644 --- a/vendor/github.com/zyedidia/glob/glob.go +++ b/lib/glob/glob.go @@ -24,6 +24,8 @@ func globToRegex(glob string) (*regexp.Regexp, error) { firstIndexInClass := -1 arr := []byte(glob) + hasGlobCharacters := false + for i := 0; i < len(arr); i++ { ch := arr[i] @@ -50,16 +52,19 @@ func globToRegex(glob string) (*regexp.Regexp, error) { } else { regex += "*" } + hasGlobCharacters = true case '?': if inClass == 0 { regex += "." } else { regex += "?" } + hasGlobCharacters = true case '[': inClass++ firstIndexInClass = i + 1 regex += "[" + hasGlobCharacters = true case ']': inClass-- regex += "]" @@ -68,21 +73,25 @@ func globToRegex(glob string) (*regexp.Regexp, error) { regex += "\\" } regex += string(ch) + hasGlobCharacters = true case '!': if firstIndexInClass == i { regex += "^" } else { regex += "!" } + hasGlobCharacters = true case '{': inGroup++ regex += "(" + hasGlobCharacters = true case '}': inGroup-- regex += ")" case ',': if inGroup > 0 { regex += "|" + hasGlobCharacters = true } else { regex += "," } @@ -90,5 +99,10 @@ func globToRegex(glob string) (*regexp.Regexp, error) { regex += string(ch) } } - return regexp.Compile("^" + regex + "$") + + if hasGlobCharacters { + return regexp.Compile("^" + regex + "$") + } else { + return regexp.Compile(regex) + } } diff --git a/matrix/pushrules/condition.go b/matrix/pushrules/condition.go index 4d17695..6607323 100644 --- a/matrix/pushrules/condition.go +++ b/matrix/pushrules/condition.go @@ -21,7 +21,7 @@ import ( "strconv" "strings" - "github.com/zyedidia/glob" + "maunium.net/go/gomuks/lib/glob" "maunium.net/go/gomatrix" "maunium.net/go/gomuks/matrix/rooms" ) @@ -82,7 +82,10 @@ func (cond *PushCondition) matchValue(room Room, event *gomatrix.Event) bool { key = key[0:index] } - pattern, _ := glob.Compile(cond.Pattern) + pattern, err := glob.Compile(cond.Pattern) + if err != nil { + return false + } switch key { case "type": diff --git a/matrix/pushrules/condition_eventmatch_test.go b/matrix/pushrules/condition_eventmatch_test.go index 2fcd054..160edd5 100644 --- a/matrix/pushrules/condition_eventmatch_test.go +++ b/matrix/pushrules/condition_eventmatch_test.go @@ -47,6 +47,12 @@ func TestPushCondition_Match_KindEvent_EventType(t *testing.T) { assert.True(t, condition.Match(blankTestRoom, event)) } +func TestPushCondition_Match_KindEvent_EventType_IllegalGlob(t *testing.T) { + condition := newMatchPushCondition("type", "m.room.invalid_glo[b") + event := newFakeEvent("m.room.invalid_glob", map[string]interface{}{}) + assert.False(t, condition.Match(blankTestRoom, event)) +} + func TestPushCondition_Match_KindEvent_Sender_Fail(t *testing.T) { condition := newMatchPushCondition("sender", "@foo:maunium.net") event := newFakeEvent("m.room.foo", map[string]interface{}{}) diff --git a/matrix/pushrules/rule.go b/matrix/pushrules/rule.go index 0caa13d..5c32a05 100644 --- a/matrix/pushrules/rule.go +++ b/matrix/pushrules/rule.go @@ -17,7 +17,7 @@ package pushrules import ( - "github.com/zyedidia/glob" + "maunium.net/go/gomuks/lib/glob" "maunium.net/go/gomatrix" ) diff --git a/matrix/pushrules/rule_test.go b/matrix/pushrules/rule_test.go index e8b56f4..3d3f03c 100644 --- a/matrix/pushrules/rule_test.go +++ b/matrix/pushrules/rule_test.go @@ -15,3 +15,169 @@ // along with this program. If not, see . package pushrules_test + +import ( + "testing" + "github.com/stretchr/testify/assert" + "maunium.net/go/gomuks/matrix/pushrules" +) + +func TestPushRule_Match_Conditions(t *testing.T) { + cond1 := newMatchPushCondition("content.msgtype", "m.emote") + cond2 := newMatchPushCondition("content.body", "*pushrules") + rule := &pushrules.PushRule{ + Type: pushrules.OverrideRule, + Enabled: true, + Conditions: []*pushrules.PushCondition{cond1, cond2}, + } + + event := newFakeEvent("m.room.message", map[string]interface{}{ + "msgtype": "m.emote", + "body": "is testing pushrules", + }) + assert.True(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Conditions_Disabled(t *testing.T) { + cond1 := newMatchPushCondition("content.msgtype", "m.emote") + cond2 := newMatchPushCondition("content.body", "*pushrules") + rule := &pushrules.PushRule{ + Type: pushrules.OverrideRule, + Enabled: false, + Conditions: []*pushrules.PushCondition{cond1, cond2}, + } + + event := newFakeEvent("m.room.message", map[string]interface{}{ + "msgtype": "m.emote", + "body": "is testing pushrules", + }) + assert.False(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Conditions_FailIfOneFails(t *testing.T) { + cond1 := newMatchPushCondition("content.msgtype", "m.emote") + cond2 := newMatchPushCondition("content.body", "*pushrules") + rule := &pushrules.PushRule{ + Type: pushrules.OverrideRule, + Enabled: true, + Conditions: []*pushrules.PushCondition{cond1, cond2}, + } + + event := newFakeEvent("m.room.message", map[string]interface{}{ + "msgtype": "m.text", + "body": "I'm testing pushrules", + }) + assert.False(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Content(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.ContentRule, + Enabled: true, + Pattern: "is testing*", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{ + "msgtype": "m.emote", + "body": "is testing pushrules", + }) + assert.True(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Content_Fail(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.ContentRule, + Enabled: true, + Pattern: "is testing*", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{ + "msgtype": "m.emote", + "body": "is not testing pushrules", + }) + assert.False(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Content_ImplicitGlob(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.ContentRule, + Enabled: true, + Pattern: "testing", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{ + "msgtype": "m.emote", + "body": "is not testing pushrules", + }) + assert.True(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Content_IllegalGlob(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.ContentRule, + Enabled: true, + Pattern: "this is not a valid glo[b", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{ + "msgtype": "m.emote", + "body": "this is not a valid glob", + }) + assert.False(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Room(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.RoomRule, + Enabled: true, + RuleID: "!fakeroom:maunium.net", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{}) + assert.True(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Room_Fail(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.RoomRule, + Enabled: true, + RuleID: "!otherroom:maunium.net", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{}) + assert.False(t, rule.Match(blankTestRoom, event)) +} + + +func TestPushRule_Match_Sender(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.SenderRule, + Enabled: true, + RuleID: "@tulir:maunium.net", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{}) + assert.True(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_Sender_Fail(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.RoomRule, + Enabled: true, + RuleID: "@someone:matrix.org", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{}) + assert.False(t, rule.Match(blankTestRoom, event)) +} + +func TestPushRule_Match_UnknownTypeAlwaysFail(t *testing.T) { + rule := &pushrules.PushRule{ + Type: pushrules.PushRuleType("foobar"), + Enabled: true, + RuleID: "@someone:matrix.org", + } + + event := newFakeEvent("m.room.message", map[string]interface{}{}) + assert.False(t, rule.Match(blankTestRoom, event)) +}