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