alby-hub/db/queries/get_budget_usage_test.go
Anshuman 1d3f9ecd41
feat: suffix balance/amount fields with explicit unit (Sat or Msat) (#2153)
* feat: add both Sat and Msat companion fields for all ambiguous balance/amount properties

* feat: add sat and msat companion fields to backend API responses

* chore: align frontend types and other missing fields

* chore: keep old formula for calculating total fee sat

* chore: remove unnecessary balance assignments in cashu and phoenix

* chore: add deprecated comment to non unit fields

* chore: rename callers and variable to specify units

* chore: remove msat fields for channel size and liquidity fields

* chore: drop msat fields from onchain channel size and liquidity responses

* chore: further changes

* chore: remove amount msat field onchain tx

* chore: remove msats from onchain balance response

* chore: remove msat fields for swaps

* chore: remove msat fields for punishment reserves

* chore: simplify rebalancing fee calculation

* chore: remove unnecessary fields

* chore: mark deprecated fields in frontend types

---------

Co-authored-by: im-adithya <imadithyavardhan@gmail.com>
2026-04-17 13:53:28 +05:30

234 lines
6.5 KiB
Go

package queries
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/getAlby/hub/constants"
"github.com/getAlby/hub/db"
"github.com/getAlby/hub/tests"
)
func TestGetBudgetUsage_IncludesPendingAndSettledOutgoing(t *testing.T) {
svc, err := tests.CreateTestService(t)
require.NoError(t, err)
defer svc.Remove()
app, _, err := tests.CreateApp(svc)
require.NoError(t, err)
appPermission := &db.AppPermission{
AppId: app.ID,
App: *app,
Scope: constants.PAY_INVOICE_SCOPE,
BudgetRenewal: constants.BUDGET_RENEWAL_NEVER,
}
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_PENDING,
AmountMsat: 50000,
FeeMsat: 1000,
FeeReserveMsat: 2000,
}).Error)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_SETTLED,
AmountMsat: 25000,
FeeMsat: 500,
FeeReserveMsat: 500,
}).Error)
budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission)
require.NoError(t, err)
assert.Equal(t, uint64(79000), budgetUsageMsat)
}
func TestGetBudgetUsage_ExcludesWrongStateTypeAndApp(t *testing.T) {
svc, err := tests.CreateTestService(t)
require.NoError(t, err)
defer svc.Remove()
app, _, err := tests.CreateApp(svc)
require.NoError(t, err)
otherApp, _, err := tests.CreateApp(svc)
require.NoError(t, err)
appPermission := &db.AppPermission{
AppId: app.ID,
App: *app,
Scope: constants.PAY_INVOICE_SCOPE,
BudgetRenewal: constants.BUDGET_RENEWAL_NEVER,
}
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_SETTLED,
AmountMsat: 20000,
FeeMsat: 1000,
FeeReserveMsat: 0,
}).Error)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_INCOMING,
State: constants.TRANSACTION_STATE_SETTLED,
AmountMsat: 90000,
FeeMsat: 0,
FeeReserveMsat: 0,
}).Error)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_FAILED,
AmountMsat: 90000,
FeeMsat: 0,
FeeReserveMsat: 0,
}).Error)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &otherApp.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_SETTLED,
AmountMsat: 90000,
FeeMsat: 0,
FeeReserveMsat: 0,
}).Error)
budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission)
require.NoError(t, err)
assert.Equal(t, uint64(21000), budgetUsageMsat)
}
func TestGetBudgetUsage_BudgetWindowDaily(t *testing.T) {
svc, err := tests.CreateTestService(t)
require.NoError(t, err)
defer svc.Remove()
app, _, err := tests.CreateApp(svc)
require.NoError(t, err)
appPermissionDaily := &db.AppPermission{
AppId: app.ID,
App: *app,
Scope: constants.PAY_INVOICE_SCOPE,
BudgetRenewal: constants.BUDGET_RENEWAL_DAILY,
}
dailyStart := getStartOfBudget(constants.BUDGET_RENEWAL_DAILY)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_SETTLED,
AmountMsat: 20000,
FeeMsat: 1000,
FeeReserveMsat: 0,
CreatedAt: dailyStart.Add(1 * time.Minute),
}).Error)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_PENDING,
AmountMsat: 20000,
FeeMsat: 0,
FeeReserveMsat: 1000,
CreatedAt: dailyStart.Add(2 * time.Hour),
}).Error)
budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermissionDaily)
require.NoError(t, err)
assert.Equal(t, uint64(42000), budgetUsageMsat)
}
func TestGetBudgetUsage_BudgetWindowWeekly(t *testing.T) {
svc, err := tests.CreateTestService(t)
require.NoError(t, err)
defer svc.Remove()
app, _, err := tests.CreateApp(svc)
require.NoError(t, err)
appPermissionWeekly := &db.AppPermission{
AppId: app.ID,
App: *app,
Scope: constants.PAY_INVOICE_SCOPE,
BudgetRenewal: constants.BUDGET_RENEWAL_WEEKLY,
}
weeklyStart := getStartOfBudget(constants.BUDGET_RENEWAL_WEEKLY)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_SETTLED,
AmountMsat: 10000,
FeeMsat: 1000,
FeeReserveMsat: 0,
CreatedAt: weeklyStart.Add(30 * time.Minute),
}).Error)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_PENDING,
AmountMsat: 7000,
FeeMsat: 0,
FeeReserveMsat: 0,
CreatedAt: weeklyStart.Add(-1 * time.Hour),
}).Error)
budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermissionWeekly)
require.NoError(t, err)
assert.Equal(t, uint64(11000), budgetUsageMsat)
}
func TestGetBudgetUsage_BudgetWindowNever(t *testing.T) {
svc, err := tests.CreateTestService(t)
require.NoError(t, err)
defer svc.Remove()
app, _, err := tests.CreateApp(svc)
require.NoError(t, err)
appPermission := &db.AppPermission{
AppId: app.ID,
App: *app,
Scope: constants.PAY_INVOICE_SCOPE,
BudgetRenewal: constants.BUDGET_RENEWAL_NEVER,
}
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_SETTLED,
AmountMsat: 5000,
FeeMsat: 1000,
FeeReserveMsat: 0,
CreatedAt: time.Now().AddDate(-2, 0, 0),
}).Error)
require.NoError(t, svc.DB.Create(&db.Transaction{
AppId: &app.ID,
Type: constants.TRANSACTION_TYPE_OUTGOING,
State: constants.TRANSACTION_STATE_PENDING,
AmountMsat: 4000,
FeeMsat: 0,
FeeReserveMsat: 1000,
CreatedAt: time.Now().AddDate(-1, 0, 0),
}).Error)
budgetUsageMsat, err := GetBudgetUsageMsat(svc.DB, appPermission)
require.NoError(t, err)
assert.Equal(t, uint64(11000), budgetUsageMsat)
}