package http import ( "io" "net/http" "net/http/httptest" "strings" "testing" ) type fakeResultClient func(*http.Request) (*http.Response, error) func (f fakeResultClient) Do(r *http.Request) (*http.Response, error) { return f(r) } func TestUpdateResultForwarderPreservesPayloadAndResponse(t *testing.T) { const body = `{"kode_rs":"GM","no_regpas":"MCU260900031","results":[{"layanan_id":"1102","result":"5","unit":"mm\/jam"}]}` called := false client := fakeResultClient(func(r *http.Request) (*http.Response, error) { called = true if r.Method != http.MethodPost || r.URL.Host != "devcpone.aplikasi.web.id" || r.URL.Path != "/one-api/api_his/update_result" { t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path) } gotBody, _ := io.ReadAll(r.Body) if string(gotBody) != body { t.Errorf("payload changed: %s", gotBody) } if r.Header.Get("Authorization") != "" || r.Header.Get("Cookie") != "" { t.Error("caller credentials were forwarded") } return &http.Response{ StatusCode: http.StatusUnprocessableEntity, Header: http.Header{"Content-Type": []string{"application/json"}}, Body: io.NopCloser(strings.NewReader(`{"Status":{"OK":false,"Messages":"ORDER_STORED_PENDING_MATCH"}}`)), }, nil }) handler := NewUpdateResultForwarder("https://devcpone.aplikasi.web.id/one-api/api_his/update_result", client) r := httptest.NewRequest(http.MethodPost, "/api/cpone/his/update-result", strings.NewReader(body)) r.Header.Set("Content-Type", "application/json") r.Header.Set("Authorization", "Bearer middleware-secret") r.Header.Set("Cookie", "session=secret") w := httptest.NewRecorder() handler.ServeHTTP(w, r) if !called || w.Code != http.StatusUnprocessableEntity || !strings.Contains(w.Body.String(), "ORDER_STORED_PENDING_MATCH") { t.Fatalf("called=%t status=%d body=%s", called, w.Code, w.Body.String()) } } func TestUpdateResultForwarderRejectsInvalidJSON(t *testing.T) { called := false client := fakeResultClient(func(r *http.Request) (*http.Response, error) { called = true return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader("ok"))}, nil }) handler := NewUpdateResultForwarder("https://devcpone.aplikasi.web.id/one-api/api_his/update_result", client) r := httptest.NewRequest(http.MethodPost, "/api/cpone/his/update-result", strings.NewReader(`{"kode_rs":`)) r.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() handler.ServeHTTP(w, r) if w.Code != http.StatusBadRequest || called { t.Fatalf("status=%d upstream_called=%t", w.Code, called) } } func TestRadiologyResultForwarderPreservesPayloadAndResponse(t *testing.T) { const body = `{"kode_rs":"GM","no_regpas":"MCU260900014","medrec":"00640052","dokter_id":"DR00069","results":[{"layanan_id":"RAD-01-01-001","testName":"A103 - Thorax PA","modality":"CR","expertise":"Hasil ekspertisi"}]}` called := false client := fakeResultClient(func(r *http.Request) (*http.Response, error) { called = true if r.Method != http.MethodPost || r.URL.Host != "devcpone.aplikasi.web.id" || r.URL.Path != "/one-api/api_his/update_result_radiologi" { t.Errorf("unexpected request: %s %s", r.Method, r.URL.String()) } gotBody, _ := io.ReadAll(r.Body) if string(gotBody) != body { t.Errorf("radiology payload changed: %s", gotBody) } if r.Header.Get("Authorization") != "" || r.Header.Get("Cookie") != "" { t.Error("caller credentials were forwarded") } return &http.Response{ StatusCode: http.StatusUnprocessableEntity, Header: http.Header{"Content-Type": []string{"application/json"}}, Body: io.NopCloser(strings.NewReader(`{"Status":{"OK":false,"Messages":"dokter_id HIS belum memiliki mapping dokter CPONE [Radiology004]"}}`)), }, nil }) handler := NewUpdateResultForwarder("https://devcpone.aplikasi.web.id/one-api/api_his/update_result_radiologi", client) r := httptest.NewRequest(http.MethodPost, "/api/cpone/his/update-result-radiologi", strings.NewReader(body)) r.Header.Set("Content-Type", "application/json") r.Header.Set("Authorization", "Bearer middleware-secret") r.Header.Set("Cookie", "session=secret") w := httptest.NewRecorder() handler.ServeHTTP(w, r) if !called || w.Code != http.StatusUnprocessableEntity || !strings.Contains(w.Body.String(), "Radiology004") { t.Fatalf("called=%t status=%d body=%s", called, w.Code, w.Body.String()) } }