package handlers import ( "bytes" "encoding/json" "errors" "io" "net/http" "testing" "time" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/gofiber/fiber/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) // --- Mock service --- type MockChapaService struct { mock.Mock } func (m *MockChapaService) GetSupportedBanks() ([]domain.ChapaSupportedBank, error) { args := m.Called() return args.Get(0).([]domain.ChapaSupportedBank), args.Error(1) } // --- Tests --- func (h *Handler) TestReadChapaBanks_Success(t *testing.T) { app := fiber.New() mockService := new(MockChapaService) now := time.Now() isMobile := 1 isRtgs := 1 is24hrs := 1 mockBanks := []domain.ChapaSupportedBank{ { Id: 101, Slug: "bank-a", Swift: "BKAETHAA", Name: "Bank A", AcctLength: 13, AcctNumberRegex: "^[0-9]{13}$", ExampleValue: "1000222215735", CountryId: 1, IsMobilemoney: &isMobile, IsActive: 1, IsRtgs: &isRtgs, Active: 1, Is24Hrs: &is24hrs, CreatedAt: now, UpdatedAt: now, Currency: "ETB", }, } mockService.On("GetSupportedBanks").Return(mockBanks, nil) // handler := handlers.NewChapaHandler(mockService) app.Post("/chapa/banks", h.ReadChapaBanks) req := createTestRequest(t, "POST", "/chapa/banks", nil) resp, err := app.Test(req) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode) var body domain.ResponseWDataFactory[[]domain.ChapaSupportedBank] err = parseJSONBody(resp, &body) require.NoError(t, err) assert.True(t, body.Success) assert.Equal(t, "read successful on chapa supported banks", body.Message) require.Len(t, body.Data, 1) assert.Equal(t, mockBanks[0].Name, body.Data[0].Name) assert.Equal(t, mockBanks[0].AcctNumberRegex, body.Data[0].AcctNumberRegex) mockService.AssertExpectations(t) } func (h *Handler) TestReadChapaBanks_Failure(t *testing.T) { app := fiber.New() mockService := new(MockChapaService) mockService.On("GetSupportedBanks").Return(nil, errors.New("chapa service unavailable")) // handler := handlers.NewChapaHandler(mockService) app.Post("/chapa/banks", h.ReadChapaBanks) req := createTestRequest(t, "POST", "/chapa/banks", nil) resp, err := app.Test(req) require.NoError(t, err) assert.Equal(t, fiber.StatusInternalServerError, resp.StatusCode) var body domain.Response err = parseJSONBody(resp, &body) require.NoError(t, err) assert.False(t, body.Success) assert.Equal(t, "Internal server error", body.Message) mockService.AssertExpectations(t) } func createTestRequest(t *testing.T, method, url string, body interface{}) *http.Request { var buf io.Reader if body != nil { b, err := json.Marshal(body) if err != nil { t.Fatal(err) } buf = bytes.NewBuffer(b) } req, err := http.NewRequest(method, url, buf) if err != nil { t.Fatal(err) } req.Header.Set("Content-Type", "application/json") return req } func parseJSONBody(resp *http.Response, target interface{}) error { return json.NewDecoder(resp.Body).Decode(target) }