cancel_hold_invoice_controller_test.go raw

   1  package controllers
   2  
   3  import (
   4  	"context"
   5  	"encoding/json"
   6  	"testing"
   7  
   8  	"github.com/getAlby/go-nostr"
   9  	"github.com/stretchr/testify/assert"
  10  	"github.com/stretchr/testify/require"
  11  
  12  	"github.com/getAlby/hub/constants"
  13  	"github.com/getAlby/hub/db"
  14  	"github.com/getAlby/hub/nip47/models"
  15  	"github.com/getAlby/hub/tests"
  16  )
  17  
  18  const nip47CancelHoldInvoiceJson = `
  19  {
  20  "method": "cancel_hold_invoice",
  21  "params": {
  22  "payment_hash": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
  23  }
  24  }
  25  `
  26  
  27  const testCancelPaymentHash = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
  28  
  29  type cancelHoldInvoiceTestSetup struct {
  30  	ctx            context.Context
  31  	svc            *tests.TestService
  32  	nip47Request   *models.Request
  33  	app            *db.App
  34  	dbRequestEvent *db.RequestEvent
  35  	publishCalled  bool
  36  	response       *models.Response
  37  }
  38  
  39  func setupCancelHoldInvoiceTest(t *testing.T, paymentHash string, initialTransactionState *string) *cancelHoldInvoiceTestSetup {
  40  	ctx := context.TODO()
  41  	svc, err := tests.CreateTestService(t)
  42  	require.NoError(t, err)
  43  	// Not using defer svc.Remove() as it might be called before the test function finishes in some cases.
  44  	// Caller should call svc.Remove()
  45  
  46  	nip47Request := &models.Request{}
  47  	requestJson := `
  48  {
  49  "method": "cancel_hold_invoice",
  50  "params": {
  51  "payment_hash": "` + paymentHash + `"
  52  }
  53  }
  54  `
  55  	err = json.Unmarshal([]byte(requestJson), nip47Request)
  56  	require.NoError(t, err)
  57  
  58  	app, _, err := tests.CreateApp(svc)
  59  	require.NoError(t, err)
  60  
  61  	appPermission := &db.AppPermission{
  62  		AppId: app.ID,
  63  		Scope: constants.MAKE_INVOICE_SCOPE,
  64  	}
  65  	err = svc.DB.Create(appPermission).Error
  66  	require.NoError(t, err)
  67  
  68  	if initialTransactionState != nil {
  69  		transaction := &db.Transaction{
  70  			AppId:       &app.ID,
  71  			PaymentHash: paymentHash,
  72  			Type:        constants.TRANSACTION_TYPE_INCOMING,
  73  			State:       *initialTransactionState,
  74  			AmountMsat:  1000,
  75  		}
  76  		err = svc.DB.Create(transaction).Error
  77  		require.NoError(t, err)
  78  	}
  79  
  80  	dbRequestEvent := &db.RequestEvent{
  81  		AppId: &app.ID,
  82  	}
  83  	err = svc.DB.Create(&dbRequestEvent).Error
  84  	require.NoError(t, err)
  85  
  86  	setup := &cancelHoldInvoiceTestSetup{
  87  		ctx:            ctx,
  88  		svc:            svc,
  89  		nip47Request:   nip47Request,
  90  		app:            app,
  91  		dbRequestEvent: dbRequestEvent,
  92  	}
  93  
  94  	return setup
  95  }
  96  
  97  func (s *cancelHoldInvoiceTestSetup) TearDown() {
  98  	s.svc.Remove()
  99  }
 100  
 101  func (s *cancelHoldInvoiceTestSetup) PublishResponse(response *models.Response, tags nostr.Tags) {
 102  	s.publishCalled = true
 103  	s.response = response
 104  }
 105  
 106  func TestHandleCancelHoldInvoiceEvent(t *testing.T) {
 107  	initialState := constants.TRANSACTION_STATE_ACCEPTED
 108  	setup := setupCancelHoldInvoiceTest(t, testCancelPaymentHash, &initialState)
 109  	defer setup.TearDown()
 110  
 111  	NewTestNip47Controller(setup.svc).
 112  		HandleCancelHoldInvoiceEvent(setup.ctx, setup.nip47Request, setup.dbRequestEvent.ID, *setup.dbRequestEvent.AppId, setup.PublishResponse)
 113  
 114  	assert.True(t, setup.publishCalled)
 115  	assert.Nil(t, setup.response.Error)
 116  	assert.Equal(t, &cancelHoldInvoiceResponse{}, setup.response.Result)
 117  
 118  	var updatedTransaction db.Transaction
 119  	err := setup.svc.DB.First(&updatedTransaction, "payment_hash = ?", testCancelPaymentHash).Error
 120  	assert.NoError(t, err)
 121  	assert.Equal(t, constants.TRANSACTION_STATE_FAILED, updatedTransaction.State)
 122  }
 123  
 124  func TestHandleCancelHoldInvoiceEvent_InvoiceNotFound(t *testing.T) {
 125  	nonExistentPaymentHash := "nonexistentpaymenthashnonexistentpaymenthashnonexistentpaymenthash"
 126  	setup := setupCancelHoldInvoiceTest(t, nonExistentPaymentHash, nil) // nil for initialTransactionState means no transaction created
 127  	defer setup.TearDown()
 128  
 129  	NewTestNip47Controller(setup.svc).
 130  		HandleCancelHoldInvoiceEvent(setup.ctx, setup.nip47Request, setup.dbRequestEvent.ID, *setup.dbRequestEvent.AppId, setup.PublishResponse)
 131  
 132  	assert.True(t, setup.publishCalled)
 133  	require.NotNil(t, setup.response.Error)
 134  	assert.Equal(t, constants.ERROR_NOT_FOUND, setup.response.Error.Code)
 135  }
 136