notification_test.go (6677B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package bundb_test 19 20 import ( 21 "context" 22 "errors" 23 "fmt" 24 "testing" 25 "time" 26 27 "github.com/stretchr/testify/suite" 28 "github.com/superseriousbusiness/gotosocial/internal/db" 29 "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 30 "github.com/superseriousbusiness/gotosocial/internal/id" 31 "github.com/superseriousbusiness/gotosocial/testrig" 32 ) 33 34 func (suite *NotificationTestSuite) spamNotifs() { 35 // spam a shit ton of notifs into the database 36 // half of them will be for zork, the other half 37 // will be for random accounts 38 notifCount := 10000 39 40 zork := suite.testAccounts["local_account_1"] 41 42 for i := 0; i < notifCount; i++ { 43 notifID := id.NewULID() 44 45 var targetAccountID string 46 if i%2 == 0 { 47 targetAccountID = zork.ID 48 } else { 49 randomAssID, err := id.NewRandomULID() 50 if err != nil { 51 panic(err) 52 } 53 targetAccountID = randomAssID 54 } 55 56 statusID, err := id.NewRandomULID() 57 if err != nil { 58 panic(err) 59 } 60 61 originAccountID, err := id.NewRandomULID() 62 if err != nil { 63 panic(err) 64 } 65 66 notif := >smodel.Notification{ 67 ID: notifID, 68 NotificationType: gtsmodel.NotificationFave, 69 CreatedAt: time.Now(), 70 TargetAccountID: targetAccountID, 71 OriginAccountID: originAccountID, 72 StatusID: statusID, 73 Read: testrig.FalseBool(), 74 } 75 76 if err := suite.db.Put(context.Background(), notif); err != nil { 77 panic(err) 78 } 79 } 80 81 fmt.Printf("\n\n\nput %d notifs in the db\n\n\n", notifCount) 82 } 83 84 type NotificationTestSuite struct { 85 BunDBStandardTestSuite 86 } 87 88 func (suite *NotificationTestSuite) TestGetAccountNotificationsWithSpam() { 89 suite.spamNotifs() 90 testAccount := suite.testAccounts["local_account_1"] 91 before := time.Now() 92 notifications, err := suite.db.GetAccountNotifications(context.Background(), testAccount.ID, id.Highest, id.Lowest, "", 20, nil) 93 suite.NoError(err) 94 timeTaken := time.Since(before) 95 fmt.Printf("\n\n\n withSpam: got %d notifications in %s\n\n\n", len(notifications), timeTaken) 96 97 suite.NotNil(notifications) 98 for _, n := range notifications { 99 suite.Equal(testAccount.ID, n.TargetAccountID) 100 } 101 } 102 103 func (suite *NotificationTestSuite) TestGetAccountNotificationsWithoutSpam() { 104 testAccount := suite.testAccounts["local_account_1"] 105 before := time.Now() 106 notifications, err := suite.db.GetAccountNotifications(context.Background(), testAccount.ID, id.Highest, id.Lowest, "", 20, nil) 107 suite.NoError(err) 108 timeTaken := time.Since(before) 109 fmt.Printf("\n\n\n withoutSpam: got %d notifications in %s\n\n\n", len(notifications), timeTaken) 110 111 suite.NotNil(notifications) 112 for _, n := range notifications { 113 suite.Equal(testAccount.ID, n.TargetAccountID) 114 } 115 } 116 117 func (suite *NotificationTestSuite) TestDeleteNotificationsWithSpam() { 118 suite.spamNotifs() 119 testAccount := suite.testAccounts["local_account_1"] 120 err := suite.db.DeleteNotifications(context.Background(), nil, testAccount.ID, "") 121 suite.NoError(err) 122 123 notifications, err := suite.db.GetAccountNotifications(context.Background(), testAccount.ID, id.Highest, id.Lowest, "", 20, nil) 124 suite.NoError(err) 125 suite.Nil(notifications) 126 suite.Empty(notifications) 127 } 128 129 func (suite *NotificationTestSuite) TestDeleteNotificationsWithTwoAccounts() { 130 suite.spamNotifs() 131 testAccount := suite.testAccounts["local_account_1"] 132 err := suite.db.DeleteNotifications(context.Background(), nil, testAccount.ID, "") 133 suite.NoError(err) 134 135 notifications, err := suite.db.GetAccountNotifications(context.Background(), testAccount.ID, id.Highest, id.Lowest, "", 20, nil) 136 suite.NoError(err) 137 suite.Nil(notifications) 138 suite.Empty(notifications) 139 140 notif := []*gtsmodel.Notification{} 141 err = suite.db.GetAll(context.Background(), ¬if) 142 suite.NoError(err) 143 suite.NotEmpty(notif) 144 } 145 146 func (suite *NotificationTestSuite) TestDeleteNotificationsOriginatingFromAccount() { 147 testAccount := suite.testAccounts["local_account_2"] 148 149 if err := suite.db.DeleteNotifications(context.Background(), nil, "", testAccount.ID); err != nil { 150 suite.FailNow(err.Error()) 151 } 152 153 notif := []*gtsmodel.Notification{} 154 if err := suite.db.GetAll(context.Background(), ¬if); err != nil && !errors.Is(err, db.ErrNoEntries) { 155 suite.FailNow(err.Error()) 156 } 157 158 for _, n := range notif { 159 if n.OriginAccountID == testAccount.ID { 160 suite.FailNowf("", "no notifications with origin account id %s should remain", testAccount.ID) 161 } 162 } 163 } 164 165 func (suite *NotificationTestSuite) TestDeleteNotificationsOriginatingFromAndTargetingAccount() { 166 originAccount := suite.testAccounts["local_account_2"] 167 targetAccount := suite.testAccounts["admin_account"] 168 169 if err := suite.db.DeleteNotifications(context.Background(), nil, targetAccount.ID, originAccount.ID); err != nil { 170 suite.FailNow(err.Error()) 171 } 172 173 notif := []*gtsmodel.Notification{} 174 if err := suite.db.GetAll(context.Background(), ¬if); err != nil && !errors.Is(err, db.ErrNoEntries) { 175 suite.FailNow(err.Error()) 176 } 177 178 for _, n := range notif { 179 if n.OriginAccountID == originAccount.ID || n.TargetAccountID == targetAccount.ID { 180 suite.FailNowf( 181 "", 182 "no notifications with origin account id %s and target account %s should remain", 183 originAccount.ID, 184 targetAccount.ID, 185 ) 186 } 187 } 188 } 189 190 func (suite *NotificationTestSuite) TestDeleteNotificationsPertainingToStatusID() { 191 testStatus := suite.testStatuses["local_account_1_status_1"] 192 193 if err := suite.db.DeleteNotificationsForStatus(context.Background(), testStatus.ID); err != nil { 194 suite.FailNow(err.Error()) 195 } 196 197 notif := []*gtsmodel.Notification{} 198 if err := suite.db.GetAll(context.Background(), ¬if); err != nil && !errors.Is(err, db.ErrNoEntries) { 199 suite.FailNow(err.Error()) 200 } 201 202 for _, n := range notif { 203 if n.StatusID == testStatus.ID { 204 suite.FailNowf("", "no notifications with status id %s should remain", testStatus.ID) 205 } 206 } 207 } 208 209 func TestNotificationTestSuite(t *testing.T) { 210 suite.Run(t, new(NotificationTestSuite)) 211 }