get_budget_usage_test.go raw

   1  package queries
   2  
   3  import (
   4  	"testing"
   5  	"time"
   6  
   7  	"github.com/stretchr/testify/assert"
   8  	"github.com/stretchr/testify/require"
   9  
  10  	"github.com/getAlby/hub/constants"
  11  	"github.com/getAlby/hub/db"
  12  	"github.com/getAlby/hub/tests"
  13  )
  14  
  15  func TestGetBudgetUsage_IncludesPendingAndSettledOutgoing(t *testing.T) {
  16  	svc, err := tests.CreateTestService(t)
  17  	require.NoError(t, err)
  18  	defer svc.Remove()
  19  
  20  	app, _, err := tests.CreateApp(svc)
  21  	require.NoError(t, err)
  22  
  23  	appPermission := &db.AppPermission{
  24  		AppId:         app.ID,
  25  		App:           *app,
  26  		Scope:         constants.PAY_INVOICE_SCOPE,
  27  		BudgetRenewal: constants.BUDGET_RENEWAL_NEVER,
  28  	}
  29  
  30  	require.NoError(t, svc.DB.Create(&db.Transaction{
  31  		AppId:          &app.ID,
  32  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
  33  		State:          constants.TRANSACTION_STATE_PENDING,
  34  		AmountMsat:     50000,
  35  		FeeMsat:        1000,
  36  		FeeReserveMsat: 2000,
  37  	}).Error)
  38  
  39  	require.NoError(t, svc.DB.Create(&db.Transaction{
  40  		AppId:          &app.ID,
  41  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
  42  		State:          constants.TRANSACTION_STATE_SETTLED,
  43  		AmountMsat:     25000,
  44  		FeeMsat:        500,
  45  		FeeReserveMsat: 500,
  46  	}).Error)
  47  
  48  	budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission)
  49  	require.NoError(t, err)
  50  	assert.Equal(t, uint64(79000), budgetUsageMsat)
  51  }
  52  
  53  func TestGetBudgetUsage_ExcludesWrongStateTypeAndApp(t *testing.T) {
  54  	svc, err := tests.CreateTestService(t)
  55  	require.NoError(t, err)
  56  	defer svc.Remove()
  57  
  58  	app, _, err := tests.CreateApp(svc)
  59  	require.NoError(t, err)
  60  
  61  	otherApp, _, err := tests.CreateApp(svc)
  62  	require.NoError(t, err)
  63  
  64  	appPermission := &db.AppPermission{
  65  		AppId:         app.ID,
  66  		App:           *app,
  67  		Scope:         constants.PAY_INVOICE_SCOPE,
  68  		BudgetRenewal: constants.BUDGET_RENEWAL_NEVER,
  69  	}
  70  
  71  	require.NoError(t, svc.DB.Create(&db.Transaction{
  72  		AppId:          &app.ID,
  73  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
  74  		State:          constants.TRANSACTION_STATE_SETTLED,
  75  		AmountMsat:     20000,
  76  		FeeMsat:        1000,
  77  		FeeReserveMsat: 0,
  78  	}).Error)
  79  
  80  	require.NoError(t, svc.DB.Create(&db.Transaction{
  81  		AppId:          &app.ID,
  82  		Type:           constants.TRANSACTION_TYPE_INCOMING,
  83  		State:          constants.TRANSACTION_STATE_SETTLED,
  84  		AmountMsat:     90000,
  85  		FeeMsat:        0,
  86  		FeeReserveMsat: 0,
  87  	}).Error)
  88  
  89  	require.NoError(t, svc.DB.Create(&db.Transaction{
  90  		AppId:          &app.ID,
  91  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
  92  		State:          constants.TRANSACTION_STATE_FAILED,
  93  		AmountMsat:     90000,
  94  		FeeMsat:        0,
  95  		FeeReserveMsat: 0,
  96  	}).Error)
  97  
  98  	require.NoError(t, svc.DB.Create(&db.Transaction{
  99  		AppId:          &otherApp.ID,
 100  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 101  		State:          constants.TRANSACTION_STATE_SETTLED,
 102  		AmountMsat:     90000,
 103  		FeeMsat:        0,
 104  		FeeReserveMsat: 0,
 105  	}).Error)
 106  
 107  	budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission)
 108  	require.NoError(t, err)
 109  	assert.Equal(t, uint64(21000), budgetUsageMsat)
 110  }
 111  
 112  func TestGetBudgetUsage_BudgetWindowDaily(t *testing.T) {
 113  	svc, err := tests.CreateTestService(t)
 114  	require.NoError(t, err)
 115  	defer svc.Remove()
 116  
 117  	app, _, err := tests.CreateApp(svc)
 118  	require.NoError(t, err)
 119  
 120  	appPermissionDaily := &db.AppPermission{
 121  		AppId:         app.ID,
 122  		App:           *app,
 123  		Scope:         constants.PAY_INVOICE_SCOPE,
 124  		BudgetRenewal: constants.BUDGET_RENEWAL_DAILY,
 125  	}
 126  
 127  	dailyStart := getStartOfBudget(constants.BUDGET_RENEWAL_DAILY)
 128  
 129  	require.NoError(t, svc.DB.Create(&db.Transaction{
 130  		AppId:          &app.ID,
 131  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 132  		State:          constants.TRANSACTION_STATE_SETTLED,
 133  		AmountMsat:     20000,
 134  		FeeMsat:        1000,
 135  		FeeReserveMsat: 0,
 136  		CreatedAt:      dailyStart.Add(1 * time.Minute),
 137  	}).Error)
 138  
 139  	require.NoError(t, svc.DB.Create(&db.Transaction{
 140  		AppId:          &app.ID,
 141  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 142  		State:          constants.TRANSACTION_STATE_PENDING,
 143  		AmountMsat:     20000,
 144  		FeeMsat:        0,
 145  		FeeReserveMsat: 1000,
 146  		CreatedAt:      dailyStart.Add(2 * time.Hour),
 147  	}).Error)
 148  
 149  	budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermissionDaily)
 150  	require.NoError(t, err)
 151  	assert.Equal(t, uint64(42000), budgetUsageMsat)
 152  }
 153  
 154  func TestGetBudgetUsage_BudgetWindowWeekly(t *testing.T) {
 155  	svc, err := tests.CreateTestService(t)
 156  	require.NoError(t, err)
 157  	defer svc.Remove()
 158  
 159  	app, _, err := tests.CreateApp(svc)
 160  	require.NoError(t, err)
 161  
 162  	appPermissionWeekly := &db.AppPermission{
 163  		AppId:         app.ID,
 164  		App:           *app,
 165  		Scope:         constants.PAY_INVOICE_SCOPE,
 166  		BudgetRenewal: constants.BUDGET_RENEWAL_WEEKLY,
 167  	}
 168  
 169  	weeklyStart := getStartOfBudget(constants.BUDGET_RENEWAL_WEEKLY)
 170  
 171  	require.NoError(t, svc.DB.Create(&db.Transaction{
 172  		AppId:          &app.ID,
 173  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 174  		State:          constants.TRANSACTION_STATE_SETTLED,
 175  		AmountMsat:     10000,
 176  		FeeMsat:        1000,
 177  		FeeReserveMsat: 0,
 178  		CreatedAt:      weeklyStart.Add(30 * time.Minute),
 179  	}).Error)
 180  
 181  	require.NoError(t, svc.DB.Create(&db.Transaction{
 182  		AppId:          &app.ID,
 183  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 184  		State:          constants.TRANSACTION_STATE_PENDING,
 185  		AmountMsat:     7000,
 186  		FeeMsat:        0,
 187  		FeeReserveMsat: 0,
 188  		CreatedAt:      weeklyStart.Add(-1 * time.Hour),
 189  	}).Error)
 190  
 191  	budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermissionWeekly)
 192  	require.NoError(t, err)
 193  	assert.Equal(t, uint64(11000), budgetUsageMsat)
 194  }
 195  
 196  func TestGetBudgetUsage_BudgetWindowNever(t *testing.T) {
 197  	svc, err := tests.CreateTestService(t)
 198  	require.NoError(t, err)
 199  	defer svc.Remove()
 200  
 201  	app, _, err := tests.CreateApp(svc)
 202  	require.NoError(t, err)
 203  
 204  	appPermission := &db.AppPermission{
 205  		AppId:         app.ID,
 206  		App:           *app,
 207  		Scope:         constants.PAY_INVOICE_SCOPE,
 208  		BudgetRenewal: constants.BUDGET_RENEWAL_NEVER,
 209  	}
 210  
 211  	require.NoError(t, svc.DB.Create(&db.Transaction{
 212  		AppId:          &app.ID,
 213  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 214  		State:          constants.TRANSACTION_STATE_SETTLED,
 215  		AmountMsat:     5000,
 216  		FeeMsat:        1000,
 217  		FeeReserveMsat: 0,
 218  		CreatedAt:      time.Now().AddDate(-2, 0, 0),
 219  	}).Error)
 220  
 221  	require.NoError(t, svc.DB.Create(&db.Transaction{
 222  		AppId:          &app.ID,
 223  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 224  		State:          constants.TRANSACTION_STATE_PENDING,
 225  		AmountMsat:     4000,
 226  		FeeMsat:        0,
 227  		FeeReserveMsat: 1000,
 228  		CreatedAt:      time.Now().AddDate(-1, 0, 0),
 229  	}).Error)
 230  
 231  	budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission)
 232  	require.NoError(t, err)
 233  	assert.Equal(t, uint64(11000), budgetUsageMsat)
 234  }
 235