chore: pre-existing uncommitted platform/event changes
This commit is contained in:
1 parent
b155077d9b
commit
a53aba8b43
2 files changed
+121
No files matched your search
@@ -76,7 +76,38 @@ const (
|
|||||||
TrackPageEngaged Type = "track.page_engaged"
|
TrackPageEngaged Type = "track.page_engaged"
|
||||||
TrackPageAction Type = "track.page_action"
|
TrackPageAction Type = "track.page_action"
|
||||||
TrackExperiment Type = "track.experiment"
|
TrackExperiment Type = "track.experiment"
|
||||||
|
// TrackPurchase — cut 23. Post-checkout funnel closure; emitted by
|
||||||
|
// event_handlers.go::TrackPurchase on a purchase request. Replaces
|
||||||
|
// 5 hand-written `pevent.Type("track.purchase")` literals with this
|
||||||
|
// typed constant.
|
||||||
|
TrackPurchase Type = "track.purchase"
|
||||||
)
|
)
|
||||||
|
// KnownTypes lists every event that has a declared Track* constant above.
|
||||||
|
// New pevent constants MUST also be added here so IsKnownType stays in
|
||||||
|
// sync. Used by HTTP handlers' forward-validation (e.g. SessionsPanel
|
||||||
|
// ?event_types= param, cut 25) so caller's typo's surface as a 400
|
||||||
|
// rather than silently dropping unknown tokens.
|
||||||
|
var KnownTypes = []Type{
|
||||||
|
TrackSession, TrackSearch, TrackClick, TrackCart, TrackPurchase,
|
||||||
|
TrackImpression, TrackAction, TrackPageView, TrackPageEngaged,
|
||||||
|
TrackPageAction, TrackExperiment,
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsKnownType reports whether s matches one of the declared Track*
|
||||||
|
// constants. Case-sensitive + exact-match. Callers MUST pass the canonical
|
||||||
|
// lowercase form (e.g. "track.search", NOT "Track.Search" or
|
||||||
|
// "TRACK.SEARCH"). Track* constants are declared lowercase in this file,
|
||||||
|
// and this function matches the literal string value of each constant.
|
||||||
|
// Callers should validate with this BEFORE casting untrusted input to Type.
|
||||||
|
func IsKnownType(s string) bool {
|
||||||
|
for _, t := range KnownTypes {
|
||||||
|
if string(t) == s {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Event is the one envelope. Payload is per-Type, agreed between producer and
|
// Event is the one envelope. Payload is per-Type, agreed between producer and
|
||||||
// consumer (json.RawMessage, not a god-struct). A nil Payload means "the subject
|
// consumer (json.RawMessage, not a god-struct). A nil Payload means "the subject
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package event
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/ast"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestKnownTypes_ContainsAllTrackConstants is a build-time drift guard.
|
||||||
|
// It walks event.go's Analytics const block via go/parser + go/ast and
|
||||||
|
// asserts every `Track*` constant declared there appears in
|
||||||
|
// event.KnownTypes. Self-deriving means: adding TrackNew requires
|
||||||
|
// updating ONLY KnownTypes, not also the test. So the test cannot
|
||||||
|
// itself drift.
|
||||||
|
//
|
||||||
|
// If you add a new Track* constant and accidentally forget
|
||||||
|
// KnownTypes, this test fails. Update KnownTypes and re-run.
|
||||||
|
func TestKnownTypes_ContainsAllTrackConstants(t *testing.T) {
|
||||||
|
const srcPath = "event.go"
|
||||||
|
raw, err := os.ReadFile(srcPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Skipf("cannot read %q (running under go test in a different layout) — drift check deferred: %v", srcPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
file, err := parser.ParseFile(fset, srcPath, string(raw), parser.ParseComments)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parser.ParseFile failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var trackConsts []Type
|
||||||
|
ast.Inspect(file, func(n ast.Node) bool {
|
||||||
|
gen, ok := n.(*ast.GenDecl)
|
||||||
|
if !ok || gen.Tok != token.CONST {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, spec := range gen.Specs {
|
||||||
|
vs, ok := spec.(*ast.ValueSpec)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for i, name := range vs.Names {
|
||||||
|
if !strings.HasPrefix(name.Name, "Track") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if vs.Values == nil || i >= len(vs.Values) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bl, ok := vs.Values[i].(*ast.BasicLit)
|
||||||
|
if !ok || bl.Kind != token.STRING {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
trackConsts = append(trackConsts, Type(strings.Trim(bl.Value, `""`)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(trackConsts) == 0 {
|
||||||
|
t.Fatalf("AST scan did not find any Track* constants in event.go — check the AST walker or the file layout")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range KnownTypes {
|
||||||
|
found := false
|
||||||
|
for _, tc := range trackConsts {
|
||||||
|
if tc == c {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Errorf("KnownTypes contains %q but the const block in event.go does NOT declare a Track* with that value", string(c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, tc := range trackConsts {
|
||||||
|
found := false
|
||||||
|
for _, c := range KnownTypes {
|
||||||
|
if c == tc {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Errorf("event.go declares Track* = %q but KnownTypes is missing it — add it to KnownTypes and re-run", string(tc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user