76309b51cb
message: |- Refactor access controls to support multiple branches This was a big lift. It implements a backwards incompatible change to overhaul access control patterns to also encompass which branch is being interacted with, not only which files. The `accessctl` package was significantly rewritten to support this, as well as some of the code modifying it. The INTRODUCTION and SPEC were also appropriately updated. The change to the SPEC is _technically_ backwards incompatible, but it won't effect anything. The `access_control` previously being used will just be ignored, and the changes to `accessctl` include the definition of fallback access controls which will automatically be applied if nothing else matches, so when verifying the older history of this repo those will be used. change_hash: AIfNYLmOLGpuyTiVodT3hDe9lF4E+5DbOTgSdkbjJONb credentials: - type: pgp_signature pub_key_id: 95C46FA6A41148AC body: iQIzBAABAgAdFiEEJ6tQKp6olvZKJ0lwlcRvpqQRSKwFAl5aw0sACgkQlcRvpqQRSKy7kw//UMyS/waV/tE1vntZrMbmEtFmiXPcMVNal76cjhdiF3He50qXoWG6m0qWz+arD1tbjoZml6pvU+Xt45y/Uc54DZizzz0E9azoFW0/uvZiLApftFRArZbT9GhbDs2afalyoTJx/xvQu+a2FD/zfljEWE8Zix+bwHCLojiYHHVA65HFLEt8RsH33jFyzWvS9a2yYqZXL0qrU9tdV68hazdIm1LCp+lyVV74TjwxPAZDOmNAE9l4EjIk1pgr2Qo4u2KwJqCGdVCvka8TiFFYiP7C6319ZhDMyj4m9yZsd1xGtBd9zABVBDgmzCEjt0LI3Tv35lPd2tpFBkjQy0WGcMAhwSHWSP7lxukQMCEB7og/SwtKaExiBJhf1HRO6H9MlhNSW4X1xwUgP+739ixKKUY/RcyXgZ4pkzt6sewAMVbUOcmzXdUvuyDJQ0nhDFowgicpSh1m8tTkN1aLUx18NfnGZRgkgBeE6EpT5/+NBfFwvpiQkXZ3bcMiNhNTU/UnWMyqjKlog+8Ca/7CqgswYppMaw4iPaC54H8P6JTH+XnqDlLKSkvh7PiJJa5nFDG07fqc8lYKm1KGv6virAhEsz/AYKLoNGIsqXt+mYUDLvQpjlRsiN52euxyn5e41LcrH0RidIGMVeaS+7re1pWbkCkMMMtYlnCbC5L6mfrBu6doN8o= account: mediocregopher
179 lines
4.2 KiB
Go
179 lines
4.2 KiB
Go
package accessctl
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
)
|
|
|
|
func normalizeResult(res MatchResult) MatchResult {
|
|
if len(res.ChangeAccessControls) == 0 {
|
|
res.ChangeAccessControls = nil
|
|
}
|
|
return res
|
|
}
|
|
|
|
func TestMatch(t *testing.T) {
|
|
secondCond := Condition{
|
|
Signature: &ConditionSignature{
|
|
AnyAccount: true,
|
|
Count: "2",
|
|
},
|
|
}
|
|
|
|
tests := []struct {
|
|
descr string
|
|
|
|
branchACs []BranchAccessControl
|
|
interactions MatchInteractions
|
|
result MatchResult
|
|
}{
|
|
{
|
|
descr: "empty input empty result",
|
|
result: MatchResult{
|
|
BranchPattern: "**",
|
|
},
|
|
},
|
|
{
|
|
descr: "empty access controls",
|
|
interactions: MatchInteractions{
|
|
Branch: "trunk",
|
|
FilePathsChanged: []string{"foo", "bar"},
|
|
},
|
|
result: MatchResult{
|
|
BranchPattern: "trunk",
|
|
ChangeAccessControls: []MatchedChangeAccessControl{
|
|
{
|
|
ChangeAccessControl: DefaultChangeAccessControl,
|
|
FilePaths: []string{"foo", "bar"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
descr: "empty filesPathsChanged",
|
|
branchACs: DefaultBranchAccessControls,
|
|
interactions: MatchInteractions{Branch: "trunk"},
|
|
result: MatchResult{BranchPattern: "trunk"},
|
|
},
|
|
{
|
|
descr: "no matching branch patterns",
|
|
branchACs: []BranchAccessControl{{
|
|
BranchPattern: "dunk",
|
|
ChangeAccessControls: []ChangeAccessControl{{
|
|
FilePathPattern: "**",
|
|
Condition: secondCond,
|
|
}},
|
|
}},
|
|
interactions: MatchInteractions{
|
|
Branch: "crunk",
|
|
FilePathsChanged: []string{"foo"},
|
|
},
|
|
result: MatchResult{
|
|
BranchPattern: "**",
|
|
ChangeAccessControls: []MatchedChangeAccessControl{{
|
|
ChangeAccessControl: DefaultChangeAccessControl,
|
|
FilePaths: []string{"foo"},
|
|
}},
|
|
},
|
|
},
|
|
{
|
|
descr: "no matching files",
|
|
branchACs: []BranchAccessControl{{
|
|
BranchPattern: "trunk",
|
|
ChangeAccessControls: []ChangeAccessControl{{
|
|
FilePathPattern: "boo",
|
|
Condition: secondCond,
|
|
}},
|
|
}},
|
|
interactions: MatchInteractions{
|
|
Branch: "trunk",
|
|
FilePathsChanged: []string{"foo"},
|
|
},
|
|
result: MatchResult{
|
|
BranchPattern: "trunk",
|
|
ChangeAccessControls: []MatchedChangeAccessControl{{
|
|
ChangeAccessControl: DefaultChangeAccessControl,
|
|
FilePaths: []string{"foo"},
|
|
}},
|
|
},
|
|
},
|
|
{
|
|
descr: "branch pattern precedent",
|
|
branchACs: []BranchAccessControl{
|
|
{
|
|
BranchPattern: "trunk",
|
|
ChangeAccessControls: []ChangeAccessControl{{
|
|
FilePathPattern: "foo",
|
|
Condition: secondCond,
|
|
}},
|
|
},
|
|
{
|
|
BranchPattern: "**",
|
|
ChangeAccessControls: []ChangeAccessControl{
|
|
DefaultChangeAccessControl,
|
|
},
|
|
},
|
|
},
|
|
interactions: MatchInteractions{
|
|
Branch: "trunk",
|
|
FilePathsChanged: []string{"foo"},
|
|
},
|
|
result: MatchResult{
|
|
BranchPattern: "trunk",
|
|
ChangeAccessControls: []MatchedChangeAccessControl{{
|
|
ChangeAccessControl: ChangeAccessControl{
|
|
FilePathPattern: "foo",
|
|
Condition: secondCond,
|
|
},
|
|
FilePaths: []string{"foo"},
|
|
}},
|
|
},
|
|
},
|
|
{
|
|
descr: "multiple files matching FilePathPatterns",
|
|
branchACs: []BranchAccessControl{{
|
|
BranchPattern: "trunk",
|
|
ChangeAccessControls: []ChangeAccessControl{{
|
|
FilePathPattern: "foo*",
|
|
Condition: secondCond,
|
|
}},
|
|
}},
|
|
interactions: MatchInteractions{
|
|
Branch: "trunk",
|
|
FilePathsChanged: []string{"foo_a", "bar", "foo_b"},
|
|
},
|
|
result: MatchResult{
|
|
BranchPattern: "trunk",
|
|
ChangeAccessControls: []MatchedChangeAccessControl{
|
|
{
|
|
ChangeAccessControl: DefaultChangeAccessControl,
|
|
FilePaths: []string{"bar"},
|
|
},
|
|
{
|
|
ChangeAccessControl: ChangeAccessControl{
|
|
FilePathPattern: "foo*",
|
|
Condition: secondCond,
|
|
},
|
|
FilePaths: []string{"foo_a", "foo_b"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.descr, func(t *testing.T) {
|
|
res, err := Match(test.branchACs, test.interactions)
|
|
if err != nil {
|
|
t.Fatalf("error matching: %v", err)
|
|
}
|
|
res, expRes := normalizeResult(res), normalizeResult(test.result)
|
|
if !reflect.DeepEqual(res, expRes) {
|
|
t.Fatalf("expected:%s\ngot: %s", spew.Sdump(expRes), spew.Sdump(res))
|
|
}
|
|
})
|
|
}
|
|
}
|