187 lines
6.3 KiB
Go
187 lines
6.3 KiB
Go
package publishpush
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"galaxy/notification/internal/api/intentstream"
|
|
"galaxy/notification/internal/service/acceptintent"
|
|
"galaxy/transcoder"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestEncoderEncodesSupportedPushNotificationTypes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.UnixMilli(1775121700000).UTC()
|
|
tests := []struct {
|
|
name string
|
|
notificationType intentstream.NotificationType
|
|
payloadJSON string
|
|
assertPayload func(*testing.T, []byte)
|
|
}{
|
|
{
|
|
name: "game turn ready",
|
|
notificationType: intentstream.NotificationTypeGameTurnReady,
|
|
payloadJSON: `{"game_id":"game-1","game_name":"Nebula Clash","turn_number":54}`,
|
|
assertPayload: func(t *testing.T, payload []byte) {
|
|
t.Helper()
|
|
event, err := transcoder.PayloadToGameTurnReadyEvent(payload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "game-1", event.GameID)
|
|
require.Equal(t, int64(54), event.TurnNumber)
|
|
},
|
|
},
|
|
{
|
|
name: "game finished",
|
|
notificationType: intentstream.NotificationTypeGameFinished,
|
|
payloadJSON: `{"final_turn_number":81,"game_id":"game-2","game_name":"Nova"}`,
|
|
assertPayload: func(t *testing.T, payload []byte) {
|
|
t.Helper()
|
|
event, err := transcoder.PayloadToGameFinishedEvent(payload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "game-2", event.GameID)
|
|
require.Equal(t, int64(81), event.FinalTurnNumber)
|
|
},
|
|
},
|
|
{
|
|
name: "lobby application submitted",
|
|
notificationType: intentstream.NotificationTypeLobbyApplicationSubmitted,
|
|
payloadJSON: `{"applicant_name":"Nova Pilot","applicant_user_id":"user-2","game_id":"game-3","game_name":"Orion Front"}`,
|
|
assertPayload: func(t *testing.T, payload []byte) {
|
|
t.Helper()
|
|
event, err := transcoder.PayloadToLobbyApplicationSubmittedEvent(payload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "game-3", event.GameID)
|
|
require.Equal(t, "user-2", event.ApplicantUserID)
|
|
},
|
|
},
|
|
{
|
|
name: "lobby membership approved",
|
|
notificationType: intentstream.NotificationTypeLobbyMembershipApproved,
|
|
payloadJSON: `{"game_id":"game-4","game_name":"Ares"}`,
|
|
assertPayload: func(t *testing.T, payload []byte) {
|
|
t.Helper()
|
|
event, err := transcoder.PayloadToLobbyMembershipApprovedEvent(payload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "game-4", event.GameID)
|
|
},
|
|
},
|
|
{
|
|
name: "lobby membership rejected",
|
|
notificationType: intentstream.NotificationTypeLobbyMembershipRejected,
|
|
payloadJSON: `{"game_id":"game-5","game_name":"Atlas"}`,
|
|
assertPayload: func(t *testing.T, payload []byte) {
|
|
t.Helper()
|
|
event, err := transcoder.PayloadToLobbyMembershipRejectedEvent(payload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "game-5", event.GameID)
|
|
},
|
|
},
|
|
{
|
|
name: "lobby invite created",
|
|
notificationType: intentstream.NotificationTypeLobbyInviteCreated,
|
|
payloadJSON: `{"game_id":"game-6","game_name":"Vega","inviter_name":"Nova Pilot","inviter_user_id":"user-9"}`,
|
|
assertPayload: func(t *testing.T, payload []byte) {
|
|
t.Helper()
|
|
event, err := transcoder.PayloadToLobbyInviteCreatedEvent(payload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "game-6", event.GameID)
|
|
require.Equal(t, "user-9", event.InviterUserID)
|
|
},
|
|
},
|
|
{
|
|
name: "lobby invite redeemed",
|
|
notificationType: intentstream.NotificationTypeLobbyInviteRedeemed,
|
|
payloadJSON: `{"game_id":"game-7","game_name":"Lyra","invitee_name":"Skipper","invitee_user_id":"user-10"}`,
|
|
assertPayload: func(t *testing.T, payload []byte) {
|
|
t.Helper()
|
|
event, err := transcoder.PayloadToLobbyInviteRedeemedEvent(payload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "game-7", event.GameID)
|
|
require.Equal(t, "user-10", event.InviteeUserID)
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
event, err := Encoder{}.Encode(
|
|
acceptintent.NotificationRecord{
|
|
NotificationID: "1775121700000-0",
|
|
NotificationType: tt.notificationType,
|
|
Producer: tt.notificationType.ExpectedProducer(),
|
|
AudienceKind: intentstream.AudienceKindUser,
|
|
RecipientUserIDs: []string{"user-1"},
|
|
PayloadJSON: tt.payloadJSON,
|
|
IdempotencyKey: "idem-1",
|
|
RequestFingerprint: "sha256:deadbeef",
|
|
RequestID: "request-1",
|
|
TraceID: "trace-1",
|
|
OccurredAt: now,
|
|
AcceptedAt: now,
|
|
UpdatedAt: now,
|
|
},
|
|
acceptintent.NotificationRoute{
|
|
NotificationID: "1775121700000-0",
|
|
RouteID: "push:user:user-1",
|
|
Channel: intentstream.ChannelPush,
|
|
RecipientRef: "user:user-1",
|
|
Status: acceptintent.RouteStatusPending,
|
|
MaxAttempts: 3,
|
|
NextAttemptAt: now,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
},
|
|
)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "user-1", event.UserID)
|
|
require.Equal(t, string(tt.notificationType), event.EventType)
|
|
require.Equal(t, "1775121700000-0/push:user:user-1", event.EventID)
|
|
require.Equal(t, "request-1", event.RequestID)
|
|
require.Equal(t, "trace-1", event.TraceID)
|
|
require.NotEmpty(t, event.PayloadBytes)
|
|
tt.assertPayload(t, event.PayloadBytes)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEncoderRejectsInvalidStoredPayload(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.UnixMilli(1775121700000).UTC()
|
|
_, err := Encoder{}.Encode(
|
|
acceptintent.NotificationRecord{
|
|
NotificationID: "1775121700000-0",
|
|
NotificationType: intentstream.NotificationTypeGameTurnReady,
|
|
Producer: intentstream.ProducerGameMaster,
|
|
AudienceKind: intentstream.AudienceKindUser,
|
|
RecipientUserIDs: []string{"user-1"},
|
|
PayloadJSON: `{"game_id":"","game_name":"Nebula Clash","turn_number":0}`,
|
|
IdempotencyKey: "idem-1",
|
|
RequestFingerprint: "sha256:deadbeef",
|
|
OccurredAt: now,
|
|
AcceptedAt: now,
|
|
UpdatedAt: now,
|
|
},
|
|
acceptintent.NotificationRoute{
|
|
NotificationID: "1775121700000-0",
|
|
RouteID: "push:user:user-1",
|
|
Channel: intentstream.ChannelPush,
|
|
RecipientRef: "user:user-1",
|
|
Status: acceptintent.RouteStatusPending,
|
|
MaxAttempts: 3,
|
|
NextAttemptAt: now,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
},
|
|
)
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "payload_encoding_failed")
|
|
}
|