Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/modules/federalsignal/tenant_tag_test.go |
| Original SHA-256 | 06823fff9a9c555d97e6a115cdb68b6d31a6b7d69b8f86d01b138473d8848c7b |
| Git blob SHA | 8a150ed6e66a37565d6a6c7c853e5aaa1aab0480 |
| Reading-copy SHA-256 | 06823fff9a9c555d97e6a115cdb68b6d31a6b7d69b8f86d01b138473d8848c7b |
Every recorded occurrence
These 15 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/modules/federalsignal/tenant_tag_test.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/tenant_tag_test.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓229 lines · 9.1 KB
package federalsignal
// Offline unit test for the Phase 5a tenant mission tagging service. It injects an in memory fake repo
// with fixture candidates and requirements and a fixed AliasIndex, runs the service with NO database, and
// asserts the exact candidate_mission_tags and requirement_mission_tags produced (codes, mechanisms, and
// evidence), plus idempotency: a second run never grows the tag set. The classifier is the same pure
// deterministic missionclass the global pass uses, so the SIGINT analyst gets a SIGINT tag and the COMSEC
// skill gets a COMSEC tag.
import (
"context"
"sort"
"testing"
"github.com/google/uuid"
"github.com/missionworkforce/missionmatch/internal/platform/database/dbgen"
"github.com/missionworkforce/missionmatch/internal/platform/missionclass"
"github.com/missionworkforce/missionmatch/internal/platform/tenant"
)
// fakeTenantTagRepo serves fixture rows and records every upserted tag so the test can assert the exact
// output. It honors idempotency the way the real ON CONFLICT DO UPDATE does, keying candidate tags on
// (candidate_id, mission_code) and requirement tags on (requirement_id, mission_code), so a second run
// never grows the row set.
type fakeTenantTagRepo struct {
candidates []dbgen.ListCandidatesForMissionTaggingRow
requirements []dbgen.ListRequirementsForMissionTaggingRow
candTags map[string]dbgen.UpsertCandidateMissionTagParams
reqTags map[string]dbgen.UpsertRequirementMissionTagParams
}
func newFakeTenantTagRepo() *fakeTenantTagRepo {
return &fakeTenantTagRepo{
candTags: map[string]dbgen.UpsertCandidateMissionTagParams{},
reqTags: map[string]dbgen.UpsertRequirementMissionTagParams{},
}
}
func (r *fakeTenantTagRepo) ListCandidatesForTagging(_ context.Context) ([]dbgen.ListCandidatesForMissionTaggingRow, error) {
return r.candidates, nil
}
func (r *fakeTenantTagRepo) ListRequirementsForTagging(_ context.Context) ([]dbgen.ListRequirementsForMissionTaggingRow, error) {
return r.requirements, nil
}
func (r *fakeTenantTagRepo) UpsertCandidateMissionTags(_ context.Context, tags []dbgen.UpsertCandidateMissionTagParams) error {
for _, t := range tags {
r.candTags[t.CandidateID.String()+"|"+t.MissionCode] = t
}
return nil
}
func (r *fakeTenantTagRepo) UpsertRequirementMissionTags(_ context.Context, tags []dbgen.UpsertRequirementMissionTagParams) error {
for _, t := range tags {
r.reqTags[t.RequirementID.String()+"|"+t.MissionCode] = t
}
return nil
}
// missionTag is the comparable shape the assertions use.
type missionTag struct {
code, mechanism, evidence string
}
func TestTenantTagCandidatesAndRequirements(t *testing.T) {
org := uuid.New()
candID := uuid.New()
reqID := uuid.New()
repo := newFakeTenantTagRepo()
// One candidate: headline mentions SIGINT, with a COMSEC skill. The classifier should produce a SIGINT
// tag (keyword in headline) and a COMSEC tag (keyword in the joined skill text).
repo.candidates = []dbgen.ListCandidatesForMissionTaggingRow{
{CandidateID: candID, Headline: "SIGINT analyst", SkillText: "COMSEC"},
}
// One requirement: title and labor category plus a required skill. The title carries Electronic Warfare
// (EW) and the labor category carries GEOINT, proving title and labor category and skill text all feed
// the classifier.
repo.requirements = []dbgen.ListRequirementsForMissionTaggingRow{
{RequirementID: reqID, Title: "Electronic Warfare Engineer", LaborCategory: "GEOINT Analyst", SkillText: "COMSEC"},
}
// A deliberately empty AliasIndex: the fixture relies on the literal keyword gazetteer only, so the
// assertions are about the deterministic keyword mechanism, not a curated alias.
idx := missionclass.NewAliasIndex(map[string]string{})
svc := NewTenantTagService(repo, idx)
ctx := tenant.WithOrg(context.Background(), org.String())
cRes, err := svc.TagCandidatesForOrg(ctx)
if err != nil {
t.Fatalf("TagCandidatesForOrg: %v", err)
}
rRes, err := svc.TagRequirementsForOrg(ctx)
if err != nil {
t.Fatalf("TagRequirementsForOrg: %v", err)
}
// Candidate: exactly SIGINT and COMSEC, both by keyword, with the canonical evidence phrases.
wantCand := []missionTag{
{"SIGINT", missionclass.MechKeyword, "sigint"},
{"COMSEC", missionclass.MechKeyword, "comsec"},
}
gotCand := collectCandTags(repo, candID)
assertTags(t, "candidate", wantCand, gotCand)
if cRes.CandidatesScanned != 1 || cRes.CandidateTags != 2 {
t.Fatalf("candidate result counts = scanned %d tags %d, want scanned 1 tags 2", cRes.CandidatesScanned, cRes.CandidateTags)
}
// Every candidate tag must carry the org from the context, never a blank or foreign org.
for k, v := range repo.candTags {
if v.OrganizationID != org {
t.Fatalf("candidate tag %s has org %s, want %s", k, v.OrganizationID, org)
}
}
// Requirement: EW from the title, GEOINT from the labor category, COMSEC from the required skill text,
// all by keyword. This proves the title, the labor category, AND the required skill names each feed the
// requirement classifier.
wantReq := []missionTag{
{"GEOINT", missionclass.MechKeyword, "geoint"},
{"COMSEC", missionclass.MechKeyword, "comsec"},
{"EW", missionclass.MechKeyword, "electronic warfare"},
}
gotReq := collectReqTags(repo, reqID)
assertTags(t, "requirement", wantReq, gotReq)
if rRes.RequirementsScanned != 1 || rRes.RequirementTags != 3 {
t.Fatalf("requirement result counts = scanned %d tags %d, want scanned 1 tags 3", rRes.RequirementsScanned, rRes.RequirementTags)
}
for k, v := range repo.reqTags {
if v.OrganizationID != org {
t.Fatalf("requirement tag %s has org %s, want %s", k, v.OrganizationID, org)
}
}
// Idempotency: a second identical run must not grow either tag set (ON CONFLICT refreshes in place).
if _, err := svc.TagCandidatesForOrg(ctx); err != nil {
t.Fatalf("second TagCandidatesForOrg: %v", err)
}
if _, err := svc.TagRequirementsForOrg(ctx); err != nil {
t.Fatalf("second TagRequirementsForOrg: %v", err)
}
if len(repo.candTags) != 2 {
t.Fatalf("idempotency broken: candidate tag set grew to %d after a second run (want 2)", len(repo.candTags))
}
if len(repo.reqTags) != 3 {
t.Fatalf("idempotency broken: requirement tag set grew to %d after a second run (want 3)", len(repo.reqTags))
}
}
// TestTenantTagRefusesUnscopedContext proves the service fails closed when no org is in the context,
// mirroring RunInTenantTx: no validated org means no tagging.
func TestTenantTagRefusesUnscopedContext(t *testing.T) {
repo := newFakeTenantTagRepo()
repo.candidates = []dbgen.ListCandidatesForMissionTaggingRow{
{CandidateID: uuid.New(), Headline: "SIGINT analyst"},
}
svc := NewTenantTagService(repo, missionclass.NewAliasIndex(map[string]string{}))
if _, err := svc.TagCandidatesForOrg(context.Background()); err == nil {
t.Fatal("TagCandidatesForOrg with no org in context must error (fail closed)")
}
if _, err := svc.TagRequirementsForOrg(context.Background()); err == nil {
t.Fatal("TagRequirementsForOrg with no org in context must error (fail closed)")
}
if len(repo.candTags) != 0 || len(repo.reqTags) != 0 {
t.Fatal("an unscoped run must write nothing")
}
}
// TestTenantTagAliasLayer proves the curated alias layer adds a mission beyond the literal keyword: an
// alias phrase that is not a gazetteer keyword still produces the right code, with the alias mechanism.
func TestTenantTagAliasLayer(t *testing.T) {
org := uuid.New()
candID := uuid.New()
repo := newFakeTenantTagRepo()
repo.candidates = []dbgen.ListCandidatesForMissionTaggingRow{
{CandidateID: candID, Headline: "intercept operator", SkillText: ""},
}
// "intercept operator" is not a SIGINT gazetteer keyword; the curated alias maps it to SIGINT.
idx := missionclass.NewAliasIndex(map[string]string{"intercept operator": "SIGINT"})
svc := NewTenantTagService(repo, idx)
ctx := tenant.WithOrg(context.Background(), org.String())
if _, err := svc.TagCandidatesForOrg(ctx); err != nil {
t.Fatalf("TagCandidatesForOrg: %v", err)
}
got := collectCandTags(repo, candID)
assertTags(t, "alias candidate", []missionTag{{"SIGINT", missionclass.MechAlias, "intercept operator"}}, got)
}
func collectCandTags(r *fakeTenantTagRepo, candID uuid.UUID) []missionTag {
var out []missionTag
for _, v := range r.candTags {
if v.CandidateID == candID {
out = append(out, missionTag{v.MissionCode, v.Mechanism, v.Evidence})
}
}
return out
}
func collectReqTags(r *fakeTenantTagRepo, reqID uuid.UUID) []missionTag {
var out []missionTag
for _, v := range r.reqTags {
if v.RequirementID == reqID {
out = append(out, missionTag{v.MissionCode, v.Mechanism, v.Evidence})
}
}
return out
}
// assertTags compares two tag sets order independently: the upsert map iteration order is not stable, so
// the test sorts both sides by code before comparing.
func assertTags(t *testing.T, label string, want, got []missionTag) {
t.Helper()
byCode := func(s []missionTag) { sort.Slice(s, func(i, j int) bool { return s[i].code < s[j].code }) }
byCode(want)
byCode(got)
if len(want) != len(got) {
t.Fatalf("%s tags: got %d %+v, want %d %+v", label, len(got), got, len(want), want)
}
for i := range want {
if want[i] != got[i] {
t.Fatalf("%s tag %d: got %+v, want %+v", label, i, got[i], want[i])
}
}
}