package dashboard import ( "context" "database/sql" "testing" "time" "github.com/go-mysql-org/go-mysql/mysql" "github.com/shopspring/decimal" ) type walletMapperTestStore struct { users map[int64]UserCountry } func (s walletMapperTestStore) WithTx(context.Context, func(*sql.Tx) error) error { return nil } func (s walletMapperTestStore) WithDashboardLock(context.Context, time.Duration, func() error) error { return nil } func (s walletMapperTestStore) MarkEventApplied(context.Context, *sql.Tx, string, string) (bool, error) { return true, nil } func (s walletMapperTestStore) SaveCheckpoint(context.Context, mysql.Position) error { return nil } func (s walletMapperTestStore) LoadCheckpoint(context.Context) (mysql.Position, bool, error) { return mysql.Position{}, false, nil } func (s walletMapperTestStore) Cleanup(context.Context) (int64, error) { return 0, nil } func (s walletMapperTestStore) UpsertUserCountry(context.Context, *sql.Tx, UserCountry) error { return nil } func (s walletMapperTestStore) UserCountry(_ context.Context, userID int64) (UserCountry, bool, error) { user, ok := s.users[userID] return user, ok, nil } func (s walletMapperTestStore) ResolveWalletGame(context.Context, string, string, string) (string, string, string, error) { return "TEST", "1", "Test", nil } func (s walletMapperTestStore) ApplyDailyContribution(context.Context, *sql.Tx, Contribution, string) error { return nil } func (s walletMapperTestStore) ApplyPeriodContribution(context.Context, *sql.Tx, Contribution, string) error { return nil } func (s walletMapperTestStore) ApplyGamePeriodContribution(context.Context, *sql.Tx, Contribution, string) error { return nil } func (s walletMapperTestStore) ApplyContributionBatch(context.Context, *sql.Tx, []Contribution, string, []string) error { return nil } func TestWalletLuckyGiftIsNotMappedAsGiftConsume(t *testing.T) { mapper := NewMapper(walletMapperTestStore{users: map[int64]UserCountry{ 1001: {UserID: 1001, SysOrigin: "LIKEI", Country: Country{Code: "BD", Name: "Bangladesh"}}, }}, []string{"LIKEI"}, "UNKNOWN", 0) row := Row{ "id": int64(11), "user_id": int64(1001), "sys_origin": "LIKEI", "event_type": "LUCKY_GIFT", "type": int64(1), "penny_amount": decimal.NewFromInt(10000), "create_time": time.Now().UnixMilli(), } contributions, err := mapper.Map(context.Background(), "likei_wallet", "wallet_gold_asset_record_1", "insert", row) if err != nil { t.Fatal(err) } if len(contributions) != 0 { t.Fatalf("expected wallet LUCKY_GIFT to be ignored, got %#v", contributions) } } func TestWalletGiveGiftIsNotMappedAsGiftConsume(t *testing.T) { mapper := NewMapper(walletMapperTestStore{users: map[int64]UserCountry{ 1001: {UserID: 1001, SysOrigin: "LIKEI", Country: Country{Code: "BD", Name: "Bangladesh"}}, }}, []string{"LIKEI"}, "UNKNOWN", 0) row := Row{ "id": int64(12), "user_id": int64(1001), "sys_origin": "LIKEI", "event_type": "GIVE_GIFT_V3", "type": int64(1), "penny_amount": decimal.NewFromInt(10000), "create_time": time.Now().UnixMilli(), } contributions, err := mapper.Map(context.Background(), "likei_wallet", "wallet_gold_asset_record_1", "insert", row) if err != nil { t.Fatal(err) } if len(contributions) != 0 { t.Fatalf("expected wallet GIVE_GIFT to be ignored, got %#v", contributions) } } func TestUserCreateTimeDisplayOffsetIsApplied(t *testing.T) { mapper := NewMapper(walletMapperTestStore{}, []string{"LIKEI"}, "UNKNOWN", 8*time.Hour) createdAt := time.Date(2026, 5, 26, 16, 2, 51, 0, time.UTC) contributions, err := mapper.Map(context.Background(), "likei", "user_base_info", "insert", Row{ "id": int64(2059304265087774722), "origin_sys": "LIKEI", "is_del": int64(0), "country_code": "PH", "country_name": "Philippines", "create_time": createdAt, }) if err != nil { t.Fatal(err) } if len(contributions) != 1 { t.Fatalf("expected one user contribution, got %d", len(contributions)) } expected := createdAt.Add(8 * time.Hour) if !contributions[0].EventTime.Equal(expected) { t.Fatalf("expected event time %s, got %s", expected, contributions[0].EventTime) } if contributions[0].CountryNewUser != 1 { t.Fatalf("expected country new user contribution, got %d", contributions[0].CountryNewUser) } }