package racenameintents_test import ( "context" "errors" "testing" "time" "galaxy/lobby/internal/adapters/intentpubstub" "galaxy/lobby/internal/adapters/racenameintents" "galaxy/lobby/internal/domain/common" "galaxy/lobby/internal/service/capabilityevaluation" "galaxy/notificationintent" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestPublisherEligibleProducesExpectedIntent(t *testing.T) { t.Parallel() stub := intentpubstub.NewPublisher() publisher, err := racenameintents.NewPublisher(racenameintents.Config{Publisher: stub}) require.NoError(t, err) finishedAt := time.UnixMilli(1775121700000).UTC() eligibleUntil := finishedAt.Add(30 * 24 * time.Hour) require.NoError(t, publisher.PublishEligible(context.Background(), capabilityevaluation.EligibleEvent{ GameID: common.GameID("game-1"), GameName: "Nebula Clash", UserID: "user-7", RaceName: "Skylancer", EligibleUntil: eligibleUntil, FinishedAt: finishedAt, })) published := stub.Published() require.Len(t, published, 1) intent := published[0] assert.Equal(t, notificationintent.NotificationTypeLobbyRaceNameRegistrationEligible, intent.NotificationType) assert.Equal(t, notificationintent.ProducerGameLobby, intent.Producer) assert.Equal(t, notificationintent.AudienceKindUser, intent.AudienceKind) assert.Equal(t, []string{"user-7"}, intent.RecipientUserIDs) assert.Equal(t, "game-lobby:race-name-eligible:game-1:user-7", intent.IdempotencyKey) assert.Equal(t, finishedAt, intent.OccurredAt) assert.JSONEq( t, `{"game_id":"game-1","game_name":"Nebula Clash","race_name":"Skylancer","eligible_until_ms":1777713700000}`, intent.PayloadJSON, ) } func TestPublisherDeniedProducesExpectedIntent(t *testing.T) { t.Parallel() stub := intentpubstub.NewPublisher() publisher, err := racenameintents.NewPublisher(racenameintents.Config{Publisher: stub}) require.NoError(t, err) finishedAt := time.UnixMilli(1775121700000).UTC() require.NoError(t, publisher.PublishDenied(context.Background(), capabilityevaluation.DeniedEvent{ GameID: common.GameID("game-2"), GameName: "Nova", UserID: "user-9", RaceName: "Skylancer", FinishedAt: finishedAt, Reason: capabilityevaluation.ReasonCapabilityNotMet, })) published := stub.Published() require.Len(t, published, 1) intent := published[0] assert.Equal(t, notificationintent.NotificationTypeLobbyRaceNameRegistrationDenied, intent.NotificationType) assert.Equal(t, notificationintent.ProducerGameLobby, intent.Producer) assert.Equal(t, notificationintent.AudienceKindUser, intent.AudienceKind) assert.Equal(t, []string{"user-9"}, intent.RecipientUserIDs) assert.Equal(t, "game-lobby:race-name-denied:game-2:user-9", intent.IdempotencyKey) assert.Equal(t, finishedAt, intent.OccurredAt) assert.JSONEq( t, `{"game_id":"game-2","game_name":"Nova","race_name":"Skylancer","reason":"capability_not_met"}`, intent.PayloadJSON, ) } func TestPublisherSurfacesPublisherError(t *testing.T) { t.Parallel() stub := intentpubstub.NewPublisher() stub.SetError(errors.New("transport unavailable")) publisher, err := racenameintents.NewPublisher(racenameintents.Config{Publisher: stub}) require.NoError(t, err) finishedAt := time.UnixMilli(1775121700000).UTC() err = publisher.PublishEligible(context.Background(), capabilityevaluation.EligibleEvent{ GameID: common.GameID("game-1"), GameName: "Nebula Clash", UserID: "user-7", RaceName: "Skylancer", EligibleUntil: finishedAt.Add(30 * 24 * time.Hour), FinishedAt: finishedAt, }) require.Error(t, err) assert.Contains(t, err.Error(), "transport unavailable") }