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"), }, } }