Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/integration/recruitmatch_integration_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/integration/recruitmatch_integration_test.go |
| Original SHA-256 | 1f0627c9d88d1e392604ee14d8a636ba8d245364c4acc0fbcd27fc10a7a7f6c9 |
| Git blob SHA | 19420af780495be570b8e2e458133cc610486822 |
| Reading-copy SHA-256 | 1f0627c9d88d1e392604ee14d8a636ba8d245364c4acc0fbcd27fc10a7a7f6c9 |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/integration/recruitmatch_integration_test.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/integration/recruitmatch_integration_test.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓190 lines · 6.8 KB
//go:build integration
package integration
import (
"context"
"testing"
"time"
"github.com/shopspring/decimal"
"github.com/missionworkforce/missionmatch/internal/modules/recruitmatch"
"github.com/missionworkforce/missionmatch/internal/platform/tenant"
)
var recruitAsOf = time.Date(2026, 7, 20, 0, 0, 0, 0, time.UTC)
// TestRecruitDashboardEmptyOrgRendersCompleteView is the day one state of every client the platform
// onboards. An organization with no candidates, no requirements and no slates must still receive a
// complete view: zeros, a full funnel, one row per reference clearance level, and the named untracked
// panels. A crash or a missing panel here is what a new customer would see on their first login.
func TestRecruitDashboardEmptyOrgRendersCompleteView(t *testing.T) {
org := seedOrg(t)
ctx := tenant.WithOrg(context.Background(), org.String())
v, err := recruitmatch.NewService(appDB).RecruiterDashboard(ctx, recruitAsOf)
if err != nil {
t.Fatalf("RecruiterDashboard on an empty org: %v", err)
}
if v.OrganizationID != org.String() {
t.Errorf("OrganizationID = %q, want %q", v.OrganizationID, org)
}
if v.AsOf != "2026-07-20" {
t.Errorf("AsOf = %q, want 2026-07-20", v.AsOf)
}
if v.Headline != (recruitmatch.Headline{}) {
t.Errorf("empty org headline is nonzero: %+v", v.Headline)
}
if len(v.Funnel) != 4 {
t.Fatalf("funnel has %d stages, want 4 even when empty", len(v.Funnel))
}
for _, s := range v.Funnel {
if s.Count != 0 || s.Pct != "0.00" {
t.Errorf("stage %q = %d (%s), want 0 (0.00)", s.Key, s.Count, s.Pct)
}
}
if v.Decisions.ApproveRate != "0.00" {
t.Errorf("approve rate = %q, want 0.00 with no decisions", v.Decisions.ApproveRate)
}
if len(v.Clearance) == 0 {
t.Error("clearance is empty, want one row per reference clearance level so the chart shape is stable")
}
for _, c := range v.Clearance {
if c.Count != 0 || c.Pct != "0.00" {
t.Errorf("clearance %q = %d (%s), want 0 (0.00)", c.Code, c.Count, c.Pct)
}
}
if v.TopJobs == nil || v.Recruiters == nil {
t.Error("TopJobs and Recruiters must be empty slices, never nil, so the JSON is [] and not null")
}
if len(v.EmptyPanels) == 0 {
t.Error("EmptyPanels is empty, the untracked panels must always be named")
}
}
// TestRecruitDashboardFailsClosedWithoutTenantContext proves the aggregate refuses to run rather than
// aggregating across the whole database.
func TestRecruitDashboardFailsClosedWithoutTenantContext(t *testing.T) {
if _, err := recruitmatch.NewService(appDB).RecruiterDashboard(context.Background(), recruitAsOf); err == nil {
t.Fatal("want an error with no tenant in context, got nil")
}
}
// TestRecruitDashboardIsolatesTenants is the multi client guarantee. missionMATCH is sold to more than
// one client, so one organization must never observe another's bench through this endpoint.
func TestRecruitDashboardIsolatesTenants(t *testing.T) {
orgA, orgB := seedOrg(t), seedOrg(t)
for i := 0; i < 3; i++ {
seedCandidate(t, orgA, "secret", "active", true)
}
for i := 0; i < 7; i++ {
seedCandidate(t, orgB, "top_secret", "active", true)
}
svc := recruitmatch.NewService(appDB)
va, err := svc.RecruiterDashboard(tenant.WithOrg(context.Background(), orgA.String()), recruitAsOf)
if err != nil {
t.Fatalf("org A: %v", err)
}
vb, err := svc.RecruiterDashboard(tenant.WithOrg(context.Background(), orgB.String()), recruitAsOf)
if err != nil {
t.Fatalf("org B: %v", err)
}
if va.Headline.Identified != 3 {
t.Errorf("org A identified = %d, want exactly 3", va.Headline.Identified)
}
if vb.Headline.Identified != 7 {
t.Errorf("org B identified = %d, want exactly 7", vb.Headline.Identified)
}
if va.OrganizationID == vb.OrganizationID {
t.Fatal("both views report the same organization id")
}
// Clearance is the sharpest cross tenant probe: A holds only secret, B only top_secret. If either
// view shows the other's level, isolation has failed in a way a total count could mask.
for _, c := range va.Clearance {
if c.Code == "top_secret" && c.Count != 0 {
t.Errorf("org A sees %d top_secret candidates, which belong to org B", c.Count)
}
}
for _, c := range vb.Clearance {
if c.Code == "secret" && c.Count != 0 {
t.Errorf("org B sees %d secret candidates, which belong to org A", c.Count)
}
}
}
// TestRecruitDashboardFunnelIsMonotonicAgainstRealData proves the invariant end to end rather than only
// in the pure unit tests. The unit tests prove buildFunnel preserves monotonic input; this proves the
// SQL actually produces monotonic input.
func TestRecruitDashboardFunnelIsMonotonicAgainstRealData(t *testing.T) {
org := seedOrg(t)
for i := 0; i < 5; i++ {
seedCandidate(t, org, "secret", "active", true)
}
ctx := tenant.WithOrg(context.Background(), org.String())
v, err := recruitmatch.NewService(appDB).RecruiterDashboard(ctx, recruitAsOf)
if err != nil {
t.Fatalf("RecruiterDashboard: %v", err)
}
h := v.Headline
if !(h.Identified >= h.Screened && h.Screened >= h.Submitted && h.Submitted >= h.Approved) {
t.Fatalf("funnel counts are not monotonic: identified=%d screened=%d submitted=%d approved=%d",
h.Identified, h.Screened, h.Submitted, h.Approved)
}
prev := decimal.NewFromInt(101)
for _, s := range v.Funnel {
cur, err := decimal.NewFromString(s.Pct)
if err != nil {
t.Fatalf("stage %q pct %q does not parse: %v", s.Key, s.Pct, err)
}
if cur.GreaterThan(prev) {
t.Fatalf("funnel rose at %q: %s after %s", s.Key, cur, prev)
}
if cur.GreaterThan(decimal.NewFromInt(100)) {
t.Fatalf("stage %q = %s exceeds 100", s.Key, cur)
}
prev = cur
}
}
// TestRecruitDashboardIsDeterministicForAFixedAsOf proves the view carries no wall clock dependence, so
// the same asOf over unchanged data yields an identical payload. This is what makes the numbers
// defensible when someone reruns a report.
func TestRecruitDashboardIsDeterministicForAFixedAsOf(t *testing.T) {
org := seedOrg(t)
seedCandidate(t, org, "ts_sci", "active", true)
ctx := tenant.WithOrg(context.Background(), org.String())
svc := recruitmatch.NewService(appDB)
first, err := svc.RecruiterDashboard(ctx, recruitAsOf)
if err != nil {
t.Fatalf("first call: %v", err)
}
second, err := svc.RecruiterDashboard(ctx, recruitAsOf)
if err != nil {
t.Fatalf("second call: %v", err)
}
if first.GeneratedAt != second.GeneratedAt {
t.Errorf("GeneratedAt drifted between calls: %q then %q", first.GeneratedAt, second.GeneratedAt)
}
if first.Headline != second.Headline {
t.Errorf("headline drifted: %+v then %+v", first.Headline, second.Headline)
}
if len(first.Clearance) != len(second.Clearance) {
t.Fatalf("clearance length drifted: %d then %d", len(first.Clearance), len(second.Clearance))
}
for i := range first.Clearance {
if first.Clearance[i] != second.Clearance[i] {
t.Errorf("clearance row %d drifted: %+v then %+v", i, first.Clearance[i], second.Clearance[i])
}
}
}