mirror of
https://github.com/warmbly/warmbly.git
synced 2026-10-28 16:02:33 +00:00
113 lines
4.0 KiB
Go
113 lines
4.0 KiB
Go
package models
|
|
|
|
import "testing"
|
|
|
|
// Acquisition values come off a query string a stranger controls, so the
|
|
// normalizer is the boundary: anything that reaches the database has been
|
|
// reduced to a path, a bare host, or a clamped scalar.
|
|
func TestOrgAcquisitionNormalize(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
in OrgAcquisition
|
|
want OrgAcquisition
|
|
}{
|
|
{
|
|
name: "a full landing URL is reduced to its path",
|
|
in: OrgAcquisition{LandingPath: "https://warmbly.com/pricing?utm_source=x&secret=y"},
|
|
want: OrgAcquisition{LandingPath: "/pricing"},
|
|
},
|
|
{
|
|
name: "a referrer URL is reduced to a bare lowercase host",
|
|
in: OrgAcquisition{ReferrerHost: "HTTPS://News.YCombinator.com/item?id=1"},
|
|
want: OrgAcquisition{ReferrerHost: "news.ycombinator.com"},
|
|
},
|
|
{
|
|
name: "a bare host with a port keeps only the host",
|
|
in: OrgAcquisition{ReferrerHost: "example.com:8443/path"},
|
|
want: OrgAcquisition{ReferrerHost: "example.com"},
|
|
},
|
|
{
|
|
name: "a relative landing path is kept as-is",
|
|
in: OrgAcquisition{LandingPath: " /guides/warmup "},
|
|
want: OrgAcquisition{LandingPath: "/guides/warmup"},
|
|
},
|
|
{
|
|
name: "a landing value that is neither a URL nor a path is dropped",
|
|
in: OrgAcquisition{LandingPath: "pricing"},
|
|
want: OrgAcquisition{},
|
|
},
|
|
{
|
|
name: "control characters are stripped from UTM values",
|
|
in: OrgAcquisition{UTMSource: "news\nletter\t"},
|
|
want: OrgAcquisition{UTMSource: "newsletter"},
|
|
},
|
|
{
|
|
// url.Parse reads this as a relative path with an empty Hostname,
|
|
// so the reduction runs on the raw string and the result has to be
|
|
// checked rather than trusted.
|
|
name: "a query string on a bare referrer host is not stored",
|
|
in: OrgAcquisition{ReferrerHost: "example.com?email=alice@example.com"},
|
|
want: OrgAcquisition{ReferrerHost: "example.com"},
|
|
},
|
|
{
|
|
name: "a fragment on a bare referrer host is not stored",
|
|
in: OrgAcquisition{ReferrerHost: "example.com#alice@example.com"},
|
|
want: OrgAcquisition{ReferrerHost: "example.com"},
|
|
},
|
|
{
|
|
name: "userinfo in a bare referrer host is not stored",
|
|
in: OrgAcquisition{ReferrerHost: "alice@example.com"},
|
|
want: OrgAcquisition{ReferrerHost: ""},
|
|
},
|
|
{
|
|
name: "a referrer that is not a hostname is dropped",
|
|
in: OrgAcquisition{ReferrerHost: "not a host"},
|
|
want: OrgAcquisition{},
|
|
},
|
|
{
|
|
// These arrive on a query string anybody can write, and an address
|
|
// here would be stored on the org and sent as an analytics property.
|
|
name: "an email address in a UTM value is redacted",
|
|
in: OrgAcquisition{UTMSource: "alice@example.com", UTMCampaign: "launch alice@example.com now"},
|
|
want: OrgAcquisition{UTMSource: "[redacted]", UTMCampaign: "launch [redacted] now"},
|
|
},
|
|
{
|
|
name: "an email in a landing path is redacted too",
|
|
in: OrgAcquisition{LandingPath: "/invite/bob@example.com"},
|
|
want: OrgAcquisition{LandingPath: "/invite/[redacted]"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := tt.in.Normalize(); got != tt.want {
|
|
t.Fatalf("Normalize() = %+v, want %+v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// An oversized value must be clamped rather than rejected: a truncated campaign
|
|
// name is still useful, and a failed signup over a long link is not acceptable.
|
|
func TestOrgAcquisitionClampsLongValues(t *testing.T) {
|
|
long := make([]byte, acquisitionFieldMax*3)
|
|
for i := range long {
|
|
long[i] = 'a'
|
|
}
|
|
got := OrgAcquisition{UTMCampaign: string(long)}.Normalize()
|
|
if len(got.UTMCampaign) != acquisitionFieldMax {
|
|
t.Fatalf("clamped length = %d, want %d", len(got.UTMCampaign), acquisitionFieldMax)
|
|
}
|
|
}
|
|
|
|
// Empty is what decides whether a row is written at all, so a direct signup
|
|
// must report empty and any single field must not.
|
|
func TestOrgAcquisitionEmpty(t *testing.T) {
|
|
if !(OrgAcquisition{}).Empty() {
|
|
t.Fatal("a signup that carried nothing should be Empty")
|
|
}
|
|
if (OrgAcquisition{UTMSource: "newsletter"}).Empty() {
|
|
t.Fatal("a signup with a utm_source should not be Empty")
|
|
}
|
|
}
|