package apperrorsx

import (
	"bytes"
	"io"
	"net/http"
	"testing"

	"github.com/gofiber/fiber/v2"
)

func TestPublicDetail(t *testing.T) {
	tests := []struct {
		status int
		want   string
	}{
		{http.StatusBadRequest, "invalid request"},
		{http.StatusUnauthorized, "unauthorized"},
		{http.StatusForbidden, "forbidden"},
		{http.StatusNotFound, "not found"},
		{http.StatusConflict, "conflict"},
		{http.StatusUnprocessableEntity, "validation failed"},
		{http.StatusTooManyRequests, "too many requests"},
		{http.StatusInternalServerError, "an internal error occurred"},
	}

	for _, tc := range tests {
		if got := PublicDetail(tc.status); got != tc.want {
			t.Fatalf("status %d: expected %q, got %q", tc.status, tc.want, got)
		}
	}
}

func TestWriteSanitizesDetail(t *testing.T) {
	app := fiber.New()
	app.Get("/", func(c *fiber.Ctx) error {
		err := New(ErrInternal)
		err.Message = "raw database message"
		return Write(c, err)
	})

	req, _ := http.NewRequest(http.MethodGet, "/", nil)
	resp, err := app.Test(req)
	if err != nil {
		t.Fatalf("app.Test: %v", err)
	}
	body, _ := io.ReadAll(resp.Body)
	if bytes.Contains(body, []byte("raw database message")) {
		t.Fatalf("expected sanitized detail, got %s", string(body))
	}
	if !bytes.Contains(body, []byte(`"detail":"an internal error occurred"`)) {
		t.Fatalf("expected generic detail, got %s", string(body))
	}
}
