feat: add lab result endpoint

This commit is contained in:
2026-08-19 10:41:07 +07:00
parent 13bbdc1328
commit 21196d8227
6 changed files with 677 additions and 4 deletions

View File

@@ -0,0 +1,126 @@
package http
import (
"context"
"errors"
"net/http"
"net/http/httptest"
"testing"
"primaya-api/cpone-middleware/internal/repository"
)
type fakeLabResultRepository struct {
outcome repository.LabResultOutcome
err error
labNumber string
}
func (f *fakeLabResultRepository) GetLabResult(_ context.Context, labNumber string) (repository.LabResultOutcome, error) {
f.labNumber = labNumber
return f.outcome, f.err
}
func TestGetLabResultResponseParity(t *testing.T) {
verifiedAt := "2026-08-19 10:00:00"
name := "Hemoglobin"
result := "14.2"
reference := "13.0 - 17.0"
unit := "g/dL"
groupID := "HEMATOLOGI"
groupName := "Hematologi"
repo := &fakeLabResultRepository{outcome: repository.LabResultOutcome{
HTTPStatus: http.StatusOK,
Success: true,
Status: "lab_result_found",
Message: "Hasil laboratorium ditemukan",
Data: &repository.LabResultData{
Lab: repository.LabResultHeader{
LabNumber: "CPLAB2608190001", TrxDepartemenID: 6103991,
Status: "authorized", VerifiedAt: &verifiedAt,
},
Groups: []repository.LabResultGroup{{
GroupID: &groupID, GroupName: &groupName,
Items: []repository.LabResultItem{{
TrxLayananID: 123456, ServiceID: "HB", Name: &name, Result: &result,
ReferenceValue: &reference, Unit: &unit, CriticalFlag: "",
}},
}},
},
}}
handler := Handler{labResultRepo: repo}
request := httptest.NewRequest(http.MethodGet, "/api/cpone/patients/lab-results/cplab2608190001", nil)
request.SetPathValue("labNumber", "cplab2608190001")
recorder := httptest.NewRecorder()
handler.GetLabResult(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
}
if repo.labNumber != "CPLAB2608190001" {
t.Fatalf("lab number=%q", repo.labNumber)
}
const expected = `{"success":true,"status":"lab_result_found","message":"Hasil laboratorium ditemukan","data":{"lab":{"lab_number":"CPLAB2608190001","trx_departemen_id":6103991,"registration_id":null,"tanggal":null,"status":"authorized","verified_at":"2026-08-19 10:00:00","authorized_at":null,"catatan":null},"patient":{"medrec_id":null,"nama":null,"tanggal_lahir":null,"jenis_kelamin":null},"doctor":{"penanggung_jawab":null,"pengirim":null},"groups":[{"group_id":"HEMATOLOGI","group_name":"Hematologi","items":[{"trx_layanan_id":123456,"service_id":"HB","service_code":null,"name":"Hemoglobin","result":"14.2","reference_value":"13.0 - 17.0","unit":"g/dL","critical_flag":"","value_type":null,"note":null}]}]}}` + "\n"
if recorder.Body.String() != expected {
t.Fatalf("body mismatch\n got: %s\nwant: %s", recorder.Body.String(), expected)
}
}
func TestGetLabResultValidationParity(t *testing.T) {
tests := []struct {
name, labNumber, message string
}{
{name: "invalid characters", labNumber: "CPLAB_260819", message: "Nomor laboratorium hanya boleh berisi huruf, angka, dan tanda hubung"},
{name: "too long", labNumber: "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNO", message: "Nomor laboratorium maksimal 50 karakter"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
handler := Handler{labResultRepo: &fakeLabResultRepository{}}
request := httptest.NewRequest(http.MethodGet, "/api/cpone/patients/lab-results/"+test.labNumber, nil)
request.SetPathValue("labNumber", test.labNumber)
recorder := httptest.NewRecorder()
handler.GetLabResult(recorder, request)
if recorder.Code != http.StatusUnprocessableEntity {
t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
}
expected := `{"success":false,"status":"validation_error","message":` + strconvQuote(test.message) + `,"data":null}` + "\n"
if recorder.Body.String() != expected {
t.Fatalf("body mismatch\n got: %s\nwant: %s", recorder.Body.String(), expected)
}
})
}
}
func TestGetLabResultForwardsDomainAndDatabaseOutcomes(t *testing.T) {
tests := []struct {
name string
repo *fakeLabResultRepository
statusCode int
expected string
}{
{
name: "not found",
repo: &fakeLabResultRepository{outcome: repository.LabResultOutcome{HTTPStatus: 404, Status: "lab_result_not_found", Message: "Hasil laboratorium tidak ditemukan"}},
statusCode: 404,
expected: `{"success":false,"status":"lab_result_not_found","message":"Hasil laboratorium tidak ditemukan","data":null}` + "\n",
},
{
name: "database error", repo: &fakeLabResultRepository{err: errors.New("database unavailable")},
statusCode: 500,
expected: `{"success":false,"status":"error","message":"database unavailable","data":null}` + "\n",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
handler := Handler{labResultRepo: test.repo}
request := httptest.NewRequest(http.MethodGet, "/api/cpone/patients/lab-results/CPLAB2608190001", nil)
request.SetPathValue("labNumber", "CPLAB2608190001")
recorder := httptest.NewRecorder()
handler.GetLabResult(recorder, request)
if recorder.Code != test.statusCode || recorder.Body.String() != test.expected {
t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
}
})
}
}