Update tests for GLOB match type

Rewrite worker unit tests: TestTemplateCandidates, TestGlobMatch,
TestSplitTokens, and updated TestFindMergeGroups with sandwich pattern
cases. Update e2e test to use GLOB instead of PREFIX.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-05-06 20:45:47 +04:00
parent 0358aafb62
commit 855de92e1f
2 changed files with 245 additions and 43 deletions

View File

@@ -103,7 +103,7 @@ func TestTrackerPattern_Create(t *testing.T) {
assert.Equal(t, bannerID, result.CreateTrackerPattern.CookieBanner.ID) assert.Equal(t, bannerID, result.CreateTrackerPattern.CookieBanner.ID)
}) })
t.Run("with PREFIX match type", func(t *testing.T) { t.Run("with GLOB match type", func(t *testing.T) {
t.Parallel() t.Parallel()
owner := testutil.NewClient(t, testutil.RoleOwner) owner := testutil.NewClient(t, testutil.RoleOwner)
@@ -143,8 +143,8 @@ func TestTrackerPattern_Create(t *testing.T) {
err := owner.Execute(query, map[string]any{ err := owner.Execute(query, map[string]any{
"input": map[string]any{ "input": map[string]any{
"cookieCategoryId": categoryID, "cookieCategoryId": categoryID,
"pattern": "_gat_", "pattern": "_gat_*",
"matchType": "PREFIX", "matchType": "GLOB",
"displayName": "GA Throttle", "displayName": "GA Throttle",
"description": "Google Analytics rate limiting", "description": "Google Analytics rate limiting",
}, },
@@ -152,8 +152,8 @@ func TestTrackerPattern_Create(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
node := result.CreateTrackerPattern.TrackerPatternEdge.Node node := result.CreateTrackerPattern.TrackerPatternEdge.Node
assert.Equal(t, "_gat_", node.Pattern) assert.Equal(t, "_gat_*", node.Pattern)
assert.Equal(t, "PREFIX", node.MatchType) assert.Equal(t, "GLOB", node.MatchType)
assert.Nil(t, node.MaxAgeSeconds) assert.Nil(t, node.MaxAgeSeconds)
}) })

View File

@@ -23,7 +23,7 @@ import (
"go.probo.inc/probo/pkg/gid" "go.probo.inc/probo/pkg/gid"
) )
func TestSeparatorPrefixes(t *testing.T) { func TestTemplateCandidates(t *testing.T) {
t.Parallel() t.Parallel()
tests := []struct { tests := []struct {
@@ -32,29 +32,49 @@ func TestSeparatorPrefixes(t *testing.T) {
expected []string expected []string
}{ }{
{ {
name: "single underscore", name: "single underscore produces prefix candidate",
input: "ph_abc123", input: "ph_abc123",
expected: []string{"ph_"}, expected: []string{
"ph_*",
},
}, },
{ {
name: "multiple underscores", name: "multiple underscores produces prefix and sandwich candidates",
input: "ph_phc_abc123def456", input: "ph_phc_abc123",
expected: []string{"ph_", "ph_phc_"}, expected: []string{
"ph_*",
"ph_phc_*",
"ph_*_abc123",
},
}, },
{ {
name: "leading underscore", name: "four tokens produces multiple sandwich candidates",
input: "_ga_GB2J3DLBHE", input: "ph_phc_abc123_posthog",
expected: []string{"_", "_ga_"}, expected: []string{
"ph_*",
"ph_phc_*",
"ph_phc_abc123_*",
"ph_*_abc123_posthog",
"ph_phc_*_posthog",
},
}, },
{ {
name: "dash separator", name: "leading underscore",
input: "c15t-consent-abc123", input: "_ga_GB2J3DLBHE",
expected: []string{"c15t-", "c15t-consent-"}, expected: []string{
"_*",
"_ga_*",
"_*_GB2J3DLBHE",
},
}, },
{ {
name: "mixed separators", name: "dash separator",
input: "_gat_UA-12345-1", input: "c15t-consent-abc123",
expected: []string{"_", "_gat_", "_gat_UA-", "_gat_UA-12345-"}, expected: []string{
"c15t-*",
"c15t-consent-*",
"c15t-*-abc123",
},
}, },
{ {
name: "no separators", name: "no separators",
@@ -62,14 +82,13 @@ func TestSeparatorPrefixes(t *testing.T) {
expected: nil, expected: nil,
}, },
{ {
name: "brand with digits", name: "brand with digits",
input: "auth0_session_abc123", input: "auth0_session_abc123",
expected: []string{"auth0_", "auth0_session_"}, expected: []string{
}, "auth0_*",
{ "auth0_session_*",
name: "woocommerce session", "auth0_*_abc123",
input: "wp_woocommerce_session_f919208d949256bc", },
expected: []string{"wp_", "wp_woocommerce_", "wp_woocommerce_session_"},
}, },
} }
@@ -78,13 +97,155 @@ func TestSeparatorPrefixes(t *testing.T) {
tt.name, tt.name,
func(t *testing.T) { func(t *testing.T) {
t.Parallel() t.Parallel()
result := separatorPrefixes(tt.input) result := templateCandidates(tt.input)
assert.Equal(t, tt.expected, result) assert.Equal(t, tt.expected, result)
}, },
) )
} }
} }
func TestGlobMatch(t *testing.T) {
t.Parallel()
tests := []struct {
name string
pattern string
input string
match bool
}{
{
name: "prefix glob matches",
pattern: "ph_phc_*",
input: "ph_phc_abc123",
match: true,
},
{
name: "prefix glob does not match different prefix",
pattern: "ph_phc_*",
input: "ph_session_abc123",
match: false,
},
{
name: "suffix glob matches",
pattern: "*_posthog",
input: "ph_phc_abc123_posthog",
match: true,
},
{
name: "suffix glob does not match different suffix",
pattern: "*_posthog",
input: "ph_phc_abc123_analytics",
match: false,
},
{
name: "sandwich glob matches",
pattern: "ph_phc_*_posthog",
input: "ph_phc_abc123_posthog",
match: true,
},
{
name: "sandwich glob does not match wrong prefix",
pattern: "ph_phc_*_posthog",
input: "xx_phc_abc123_posthog",
match: false,
},
{
name: "sandwich glob does not match wrong suffix",
pattern: "ph_phc_*_posthog",
input: "ph_phc_abc123_other",
match: false,
},
{
name: "sandwich glob matches minimal middle",
pattern: "ph_phc_*_posthog",
input: "ph_phc_x_posthog",
match: true,
},
{
name: "sandwich glob matches empty middle",
pattern: "ph_*_posthog",
input: "ph__posthog",
match: true,
},
{
name: "exact match without wildcard",
pattern: "probo_consent",
input: "probo_consent",
match: true,
},
{
name: "no match without wildcard",
pattern: "probo_consent",
input: "probo_consent2",
match: false,
},
{
name: "input shorter than pattern fixed chars does not match",
pattern: "ph_phc_*_posthog",
input: "ph_phc_posthog",
match: false,
},
}
for _, tt := range tests {
t.Run(
tt.name,
func(t *testing.T) {
t.Parallel()
assert.Equal(t, tt.match, globMatch(tt.pattern, tt.input))
},
)
}
}
func TestSplitTokens(t *testing.T) {
t.Parallel()
tests := []struct {
name string
input string
tokens []string
sep byte
}{
{
name: "underscore separator",
input: "ph_phc_abc",
tokens: []string{"ph", "phc", "abc"},
sep: '_',
},
{
name: "dash separator",
input: "c15t-consent-abc",
tokens: []string{"c15t", "consent", "abc"},
sep: '-',
},
{
name: "no separator",
input: "PHPSESSID",
tokens: []string{"PHPSESSID"},
sep: 0,
},
{
name: "underscore takes priority over dash",
input: "foo_bar-baz",
tokens: []string{"foo", "bar-baz"},
sep: '_',
},
}
for _, tt := range tests {
t.Run(
tt.name,
func(t *testing.T) {
t.Parallel()
tokens, sep := splitTokens(tt.input)
assert.Equal(t, tt.tokens, tokens)
assert.Equal(t, tt.sep, sep)
},
)
}
}
func TestFindMergeGroups(t *testing.T) { func TestFindMergeGroups(t *testing.T) {
t.Parallel() t.Parallel()
@@ -100,7 +261,7 @@ func TestFindMergeGroups(t *testing.T) {
} }
t.Run( t.Run(
"multi-separator names pick longest prefix", "multi-separator names pick longest prefix template",
func(t *testing.T) { func(t *testing.T) {
t.Parallel() t.Parallel()
@@ -113,7 +274,7 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 1) require.Len(t, groups, 1)
group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "ph_phc_", durationBucket: durationBucket(&oneYear)}] group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "ph_phc_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, group, 3) assert.Len(t, group, 3)
}, },
@@ -133,7 +294,7 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 1) require.Len(t, groups, 1)
group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "_ga_", durationBucket: durationBucket(&oneYear)}] group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "_ga_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, group, 3) assert.Len(t, group, 3)
}, },
@@ -153,7 +314,7 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 1) require.Len(t, groups, 1)
group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "auth0_session_", durationBucket: durationBucket(&oneYear)}] group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "auth0_session_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, group, 3) assert.Len(t, group, 3)
}, },
@@ -191,11 +352,11 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 2) require.Len(t, groups, 2)
barGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "foo_bar_", durationBucket: durationBucket(&oneYear)}] barGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "foo_bar_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, barGroup, 3) assert.Len(t, barGroup, 3)
bazGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "foo_baz_", durationBucket: durationBucket(&oneYear)}] bazGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "foo_baz_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, bazGroup, 3) assert.Len(t, bazGroup, 3)
}, },
@@ -216,7 +377,7 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 1) require.Len(t, groups, 1)
group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "ph_phc_", durationBucket: durationBucket(&oneYear)}] group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "ph_phc_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, group, 3) assert.Len(t, group, 3)
}, },
@@ -239,11 +400,11 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 2) require.Len(t, groups, 2)
phcGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "ph_phc_", durationBucket: durationBucket(&oneYear)}] phcGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "ph_phc_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, phcGroup, 3) assert.Len(t, phcGroup, 3)
sessionGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "ph_session_", durationBucket: durationBucket(&oneYear)}] sessionGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "ph_session_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, sessionGroup, 3) assert.Len(t, sessionGroup, 3)
}, },
@@ -282,11 +443,11 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 2) require.Len(t, groups, 2)
sessionGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "_ga_", durationBucket: -1}] sessionGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "_ga_*", durationBucket: -1}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, sessionGroup, 3) assert.Len(t, sessionGroup, 3)
persistentGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "_ga_", durationBucket: durationBucket(&oneYear)}] persistentGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "_ga_*", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, persistentGroup, 3) assert.Len(t, persistentGroup, 3)
}, },
@@ -331,15 +492,56 @@ func TestFindMergeGroups(t *testing.T) {
groups := findMergeGroups(patterns, 3) groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 2) require.Len(t, groups, 2)
dayGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "_ga_", durationBucket: durationBucket(&oneDay)}] dayGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "_ga_*", durationBucket: durationBucket(&oneDay)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, dayGroup, 3) assert.Len(t, dayGroup, 3)
monthGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, prefix: "_ga_", durationBucket: durationBucket(&thirtyDays)}] monthGroup, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "_ga_*", durationBucket: durationBucket(&thirtyDays)}]
require.True(t, ok) require.True(t, ok)
assert.Len(t, monthGroup, 3) assert.Len(t, monthGroup, 3)
}, },
) )
t.Run(
"sandwich pattern discovered from shared prefix and suffix",
func(t *testing.T) {
t.Parallel()
patterns := coredata.TrackerPatterns{
makePattern("ph_phc_abc123_posthog", &oneYear),
makePattern("ph_phc_def456_posthog", &oneYear),
makePattern("ph_phc_ghi789_posthog", &oneYear),
}
groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 1)
group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "ph_phc_*_posthog", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok)
assert.Len(t, group, 3)
},
)
t.Run(
"sandwich pattern wins over shorter prefix",
func(t *testing.T) {
t.Parallel()
patterns := coredata.TrackerPatterns{
makePattern("ph_phc_abc123_posthog", &oneYear),
makePattern("ph_phc_def456_posthog", &oneYear),
makePattern("ph_phc_ghi789_posthog", &oneYear),
makePattern("ph_phc_other", &oneYear),
}
groups := findMergeGroups(patterns, 3)
require.Len(t, groups, 1)
group, ok := groups[mergeGroupKey{categoryID: gid.Nil, trackerType: coredata.TrackerTypeCookie, template: "ph_phc_*_posthog", durationBucket: durationBucket(&oneYear)}]
require.True(t, ok)
assert.Len(t, group, 3)
},
)
} }
func TestDurationBucket(t *testing.T) { func TestDurationBucket(t *testing.T) {