feat(handler): 暴露健康档案 upsert 接口(T-204)
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"chis_osi/contract"
|
||||
"chis_osi/osi"
|
||||
"chis_osi/pipeline"
|
||||
"chis_osi/source"
|
||||
)
|
||||
|
||||
func TestServerHealthRecordUpserterLoadsMasterDataAndCreates(t *testing.T) {
|
||||
task := loadRuntimeHealthRecordTask(t)
|
||||
client := &fakeRuntimeHealthRecordClient{
|
||||
doctors: []osi.Doctor{{PersonID: task.Record.ManaDoctorID, PersonName: "测试医生"}},
|
||||
orgs: []osi.Org{{OrganizCode: task.Record.ManaUnitID, OrganizName: "测试机构"}},
|
||||
records: []contract.FindHealthRecord{},
|
||||
}
|
||||
upserter := newServerHealthRecordUpserter(client)
|
||||
|
||||
outcome, err := upserter.Upsert(context.Background(), task)
|
||||
if err != nil || outcome.Status != pipeline.StatusDone || outcome.Action != pipeline.ActionCreate {
|
||||
t.Fatalf("outcome=%#v err=%v", outcome, err)
|
||||
}
|
||||
if client.doctorQueries != 1 || client.orgQueries != 1 || client.createCalls != 1 {
|
||||
t.Fatalf("doctorQueries=%d orgQueries=%d create=%d", client.doctorQueries, client.orgQueries, client.createCalls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerHealthRecordUpserterStopsWhenMasterDataFails(t *testing.T) {
|
||||
task := loadRuntimeHealthRecordTask(t)
|
||||
client := &fakeRuntimeHealthRecordClient{masterErr: errors.New("dictionary unavailable")}
|
||||
upserter := newServerHealthRecordUpserter(client)
|
||||
|
||||
_, err := upserter.Upsert(context.Background(), task)
|
||||
if err == nil || client.findCalls != 0 || client.createCalls != 0 {
|
||||
t.Fatalf("err=%v find=%d create=%d", err, client.findCalls, client.createCalls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerHealthRecordUpserterValidatesBeforeMasterDataCalls(t *testing.T) {
|
||||
client := &fakeRuntimeHealthRecordClient{masterErr: errors.New("must not be called")}
|
||||
upserter := newServerHealthRecordUpserter(client)
|
||||
|
||||
outcome, err := upserter.Upsert(context.Background(), source.HealthRecordTask{ArchID: "ARCH-INVALID"})
|
||||
if err != nil || outcome.Status != pipeline.StatusFailed || client.doctorQueries != 0 || client.orgQueries != 0 {
|
||||
t.Fatalf("outcome=%#v err=%v doctorQueries=%d orgQueries=%d", outcome, err, client.doctorQueries, client.orgQueries)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerMuxRegistersHealthRecordUpsert(t *testing.T) {
|
||||
upserter := &fakeServerUpserter{outcome: pipeline.Outcome{Status: pipeline.StatusDone, Action: pipeline.ActionCreate}}
|
||||
mux := newServerMux(nil, upserter)
|
||||
raw, err := os.ReadFile("source/testdata/health_record.json")
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile: %v", err)
|
||||
}
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/health-record/upsert", strings.NewReader(string(raw)))
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK || upserter.calls != 1 {
|
||||
t.Fatalf("status=%d calls=%d body=%s", rec.Code, upserter.calls, rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func loadRuntimeHealthRecordTask(t *testing.T) source.HealthRecordTask {
|
||||
t.Helper()
|
||||
raw, err := os.ReadFile("source/testdata/health_record.json")
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile: %v", err)
|
||||
}
|
||||
task, err := source.DecodeHealthRecordTask(raw)
|
||||
if err != nil {
|
||||
t.Fatalf("DecodeHealthRecordTask: %v", err)
|
||||
}
|
||||
return task
|
||||
}
|
||||
|
||||
type fakeRuntimeHealthRecordClient struct {
|
||||
doctors []osi.Doctor
|
||||
orgs []osi.Org
|
||||
records []contract.FindHealthRecord
|
||||
masterErr error
|
||||
doctorQueries, orgQueries int
|
||||
findCalls, createCalls int
|
||||
}
|
||||
|
||||
func (f *fakeRuntimeHealthRecordClient) QueryDoctors(context.Context, osi.DoctorQuery) ([]osi.Doctor, osi.Result, error) {
|
||||
f.doctorQueries++
|
||||
return f.doctors, osi.Result{Success: f.masterErr == nil, Code: "01"}, f.masterErr
|
||||
}
|
||||
func (f *fakeRuntimeHealthRecordClient) QueryOrgs(context.Context, osi.OrgQuery) ([]osi.Org, osi.Result, error) {
|
||||
f.orgQueries++
|
||||
return f.orgs, osi.Result{Success: f.masterErr == nil, Code: "01"}, f.masterErr
|
||||
}
|
||||
func (f *fakeRuntimeHealthRecordClient) FindHealthRecord(context.Context, osi.FindHealthRecordQuery) ([]contract.FindHealthRecord, osi.Result, error) {
|
||||
f.findCalls++
|
||||
return f.records, osi.Result{Success: true, Code: "01"}, nil
|
||||
}
|
||||
func (f *fakeRuntimeHealthRecordClient) CreateHealthRecord(context.Context, contract.HealthRecordCreate) (contract.HealthRecordSaveResult, osi.Result, error) {
|
||||
f.createCalls++
|
||||
return contract.HealthRecordSaveResult{PhrID: "PHR-RUNTIME"}, osi.Result{Success: true, Code: "01"}, nil
|
||||
}
|
||||
func (f *fakeRuntimeHealthRecordClient) UpdateHealthRecord(context.Context, contract.HealthRecordCreate) (contract.HealthRecordSaveResult, osi.Result, error) {
|
||||
return contract.HealthRecordSaveResult{}, osi.Result{Success: true, Code: "01"}, nil
|
||||
}
|
||||
|
||||
type fakeServerUpserter struct {
|
||||
outcome pipeline.Outcome
|
||||
calls int
|
||||
}
|
||||
|
||||
func (f *fakeServerUpserter) Upsert(context.Context, source.HealthRecordTask) (pipeline.Outcome, error) {
|
||||
f.calls++
|
||||
return f.outcome, nil
|
||||
}
|
||||
Reference in New Issue
Block a user