package http import ( "context" "errors" "net/http" "net/http/httptest" "strings" "testing" "primaya-api/cpone-middleware/internal/repository" ) type fakePeriodeTarifDetailRepository struct { items []repository.PeriodeTarifLayanan err error id int64 params repository.PeriodeTarifLayananListParams total int } func (f *fakePeriodeTarifDetailRepository) ListPeriodeTarifLayanan(_ context.Context, params repository.PeriodeTarifLayananListParams) (repository.PeriodeTarifLayananPage, error) { f.id = params.PeriodeTarifID f.params = params total := f.total if total == 0 { total = len(f.items) } return repository.PeriodeTarifLayananPage{Items: f.items, Total: total}, f.err } func TestListPeriodeTarifLayananReturnsRows(t *testing.T) { layananID, nama, departemen, kelas, namaKelas, harga := "6413", "Darah Lengkap", "LAB", "Default", "Default", "125000.00" repo := &fakePeriodeTarifDetailRepository{items: []repository.PeriodeTarifLayanan{{ TarifLayananID: 10, LayananID: &layananID, NamaLayanan: &nama, LayananDepartemenID: 20, Departemen: &departemen, Kelas: kelas, NamaKelas: &namaKelas, Harga: &harga, }}} recorder := httptest.NewRecorder() request := httptest.NewRequest(http.MethodGet, "/api/cpone/periode-tarif/12?search=Darah&page=2", nil) request.SetPathValue("periodeTarifID", "12") Handler{periodeTarifDetailRepo: repo}.ListPeriodeTarifLayanan(recorder, request) if recorder.Code != http.StatusOK || repo.id != 12 { t.Fatalf("status=%d id=%d body=%s", recorder.Code, repo.id, recorder.Body.String()) } for _, expected := range []string{ `"LayananID":"6413"`, `"NamaLayanan":"Darah Lengkap"`, `"LayananDepartemenID":20`, `"Departemen":"LAB"`, `"Kelas":"Default"`, `"Harga":"125000.00"`, } { if !strings.Contains(recorder.Body.String(), expected) { t.Fatalf("response missing %s: %s", expected, recorder.Body.String()) } } } func TestListPeriodeTarifLayananUsesSearchAndPagination(t *testing.T) { repo := &fakePeriodeTarifDetailRepository{total: 41} recorder := httptest.NewRecorder() request := httptest.NewRequest(http.MethodGet, "http://localhost/api/cpone/periode-tarif/12?search=Admin&page=1", nil) request.SetPathValue("periodeTarifID", "12") Handler{periodeTarifDetailRepo: repo}.ListPeriodeTarifLayanan(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 != periodeTarifLayananPerPage || repo.params.Search != "Admin" { t.Fatalf("params=%+v", repo.params) } for _, expected := range []string{ `"current_page":1`, `"last_page":3`, `"per_page":20`, `"total":41`, `"next_page_url":"http://localhost/api/cpone/periode-tarif/12?page=2\u0026per_page=20\u0026search=Admin"`, } { if !strings.Contains(recorder.Body.String(), expected) { t.Fatalf("response missing %s: %s", expected, recorder.Body.String()) } } } func TestListPeriodeTarifLayananValidationAndMissingTable(t *testing.T) { for _, rawID := range []string{"", "abc", "0", "1.5"} { recorder := httptest.NewRecorder() request := httptest.NewRequest(http.MethodGet, "/api/cpone/periode-tarif/"+rawID, nil) request.SetPathValue("periodeTarifID", rawID) Handler{periodeTarifDetailRepo: &fakePeriodeTarifDetailRepository{}}.ListPeriodeTarifLayanan(recorder, request) if recorder.Code != http.StatusUnprocessableEntity { t.Fatalf("id=%q status=%d body=%s", rawID, recorder.Code, recorder.Body.String()) } } recorder := httptest.NewRecorder() request := httptest.NewRequest(http.MethodGet, "/api/cpone/periode-tarif/12", nil) request.SetPathValue("periodeTarifID", "12") Handler{periodeTarifDetailRepo: &fakePeriodeTarifDetailRepository{err: repository.ErrTarifTableNotFound}}. ListPeriodeTarifLayanan(recorder, request) if recorder.Code != http.StatusNotFound || !strings.Contains(recorder.Body.String(), "harga_layanan_12") { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } } func TestListPeriodeTarifLayananInternalError(t *testing.T) { recorder := httptest.NewRecorder() request := httptest.NewRequest(http.MethodGet, "/api/cpone/periode-tarif/12", nil) request.SetPathValue("periodeTarifID", "12") Handler{periodeTarifDetailRepo: &fakePeriodeTarifDetailRepository{err: errors.New("query failed")}}. ListPeriodeTarifLayanan(recorder, request) if recorder.Code != http.StatusInternalServerError { t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String()) } }