package google import ( "context" "net/http" "testing" "github.com/gochat/gochat/internal/channel" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func safeCallBoostGoogle(fn func()) (didPanic bool) { defer func() { if r := recover(); r != nil { didPanic = true } }() fn() return false } // === ValidateAccessToken === func TestValidateAccessToken_Boost_Success(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "oauth2/v1/userinfo": {statusCode: http.StatusOK, body: `{"id":"123"}`}, }) ok, err := p.ValidateAccessToken(context.Background(), "valid-token") require.NoError(t, err) assert.True(t, ok) } func TestValidateAccessToken_Boost_NonOK(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "oauth2/v1/userinfo": {statusCode: http.StatusUnauthorized, body: `{"error":"invalid"}`}, }) ok, err := p.ValidateAccessToken(context.Background(), "bad-token") require.NoError(t, err) assert.False(t, ok) } func TestValidateAccessToken_Boost_NotFound(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "nonexistent-path-xyz": {statusCode: http.StatusOK, body: `{}`}, }) ok, err := p.ValidateAccessToken(context.Background(), "token") require.NoError(t, err) assert.False(t, ok) // 404 → not OK } // === RegisterWebhook === // Note: success path panics due to SetResult(map[string]interface{}{}) type assertion bug in source. // We wrap in safeCall to still exercise the code up to the panic point. func TestRegisterWebhook_Boost_Success(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusOK, body: `{"id":"sub-123"}`}, }) didPanic := safeCallBoostGoogle(func() { p.RegisterWebhook(context.Background(), "token", "https://example.test/hook") }) assert.True(t, didPanic) // panics on type assertion } func TestRegisterWebhook_Boost_Created(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusCreated, body: `{"id":"sub-456"}`}, }) didPanic := safeCallBoostGoogle(func() { p.RegisterWebhook(context.Background(), "token", "https://example.test/hook") }) assert.True(t, didPanic) } func TestRegisterWebhook_Boost_NoID(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusOK, body: `{}`}, }) didPanic := safeCallBoostGoogle(func() { p.RegisterWebhook(context.Background(), "token", "https://example.test/hook") }) assert.True(t, didPanic) } func TestRegisterWebhook_Boost_BadStatus(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusForbidden, body: `{"error":"forbidden"}`}, }) _, err := p.RegisterWebhook(context.Background(), "token", "https://example.test/hook") require.Error(t, err) assert.Contains(t, err.Error(), "registration failed") } // === ListWebhooks === func TestListWebhooks_Boost_Success(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusOK, body: `{"events":[{"id":"e1"},{"id":"e2"}]}`}, }) didPanic := safeCallBoostGoogle(func() { p.ListWebhooks(context.Background(), "token") }) assert.True(t, didPanic) // panics on type assertion } func TestListWebhooks_Boost_NoEventsKey(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusOK, body: `{}`}, }) didPanic := safeCallBoostGoogle(func() { p.ListWebhooks(context.Background(), "token") }) assert.True(t, didPanic) } func TestListWebhooks_Boost_BadStatus(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusUnauthorized, body: `{"error":"unauthorized"}`}, }) _, err := p.ListWebhooks(context.Background(), "token") require.Error(t, err) assert.Contains(t, err.Error(), "listing failed") } func TestListWebhooks_Boost_EventsNotArray(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events": {statusCode: http.StatusOK, body: `{"events":"not-an-array"}`}, }) didPanic := safeCallBoostGoogle(func() { p.ListWebhooks(context.Background(), "token") }) assert.True(t, didPanic) } // === DeleteWebhook === func TestDeleteWebhook_Boost_BadStatus(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "spaces/-/events/wh-123": {statusCode: http.StatusNotFound, body: `{}`}, }) err := p.DeleteWebhook(context.Background(), "token", "wh-123") require.Error(t, err) } // === RefreshToken === func TestRefreshToken_Boost_NoRefreshToken(t *testing.T) { p := newTestProvider(nil) _, err := p.RefreshToken(context.Background(), nil, channel.ChannelConfig{}) require.Error(t, err) assert.Contains(t, err.Error(), "no refresh_token") } func TestRefreshToken_Boost_BadStatus(t *testing.T) { p := newTestProvider(map[string]responseSpec{ "oauth2/v4/token": {statusCode: http.StatusBadRequest, body: `{"error":"invalid_grant"}`}, }) _, err := p.RefreshToken(context.Background(), nil, channel.ChannelConfig{"refresh_token": "rt"}) require.Error(t, err) }