list_transactions_controller_test.go raw

   1  package controllers
   2  
   3  import (
   4  	"context"
   5  	"encoding/json"
   6  	"testing"
   7  	"time"
   8  
   9  	"github.com/getAlby/go-nostr"
  10  	"github.com/stretchr/testify/assert"
  11  	"github.com/stretchr/testify/require"
  12  
  13  	"github.com/getAlby/hub/constants"
  14  	"github.com/getAlby/hub/db"
  15  	"github.com/getAlby/hub/nip47/models"
  16  	"github.com/getAlby/hub/tests"
  17  )
  18  
  19  func TestHandleListTransactionsEvent(t *testing.T) {
  20  	ctx := context.TODO()
  21  	svc, err := tests.CreateTestService(t)
  22  	require.NoError(t, err)
  23  	defer svc.Remove()
  24  
  25  	const nip47ListTransactionsJson = `
  26  {
  27  	"method": "list_transactions",
  28  	"params": {
  29  		"from": 0,
  30  		"until": 0,
  31  		"limit": 10,
  32  		"offset": 0,
  33  		"type": "incoming"
  34  	}
  35  }
  36  `
  37  
  38  	nip47Request := &models.Request{}
  39  	err = json.Unmarshal([]byte(nip47ListTransactionsJson), nip47Request)
  40  	assert.NoError(t, err)
  41  
  42  	app, _, err := tests.CreateApp(svc)
  43  	assert.NoError(t, err)
  44  
  45  	dbRequestEvent := &db.RequestEvent{
  46  		AppId: &app.ID,
  47  	}
  48  	err = svc.DB.Create(&dbRequestEvent).Error
  49  	assert.NoError(t, err)
  50  
  51  	for i, _ := range tests.MockLNClientTransactions {
  52  		settledAt := time.Unix(*tests.MockLNClientTransactions[i].SettledAt, 0)
  53  		err = svc.DB.Create(&db.Transaction{
  54  			Type:            tests.MockLNClientTransactions[i].Type,
  55  			PaymentRequest:  tests.MockLNClientTransactions[i].Invoice,
  56  			Description:     tests.MockLNClientTransactions[i].Description,
  57  			DescriptionHash: tests.MockLNClientTransactions[i].DescriptionHash,
  58  			Preimage:        &tests.MockLNClientTransactions[i].Preimage,
  59  			PaymentHash:     tests.MockLNClientTransactions[i].PaymentHash,
  60  			AmountMsat:      uint64(tests.MockLNClientTransactions[i].AmountMsat),
  61  			FeeMsat:         uint64(tests.MockLNClientTransactions[i].FeesPaidMsat),
  62  			SettledAt:       &settledAt,
  63  			State:           constants.TRANSACTION_STATE_SETTLED,
  64  			AppId:           &app.ID,
  65  			UpdatedAt:       time.Now().Add(time.Duration(-i) * time.Hour),
  66  		}).Error
  67  		assert.NoError(t, err)
  68  	}
  69  
  70  	var publishedResponse *models.Response
  71  
  72  	publishResponse := func(response *models.Response, tags nostr.Tags) {
  73  		publishedResponse = response
  74  	}
  75  
  76  	NewTestNip47Controller(svc).
  77  		HandleListTransactionsEvent(ctx, nip47Request, dbRequestEvent.ID, *dbRequestEvent.AppId, publishResponse)
  78  
  79  	assert.Nil(t, publishedResponse.Error)
  80  
  81  	assert.Equal(t, 2, len(publishedResponse.Result.(*listTransactionsResponse).Transactions))
  82  	transaction := publishedResponse.Result.(*listTransactionsResponse).Transactions[0]
  83  	assert.Equal(t, tests.MockLNClientTransactions[0].Type, transaction.Type)
  84  	assert.Equal(t, tests.MockLNClientTransactions[0].Invoice, transaction.Invoice)
  85  	assert.Equal(t, tests.MockLNClientTransactions[0].Description, transaction.Description)
  86  	assert.Equal(t, tests.MockLNClientTransactions[0].DescriptionHash, transaction.DescriptionHash)
  87  	assert.Equal(t, tests.MockLNClientTransactions[0].Preimage, transaction.Preimage)
  88  	assert.Equal(t, tests.MockLNClientTransactions[0].PaymentHash, transaction.PaymentHash)
  89  	assert.Equal(t, tests.MockLNClientTransactions[0].AmountMsat, transaction.Amount)
  90  	assert.Equal(t, tests.MockLNClientTransactions[0].FeesPaidMsat, transaction.FeesPaid)
  91  	assert.Equal(t, tests.MockLNClientTransactions[0].SettledAt, transaction.SettledAt)
  92  	assert.Equal(t, "settled", transaction.State)
  93  }
  94  
  95  func TestHandleListTransactionsEvent_UnpaidOutgoingOnly(t *testing.T) {
  96  	ctx := context.TODO()
  97  	svc, err := tests.CreateTestService(t)
  98  	require.NoError(t, err)
  99  	defer svc.Remove()
 100  
 101  	const nip47ListTransactionsJson = `
 102  {
 103  	"method": "list_transactions",
 104  	"params": {
 105  		"from": 0,
 106  		"until": 0,
 107  		"limit": 10,
 108  		"offset": 0,
 109  		"unpaid_outgoing": true
 110  	}
 111  }
 112  `
 113  
 114  	nip47Request := &models.Request{}
 115  	err = json.Unmarshal([]byte(nip47ListTransactionsJson), nip47Request)
 116  	assert.NoError(t, err)
 117  
 118  	app, _, err := tests.CreateApp(svc)
 119  	assert.NoError(t, err)
 120  
 121  	dbRequestEvent := &db.RequestEvent{
 122  		AppId: &app.ID,
 123  	}
 124  	err = svc.DB.Create(&dbRequestEvent).Error
 125  	assert.NoError(t, err)
 126  
 127  	err = svc.DB.Create(&db.Transaction{
 128  		Type:  constants.TRANSACTION_TYPE_INCOMING,
 129  		State: constants.TRANSACTION_STATE_PENDING,
 130  	}).Error
 131  	assert.NoError(t, err)
 132  
 133  	err = svc.DB.Create(&db.Transaction{
 134  		Type:  constants.TRANSACTION_TYPE_OUTGOING,
 135  		State: constants.TRANSACTION_STATE_PENDING,
 136  	}).Error
 137  	assert.NoError(t, err)
 138  
 139  	var publishedResponse *models.Response
 140  
 141  	publishResponse := func(response *models.Response, tags nostr.Tags) {
 142  		publishedResponse = response
 143  	}
 144  
 145  	NewTestNip47Controller(svc).
 146  		HandleListTransactionsEvent(ctx, nip47Request, dbRequestEvent.ID, *dbRequestEvent.AppId, publishResponse)
 147  
 148  	assert.Nil(t, publishedResponse.Error)
 149  
 150  	assert.Equal(t, 1, len(publishedResponse.Result.(*listTransactionsResponse).Transactions))
 151  	transaction := publishedResponse.Result.(*listTransactionsResponse).Transactions[0]
 152  	assert.Equal(t, constants.TRANSACTION_TYPE_OUTGOING, transaction.Type)
 153  }
 154  
 155  func TestHandleListTransactionsEvent_UnpaidIncomingOnly(t *testing.T) {
 156  	ctx := context.TODO()
 157  	svc, err := tests.CreateTestService(t)
 158  	require.NoError(t, err)
 159  	defer svc.Remove()
 160  
 161  	const nip47ListTransactionsJson = `
 162  {
 163  	"method": "list_transactions",
 164  	"params": {
 165  		"from": 0,
 166  		"until": 0,
 167  		"limit": 10,
 168  		"offset": 0,
 169  		"unpaid_incoming": true
 170  	}
 171  }
 172  `
 173  
 174  	nip47Request := &models.Request{}
 175  	err = json.Unmarshal([]byte(nip47ListTransactionsJson), nip47Request)
 176  	assert.NoError(t, err)
 177  
 178  	app, _, err := tests.CreateApp(svc)
 179  	assert.NoError(t, err)
 180  
 181  	dbRequestEvent := &db.RequestEvent{
 182  		AppId: &app.ID,
 183  	}
 184  	err = svc.DB.Create(&dbRequestEvent).Error
 185  	assert.NoError(t, err)
 186  
 187  	err = svc.DB.Create(&db.Transaction{
 188  		Type:  constants.TRANSACTION_TYPE_INCOMING,
 189  		State: constants.TRANSACTION_STATE_PENDING,
 190  	}).Error
 191  	assert.NoError(t, err)
 192  
 193  	err = svc.DB.Create(&db.Transaction{
 194  		Type:  constants.TRANSACTION_TYPE_OUTGOING,
 195  		State: constants.TRANSACTION_STATE_PENDING,
 196  	}).Error
 197  	assert.NoError(t, err)
 198  
 199  	var publishedResponse *models.Response
 200  
 201  	publishResponse := func(response *models.Response, tags nostr.Tags) {
 202  		publishedResponse = response
 203  	}
 204  
 205  	NewTestNip47Controller(svc).
 206  		HandleListTransactionsEvent(ctx, nip47Request, dbRequestEvent.ID, *dbRequestEvent.AppId, publishResponse)
 207  
 208  	assert.Nil(t, publishedResponse.Error)
 209  
 210  	assert.Equal(t, 1, len(publishedResponse.Result.(*listTransactionsResponse).Transactions))
 211  	transaction := publishedResponse.Result.(*listTransactionsResponse).Transactions[0]
 212  	assert.Equal(t, constants.TRANSACTION_TYPE_INCOMING, transaction.Type)
 213  }
 214  
 215  func TestHandleListTransactionsEvent_Unpaid(t *testing.T) {
 216  	ctx := context.TODO()
 217  	svc, err := tests.CreateTestService(t)
 218  	require.NoError(t, err)
 219  	defer svc.Remove()
 220  
 221  	const nip47ListTransactionsJson = `
 222  {
 223  	"method": "list_transactions",
 224  	"params": {
 225  		"from": 0,
 226  		"until": 0,
 227  		"limit": 10,
 228  		"offset": 0,
 229  		"unpaid": true
 230  	}
 231  }
 232  `
 233  
 234  	nip47Request := &models.Request{}
 235  	err = json.Unmarshal([]byte(nip47ListTransactionsJson), nip47Request)
 236  	assert.NoError(t, err)
 237  
 238  	app, _, err := tests.CreateApp(svc)
 239  	assert.NoError(t, err)
 240  
 241  	dbRequestEvent := &db.RequestEvent{
 242  		AppId: &app.ID,
 243  	}
 244  	err = svc.DB.Create(&dbRequestEvent).Error
 245  	assert.NoError(t, err)
 246  
 247  	err = svc.DB.Create(&db.Transaction{
 248  		Type:  constants.TRANSACTION_TYPE_INCOMING,
 249  		State: constants.TRANSACTION_STATE_PENDING,
 250  	}).Error
 251  	assert.NoError(t, err)
 252  
 253  	err = svc.DB.Create(&db.Transaction{
 254  		Type:  constants.TRANSACTION_TYPE_OUTGOING,
 255  		State: constants.TRANSACTION_STATE_PENDING,
 256  	}).Error
 257  	assert.NoError(t, err)
 258  
 259  	var publishedResponse *models.Response
 260  
 261  	publishResponse := func(response *models.Response, tags nostr.Tags) {
 262  		publishedResponse = response
 263  	}
 264  
 265  	NewTestNip47Controller(svc).
 266  		HandleListTransactionsEvent(ctx, nip47Request, dbRequestEvent.ID, *dbRequestEvent.AppId, publishResponse)
 267  
 268  	assert.Nil(t, publishedResponse.Error)
 269  
 270  	assert.Equal(t, 2, len(publishedResponse.Result.(*listTransactionsResponse).Transactions))
 271  }
 272  
 273  func TestHandleListTransactionsEvent_Paid(t *testing.T) {
 274  	ctx := context.TODO()
 275  	svc, err := tests.CreateTestService(t)
 276  	require.NoError(t, err)
 277  	defer svc.Remove()
 278  
 279  	const nip47ListTransactionsJson = `
 280  {
 281  	"method": "list_transactions",
 282  	"params": {
 283  		"from": 0,
 284  		"until": 0,
 285  		"limit": 10,
 286  		"offset": 0
 287  	}
 288  }
 289  `
 290  
 291  	nip47Request := &models.Request{}
 292  	err = json.Unmarshal([]byte(nip47ListTransactionsJson), nip47Request)
 293  	assert.NoError(t, err)
 294  
 295  	app, _, err := tests.CreateApp(svc)
 296  	assert.NoError(t, err)
 297  
 298  	dbRequestEvent := &db.RequestEvent{
 299  		AppId: &app.ID,
 300  	}
 301  	err = svc.DB.Create(&dbRequestEvent).Error
 302  	assert.NoError(t, err)
 303  
 304  	err = svc.DB.Create(&db.Transaction{
 305  		Type:  constants.TRANSACTION_TYPE_INCOMING,
 306  		State: constants.TRANSACTION_STATE_PENDING,
 307  	}).Error
 308  	assert.NoError(t, err)
 309  
 310  	err = svc.DB.Create(&db.Transaction{
 311  		Type:  constants.TRANSACTION_TYPE_OUTGOING,
 312  		State: constants.TRANSACTION_STATE_PENDING,
 313  	}).Error
 314  	assert.NoError(t, err)
 315  
 316  	settledPaymentHash := "dummy payment hash"
 317  
 318  	err = svc.DB.Create(&db.Transaction{
 319  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 320  		State:       constants.TRANSACTION_STATE_SETTLED,
 321  		PaymentHash: settledPaymentHash,
 322  	}).Error
 323  	assert.NoError(t, err)
 324  
 325  	var publishedResponse *models.Response
 326  
 327  	publishResponse := func(response *models.Response, tags nostr.Tags) {
 328  		publishedResponse = response
 329  	}
 330  
 331  	NewTestNip47Controller(svc).
 332  		HandleListTransactionsEvent(ctx, nip47Request, dbRequestEvent.ID, *dbRequestEvent.AppId, publishResponse)
 333  
 334  	assert.Nil(t, publishedResponse.Error)
 335  
 336  	assert.Equal(t, 1, len(publishedResponse.Result.(*listTransactionsResponse).Transactions))
 337  	transaction := publishedResponse.Result.(*listTransactionsResponse).Transactions[0]
 338  	assert.Equal(t, settledPaymentHash, transaction.PaymentHash)
 339  }
 340  
 341  // TODO: add tests for pagination args
 342