feat: add search and pagination to tariff period services

This commit is contained in:
2026-09-02 09:27:23 +07:00
parent 1d5bc309c0
commit 181d53af45
8 changed files with 560 additions and 8 deletions

View File

@@ -0,0 +1,113 @@
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())
}
}