package processor import ( "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "apskel-pos-be/internal/constants" "apskel-pos-be/internal/models" "apskel-pos-be/internal/repository" ) func TestAnalyticsRange(t *testing.T) { start, end, err := analyticsRange(models.EnakGameAnalyticsQuery{From: "2026-10-01", To: "2026-10-31"}) require.NoError(t, err) assert.Equal(t, time.Date(2026, 9, 30, 17, 0, 0, 0, time.UTC), start.UTC(), "midnight in Jakarta") assert.Equal(t, time.Date(2026, 10, 31, 17, 0, 0, 0, time.UTC), end.UTC(), "the last day included") _, _, err = analyticsRange(models.EnakGameAnalyticsQuery{From: "2026-01-01", To: "2027-01-01"}) require.NoError(t, err, "366 days") for name, q := range map[string]models.EnakGameAnalyticsQuery{ "no from": {To: "2026-10-31"}, "no to": {From: "2026-10-01"}, "backwards": {From: "2026-10-31", To: "2026-10-01"}, "too long": {From: "2026-01-01", To: "2027-01-02"}, "not dates": {From: "1 Oct", To: "31 Oct"}, } { _, _, err := analyticsRange(q) assert.ErrorIs(t, err, ErrEnakGameRejected, name) } } func TestGameStats(t *testing.T) { s := gameStats(repository.GameSessionStats{Plays: 3, Completed: 2, CoinIssued: 25, EntryCost: 6, CoinRefunded: 2}) assert.EqualValues(t, 12.5, s.AverageReward) assert.InDelta(t, 8.33, s.RewardPerPlay, 1e-9) assert.EqualValues(t, 6, s.EntryCostPaid) s = gameStats(repository.GameSessionStats{}) assert.Zero(t, s.AverageReward, "no division by zero") assert.Zero(t, s.RewardPerPlay) assert.Nil(t, s.AverageScore) } // EG-903: the economy's headline numbers from the ledger's totals. func TestEconomy(t *testing.T) { coin, point := constants.WalletCurrencyCoin, constants.WalletCurrencyPoint flows := []repository.WalletFlow{ {Currency: coin, Type: constants.WalletTxTypeGameReward, Credit: 500, Transactions: 40}, {Currency: coin, Type: constants.WalletTxTypeMigration, Credit: 100, Transactions: 2}, {Currency: coin, Type: constants.WalletTxTypeAdjustment, Credit: 30, Debit: 10, Transactions: 2}, {Currency: coin, Type: constants.WalletTxTypeGameSpend, Debit: 200, Transactions: 50}, {Currency: coin, Type: constants.WalletTxTypeGameSpendRefund, Credit: 8, Transactions: 2}, {Currency: coin, Type: constants.WalletTxTypeExchangeOut, Debit: 120, Transactions: 3}, {Currency: coin, Type: constants.WalletTxTypeExpire, Debit: 15, Transactions: 1}, {Currency: coin, Type: constants.WalletTxTypeTransferOut, Debit: 50, Transactions: 1}, {Currency: coin, Type: constants.WalletTxTypeTransferIn, Credit: 50, Transactions: 1}, {Currency: point, Type: constants.WalletTxTypeEarn, Credit: 1_000, Transactions: 9}, {Currency: point, Type: constants.WalletTxTypeEarnReversal, Debit: 100, Transactions: 1}, {Currency: point, Type: constants.WalletTxTypeExchangeIn, Credit: 120, Transactions: 3}, {Currency: point, Type: constants.WalletTxTypeRewardRedeem, Debit: 700, Transactions: 7}, {Currency: point, Type: constants.WalletTxTypeRewardRedeemRefund, Credit: 100, Transactions: 1}, {Currency: point, Type: constants.WalletTxTypeExpire, Debit: 40, Transactions: 2}, } e := economy(flows, map[string]int64{coin: 900, point: 2_500}) assert.Equal(t, models.EnakGameCoinFlows{ Generated: 630, GameRewards: 500, SpentOnGames: 192, Exchanged: 120, Spent: 312, Expired: 15, Outstanding: 900, }, e.Coin, "transfers count nowhere") assert.Equal(t, models.EnakGamePointFlows{Earned: 900, Exchanged: 120, Redeemed: 600, Expired: 40, Balance: 2_500}, e.Point) assert.Len(t, e.ByType, len(flows)) empty := economy(nil, map[string]int64{}) assert.Zero(t, empty.Coin) assert.NotNil(t, empty.ByType, "an empty list, not null") }