Files
santifer--career-ops/dashboard/internal/data/derive_test.go
T
wehub-resource-sync d083df1fdb
CodeQL Analysis / Analyze (javascript-typescript) (push) Failing after 2s
Web CI / web typecheck + build (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
CodeQL Analysis / Analyze (go) (push) Failing after 16s
chore: import upstream snapshot with attribution
2026-07-13 12:02:43 +08:00

213 lines
5.7 KiB
Go

package data
import (
"testing"
"github.com/santifer/career-ops/dashboard/internal/model"
)
func TestDeriveNoteFields(t *testing.T) {
cases := []struct {
name string
app model.CareerApplication
location string
workMode string
payRange string
paySrc string
last string
}{
{
name: "remote with posted comma range and rejection date",
app: model.CareerApplication{
Date: "2026-06-04",
Notes: "Remote US (EST/CST). Base $174,986-209,983 + RSUs (POSTED). Rejected 2026-06-05 (not moving forward). Via Greenhouse",
},
workMode: "Remote",
payRange: "$174,986-209,983",
paySrc: "POSTED",
last: "2026-06-05",
},
{
name: "hybrid city state with estimate",
app: model.CareerApplication{
Date: "2026-06-03",
Notes: "Charlotte NC (Hybrid), via LinkedIn. Comp ~$130-170K (est). Application VIEWED by recruiter 2026-06-04",
},
location: "Charlotte, NC",
workMode: "Hybrid",
payRange: "~$130-170K",
paySrc: "est",
last: "2026-06-04",
},
{
name: "bare location implies full onsite, decimal K range",
app: model.CareerApplication{
Date: "2026-06-01",
Notes: "Austin TX (location mismatch). Salary $124.2-198.7K (POSTED)",
},
location: "Austin, TX",
workMode: "Full",
payRange: "$124.2-198.7K",
paySrc: "POSTED",
last: "2026-06-01",
},
{
name: "lone amount fallback when no range, date falls back to applied",
app: model.CareerApplication{
Date: "2026-06-02",
Notes: "Via LinkedIn (recruiting agency). Sam stated $170K min floor",
},
workMode: "",
payRange: "$170K",
last: "2026-06-02",
},
{
name: "range preferred over earlier lone amount",
app: model.CareerApplication{
Date: "2026-05-31",
Notes: "Comp $100-175K base + 10% bonus + $300 health credit (recruiter-confirmed). Phone screen DONE 2026-06-03",
},
payRange: "$100-175K",
last: "2026-06-03",
},
{
name: "city falls back to role title, timezone parens are not an estimate",
app: model.CareerApplication{
Date: "2026-05-31",
Role: "Sr Software Engineer, Enterprise Systems — Charlotte, NC",
Notes: "Referral via friend. Remote US (EST/CST). Comp $100-175K base (recruiter-confirmed)",
},
location: "Charlotte, NC",
workMode: "Remote",
payRange: "$100-175K",
paySrc: "",
last: "2026-05-31",
},
{
name: "marketing role and interest prose are not estimate markers",
app: model.CareerApplication{
Date: "2026-06-01",
Role: "Product Marketing Manager",
Notes: "Strong fit (AI-augmented interest). Salary $140-180K. Via Lever",
},
payRange: "$140-180K",
paySrc: "",
last: "2026-06-01",
},
{
name: "no false-positive city from prose",
app: model.CareerApplication{
Date: "2026-06-01",
Notes: "Strong fit for Sams AI-augmented edge. Rejected by recruiter Nadia Kong",
},
location: "",
workMode: "",
last: "2026-06-01",
},
{
name: "remote EU with EUR estimate range",
app: model.CareerApplication{
Date: "2026-06-10",
Notes: "Remote EU (Portugal eligible). Comp ~€130-170K (est). Applied 2026-06-10",
},
location: "",
workMode: "Remote",
payRange: "~€130-170K",
paySrc: "est",
last: "2026-06-10",
},
{
name: "international city hybrid with EUR posted",
app: model.CareerApplication{
Date: "2026-06-09",
Notes: "Berlin (Hybrid). Base €90-110K (POSTED). Via Greenhouse",
},
location: "Berlin",
workMode: "Hybrid",
payRange: "€90-110K",
paySrc: "POSTED",
last: "2026-06-09",
},
{
name: "CHF range, bare intl city implies onsite",
app: model.CareerApplication{
Date: "2026-06-08",
Notes: "Zurich. CHF 165-185K. Check Point-backed",
},
location: "Zurich",
workMode: "Full",
payRange: "CHF 165-185K",
paySrc: "",
last: "2026-06-08",
},
{
name: "GBP posted range, London",
app: model.CareerApplication{
Date: "2026-06-07",
Notes: "London. £175-225K (POSTED). 30+ teams",
},
location: "London",
workMode: "Full",
payRange: "£175-225K",
paySrc: "POSTED",
last: "2026-06-07",
},
{
name: "Portugal home market, city from role title",
app: model.CareerApplication{
Date: "2026-06-06",
Role: "Senior Engineering Manager — Porto",
Notes: "Onsite. Comp €60-90K (est, below floor)",
},
location: "Porto",
workMode: "Full",
payRange: "€60-90K",
paySrc: "est",
last: "2026-06-06",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
deriveNoteFields(&tc.app)
if want := payCeiling(tc.payRange); tc.app.PayMax != want {
t.Errorf("PayMax = %v, want %v", tc.app.PayMax, want)
}
if tc.app.Location != tc.location {
t.Errorf("Location = %q, want %q", tc.app.Location, tc.location)
}
if tc.app.WorkMode != tc.workMode {
t.Errorf("WorkMode = %q, want %q", tc.app.WorkMode, tc.workMode)
}
if tc.app.PayRange != tc.payRange {
t.Errorf("PayRange = %q, want %q", tc.app.PayRange, tc.payRange)
}
if tc.app.PaySource != tc.paySrc {
t.Errorf("PaySource = %q, want %q", tc.app.PaySource, tc.paySrc)
}
if tc.app.LastContact != tc.last {
t.Errorf("LastContact = %q, want %q", tc.app.LastContact, tc.last)
}
})
}
}
func TestPayCeiling(t *testing.T) {
cases := map[string]float64{
"$140-210K": 210_000,
"$174,986-209,983": 209_983,
"~$124.2-198.7K": 198_700,
"$170K": 170_000,
"$95-159K": 159_000,
"€130-170K": 170_000,
"£175-225K": 225_000,
"CHF 165-185K": 185_000,
"": 0,
}
for span, want := range cases {
if got := payCeiling(span); got != want {
t.Errorf("payCeiling(%q) = %v, want %v", span, got, want)
}
}
}