package mapping import "testing" func TestBuildHealthRecordCreateUsesMappedFieldsAndCheckID(t *testing.T) { mapped, errs := MapHealthRecord(validPHISHealthRecord(), MapContext{Dicts: DefaultDictSnapshot()}) if len(errs) != 0 { t.Fatalf("errors = %#v", errs) } create := BuildHealthRecordCreate(mapped) if create.HealthRecord.CheckID != mapped.CheckID { t.Fatalf("checkId = %q, want %q", create.HealthRecord.CheckID, mapped.CheckID) } if create.HealthRecord.IDCard != mapped.IDCard || create.HealthRecord.PersonName != mapped.PersonName { t.Fatalf("healthRecord demographics = %#v", create.HealthRecord) } if create.HealthRecord.RegionCode != mapped.RegionCode || create.HealthRecord.ManaDoctorID != mapped.ManaDoctorID || create.HealthRecord.ManaUnitID != mapped.ManaUnitID || create.HealthRecord.CreateUser != mapped.ManaDoctorID || create.HealthRecord.CreateUnit != mapped.ManaUnitID { t.Fatalf("management fields = %#v", create.HealthRecord) } if create.BaseInfo.IDCard != mapped.IDCard || create.BaseInfo.PersonName != mapped.PersonName { t.Fatalf("baseInfo = %#v", create.BaseInfo) } } func TestMapHealthRecordMapsDirectFieldsDictsAndCheckID(t *testing.T) { src := validPHISHealthRecord() got, errs := MapHealthRecord(src, MapContext{Dicts: DefaultDictSnapshot()}) if len(errs) != 0 { t.Fatalf("errors = %#v", errs) } if got.IDCard != src.IDCard || got.PersonName != src.PersonName || got.Birthday != src.Birthday || got.MobileNumber != src.MobileNumber { t.Fatalf("direct fields not mapped: %#v", got) } if got.SexCode != "1" || got.NationCode != "01" || got.EducationCode != "31" || got.WorkCode != "Y" { t.Fatalf("dict fields not mapped: %#v", got) } if got.MaritalStatusCode != "20" || got.BloodTypeCode != "4" || got.RhBloodCode != "1" || got.InsuranceCode != "01" { t.Fatalf("dict fields not mapped: %#v", got) } if got.RegionCode != src.RegionCode || got.ManaDoctorID != src.ManaDoctorID || got.ManaUnitID != src.ManaUnitID { t.Fatalf("management fields not mapped: %#v", got) } if got.CheckID == "" || len(got.CheckID) != 20 { t.Fatalf("checkId = %q", got.CheckID) } } func TestMapHealthRecordReportsRequiredFieldErrors(t *testing.T) { src := validPHISHealthRecord() src.IDCard = "" src.PersonName = "" src.ManaUnitID = "" _, errs := MapHealthRecord(src, MapContext{Dicts: DefaultDictSnapshot()}) if len(errs) != 3 { t.Fatalf("errors = %#v", errs) } assertValidationField(t, errs, "idCard", "required") assertValidationField(t, errs, "personName", "required") assertValidationField(t, errs, "manaUnitId", "required") } func TestMapHealthRecordReportsDictValidationErrors(t *testing.T) { src := validPHISHealthRecord() src.SexCode = "bad" _, errs := MapHealthRecord(src, MapContext{Dicts: DefaultDictSnapshot()}) if len(errs) != 1 { t.Fatalf("errors = %#v", errs) } if errs[0].Field != "sexCode" || errs[0].Code != "bad" || errs[0].Direction != DirectionPHISToOSI { t.Fatalf("error = %#v", errs[0]) } } func TestMapHealthRecordUsesInjectedDictSnapshot(t *testing.T) { src := validPHISHealthRecord() src.SexCode = "M" dicts := DefaultDictSnapshot() dicts.Sex = Dict{Name: "sex", Field: "sexCode", Entries: []Entry{{PHIS: "M", OSI: "1", Name: "男"}}} got, errs := MapHealthRecord(src, MapContext{Dicts: dicts}) if len(errs) != 0 { t.Fatalf("errors = %#v", errs) } if got.SexCode != "1" { t.Fatalf("SexCode = %q", got.SexCode) } } func TestMapHealthRecordUsesMasterDataLookupWhenCodesMissing(t *testing.T) { src := validPHISHealthRecord() src.RegionCode = "" src.ManaDoctorID = "" src.ManaUnitID = "" src.RegionName = "测试网格" src.ManaDoctorName = "测试医生" src.ManaUnitName = "测试机构" got, errs := MapHealthRecord(src, MapContext{ Dicts: DefaultDictSnapshot(), MasterData: fakeMasterDataLookup{}, }) if len(errs) != 0 { t.Fatalf("errors = %#v", errs) } if got.RegionCode != "441625000000" || got.ManaDoctorID != "doc-001" || got.ManaUnitID != "123456789" { t.Fatalf("master data not resolved: %#v", got) } } func TestGenerateCheckIDIsDeterministicForStableSourceRecord(t *testing.T) { first := GenerateCheckID("PHIS", "JKDA", "record-001") second := GenerateCheckID("PHIS", "JKDA", "record-001") third := GenerateCheckID("PHIS", "JKDA", "record-002") if first != second { t.Fatalf("checkId not deterministic: %q != %q", first, second) } if len(first) != 20 { t.Fatalf("checkId length = %d, want 20", len(first)) } if first == third { t.Fatalf("different source record reused checkId: %q", first) } } type fakeMasterDataLookup struct{} func (fakeMasterDataLookup) RegionCodeByName(name string) (string, bool) { return map[string]string{"测试网格": "441625000000"}[name], name == "测试网格" } func (fakeMasterDataLookup) DoctorIDByName(name string) (string, bool) { return map[string]string{"测试医生": "doc-001"}[name], name == "测试医生" } func (fakeMasterDataLookup) ManaUnitIDByName(name string) (string, bool) { return map[string]string{"测试机构": "123456789"}[name], name == "测试机构" } func (fakeMasterDataLookup) DoctorIDExists(id string) bool { return id == "D001" || id == "doc-001" || id == "DOC001" } func (fakeMasterDataLookup) ManaUnitIDExists(id string) bool { return id == "123456789" } func validPHISHealthRecord() PHISHealthRecord { return PHISHealthRecord{ SourceSystem: "PHIS", SourceRecordID: "record-001", UpdatedAt: "20260707010101", IDCard: "440000********1234", PersonName: "测试人员", SexCode: "1", Birthday: "1970-01-01", MobileNumber: "13900000000", RegionCode: "441625000000", ManaDoctorID: "D001", ManaUnitID: "123456789", NationCode: "01", EducationCode: "31", WorkCode: "Y", MaritalStatusCode: "20", BloodTypeCode: "4", RhBloodCode: "1", InsuranceCode: "01", } } func assertValidationField(t *testing.T, errs []ValidationError, field string, reason string) { t.Helper() for _, err := range errs { if err.Field == field && err.Reason == reason { return } } t.Fatalf("missing validation error field=%s reason=%s in %#v", field, reason, errs) }