diff --git a/handlers/bounty.go b/handlers/bounty.go index aeba337e0..bc1210300 100644 --- a/handlers/bounty.go +++ b/handlers/bounty.go @@ -1010,7 +1010,7 @@ func (h *bountyHandler) MakeBountyPayment(w http.ResponseWriter, r *http.Request // Get Bounty Assignee assignee := h.db.GetPersonByPubkey(bounty.Assignee) - memoData := fmt.Sprintf("Payment For: %ss", bounty.Title) + memoData := utils.BuildBountyPaymentMemo(bounty.Title) memoText := url.QueryEscape(memoData) now := time.Now() diff --git a/handlers/bounty_test.go b/handlers/bounty_test.go index c9b24b987..76876e0f0 100644 --- a/handlers/bounty_test.go +++ b/handlers/bounty_test.go @@ -1436,11 +1436,11 @@ func TestMakeBountyPayment(t *testing.T) { bHandler2.getSocketConnections = mockGetSocketConnections bHandler2.userHasAccess = mockUserHasAccessTrue - memoData := fmt.Sprintf("Payment For: %ss", bounty.Title) + memoData := utils.BuildBountyPaymentMemo(bounty.Title) memoText := url.QueryEscape(memoData) expectedUrl := fmt.Sprintf("%s/payment", config.RelayUrl) - expectedBody := fmt.Sprintf(`{"amount": %d, "destination_key": "%s", "text": "memotext added for notification", "data": "%s"}`, bountyAmount, person.OwnerPubKey, memoText) + expectedBody := fmt.Sprintf(`{"amount": %d, "destination_key": "%s", "text": "%s", "data": "%s"}`, bountyAmount, person.OwnerPubKey, memoText, memoText) expectedV2Url := fmt.Sprintf("%s/pay", botURL) expectedV2Body := @@ -1485,11 +1485,11 @@ func TestMakeBountyPayment(t *testing.T) { bHandler.getSocketConnections = mockGetSocketConnections bHandler.userHasAccess = mockUserHasAccessTrue - memoData := fmt.Sprintf("Payment For: %ss", bounty.Title) + memoData := utils.BuildBountyPaymentMemo(bounty.Title) memoText := url.QueryEscape(memoData) expectedUrl := fmt.Sprintf("%s/payment", config.RelayUrl) - expectedBody := fmt.Sprintf(`{"amount": %d, "destination_key": "%s", "text": "memotext added for notification", "data": "%s"}`, bountyAmount, person.OwnerPubKey, memoText) + expectedBody := fmt.Sprintf(`{"amount": %d, "destination_key": "%s", "text": "%s", "data": "%s"}`, bountyAmount, person.OwnerPubKey, memoText, memoText) expectedV2Url := fmt.Sprintf("%s/pay", botURL) expectedV2Body := diff --git a/mocks/Database.go b/mocks/Database.go index 5c98b7f66..e9b8d53c5 100644 --- a/mocks/Database.go +++ b/mocks/Database.go @@ -5696,6 +5696,62 @@ func (_c *Database_GetBountyByCreated_Call) RunAndReturn(run func(uint) (db.NewB return _c } +// GetBountyByUnlockCode provides a mock function with given fields: code +func (_m *Database) GetBountyByUnlockCode(code string) (db.NewBounty, error) { + ret := _m.Called(code) + + if len(ret) == 0 { + panic("no return value specified for GetBountyByUnlockCode") + } + + var r0 db.NewBounty + var r1 error + if rf, ok := ret.Get(0).(func(string) (db.NewBounty, error)); ok { + return rf(code) + } + if rf, ok := ret.Get(0).(func(string) db.NewBounty); ok { + r0 = rf(code) + } else { + r0 = ret.Get(0).(db.NewBounty) + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(code) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Database_GetBountyByUnlockCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBountyByUnlockCode' +type Database_GetBountyByUnlockCode_Call struct { + *mock.Call +} + +// GetBountyByUnlockCode is a helper method to define mock.On call +// - code string +func (_e *Database_Expecter) GetBountyByUnlockCode(code interface{}) *Database_GetBountyByUnlockCode_Call { + return &Database_GetBountyByUnlockCode_Call{Call: _e.mock.On("GetBountyByUnlockCode", code)} +} + +func (_c *Database_GetBountyByUnlockCode_Call) Run(run func(code string)) *Database_GetBountyByUnlockCode_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *Database_GetBountyByUnlockCode_Call) Return(_a0 db.NewBounty, _a1 error) *Database_GetBountyByUnlockCode_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Database_GetBountyByUnlockCode_Call) RunAndReturn(run func(string) (db.NewBounty, error)) *Database_GetBountyByUnlockCode_Call { + _c.Call.Return(run) + return _c +} + // GetBountyById provides a mock function with given fields: id func (_m *Database) GetBountyById(id string) ([]db.NewBounty, error) { ret := _m.Called(id) @@ -17486,7 +17542,6 @@ func (_c *Database_GetAllBountyStakes_Call) RunAndReturn(run func() ([]db.Bounty return _c } - func (_m *Database) GetBountyStakesByBountyID(bountyID uint) ([]db.BountyStake, error) { ret := _m.Called(bountyID) @@ -17703,7 +17758,6 @@ func (_c *Database_UpdateBountyStake_Call) RunAndReturn(run func(uuid.UUID, map[ return _c } - func (_m *Database) DeleteBountyStake(stakeID uuid.UUID) error { ret := _m.Called(stakeID) @@ -17746,7 +17800,6 @@ func (_c *Database_DeleteBountyStake_Call) RunAndReturn(run func(uuid.UUID) erro return _c } - func (_m *Database) AddChatStatus(status *db.ChatWorkflowStatus) (db.ChatWorkflowStatus, error) { ret := _m.Called(status) @@ -17778,7 +17831,6 @@ type Database_AddChatStatus_Call struct { *mock.Call } - func (_e *Database_Expecter) AddChatStatus(status interface{}) *Database_AddChatStatus_Call { return &Database_AddChatStatus_Call{Call: _e.mock.On("AddChatStatus", status)} } @@ -17800,7 +17852,6 @@ func (_c *Database_AddChatStatus_Call) RunAndReturn(run func(*db.ChatWorkflowSta return _c } - func (_m *Database) UpdateChatStatus(status *db.ChatWorkflowStatus) (db.ChatWorkflowStatus, error) { ret := _m.Called(status) @@ -17832,7 +17883,6 @@ type Database_UpdateChatStatus_Call struct { *mock.Call } - func (_e *Database_Expecter) UpdateChatStatus(status interface{}) *Database_UpdateChatStatus_Call { return &Database_UpdateChatStatus_Call{Call: _e.mock.On("UpdateChatStatus", status)} } @@ -17908,7 +17958,6 @@ func (_c *Database_GetChatStatusByChatID_Call) RunAndReturn(run func(string) ([] return _c } - func (_m *Database) GetLatestChatStatusByChatID(chatID string) (db.ChatWorkflowStatus, error) { ret := _m.Called(chatID) @@ -17982,7 +18031,6 @@ type Database_DeleteChatStatus_Call struct { *mock.Call } - func (_e *Database_Expecter) DeleteChatStatus(_a0 interface{}) *Database_DeleteChatStatus_Call { return &Database_DeleteChatStatus_Call{Call: _e.mock.On("DeleteChatStatus", _a0)} } @@ -18110,7 +18158,6 @@ func (_c *Database_CreateBountyStakeProcess_Call) RunAndReturn(run func(*db.Boun return _c } - func (_m *Database) GetBountyStakeProcessByID(id uuid.UUID) (*db.BountyStakeProcess, error) { ret := _m.Called(id) @@ -18219,7 +18266,6 @@ func (_c *Database_GetBountyStakeProcessesByBountyID_Call) RunAndReturn(run func return _c } - func (_m *Database) GetBountyStakeProcessesByHunterPubKey(hunterPubKey string) ([]db.BountyStakeProcess, error) { ret := _m.Called(hunterPubKey) @@ -18328,7 +18374,6 @@ func (_c *Database_GetAllBountyStakeProcesses_Call) RunAndReturn(run func() ([]d return _c } - func (_m *Database) UpdateBountyStakeProcess(id uuid.UUID, updates map[string]interface{}) (*db.BountyStakeProcess, error) { ret := _m.Called(id, updates) @@ -18423,4 +18468,4 @@ func (_c *Database_DeleteBountyStakeProcess_Call) Return(_a0 error) *Database_De func (_c *Database_DeleteBountyStakeProcess_Call) RunAndReturn(run func(uuid.UUID) error) *Database_DeleteBountyStakeProcess_Call { _c.Call.Return(run) return _c -} \ No newline at end of file +} diff --git a/utils/utils.go b/utils/utils.go index fd6d63cad..91227e0ec 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -61,6 +61,15 @@ func BuildSearchQuery(key string, term string) (string, string) { return arg1, arg2 } +func BuildBountyPaymentMemo(title string) string { + title = strings.TrimSpace(title) + if title == "" { + return "Bounty Payment" + } + + return fmt.Sprintf("Bounty Payment: %s", title) +} + func BuildKeysendBodyData(amount uint, receiver_pubkey string, route_hint string, memo string) string { var bodyData string if route_hint != "" { diff --git a/utils/utils_test.go b/utils/utils_test.go index e384ddb1e..7a7268cb4 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -102,6 +102,37 @@ func TestBuildV2KeysendBodyData(t *testing.T) { } } +func TestBuildBountyPaymentMemo(t *testing.T) { + tests := []struct { + name string + title string + expected string + }{ + { + name: "includes bounty title", + title: "Fix the payout flow", + expected: "Bounty Payment: Fix the payout flow", + }, + { + name: "trims surrounding title whitespace", + title: " Fix the payout flow ", + expected: "Bounty Payment: Fix the payout flow", + }, + { + name: "uses fallback for empty title", + title: " ", + expected: "Bounty Payment", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, BuildBountyPaymentMemo(tt.title)) + assert.NotContains(t, BuildBountyPaymentMemo(tt.title), "%ss") + }) + } +} + func TestGetPaginationParams(t *testing.T) { tests := []struct { name string