151 lines
3.9 KiB
Go
151 lines
3.9 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"galaxy/backend/internal/geo"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"go.uber.org/zap/zaptest"
|
|
)
|
|
|
|
type fakeAdminGeoLister struct {
|
|
entries []geo.CountryCounter
|
|
err error
|
|
}
|
|
|
|
func (f *fakeAdminGeoLister) ListUserCounters(_ context.Context, _ uuid.UUID) ([]geo.CountryCounter, error) {
|
|
if f.err != nil {
|
|
return nil, f.err
|
|
}
|
|
return f.entries, nil
|
|
}
|
|
|
|
func newAdminGeoEngine(t *testing.T, fake AdminGeoLister) *gin.Engine {
|
|
t.Helper()
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
h := NewAdminGeoHandlers(fake, zaptest.NewLogger(t))
|
|
r.GET("/api/v1/admin/geo/users/:user_id/countries", h.ListUserCountries())
|
|
return r
|
|
}
|
|
|
|
func TestAdminGeoListUserCountriesSuccess(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.Date(2026, 5, 4, 12, 0, 0, 0, time.UTC)
|
|
fake := &fakeAdminGeoLister{entries: []geo.CountryCounter{
|
|
{Country: "AU", Count: 3, LastSeenAt: &now},
|
|
{Country: "DE", Count: 1, LastSeenAt: nil},
|
|
}}
|
|
r := newAdminGeoEngine(t, fake)
|
|
|
|
userID := uuid.New()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/geo/users/"+userID.String()+"/countries", nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status: want 200, got %d (%s)", rec.Code, rec.Body.String())
|
|
}
|
|
var body adminGeoListWire
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if body.UserID != userID.String() {
|
|
t.Errorf("user_id: want %s, got %s", userID, body.UserID)
|
|
}
|
|
if len(body.Items) != 2 {
|
|
t.Fatalf("items: want 2, got %d (%+v)", len(body.Items), body.Items)
|
|
}
|
|
if body.Items[0].Country != "AU" || body.Items[0].Count != 3 || body.Items[0].LastSeenAt == nil {
|
|
t.Errorf("items[0] mismatch: %+v", body.Items[0])
|
|
}
|
|
if body.Items[1].Country != "DE" || body.Items[1].Count != 1 || body.Items[1].LastSeenAt != nil {
|
|
t.Errorf("items[1] mismatch: %+v", body.Items[1])
|
|
}
|
|
}
|
|
|
|
func TestAdminGeoListUserCountriesEmpty(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
r := newAdminGeoEngine(t, &fakeAdminGeoLister{})
|
|
|
|
userID := uuid.New()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/geo/users/"+userID.String()+"/countries", nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status: want 200, got %d", rec.Code)
|
|
}
|
|
var body adminGeoListWire
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if body.Items == nil {
|
|
t.Fatal("items: want non-nil empty slice, got nil")
|
|
}
|
|
if len(body.Items) != 0 {
|
|
t.Fatalf("items: want empty, got %+v", body.Items)
|
|
}
|
|
}
|
|
|
|
func TestAdminGeoListUserCountriesInvalidUserID(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
r := newAdminGeoEngine(t, &fakeAdminGeoLister{})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/geo/users/not-a-uuid/countries", nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("status: want 400, got %d", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestAdminGeoListUserCountriesStoreError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
r := newAdminGeoEngine(t, &fakeAdminGeoLister{err: errors.New("boom")})
|
|
|
|
userID := uuid.New()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/geo/users/"+userID.String()+"/countries", nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusInternalServerError {
|
|
t.Fatalf("status: want 500, got %d", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestAdminGeoListUserCountriesNilServiceReturns501(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
h := NewAdminGeoHandlers(nil, zaptest.NewLogger(t))
|
|
r.GET("/api/v1/admin/geo/users/:user_id/countries", h.ListUserCountries())
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/geo/users/"+uuid.New().String()+"/countries", nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusNotImplemented {
|
|
t.Fatalf("status: want 501, got %d", rec.Code)
|
|
}
|
|
}
|