Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/federalsignal/service_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/modules/federalsignal/service_test.go |
| Original SHA-256 | dcd0aeb3e8c548fcd931ad73940cd627d2fce222f988db5e6c5a2c8f896ebf9d |
| Git blob SHA | fec3413b6a898f5eb0e94ddf994e1930372b653a |
| Reading-copy SHA-256 | dcd0aeb3e8c548fcd931ad73940cd627d2fce222f988db5e6c5a2c8f896ebf9d |
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/service_test.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / internal/modules/federalsignal/service_test.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓279 lines · 10.9 KB
package federalsignal
import (
"context"
"sort"
"testing"
"github.com/missionworkforce/missionmatch/internal/platform/audit"
"github.com/missionworkforce/missionmatch/internal/platform/database/dbgen"
)
// fakeRepo is an in memory Repo: it serves fixture rows and records every upsert so the test can assert
// the exact tags and incumbent roles the service wrote. It honors idempotency the way the real ON
// CONFLICT DO UPDATE does, keying mission tags on (record_table, record_id, mission_code) and incumbent
// roles on (record_table, record_id, labor_category), so a second run never grows the row set.
type fakeRepo struct {
aliasPairs map[string]string
opps []dbgen.ListOpportunityRecordsForClassifyRow
awards []dbgen.ListAwardsForClassifyRow
sam []dbgen.ListSamForClassifyRow
missionTags map[string]dbgen.UpsertFederalMissionTagParams
incumbentRoles map[string]dbgen.UpsertAwardIncumbentRoleParams
}
func newFakeRepo() *fakeRepo {
return &fakeRepo{
missionTags: map[string]dbgen.UpsertFederalMissionTagParams{},
incumbentRoles: map[string]dbgen.UpsertAwardIncumbentRoleParams{},
}
}
func (r *fakeRepo) AliasPairs(_ context.Context) (map[string]string, error) { return r.aliasPairs, nil }
func (r *fakeRepo) ListOpportunityRecordsForClassify(_ context.Context) ([]dbgen.ListOpportunityRecordsForClassifyRow, error) {
return r.opps, nil
}
func (r *fakeRepo) ListAwardsForClassify(_ context.Context) ([]dbgen.ListAwardsForClassifyRow, error) {
return r.awards, nil
}
func (r *fakeRepo) ListSamForClassify(_ context.Context) ([]dbgen.ListSamForClassifyRow, error) {
return r.sam, nil
}
func (r *fakeRepo) UpsertFederalMissionTag(_ context.Context, p dbgen.UpsertFederalMissionTagParams) error {
r.missionTags[p.RecordTable+"|"+p.RecordID+"|"+p.MissionCode] = p
return nil
}
func (r *fakeRepo) UpsertAwardIncumbentRole(_ context.Context, p dbgen.UpsertAwardIncumbentRoleParams) error {
r.incumbentRoles[p.RecordTable+"|"+p.RecordID+"|"+p.LaborCategory] = p
return nil
}
// fakeFetcher returns fixed attachment text per description URL, no network. A miss returns empty text.
type fakeFetcher struct{ byURL map[string]string }
func (f *fakeFetcher) FetchSolicitationText(_ context.Context, descURL string, _ []string) (string, error) {
return f.byURL[descURL], nil
}
// fakeAuditor records the events the service emits so the test can assert exactly one, with the counts
// only action and no PII or record text in the body.
type fakeAuditor struct{ events []audit.Event }
func (a *fakeAuditor) System(_ context.Context, e audit.Event) error {
a.events = append(a.events, e)
return nil
}
// fixtureRepo builds the spec fixtures: one opportunity titled "SIGINT collection support", one award
// described "3 ISSO and 2 Cyber Engineer", and one sam notice whose fetcher returns
// "SIGINT Analyst x2 and ISSO". The alias index maps a curated phrase to COMSEC so the alias mechanism is
// exercised alongside the keyword mechanism.
func fixtureRepo() *fakeRepo {
r := newFakeRepo()
r.aliasPairs = map[string]string{
"comsec custodian": "COMSEC",
}
r.opps = []dbgen.ListOpportunityRecordsForClassifyRow{
{RecordID: "opp-1", Title: "SIGINT collection support", Psc: "", Naics: ""},
}
r.awards = []dbgen.ListAwardsForClassifyRow{
{RecordID: "award-1", Description: "3 ISSO and 2 Cyber Engineer", NaicsDescription: "", NaicsCode: ""},
}
r.sam = []dbgen.ListSamForClassifyRow{
{RecordID: "sam-1", DescriptionUrl: "https://api.sam.gov/desc/sam-1", ResourceLinks: []byte(`[]`)},
}
return r
}
func fixtureFetcher() *fakeFetcher {
return &fakeFetcher{byURL: map[string]string{
"https://api.sam.gov/desc/sam-1": "SIGINT Analyst x2 and ISSO",
}}
}
// TestClassifyAllWritesExactTagsAndRoles asserts the service writes exactly the expected mission tags and
// incumbent roles from the fixture records, with the right codes, mechanisms, evidence, and counts.
func TestClassifyAllWritesExactTagsAndRoles(t *testing.T) {
repo := fixtureRepo()
aud := &fakeAuditor{}
svc := NewService(repo, fixtureFetcher(), aud, 50)
res, err := svc.ClassifyAll(context.Background())
if err != nil {
t.Fatalf("ClassifyAll: %v", err)
}
// Mission tags. The opportunity title yields a SIGINT keyword hit. The award has no mission bearing
// text, so it produces no mission tag. SAM notices are never mission tagged here (the 0026 CHECK
// forbids it), so the only mission tag is the opportunity SIGINT one.
wantTags := map[string]dbgen.UpsertFederalMissionTagParams{
"opportunity_records|opp-1|SIGINT": {
RecordTable: "opportunity_records", RecordID: "opp-1", MissionCode: "SIGINT",
Mechanism: "keyword", Evidence: "sigint", Confidence: confidenceFull,
},
}
if len(repo.missionTags) != len(wantTags) {
t.Fatalf("mission tags = %v, want %v", keysOf(repo.missionTags), keysOf(wantTags))
}
for k, want := range wantTags {
got, ok := repo.missionTags[k]
if !ok {
t.Fatalf("missing mission tag %q", k)
}
if got.MissionCode != want.MissionCode || got.Mechanism != want.Mechanism || got.Evidence != want.Evidence || !got.Confidence.Equal(want.Confidence) {
t.Fatalf("mission tag %q = %+v, want %+v", k, got, want)
}
}
// Incumbent roles. The award description "3 ISSO and 2 Cyber Engineer" yields ISSO (one "isso" match)
// and Cyber Engineer (one "cyber engineer" match). The SAM attachment text "SIGINT Analyst x2 and
// ISSO" yields ISSO (one match) and Intelligence Analyst (one "sigint" match). Counts are the literal
// occurrence totals, never fabricated.
wantRoles := map[string]dbgen.UpsertAwardIncumbentRoleParams{
"usaspending_awards|award-1|ISSO": {RecordTable: "usaspending_awards", RecordID: "award-1", LaborCategory: "ISSO", RoleCount: 1, Evidence: "isso"},
"usaspending_awards|award-1|Cyber Engineer": {RecordTable: "usaspending_awards", RecordID: "award-1", LaborCategory: "Cyber Engineer", RoleCount: 1, Evidence: "cyber engineer"},
"sam_opportunities|sam-1|ISSO": {RecordTable: "sam_opportunities", RecordID: "sam-1", LaborCategory: "ISSO", RoleCount: 1, Evidence: "isso"},
"sam_opportunities|sam-1|Intelligence Analyst": {RecordTable: "sam_opportunities", RecordID: "sam-1", LaborCategory: "Intelligence Analyst", RoleCount: 1, Evidence: "sigint"},
}
if len(repo.incumbentRoles) != len(wantRoles) {
t.Fatalf("incumbent roles = %v, want %v", keysOf(repo.incumbentRoles), keysOf(wantRoles))
}
for k, want := range wantRoles {
got, ok := repo.incumbentRoles[k]
if !ok {
t.Fatalf("missing incumbent role %q", k)
}
if got != want {
t.Fatalf("incumbent role %q = %+v, want %+v", k, got, want)
}
}
// Result counts reflect what was actually written.
if res.RecordsScanned != 3 {
t.Fatalf("RecordsScanned = %d, want 3", res.RecordsScanned)
}
if res.MissionTagsWritten != 1 {
t.Fatalf("MissionTagsWritten = %d, want 1", res.MissionTagsWritten)
}
if res.IncumbentRoles != 4 {
t.Fatalf("IncumbentRoles = %d, want 4", res.IncumbentRoles)
}
if res.SamFetched != 1 || res.SamSkippedCap != 0 {
t.Fatalf("SamFetched=%d SamSkippedCap=%d, want 1 and 0", res.SamFetched, res.SamSkippedCap)
}
// Exactly one audit event, counts only action, no PII in the action or entity fields.
if len(aud.events) != 1 {
t.Fatalf("audit events = %d, want 1", len(aud.events))
}
if aud.events[0].Action != "aedt.federalsignal.classified" {
t.Fatalf("audit action = %q", aud.events[0].Action)
}
}
// TestClassifyAllAliasMechanism proves a curated alias phrase tags a mission with the alias mechanism,
// separate from the keyword path. The alias phrase "spectrum operations" carries no mission keyword of
// its own (EW's keyword form is "electronic warfare"), so only the alias layer can produce the tag,
// proving the alias mechanism is genuinely exercised and not shadowed by a keyword.
func TestClassifyAllAliasMechanism(t *testing.T) {
repo := newFakeRepo()
repo.aliasPairs = map[string]string{"spectrum operations": "EW"}
repo.opps = []dbgen.ListOpportunityRecordsForClassifyRow{
{RecordID: "opp-alias", Title: "seeking Spectrum Operations support for the program", Psc: "", Naics: ""},
}
svc := NewService(repo, fixtureFetcher(), &fakeAuditor{}, 50)
if _, err := svc.ClassifyAll(context.Background()); err != nil {
t.Fatalf("ClassifyAll: %v", err)
}
got, ok := repo.missionTags["opportunity_records|opp-alias|EW"]
if !ok {
t.Fatalf("missing EW alias tag, have %v", keysOf(repo.missionTags))
}
if got.Mechanism != "alias" || got.Evidence != "spectrum operations" {
t.Fatalf("alias tag = %+v, want alias mechanism with evidence spectrum operations", got)
}
}
// TestClassifyAllIsIdempotent runs the pass twice over the same fixtures and asserts the second run wrote
// the exact same row set (no duplicates, no growth), the AEDT reproducibility mandate for a repeatable
// sync.
func TestClassifyAllIsIdempotent(t *testing.T) {
repo := fixtureRepo()
svc := NewService(repo, fixtureFetcher(), &fakeAuditor{}, 50)
r1, err := svc.ClassifyAll(context.Background())
if err != nil {
t.Fatalf("first run: %v", err)
}
tagsAfterFirst := keysOf(repo.missionTags)
rolesAfterFirst := keysOf(repo.incumbentRoles)
r2, err := svc.ClassifyAll(context.Background())
if err != nil {
t.Fatalf("second run: %v", err)
}
if !equalStrings(tagsAfterFirst, keysOf(repo.missionTags)) {
t.Fatalf("mission tags grew on rerun: %v then %v", tagsAfterFirst, keysOf(repo.missionTags))
}
if !equalStrings(rolesAfterFirst, keysOf(repo.incumbentRoles)) {
t.Fatalf("incumbent roles grew on rerun: %v then %v", rolesAfterFirst, keysOf(repo.incumbentRoles))
}
if r1 != r2 {
t.Fatalf("result not deterministic across runs: %+v then %+v", r1, r2)
}
}
// TestClassifyAllAttachmentCap proves the max attachments bound skips SAM notices past the cap and counts
// them as skipped, never silently dropping them, and that mission tags and award roles are unaffected.
func TestClassifyAllAttachmentCap(t *testing.T) {
repo := fixtureRepo()
repo.sam = []dbgen.ListSamForClassifyRow{
{RecordID: "sam-1", DescriptionUrl: "https://api.sam.gov/desc/sam-1", ResourceLinks: []byte(`[]`)},
{RecordID: "sam-2", DescriptionUrl: "https://api.sam.gov/desc/sam-2", ResourceLinks: []byte(`[]`)},
}
fetch := &fakeFetcher{byURL: map[string]string{
"https://api.sam.gov/desc/sam-1": "ISSO",
"https://api.sam.gov/desc/sam-2": "ISSO",
}}
svc := NewService(repo, fetch, &fakeAuditor{}, 1) // cap at one SAM notice
res, err := svc.ClassifyAll(context.Background())
if err != nil {
t.Fatalf("ClassifyAll: %v", err)
}
if res.SamFetched != 1 || res.SamSkippedCap != 1 {
t.Fatalf("SamFetched=%d SamSkippedCap=%d, want 1 and 1", res.SamFetched, res.SamSkippedCap)
}
if _, ok := repo.incumbentRoles["sam_opportunities|sam-2|ISSO"]; ok {
t.Fatalf("sam-2 was over the cap and must not have been mined")
}
}
func keysOf[V any](m map[string]V) []string {
out := make([]string, 0, len(m))
for k := range m {
out = append(out, k)
}
sort.Strings(out)
return out
}
func equalStrings(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}