mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
312 lines
11 KiB
Go
312 lines
11 KiB
Go
package notifications
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/getAlby/go-nostr"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/getAlby/hub/constants"
|
|
"github.com/getAlby/hub/db"
|
|
"github.com/getAlby/hub/events"
|
|
"github.com/getAlby/hub/lnclient"
|
|
"github.com/getAlby/hub/nip47/permissions"
|
|
"github.com/getAlby/hub/tests"
|
|
)
|
|
|
|
type mockConsumer struct {
|
|
nip47NotificationQueue Nip47NotificationQueue
|
|
}
|
|
|
|
func NewMockConsumer(nip47NotificationQueue Nip47NotificationQueue) *mockConsumer {
|
|
return &mockConsumer{
|
|
nip47NotificationQueue: nip47NotificationQueue,
|
|
}
|
|
}
|
|
|
|
func (svc *mockConsumer) ConsumeEvent(ctx context.Context, event *events.Event, globalProperties map[string]interface{}) {
|
|
svc.nip47NotificationQueue.AddToQueue(event)
|
|
}
|
|
|
|
func doTestSendNotificationPaymentReceived(t *testing.T, svc *tests.TestService, createAppFn tests.CreateAppFn, nip47Encryption string) {
|
|
ctx := context.TODO()
|
|
|
|
app, cipher, err := createAppFn(svc, nostr.GeneratePrivateKey(), nip47Encryption)
|
|
assert.NoError(t, err)
|
|
|
|
appPermission := &db.AppPermission{
|
|
AppId: app.ID,
|
|
App: *app,
|
|
Scope: constants.NOTIFICATIONS_SCOPE,
|
|
}
|
|
err = svc.DB.Create(appPermission).Error
|
|
assert.NoError(t, err)
|
|
|
|
settledAt := time.Unix(*tests.MockLNClientTransaction.SettledAt, 0)
|
|
initialTransaction := db.Transaction{
|
|
Type: constants.TRANSACTION_TYPE_INCOMING,
|
|
PaymentRequest: tests.MockLNClientTransaction.Invoice,
|
|
Description: tests.MockLNClientTransaction.Description,
|
|
DescriptionHash: tests.MockLNClientTransaction.DescriptionHash,
|
|
Preimage: &tests.MockLNClientTransaction.Preimage,
|
|
PaymentHash: tests.MockLNClientTransaction.PaymentHash,
|
|
AmountMsat: uint64(tests.MockLNClientTransaction.AmountMsat),
|
|
FeeMsat: uint64(tests.MockLNClientTransaction.FeesPaidMsat),
|
|
SettledAt: &settledAt,
|
|
AppId: &app.ID,
|
|
State: constants.TRANSACTION_STATE_SETTLED,
|
|
}
|
|
err = svc.DB.Create(&initialTransaction).Error
|
|
assert.NoError(t, err)
|
|
|
|
nip47NotificationQueue := NewNip47NotificationQueue()
|
|
svc.EventPublisher.RegisterSubscriber(NewMockConsumer(nip47NotificationQueue))
|
|
|
|
testEvent := &events.Event{
|
|
Event: "nwc_payment_received",
|
|
Properties: &initialTransaction,
|
|
}
|
|
|
|
svc.EventPublisher.Publish(testEvent)
|
|
|
|
receivedEvent := <-nip47NotificationQueue.Channel()
|
|
assert.Equal(t, testEvent, receivedEvent)
|
|
|
|
pool := tests.NewMockSimplePool()
|
|
|
|
permissionsSvc := permissions.NewPermissionsService(svc.DB, svc.EventPublisher)
|
|
|
|
notifier := NewNip47Notifier(pool, svc.DB, svc.Cfg, svc.Keys, permissionsSvc)
|
|
notifier.ConsumeEvent(ctx, receivedEvent)
|
|
|
|
var publishedEvent *nostr.Event
|
|
if nip47Encryption == constants.ENCRYPTION_TYPE_NIP04 {
|
|
publishedEvent = pool.PublishedEvents[0]
|
|
} else {
|
|
publishedEvent = pool.PublishedEvents[1]
|
|
}
|
|
|
|
assert.NotNil(t, publishedEvent)
|
|
assert.NotEmpty(t, publishedEvent.Content)
|
|
|
|
decrypted, err := cipher.Decrypt(publishedEvent.Content)
|
|
assert.NoError(t, err)
|
|
unmarshalledResponse := Notification{
|
|
Notification: &PaymentReceivedNotification{},
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(decrypted), &unmarshalledResponse)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, PAYMENT_RECEIVED_NOTIFICATION, unmarshalledResponse.NotificationType)
|
|
|
|
transaction := (unmarshalledResponse.Notification.(*PaymentReceivedNotification))
|
|
assert.Equal(t, constants.TRANSACTION_TYPE_INCOMING, transaction.Type)
|
|
assert.Equal(t, tests.MockLNClientTransaction.Invoice, transaction.Invoice)
|
|
assert.Equal(t, tests.MockLNClientTransaction.Description, transaction.Description)
|
|
assert.Equal(t, tests.MockLNClientTransaction.DescriptionHash, transaction.DescriptionHash)
|
|
assert.Equal(t, tests.MockLNClientTransaction.Preimage, transaction.Preimage)
|
|
assert.Equal(t, tests.MockLNClientTransaction.PaymentHash, transaction.PaymentHash)
|
|
assert.Equal(t, tests.MockLNClientTransaction.AmountMsat, transaction.Amount)
|
|
assert.Equal(t, tests.MockLNClientTransaction.FeesPaidMsat, transaction.FeesPaid)
|
|
assert.Equal(t, tests.MockLNClientTransaction.SettledAt, transaction.SettledAt)
|
|
}
|
|
|
|
func TestSendNotification_Nip04_PaymentReceived(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestSendNotificationPaymentReceived(t, svc, tests.CreateAppWithPrivateKey, constants.ENCRYPTION_TYPE_NIP04)
|
|
}
|
|
|
|
func TestSendNotification_Nip44_PaymentReceived(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestSendNotificationPaymentReceived(t, svc, tests.CreateAppWithPrivateKey, constants.ENCRYPTION_TYPE_NIP44_V2)
|
|
}
|
|
|
|
func TestSendNotification_SharedWalletPubkey_Nip04_PaymentReceived(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
defer svc.Remove()
|
|
require.NoError(t, err)
|
|
|
|
doTestSendNotificationPaymentReceived(t, svc, tests.CreateAppWithSharedWalletPubkey, constants.ENCRYPTION_TYPE_NIP04)
|
|
}
|
|
|
|
func TestSendNotification_SharedWalletPubkey_Nip44_PaymentReceived(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
defer svc.Remove()
|
|
require.NoError(t, err)
|
|
|
|
doTestSendNotificationPaymentReceived(t, svc, tests.CreateAppWithSharedWalletPubkey, constants.ENCRYPTION_TYPE_NIP44_V2)
|
|
}
|
|
|
|
func doTestSendNotificationPaymentSent(t *testing.T, svc *tests.TestService, createAppFn tests.CreateAppFn, nip47Encryption string) {
|
|
ctx := context.TODO()
|
|
|
|
app, cipher, err := createAppFn(svc, nostr.GeneratePrivateKey(), nip47Encryption)
|
|
assert.NoError(t, err)
|
|
|
|
appPermission := &db.AppPermission{
|
|
AppId: app.ID,
|
|
App: *app,
|
|
Scope: constants.NOTIFICATIONS_SCOPE,
|
|
}
|
|
err = svc.DB.Create(appPermission).Error
|
|
assert.NoError(t, err)
|
|
|
|
settledAt := time.Unix(*tests.MockLNClientTransaction.SettledAt, 0)
|
|
initialTransaction := db.Transaction{
|
|
Type: constants.TRANSACTION_TYPE_OUTGOING,
|
|
PaymentRequest: tests.MockLNClientTransaction.Invoice,
|
|
Description: tests.MockLNClientTransaction.Description,
|
|
DescriptionHash: tests.MockLNClientTransaction.DescriptionHash,
|
|
Preimage: &tests.MockLNClientTransaction.Preimage,
|
|
PaymentHash: tests.MockLNClientTransaction.PaymentHash,
|
|
AmountMsat: uint64(tests.MockLNClientTransaction.AmountMsat),
|
|
FeeMsat: uint64(tests.MockLNClientTransaction.FeesPaidMsat),
|
|
SettledAt: &settledAt,
|
|
AppId: &app.ID,
|
|
}
|
|
err = svc.DB.Create(&initialTransaction).Error
|
|
assert.NoError(t, err)
|
|
|
|
nip47NotificationQueue := NewNip47NotificationQueue()
|
|
svc.EventPublisher.RegisterSubscriber(NewMockConsumer(nip47NotificationQueue))
|
|
|
|
testEvent := &events.Event{
|
|
Event: "nwc_payment_sent",
|
|
Properties: &initialTransaction,
|
|
}
|
|
|
|
svc.EventPublisher.Publish(testEvent)
|
|
|
|
receivedEvent := <-nip47NotificationQueue.Channel()
|
|
assert.Equal(t, testEvent, receivedEvent)
|
|
|
|
pool := tests.NewMockSimplePool()
|
|
|
|
permissionsSvc := permissions.NewPermissionsService(svc.DB, svc.EventPublisher)
|
|
|
|
notifier := NewNip47Notifier(pool, svc.DB, svc.Cfg, svc.Keys, permissionsSvc)
|
|
notifier.ConsumeEvent(ctx, receivedEvent)
|
|
|
|
var publishedEvent *nostr.Event
|
|
if nip47Encryption == constants.ENCRYPTION_TYPE_NIP04 {
|
|
publishedEvent = pool.PublishedEvents[0]
|
|
} else {
|
|
publishedEvent = pool.PublishedEvents[1]
|
|
}
|
|
|
|
assert.NotNil(t, publishedEvent)
|
|
assert.NotEmpty(t, publishedEvent.Content)
|
|
|
|
decrypted, err := cipher.Decrypt(publishedEvent.Content)
|
|
assert.NoError(t, err)
|
|
unmarshalledResponse := Notification{
|
|
Notification: &PaymentReceivedNotification{},
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(decrypted), &unmarshalledResponse)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, PAYMENT_SENT_NOTIFICATION, unmarshalledResponse.NotificationType)
|
|
|
|
transaction := (unmarshalledResponse.Notification.(*PaymentReceivedNotification))
|
|
assert.Equal(t, constants.TRANSACTION_TYPE_OUTGOING, transaction.Type)
|
|
assert.Equal(t, tests.MockLNClientTransaction.Invoice, transaction.Invoice)
|
|
assert.Equal(t, tests.MockLNClientTransaction.Description, transaction.Description)
|
|
assert.Equal(t, tests.MockLNClientTransaction.DescriptionHash, transaction.DescriptionHash)
|
|
assert.Equal(t, tests.MockLNClientTransaction.Preimage, transaction.Preimage)
|
|
assert.Equal(t, tests.MockLNClientTransaction.PaymentHash, transaction.PaymentHash)
|
|
assert.Equal(t, tests.MockLNClientTransaction.AmountMsat, transaction.Amount)
|
|
assert.Equal(t, tests.MockLNClientTransaction.FeesPaidMsat, transaction.FeesPaid)
|
|
assert.Equal(t, tests.MockLNClientTransaction.SettledAt, transaction.SettledAt)
|
|
}
|
|
|
|
func TestSendNotification_Nip04_PaymentSent(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestSendNotificationPaymentSent(t, svc, tests.CreateAppWithPrivateKey, constants.ENCRYPTION_TYPE_NIP04)
|
|
}
|
|
|
|
func TestSendNotification_Nip44_PaymentSent(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestSendNotificationPaymentSent(t, svc, tests.CreateAppWithPrivateKey, constants.ENCRYPTION_TYPE_NIP44_V2)
|
|
}
|
|
|
|
func TestSendNotification_SharedWalletPubkey_Nip04_PaymentSent(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestSendNotificationPaymentSent(t, svc, tests.CreateAppWithSharedWalletPubkey, constants.ENCRYPTION_TYPE_NIP04)
|
|
}
|
|
|
|
func TestSendNotification_SharedWalletPubkey_Nip44_PaymentSent(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestSendNotificationPaymentSent(t, svc, tests.CreateAppWithSharedWalletPubkey, constants.ENCRYPTION_TYPE_NIP44_V2)
|
|
}
|
|
|
|
func doTestSendNotificationNoPermission(t *testing.T, svc *tests.TestService) {
|
|
ctx := context.TODO()
|
|
|
|
svc.DB.Create(&db.Transaction{
|
|
PaymentHash: tests.MockPaymentHash,
|
|
})
|
|
|
|
nip47NotificationQueue := NewNip47NotificationQueue()
|
|
svc.EventPublisher.RegisterSubscriber(NewMockConsumer(nip47NotificationQueue))
|
|
|
|
testEvent := &events.Event{
|
|
Event: "nwc_payment_received",
|
|
Properties: &lnclient.Transaction{
|
|
PaymentHash: tests.MockPaymentHash,
|
|
},
|
|
}
|
|
|
|
svc.EventPublisher.Publish(testEvent)
|
|
|
|
receivedEvent := <-nip47NotificationQueue.Channel()
|
|
assert.Equal(t, testEvent, receivedEvent)
|
|
|
|
pool := tests.NewMockSimplePool()
|
|
|
|
permissionsSvc := permissions.NewPermissionsService(svc.DB, svc.EventPublisher)
|
|
|
|
notifier := NewNip47Notifier(pool, svc.DB, svc.Cfg, svc.Keys, permissionsSvc)
|
|
notifier.ConsumeEvent(ctx, receivedEvent)
|
|
|
|
assert.Nil(t, pool.PublishedEvents)
|
|
}
|
|
|
|
func TestSendNotification_NoPermission(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
_, _, err = tests.CreateAppWithPrivateKey(svc, nostr.GeneratePrivateKey(), constants.ENCRYPTION_TYPE_NIP44_V2)
|
|
assert.NoError(t, err)
|
|
doTestSendNotificationNoPermission(t, svc)
|
|
}
|
|
|
|
func TestSendNotification_SharedWalletPubkey_NoPermission(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
_, _, err = tests.CreateAppWithSharedWalletPubkey(svc, nostr.GeneratePrivateKey(), constants.ENCRYPTION_TYPE_NIP44_V2)
|
|
assert.NoError(t, err)
|
|
doTestSendNotificationNoPermission(t, svc)
|
|
}
|