4b42b55928
- Add project configuration for WeChat mini program. - Create skills lock file for Taroify integration. - Set up app configuration and styles. - Implement main app component and index page with welcome message. - Add health check service to verify backend readiness. - Configure TypeScript settings and global types.
68 lines
2.1 KiB
Go
68 lines
2.1 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestHealthRemainsLiveWithoutDatabase(t *testing.T) {
|
|
handler := NewHandler(func(context.Context) error {
|
|
t.Fatal("liveness must not query the database")
|
|
return nil
|
|
})
|
|
response := httptest.NewRecorder()
|
|
handler.ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/healthz", nil))
|
|
if response.Code != http.StatusOK || response.Body.String() != "{\"status\":\"ok\"}\n" {
|
|
t.Fatalf("unexpected response: %d %s", response.Code, response.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestReadinessReflectsDatabaseState(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
err error
|
|
code int
|
|
body string
|
|
}{
|
|
{"ready", nil, http.StatusOK, "{\"status\":\"ok\"}\n"},
|
|
{"unavailable", errors.New("private database details"), http.StatusServiceUnavailable, "{\"status\":\"unavailable\"}\n"},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
called := false
|
|
handler := NewHandler(func(ctx context.Context) error {
|
|
called = true
|
|
deadline, ok := ctx.Deadline()
|
|
if !ok || time.Until(deadline) > 2*time.Second {
|
|
t.Fatal("database check must have a bounded deadline")
|
|
}
|
|
return tc.err
|
|
})
|
|
response := httptest.NewRecorder()
|
|
handler.ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/readyz", nil))
|
|
if !called || response.Code != tc.code || response.Body.String() != tc.body {
|
|
t.Fatalf("unexpected response: %d %s", response.Code, response.Body.String())
|
|
}
|
|
if !strings.HasPrefix(response.Header().Get("Content-Type"), "application/json") {
|
|
t.Fatal("health response must be JSON")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReadinessPreservesRequestCancellation(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
handler := NewHandler(func(ctx context.Context) error { return ctx.Err() })
|
|
response := httptest.NewRecorder()
|
|
request := httptest.NewRequest(http.MethodGet, "/readyz", nil).WithContext(ctx)
|
|
handler.ServeHTTP(response, request)
|
|
if response.Code != http.StatusServiceUnavailable {
|
|
t.Fatalf("got %d, want 503", response.Code)
|
|
}
|
|
}
|