package http import ( "context" "errors" "net/http" "net/http/httptest" "strings" "testing" "primaya-api/cpone-middleware/internal/repository" ) type fakeLayananRepository struct { page repository.LayananPage err error params repository.LayananListParams } func (f *fakeLayananRepository) ListLayanan(_ context.Context, params repository.LayananListParams) (repository.LayananPage, error) { f.params = params return f.page, f.err } func (f *fakeLayananRepository) MappingHarga(context.Context, repository.MappingHargaParams) ([]repository.TarifLayanan, error) { return nil, nil } func TestListLayananResponseParity(t *testing.T) { group, department := "MCU", "MEDICAL CHECK UP" layananID, code, name := "6413", "DL", "DARAH LENGKAP" repo := &fakeLayananRepository{page: repository.LayananPage{ Total: 16, Items: []repository.LayananDepartemen{{ GroupLayananID: &group, Departemen: &department, LayananDepartemenID: 987, LayananID: &layananID, LayananCode: &code, NamaLayanan: &name, }}, }} handler := Handler{layananRepo: repo} request := httptest.NewRequest(http.MethodGet, "http://localhost/api/cpone/layanan?page=1&search=tes&departemen_id=MCU&kode_rs=AWALBROS_DEV", nil) recorder := httptest.NewRecorder() handler.ListLayanan(recorder, request) if recorder.Code != http.StatusOK { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } if repo.params.Page != 1 || repo.params.PerPage != defaultLayananPerPage || repo.params.Search != "tes" || repo.params.DepartemenID != "MCU" { t.Fatalf("params = %+v", repo.params) } for _, expected := range []string{ `"GroupLayananID":"MCU"`, `"Departemen":"MEDICAL CHECK UP"`, `"LayananDepartemenID":987`, `"LayananID":"6413"`, `"NamaLayanan":"DARAH LENGKAP"`, `"LayananCode":"DL"`, `"last_page":2`, `"per_page":15`, `"next_page_url":"http://localhost/api/cpone/layanan?kode_rs=AWALBROS_DEV\u0026page=2"`, } { if !strings.Contains(recorder.Body.String(), expected) { t.Fatalf("response missing %s: %s", expected, recorder.Body.String()) } } } func TestListLayananUsesLaravelPageFallback(t *testing.T) { repo := &fakeLayananRepository{page: repository.LayananPage{Items: []repository.LayananDepartemen{}}} handler := Handler{layananRepo: repo} for _, target := range []string{"/api/cpone/layanan", "/api/cpone/layanan?page=0", "/api/cpone/layanan?page=invalid"} { recorder := httptest.NewRecorder() handler.ListLayanan(recorder, httptest.NewRequest(http.MethodGet, target, nil)) if recorder.Code != http.StatusOK || repo.params.Page != 1 || repo.params.PerPage != defaultLayananPerPage { t.Fatalf("target=%s status=%d params=%+v", target, recorder.Code, repo.params) } } } func TestListLayananAcceptsBoundedPerPage(t *testing.T) { repo := &fakeLayananRepository{page: repository.LayananPage{Items: []repository.LayananDepartemen{}}} handler := Handler{layananRepo: repo} for target, expected := range map[string]int{ "/api/cpone/layanan?per_page=250": 250, "/api/cpone/layanan?per_page=5000": maxLayananPerPage, } { recorder := httptest.NewRecorder() handler.ListLayanan(recorder, httptest.NewRequest(http.MethodGet, target, nil)) if recorder.Code != http.StatusOK || repo.params.PerPage != expected { t.Fatalf("target=%s status=%d per_page=%d", target, recorder.Code, repo.params.PerPage) } } } func TestListLayananInternalError(t *testing.T) { handler := Handler{layananRepo: &fakeLayananRepository{err: errors.New("query failed")}} recorder := httptest.NewRecorder() handler.ListLayanan(recorder, httptest.NewRequest(http.MethodGet, "/api/cpone/layanan", nil)) if recorder.Code != http.StatusInternalServerError { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } }