125 lines
4.6 KiB
Go
125 lines
4.6 KiB
Go
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
|
||
|
|
}
|