package config import ( "testing" "backend/pkg/permission/domain/token" "github.com/stretchr/testify/assert" ) func TestTokenConfig_Validate(t *testing.T) { tests := []struct { name string config *TokenConfig wantErr bool check func(*testing.T, *TokenConfig) }{ { name: "valid config", config: &TokenConfig{ Secret: "test-secret", Expired: ExpiredConfig{ Seconds: 900, }, RefreshExpires: ExpiredConfig{ Seconds: 604800, }, Issuer: "test-issuer", MaxTokensPerUser: 10, MaxTokensPerDevice: 5, }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { assert.Equal(t, "test-secret", c.Secret) assert.Equal(t, int64(900), c.Expired.Seconds) assert.Equal(t, int64(604800), c.RefreshExpires.Seconds) }, }, { name: "missing secret", config: &TokenConfig{ Secret: "", Expired: ExpiredConfig{ Seconds: 900, }, }, wantErr: true, check: nil, }, { name: "use default expiry", config: &TokenConfig{ Secret: "test-secret", Expired: ExpiredConfig{ Seconds: 0, }, RefreshExpires: ExpiredConfig{ Seconds: 0, }, }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { assert.Equal(t, int64(token.DefaultAccessTokenExpiry), c.Expired.Seconds) assert.Equal(t, int64(token.DefaultRefreshTokenExpiry), c.RefreshExpires.Seconds) }, }, { name: "use default issuer", config: &TokenConfig{ Secret: "test-secret", Issuer: "", }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { assert.Equal(t, "playone-backend", c.Issuer) }, }, { name: "use default token limits", config: &TokenConfig{ Secret: "test-secret", MaxTokensPerUser: 0, MaxTokensPerDevice: 0, }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { assert.Equal(t, token.MaxTokensPerUser, c.MaxTokensPerUser) assert.Equal(t, token.MaxTokensPerDevice, c.MaxTokensPerDevice) }, }, { name: "negative expiry time", config: &TokenConfig{ Secret: "test-secret", Expired: ExpiredConfig{ Seconds: -100, }, }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { // Negative values should be replaced with defaults assert.Equal(t, int64(token.DefaultAccessTokenExpiry), c.Expired.Seconds) }, }, { name: "custom token limits", config: &TokenConfig{ Secret: "test-secret", MaxTokensPerUser: 20, MaxTokensPerDevice: 10, }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { assert.Equal(t, 20, c.MaxTokensPerUser) assert.Equal(t, 10, c.MaxTokensPerDevice) }, }, { name: "device tracking enabled", config: &TokenConfig{ Secret: "test-secret", EnableDeviceTracking: true, }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { assert.True(t, c.EnableDeviceTracking) }, }, { name: "device tracking disabled", config: &TokenConfig{ Secret: "test-secret", EnableDeviceTracking: false, }, wantErr: false, check: func(t *testing.T, c *TokenConfig) { assert.False(t, c.EnableDeviceTracking) }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := tt.config.Validate() if tt.wantErr { assert.Error(t, err) } else { assert.NoError(t, err) if tt.check != nil { tt.check(t, tt.config) } } }) } } func TestExpiredConfig(t *testing.T) { tests := []struct { name string seconds int64 }{ { name: "900 seconds (15 minutes)", seconds: 900, }, { name: "3600 seconds (1 hour)", seconds: 3600, }, { name: "604800 seconds (7 days)", seconds: 604800, }, { name: "zero seconds", seconds: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { config := ExpiredConfig{ Seconds: tt.seconds, } assert.Equal(t, tt.seconds, config.Seconds) }) } } func TestConfig_Struct(t *testing.T) { t.Run("full config", func(t *testing.T) { config := Config{ Token: TokenConfig{ Secret: "my-secret", Expired: ExpiredConfig{ Seconds: 900, }, RefreshExpires: ExpiredConfig{ Seconds: 604800, }, Issuer: "my-app", MaxTokensPerUser: 15, MaxTokensPerDevice: 8, EnableDeviceTracking: true, }, } assert.NotNil(t, config.Token) assert.Equal(t, "my-secret", config.Token.Secret) assert.Equal(t, int64(900), config.Token.Expired.Seconds) assert.Equal(t, int64(604800), config.Token.RefreshExpires.Seconds) assert.Equal(t, "my-app", config.Token.Issuer) assert.Equal(t, 15, config.Token.MaxTokensPerUser) assert.Equal(t, 8, config.Token.MaxTokensPerDevice) assert.True(t, config.Token.EnableDeviceTracking) }) t.Run("empty config", func(t *testing.T) { config := Config{} assert.Empty(t, config.Token.Secret) assert.Equal(t, int64(0), config.Token.Expired.Seconds) }) } func TestTokenConfig_AllDefaults(t *testing.T) { config := &TokenConfig{ Secret: "test-secret", // Only required field } err := config.Validate() assert.NoError(t, err) // Check all defaults are applied assert.Equal(t, int64(token.DefaultAccessTokenExpiry), config.Expired.Seconds) assert.Equal(t, int64(token.DefaultRefreshTokenExpiry), config.RefreshExpires.Seconds) assert.Equal(t, "playone-backend", config.Issuer) assert.Equal(t, token.MaxTokensPerUser, config.MaxTokensPerUser) assert.Equal(t, token.MaxTokensPerDevice, config.MaxTokensPerDevice) }