package userservice_test import ( "context" "errors" "net/http" "net/http/httptest" "testing" "time" "galaxy/lobby/internal/adapters/userservice" "galaxy/lobby/internal/ports" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestClientNewRejectsInvalidConfig(t *testing.T) { t.Parallel() _, err := userservice.NewClient(userservice.Config{}) require.Error(t, err) _, err = userservice.NewClient(userservice.Config{BaseURL: "http://x", Timeout: 0}) require.Error(t, err) } func TestGetEligibilityHappyPath(t *testing.T) { t.Parallel() body := `{ "exists": true, "user_id": "user-1", "markers": { "can_login": true, "can_create_private_game": true, "can_manage_private_game": true, "can_join_game": true, "can_update_profile": true }, "active_sanctions": [], "effective_limits": [ {"limit_code": "max_registered_race_names", "value": 6}, {"limit_code": "max_active_game_memberships", "value": 10} ] }` server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, http.MethodGet, r.Method) require.Equal(t, "/api/v1/internal/users/user-1/eligibility", r.URL.Path) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(body)) })) defer server.Close() client, err := userservice.NewClient(userservice.Config{BaseURL: server.URL, Timeout: 2 * time.Second}) require.NoError(t, err) got, err := client.GetEligibility(context.Background(), "user-1") require.NoError(t, err) assert.True(t, got.Exists) assert.True(t, got.CanLogin) assert.True(t, got.CanJoinGame) assert.True(t, got.CanCreatePrivateGame) assert.True(t, got.CanManagePrivateGame) assert.True(t, got.CanUpdateProfile) assert.False(t, got.PermanentBlocked) assert.Equal(t, 6, got.MaxRegisteredRaceNames) } func TestGetEligibilityPermanentBlockSurfaces(t *testing.T) { t.Parallel() body := `{ "exists": true, "markers": {"can_login": false, "can_join_game": false}, "active_sanctions": [{"sanction_code": "permanent_block"}], "effective_limits": [] }` server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(body)) })) defer server.Close() client, err := userservice.NewClient(userservice.Config{BaseURL: server.URL, Timeout: time.Second}) require.NoError(t, err) got, err := client.GetEligibility(context.Background(), "user-blocked") require.NoError(t, err) assert.True(t, got.Exists) assert.False(t, got.CanJoinGame) assert.True(t, got.PermanentBlocked) } func TestGetEligibilityNotFoundExistsFalse(t *testing.T) { t.Parallel() server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) })) defer server.Close() client, err := userservice.NewClient(userservice.Config{BaseURL: server.URL, Timeout: time.Second}) require.NoError(t, err) got, err := client.GetEligibility(context.Background(), "user-missing") require.NoError(t, err) assert.False(t, got.Exists) } func TestGetEligibilityUnexpectedStatusUnavailable(t *testing.T) { t.Parallel() server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer server.Close() client, err := userservice.NewClient(userservice.Config{BaseURL: server.URL, Timeout: time.Second}) require.NoError(t, err) _, err = client.GetEligibility(context.Background(), "user-1") require.Error(t, err) require.True(t, errors.Is(err, ports.ErrUserServiceUnavailable)) } func TestGetEligibilityTransportErrorUnavailable(t *testing.T) { t.Parallel() client, err := userservice.NewClient(userservice.Config{BaseURL: "http://127.0.0.1:1", Timeout: 100 * time.Millisecond}) require.NoError(t, err) _, err = client.GetEligibility(context.Background(), "user-1") require.Error(t, err) require.True(t, errors.Is(err, ports.ErrUserServiceUnavailable)) } func TestGetEligibilityMalformedBodyError(t *testing.T) { t.Parallel() server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte("not-json")) })) defer server.Close() client, err := userservice.NewClient(userservice.Config{BaseURL: server.URL, Timeout: time.Second}) require.NoError(t, err) _, err = client.GetEligibility(context.Background(), "user-1") require.Error(t, err) require.False(t, errors.Is(err, ports.ErrUserServiceUnavailable)) } func TestGetEligibilityRejectsEmptyUserID(t *testing.T) { t.Parallel() client, err := userservice.NewClient(userservice.Config{BaseURL: "http://x", Timeout: time.Second}) require.NoError(t, err) _, err = client.GetEligibility(context.Background(), " ") require.Error(t, err) }