Files
galaxy-game/authsession/internal/ports/ports_test.go
T
2026-04-08 16:23:07 +02:00

372 lines
9.1 KiB
Go

package ports
import (
"github.com/stretchr/testify/require"
"testing"
"time"
"galaxy/authsession/internal/domain/challenge"
"galaxy/authsession/internal/domain/common"
"galaxy/authsession/internal/domain/devicesession"
"galaxy/authsession/internal/domain/userresolution"
)
func TestRevokeSessionOutcomeIsKnown(t *testing.T) {
t.Parallel()
tests := []struct {
name string
value RevokeSessionOutcome
want bool
}{
{name: "revoked", value: RevokeSessionOutcomeRevoked, want: true},
{name: "already revoked", value: RevokeSessionOutcomeAlreadyRevoked, want: true},
{name: "unknown", value: RevokeSessionOutcome("unknown"), want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.value.IsKnown(); got != tt.want {
require.Failf(t, "test failed", "IsKnown() = %v, want %v", got, tt.want)
}
})
}
}
func TestRevokeUserSessionsOutcomeIsKnown(t *testing.T) {
t.Parallel()
tests := []struct {
name string
value RevokeUserSessionsOutcome
want bool
}{
{name: "revoked", value: RevokeUserSessionsOutcomeRevoked, want: true},
{name: "no active sessions", value: RevokeUserSessionsOutcomeNoActiveSessions, want: true},
{name: "unknown", value: RevokeUserSessionsOutcome("unknown"), want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.value.IsKnown(); got != tt.want {
require.Failf(t, "test failed", "IsKnown() = %v, want %v", got, tt.want)
}
})
}
}
func TestEnsureUserOutcomeIsKnown(t *testing.T) {
t.Parallel()
tests := []struct {
name string
value EnsureUserOutcome
want bool
}{
{name: "existing", value: EnsureUserOutcomeExisting, want: true},
{name: "created", value: EnsureUserOutcomeCreated, want: true},
{name: "blocked", value: EnsureUserOutcomeBlocked, want: true},
{name: "unknown", value: EnsureUserOutcome("unknown"), want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.value.IsKnown(); got != tt.want {
require.Failf(t, "test failed", "IsKnown() = %v, want %v", got, tt.want)
}
})
}
}
func TestBlockUserOutcomeIsKnown(t *testing.T) {
t.Parallel()
tests := []struct {
name string
value BlockUserOutcome
want bool
}{
{name: "blocked", value: BlockUserOutcomeBlocked, want: true},
{name: "already blocked", value: BlockUserOutcomeAlreadyBlocked, want: true},
{name: "unknown", value: BlockUserOutcome("unknown"), want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.value.IsKnown(); got != tt.want {
require.Failf(t, "test failed", "IsKnown() = %v, want %v", got, tt.want)
}
})
}
}
func TestSendLoginCodeOutcomeIsKnown(t *testing.T) {
t.Parallel()
tests := []struct {
name string
value SendLoginCodeOutcome
want bool
}{
{name: "sent", value: SendLoginCodeOutcomeSent, want: true},
{name: "suppressed", value: SendLoginCodeOutcomeSuppressed, want: true},
{name: "unknown", value: SendLoginCodeOutcome("unknown"), want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.value.IsKnown(); got != tt.want {
require.Failf(t, "test failed", "IsKnown() = %v, want %v", got, tt.want)
}
})
}
}
func TestSessionLimitConfigValidate(t *testing.T) {
t.Parallel()
positive := 3
zero := 0
tests := []struct {
name string
value SessionLimitConfig
wantErr bool
}{
{name: "absent", value: SessionLimitConfig{}},
{name: "positive", value: SessionLimitConfig{ActiveSessionLimit: &positive}},
{name: "zero", value: SessionLimitConfig{ActiveSessionLimit: &zero}, wantErr: true},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := tt.value.Validate()
if tt.wantErr && err == nil {
require.FailNow(t, "Validate() returned nil error")
}
if !tt.wantErr && err != nil {
require.Failf(t, "test failed", "Validate() returned error: %v", err)
}
})
}
}
func TestRevokeSessionInputValidate(t *testing.T) {
t.Parallel()
input := RevokeSessionInput{
DeviceSessionID: common.DeviceSessionID("device-session-1"),
Revocation: devicesession.Revocation{
At: time.Unix(10, 0).UTC(),
ReasonCode: devicesession.RevokeReasonLogoutAll,
ActorType: common.RevokeActorType("system"),
},
}
if err := input.Validate(); err != nil {
require.Failf(t, "test failed", "Validate() returned error: %v", err)
}
}
func TestRevokeSessionResultValidate(t *testing.T) {
t.Parallel()
result := RevokeSessionResult{
Outcome: RevokeSessionOutcomeRevoked,
Session: revokedSessionFixture(),
}
if err := result.Validate(); err != nil {
require.Failf(t, "test failed", "Validate() returned error: %v", err)
}
}
func TestRevokeUserSessionsResultValidate(t *testing.T) {
t.Parallel()
result := RevokeUserSessionsResult{
Outcome: RevokeUserSessionsOutcomeRevoked,
UserID: common.UserID("user-1"),
Sessions: []devicesession.Session{
revokedSessionFixture(),
},
}
if err := result.Validate(); err != nil {
require.Failf(t, "test failed", "Validate() returned error: %v", err)
}
}
func TestEnsureUserResultValidate(t *testing.T) {
t.Parallel()
tests := []struct {
name string
value EnsureUserResult
wantErr bool
}{
{
name: "existing",
value: EnsureUserResult{
Outcome: EnsureUserOutcomeExisting,
UserID: common.UserID("user-1"),
},
},
{
name: "created",
value: EnsureUserResult{
Outcome: EnsureUserOutcomeCreated,
UserID: common.UserID("user-2"),
},
},
{
name: "blocked",
value: EnsureUserResult{
Outcome: EnsureUserOutcomeBlocked,
BlockReasonCode: userresolution.BlockReasonCode("policy_block"),
},
},
{
name: "blocked with user id",
value: EnsureUserResult{
Outcome: EnsureUserOutcomeBlocked,
UserID: common.UserID("user-1"),
BlockReasonCode: userresolution.BlockReasonCode("policy_block"),
},
wantErr: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := tt.value.Validate()
if tt.wantErr && err == nil {
require.FailNow(t, "Validate() returned nil error")
}
if !tt.wantErr && err != nil {
require.Failf(t, "test failed", "Validate() returned error: %v", err)
}
})
}
}
func TestBlockUserInputsAndResultValidate(t *testing.T) {
t.Parallel()
byID := BlockUserByIDInput{
UserID: common.UserID("user-1"),
ReasonCode: userresolution.BlockReasonCode("policy_block"),
}
if err := byID.Validate(); err != nil {
require.Failf(t, "test failed", "BlockUserByIDInput.Validate() returned error: %v", err)
}
byEmail := BlockUserByEmailInput{
Email: common.Email("pilot@example.com"),
ReasonCode: userresolution.BlockReasonCode("policy_block"),
}
if err := byEmail.Validate(); err != nil {
require.Failf(t, "test failed", "BlockUserByEmailInput.Validate() returned error: %v", err)
}
result := BlockUserResult{
Outcome: BlockUserOutcomeBlocked,
UserID: common.UserID("user-1"),
}
if err := result.Validate(); err != nil {
require.Failf(t, "test failed", "BlockUserResult.Validate() returned error: %v", err)
}
}
func TestSendLoginCodeInputAndResultValidate(t *testing.T) {
t.Parallel()
input := SendLoginCodeInput{
Email: common.Email("pilot@example.com"),
Code: "654321",
}
if err := input.Validate(); err != nil {
require.Failf(t, "test failed", "SendLoginCodeInput.Validate() returned error: %v", err)
}
result := SendLoginCodeResult{Outcome: SendLoginCodeOutcomeSent}
if err := result.Validate(); err != nil {
require.Failf(t, "test failed", "SendLoginCodeResult.Validate() returned error: %v", err)
}
}
func TestValidateComparableChallenges(t *testing.T) {
t.Parallel()
previous := challengeFixture()
next := challengeFixture()
next.Status = challenge.StatusSent
next.DeliveryState = challenge.DeliverySent
if err := ValidateComparableChallenges(previous, next); err != nil {
require.Failf(t, "test failed", "ValidateComparableChallenges() returned error: %v", err)
}
}
func challengeFixture() challenge.Challenge {
timestamp := time.Unix(10, 0).UTC()
return challenge.Challenge{
ID: common.ChallengeID("challenge-1"),
Email: common.Email("pilot@example.com"),
CodeHash: []byte("hash"),
Status: challenge.StatusPendingSend,
DeliveryState: challenge.DeliveryPending,
CreatedAt: timestamp,
ExpiresAt: timestamp.Add(5 * time.Minute),
}
}
func revokedSessionFixture() devicesession.Session {
timestamp := time.Unix(10, 0).UTC()
key, err := common.NewClientPublicKey(make([]byte, 32))
if err != nil {
panic(err)
}
return devicesession.Session{
ID: common.DeviceSessionID("device-session-1"),
UserID: common.UserID("user-1"),
ClientPublicKey: key,
Status: devicesession.StatusRevoked,
CreatedAt: timestamp.Add(-time.Minute),
Revocation: &devicesession.Revocation{
At: timestamp,
ReasonCode: devicesession.RevokeReasonLogoutAll,
ActorType: common.RevokeActorType("system"),
},
}
}