Add tests for OAuth functionality: - GetUserAgent - BaseURLs and ForwardBaseURLs - URLAvailability (mark/unavailable, mark/success, expired) - SessionStore (set/get/delete, expired sessions) - Generate functions (random bytes, state, session ID, verifier, challenge) - base64URLEncode - BuildAuthorizationURL - Constants Coverage: antigravity 19.6% → 27.1%
219 lines
5.3 KiB
Go
219 lines
5.3 KiB
Go
package antigravity
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestGetUserAgent(t *testing.T) {
|
|
ua := GetUserAgent()
|
|
assert.Contains(t, ua, "antigravity/")
|
|
assert.Contains(t, ua, "windows/amd64")
|
|
}
|
|
|
|
func TestBaseURLs(t *testing.T) {
|
|
assert.NotEmpty(t, BaseURLs)
|
|
assert.GreaterOrEqual(t, len(BaseURLs), 2)
|
|
assert.Contains(t, BaseURLs, antigravityProdBaseURL)
|
|
assert.Contains(t, BaseURLs, antigravityDailyBaseURL)
|
|
}
|
|
|
|
func TestForwardBaseURLs(t *testing.T) {
|
|
urls := ForwardBaseURLs()
|
|
assert.NotEmpty(t, urls)
|
|
|
|
// daily should be first if it exists
|
|
if len(urls) >= 2 {
|
|
assert.Equal(t, antigravityDailyBaseURL, urls[0])
|
|
}
|
|
}
|
|
|
|
func TestForwardBaseURLsEmpty(t *testing.T) {
|
|
// Temporarily set BaseURLs to empty
|
|
originalURLs := BaseURLs
|
|
BaseURLs = []string{}
|
|
defer func() { BaseURLs = originalURLs }()
|
|
|
|
urls := ForwardBaseURLs()
|
|
assert.Empty(t, urls)
|
|
}
|
|
|
|
func TestURLAvailability(t *testing.T) {
|
|
ua := NewURLAvailability(URLAvailabilityTTL)
|
|
|
|
t.Run("mark unavailable", func(t *testing.T) {
|
|
url := "http://example.com"
|
|
ua.MarkUnavailable(url)
|
|
assert.False(t, ua.IsAvailable(url))
|
|
})
|
|
|
|
t.Run("mark success", func(t *testing.T) {
|
|
url := "http://example.com"
|
|
ua.MarkSuccess(url)
|
|
assert.True(t, ua.IsAvailable(url))
|
|
})
|
|
|
|
t.Run("expired unavailable", func(t *testing.T) {
|
|
// Create with very short TTL
|
|
ua := NewURLAvailability(1 * time.Nanosecond)
|
|
url := "http://expired.com"
|
|
ua.MarkUnavailable(url)
|
|
time.Sleep(10 * time.Millisecond)
|
|
assert.True(t, ua.IsAvailable(url))
|
|
})
|
|
|
|
t.Run("get available URLs", func(t *testing.T) {
|
|
ua := NewURLAvailability(URLAvailabilityTTL)
|
|
baseURLs := []string{"http://a.com", "http://b.com", "http://c.com"}
|
|
|
|
// Mark one as unavailable
|
|
ua.MarkUnavailable("http://b.com")
|
|
|
|
available := ua.GetAvailableURLsWithBase(baseURLs)
|
|
assert.Contains(t, available, "http://a.com")
|
|
assert.Contains(t, available, "http://c.com")
|
|
assert.NotContains(t, available, "http://b.com")
|
|
})
|
|
|
|
t.Run("last success priority", func(t *testing.T) {
|
|
ua := NewURLAvailability(URLAvailabilityTTL)
|
|
baseURLs := []string{"http://a.com", "http://b.com"}
|
|
|
|
ua.MarkSuccess("http://b.com")
|
|
available := ua.GetAvailableURLsWithBase(baseURLs)
|
|
|
|
// b.com should be first
|
|
assert.Equal(t, "http://b.com", available[0])
|
|
})
|
|
}
|
|
|
|
func TestSessionStore(t *testing.T) {
|
|
store := NewSessionStore()
|
|
defer store.Stop()
|
|
|
|
t.Run("set and get", func(t *testing.T) {
|
|
session := &OAuthSession{
|
|
State: "state123",
|
|
CodeVerifier: "verifier456",
|
|
CreatedAt: time.Now(),
|
|
}
|
|
store.Set("session1", session)
|
|
|
|
got, ok := store.Get("session1")
|
|
assert.True(t, ok)
|
|
assert.Equal(t, "state123", got.State)
|
|
})
|
|
|
|
t.Run("get non-existent", func(t *testing.T) {
|
|
_, ok := store.Get("nonexistent")
|
|
assert.False(t, ok)
|
|
})
|
|
|
|
t.Run("expired session", func(t *testing.T) {
|
|
expiredSession := &OAuthSession{
|
|
State: "expired",
|
|
CodeVerifier: "verifier",
|
|
CreatedAt: time.Now().Add(-2 * SessionTTL),
|
|
}
|
|
store.Set("expired", expiredSession)
|
|
|
|
_, ok := store.Get("expired")
|
|
assert.False(t, ok)
|
|
})
|
|
|
|
t.Run("delete", func(t *testing.T) {
|
|
session := &OAuthSession{
|
|
State: "to_delete",
|
|
CreatedAt: time.Now(),
|
|
}
|
|
store.Set("to_delete", session)
|
|
store.Delete("to_delete")
|
|
|
|
_, ok := store.Get("to_delete")
|
|
assert.False(t, ok)
|
|
})
|
|
}
|
|
|
|
func TestGenerateFunctions(t *testing.T) {
|
|
t.Run("random bytes", func(t *testing.T) {
|
|
b1, err := GenerateRandomBytes(32)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 32, len(b1))
|
|
|
|
b2, _ := GenerateRandomBytes(32)
|
|
assert.NotEqual(t, b1, b2)
|
|
})
|
|
|
|
t.Run("state", func(t *testing.T) {
|
|
state, err := GenerateState()
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, state)
|
|
|
|
state2, _ := GenerateState()
|
|
assert.NotEqual(t, state, state2)
|
|
})
|
|
|
|
t.Run("session ID", func(t *testing.T) {
|
|
id, err := GenerateSessionID()
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, id)
|
|
assert.Equal(t, 32, len(id)) // 16 bytes * 2 hex chars
|
|
})
|
|
|
|
t.Run("code verifier", func(t *testing.T) {
|
|
verifier, err := GenerateCodeVerifier()
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, verifier)
|
|
})
|
|
|
|
t.Run("code challenge", func(t *testing.T) {
|
|
challenge := GenerateCodeChallenge("test_verifier")
|
|
assert.NotEmpty(t, challenge)
|
|
|
|
// Deterministic
|
|
challenge2 := GenerateCodeChallenge("test_verifier")
|
|
assert.Equal(t, challenge, challenge2)
|
|
})
|
|
}
|
|
|
|
func TestBase64URLEncode(t *testing.T) {
|
|
tests := []struct {
|
|
input []byte
|
|
expected string
|
|
}{
|
|
{[]byte("hello"), "aGVsbG8"},
|
|
{[]byte("test"), "dGVzdA"},
|
|
{[]byte{}, ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
result := base64URLEncode(tt.input)
|
|
assert.Equal(t, tt.expected, result)
|
|
assert.NotContains(t, result, "=")
|
|
}
|
|
}
|
|
|
|
func TestBuildAuthorizationURL(t *testing.T) {
|
|
url := BuildAuthorizationURL("test_state", "test_challenge")
|
|
|
|
assert.Contains(t, url, AuthorizeURL)
|
|
assert.Contains(t, url, "client_id="+ClientID)
|
|
assert.Contains(t, url, "state=test_state")
|
|
assert.Contains(t, url, "code_challenge=test_challenge")
|
|
assert.Contains(t, url, "code_challenge_method=S256")
|
|
assert.Contains(t, url, "redirect_uri=")
|
|
assert.Contains(t, url, "response_type=code")
|
|
}
|
|
|
|
func TestConstants(t *testing.T) {
|
|
assert.NotEmpty(t, ClientID)
|
|
assert.NotEmpty(t, RedirectURI)
|
|
assert.NotEmpty(t, AuthorizeURL)
|
|
assert.NotEmpty(t, TokenURL)
|
|
assert.NotEmpty(t, Scopes)
|
|
assert.Equal(t, 30*time.Minute, SessionTTL)
|
|
assert.Equal(t, 5*time.Minute, URLAvailabilityTTL)
|
|
}
|