Files
galaxy-game/lobby/internal/adapters/racenameintents/publisher_test.go
T
2026-04-28 20:39:18 +02:00

118 lines
4.1 KiB
Go

package racenameintents_test
import (
"context"
"errors"
"testing"
"time"
"galaxy/lobby/internal/adapters/mocks"
"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"
"go.uber.org/mock/gomock"
)
func captureIntents(t *testing.T) (*mocks.MockIntentPublisher, *[]notificationintent.Intent) {
t.Helper()
publisher := mocks.NewMockIntentPublisher(gomock.NewController(t))
var captured []notificationintent.Intent
publisher.EXPECT().Publish(gomock.Any(), gomock.Any()).
DoAndReturn(func(_ context.Context, intent notificationintent.Intent) (string, error) {
captured = append(captured, intent)
return "1", nil
}).AnyTimes()
return publisher, &captured
}
func TestPublisherEligibleProducesExpectedIntent(t *testing.T) {
t.Parallel()
mock, captured := captureIntents(t)
publisher, err := racenameintents.NewPublisher(racenameintents.Config{Publisher: mock})
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,
}))
require.Len(t, *captured, 1)
intent := (*captured)[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()
mock, captured := captureIntents(t)
publisher, err := racenameintents.NewPublisher(racenameintents.Config{Publisher: mock})
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,
}))
require.Len(t, *captured, 1)
intent := (*captured)[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()
mock := mocks.NewMockIntentPublisher(gomock.NewController(t))
mock.EXPECT().Publish(gomock.Any(), gomock.Any()).
Return("", errors.New("transport unavailable")).Times(1)
publisher, err := racenameintents.NewPublisher(racenameintents.Config{Publisher: mock})
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")
}