user_repo_redeem_adjustment_test.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package repository
  2. import (
  3. "context"
  4. "testing"
  5. "github.com/DATA-DOG/go-sqlmock"
  6. dbent "github.com/Wei-Shaw/sub2api/ent"
  7. "github.com/Wei-Shaw/sub2api/internal/service"
  8. "github.com/stretchr/testify/require"
  9. "entgo.io/ent/dialect"
  10. entsql "entgo.io/ent/dialect/sql"
  11. )
  12. func newRedeemAdjustmentRepoMock(t *testing.T) (*userRepository, sqlmock.Sqlmock) {
  13. t.Helper()
  14. db, mock, err := sqlmock.New()
  15. require.NoError(t, err)
  16. t.Cleanup(func() { _ = db.Close() })
  17. driver := entsql.OpenDB(dialect.Postgres, db)
  18. client := dbent.NewClient(dbent.Driver(driver))
  19. t.Cleanup(func() { _ = client.Close() })
  20. return newUserRepositoryWithSQL(client, db), mock
  21. }
  22. func TestApplyRedeemBalanceAdjustment_UsesAtomicFloor(t *testing.T) {
  23. repo, mock := newRedeemAdjustmentRepoMock(t)
  24. mock.ExpectExec(`UPDATE users SET balance = GREATEST\(balance \+ \$1, 0\), updated_at = NOW\(\) WHERE id = \$2 AND deleted_at IS NULL`).
  25. WithArgs(-7.0, int64(42)).
  26. WillReturnResult(sqlmock.NewResult(0, 1))
  27. require.NoError(t, repo.ApplyRedeemBalanceAdjustment(context.Background(), 42, -7))
  28. require.NoError(t, mock.ExpectationsWereMet())
  29. }
  30. func TestApplyRedeemConcurrencyAdjustment_UsesAtomicFloor(t *testing.T) {
  31. repo, mock := newRedeemAdjustmentRepoMock(t)
  32. mock.ExpectExec(`UPDATE users SET concurrency = GREATEST\(concurrency \+ \$1, 0\), updated_at = NOW\(\) WHERE id = \$2 AND deleted_at IS NULL`).
  33. WithArgs(-7, int64(42)).
  34. WillReturnResult(sqlmock.NewResult(0, 1))
  35. require.NoError(t, repo.ApplyRedeemConcurrencyAdjustment(context.Background(), 42, -7))
  36. require.NoError(t, mock.ExpectationsWereMet())
  37. }
  38. func TestApplyRedeemAdjustment_MissingUser(t *testing.T) {
  39. repo, mock := newRedeemAdjustmentRepoMock(t)
  40. mock.ExpectExec(`UPDATE users SET balance = GREATEST\(balance \+ \$1, 0\), updated_at = NOW\(\) WHERE id = \$2 AND deleted_at IS NULL`).
  41. WithArgs(-1.0, int64(404)).
  42. WillReturnResult(sqlmock.NewResult(0, 0))
  43. err := repo.ApplyRedeemBalanceAdjustment(context.Background(), 404, -1)
  44. require.ErrorIs(t, err, service.ErrUserNotFound)
  45. require.NoError(t, mock.ExpectationsWereMet())
  46. }