diff --git a/server/server_webpush_test.go b/server/server_webpush_test.go index 03101578..7bea9460 100644 --- a/server/server_webpush_test.go +++ b/server/server_webpush_test.go @@ -19,7 +19,6 @@ import ( "github.com/stretchr/testify/require" "heckel.io/ntfy/v2/user" "heckel.io/ntfy/v2/util" - wpush "heckel.io/ntfy/v2/webpush" ) const ( @@ -241,7 +240,7 @@ func TestServer_WebPush_Expiry(t *testing.T) { addSubscription(t, s, endpoint, "test-topic") requireSubscriptionCount(t, s, "test-topic", 1) - require.Nil(t, s.webPush.(*wpush.SQLiteStore).SetSubscriptionUpdatedAt(endpoint, time.Now().Add(-55*24*time.Hour).Unix())) + require.Nil(t, s.webPush.SetSubscriptionUpdatedAt(endpoint, time.Now().Add(-55*24*time.Hour).Unix())) s.pruneAndNotifyWebPushSubscriptions() requireSubscriptionCount(t, s, "test-topic", 1) @@ -250,7 +249,7 @@ func TestServer_WebPush_Expiry(t *testing.T) { return received.Load() }) - require.Nil(t, s.webPush.(*wpush.SQLiteStore).SetSubscriptionUpdatedAt(endpoint, time.Now().Add(-60*24*time.Hour).Unix())) + require.Nil(t, s.webPush.SetSubscriptionUpdatedAt(endpoint, time.Now().Add(-60*24*time.Hour).Unix())) s.pruneAndNotifyWebPushSubscriptions() waitFor(t, func() bool { diff --git a/webpush/postgres_test.go b/webpush/postgres_test.go deleted file mode 100644 index 77334839..00000000 --- a/webpush/postgres_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package webpush_test - -import ( - "database/sql" - "fmt" - "net/url" - "os" - "testing" - - "github.com/stretchr/testify/require" - "heckel.io/ntfy/v2/util" - "heckel.io/ntfy/v2/webpush" -) - -func newTestPostgresStore(t *testing.T) *webpush.PostgresStore { - dsn := os.Getenv("NTFY_TEST_DATABASE_URL") - if dsn == "" { - t.Skip("NTFY_TEST_DATABASE_URL not set, skipping PostgreSQL tests") - } - // Create a unique schema for this test - schema := fmt.Sprintf("test_%s", util.RandomString(10)) - setupDB, err := sql.Open("pgx", dsn) - require.Nil(t, err) - _, err = setupDB.Exec(fmt.Sprintf("CREATE SCHEMA %s", schema)) - require.Nil(t, err) - require.Nil(t, setupDB.Close()) - // Open store with search_path set to the new schema - u, err := url.Parse(dsn) - require.Nil(t, err) - q := u.Query() - q.Set("search_path", schema) - u.RawQuery = q.Encode() - store, err := webpush.NewPostgresStore(u.String()) - require.Nil(t, err) - t.Cleanup(func() { - store.Close() - cleanDB, err := sql.Open("pgx", dsn) - if err == nil { - cleanDB.Exec(fmt.Sprintf("DROP SCHEMA %s CASCADE", schema)) - cleanDB.Close() - } - }) - return store -} - -func TestPostgresStore_UpsertSubscription_SubscriptionsForTopic(t *testing.T) { - testStoreUpsertSubscription_SubscriptionsForTopic(t, newTestPostgresStore(t)) -} - -func TestPostgresStore_UpsertSubscription_SubscriberIPLimitReached(t *testing.T) { - testStoreUpsertSubscription_SubscriberIPLimitReached(t, newTestPostgresStore(t)) -} - -func TestPostgresStore_UpsertSubscription_UpdateTopics(t *testing.T) { - testStoreUpsertSubscription_UpdateTopics(t, newTestPostgresStore(t)) -} - -func TestPostgresStore_RemoveSubscriptionsByEndpoint(t *testing.T) { - testStoreRemoveSubscriptionsByEndpoint(t, newTestPostgresStore(t)) -} - -func TestPostgresStore_RemoveSubscriptionsByUserID(t *testing.T) { - testStoreRemoveSubscriptionsByUserID(t, newTestPostgresStore(t)) -} - -func TestPostgresStore_RemoveSubscriptionsByUserID_Empty(t *testing.T) { - testStoreRemoveSubscriptionsByUserID_Empty(t, newTestPostgresStore(t)) -} - -func TestPostgresStore_MarkExpiryWarningSent(t *testing.T) { - store := newTestPostgresStore(t) - testStoreMarkExpiryWarningSent(t, store, store.SetSubscriptionUpdatedAt) -} - -func TestPostgresStore_SubscriptionsExpiring(t *testing.T) { - store := newTestPostgresStore(t) - testStoreSubscriptionsExpiring(t, store, store.SetSubscriptionUpdatedAt) -} - -func TestPostgresStore_RemoveExpiredSubscriptions(t *testing.T) { - store := newTestPostgresStore(t) - testStoreRemoveExpiredSubscriptions(t, store, store.SetSubscriptionUpdatedAt) -} diff --git a/webpush/sqlite_test.go b/webpush/sqlite_test.go deleted file mode 100644 index b64a93b9..00000000 --- a/webpush/sqlite_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package webpush_test - -import ( - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "heckel.io/ntfy/v2/webpush" -) - -func newTestSQLiteStore(t *testing.T) *webpush.SQLiteStore { - store, err := webpush.NewSQLiteStore(filepath.Join(t.TempDir(), "webpush.db"), "") - require.Nil(t, err) - t.Cleanup(func() { store.Close() }) - return store -} - -func TestSQLiteStore_UpsertSubscription_SubscriptionsForTopic(t *testing.T) { - testStoreUpsertSubscription_SubscriptionsForTopic(t, newTestSQLiteStore(t)) -} - -func TestSQLiteStore_UpsertSubscription_SubscriberIPLimitReached(t *testing.T) { - testStoreUpsertSubscription_SubscriberIPLimitReached(t, newTestSQLiteStore(t)) -} - -func TestSQLiteStore_UpsertSubscription_UpdateTopics(t *testing.T) { - testStoreUpsertSubscription_UpdateTopics(t, newTestSQLiteStore(t)) -} - -func TestSQLiteStore_RemoveSubscriptionsByEndpoint(t *testing.T) { - testStoreRemoveSubscriptionsByEndpoint(t, newTestSQLiteStore(t)) -} - -func TestSQLiteStore_RemoveSubscriptionsByUserID(t *testing.T) { - testStoreRemoveSubscriptionsByUserID(t, newTestSQLiteStore(t)) -} - -func TestSQLiteStore_RemoveSubscriptionsByUserID_Empty(t *testing.T) { - testStoreRemoveSubscriptionsByUserID_Empty(t, newTestSQLiteStore(t)) -} - -func TestSQLiteStore_MarkExpiryWarningSent(t *testing.T) { - store := newTestSQLiteStore(t) - testStoreMarkExpiryWarningSent(t, store, store.SetSubscriptionUpdatedAt) -} - -func TestSQLiteStore_SubscriptionsExpiring(t *testing.T) { - store := newTestSQLiteStore(t) - testStoreSubscriptionsExpiring(t, store, store.SetSubscriptionUpdatedAt) -} - -func TestSQLiteStore_RemoveExpiredSubscriptions(t *testing.T) { - store := newTestSQLiteStore(t) - testStoreRemoveExpiredSubscriptions(t, store, store.SetSubscriptionUpdatedAt) -} diff --git a/webpush/store.go b/webpush/store.go index a711b6bb..5dd94c93 100644 --- a/webpush/store.go +++ b/webpush/store.go @@ -29,6 +29,7 @@ type Store interface { RemoveSubscriptionsByEndpoint(endpoint string) error RemoveSubscriptionsByUserID(userID string) error RemoveExpiredSubscriptions(expireAfter time.Duration) error + SetSubscriptionUpdatedAt(endpoint string, updatedAt int64) error Close() error } diff --git a/webpush/postgres.go b/webpush/store_postgres.go similarity index 93% rename from webpush/postgres.go rename to webpush/store_postgres.go index 6d4a1027..1889f92f 100644 --- a/webpush/postgres.go +++ b/webpush/store_postgres.go @@ -53,7 +53,7 @@ const ( INSERT INTO webpush_subscription (id, endpoint, key_auth, key_p256dh, user_id, subscriber_ip, updated_at, warned_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (endpoint) - DO UPDATE SET key_auth = EXCLUDED.key_auth, key_p256dh = EXCLUDED.key_p256dh, user_id = EXCLUDED.user_id, subscriber_ip = EXCLUDED.subscriber_ip, updated_at = EXCLUDED.updated_at, warned_at = EXCLUDED.warned_at + DO UPDATE SET key_auth = excluded.key_auth, key_p256dh = excluded.key_p256dh, user_id = excluded.user_id, subscriber_ip = excluded.subscriber_ip, updated_at = excluded.updated_at, warned_at = excluded.warned_at ` pgUpdateSubscriptionWarningSentQuery = `UPDATE webpush_subscription SET warned_at = $1 WHERE id = $2` pgDeleteSubscriptionByEndpointQuery = `DELETE FROM webpush_subscription WHERE endpoint = $1` @@ -95,7 +95,7 @@ func NewPostgresStore(dsn string) (*PostgresStore, error) { } func setupPostgresDB(db *sql.DB) error { - // If 'wp_schema_version' table does not exist, this must be a new database + // If 'webpush_schema_version' table does not exist, this must be a new database rows, err := db.Query(pgSelectSchemaVersionQuery) if err != nil { return setupNewPostgresDB(db) @@ -104,13 +104,18 @@ func setupPostgresDB(db *sql.DB) error { } func setupNewPostgresDB(db *sql.DB) error { - if _, err := db.Exec(pgCreateTablesQuery); err != nil { + tx, err := db.Begin() + if err != nil { return err } - if _, err := db.Exec(pgInsertSchemaVersion, pgCurrentSchemaVersion); err != nil { + defer tx.Rollback() + if _, err := tx.Exec(pgCreateTablesQuery); err != nil { return err } - return nil + if _, err := tx.Exec(pgInsertSchemaVersion, pgCurrentSchemaVersion); err != nil { + return err + } + return tx.Commit() } // UpsertSubscription adds or updates Web Push subscriptions for the given topics and user ID. diff --git a/webpush/store_postgres_test.go b/webpush/store_postgres_test.go new file mode 100644 index 00000000..07a3c6be --- /dev/null +++ b/webpush/store_postgres_test.go @@ -0,0 +1,91 @@ +package webpush_test + +import ( + "database/sql" + "fmt" + "net/url" + "os" + "testing" + + "github.com/stretchr/testify/require" + "heckel.io/ntfy/v2/util" + "heckel.io/ntfy/v2/webpush" +) + +func newTestPostgresStore(t *testing.T) *webpush.PostgresStore { + dsn := os.Getenv("NTFY_TEST_DATABASE_URL") + if dsn == "" { + t.Skip("NTFY_TEST_DATABASE_URL not set, skipping PostgreSQL tests") + } + // Create a unique schema for this test + schema := fmt.Sprintf("test_%s", util.RandomString(10)) + setupDB, err := sql.Open("pgx", dsn) + require.Nil(t, err) + _, err = setupDB.Exec(fmt.Sprintf("CREATE SCHEMA %s", schema)) + require.Nil(t, err) + require.Nil(t, setupDB.Close()) + // Open store with search_path set to the new schema + u, err := url.Parse(dsn) + require.Nil(t, err) + q := u.Query() + q.Set("search_path", schema) + u.RawQuery = q.Encode() + store, err := webpush.NewPostgresStore(u.String()) + require.Nil(t, err) + t.Cleanup(func() { + store.Close() + cleanDB, err := sql.Open("pgx", dsn) + if err == nil { + cleanDB.Exec(fmt.Sprintf("DROP SCHEMA %s CASCADE", schema)) + cleanDB.Close() + } + }) + return store +} + +func TestPostgresStoreUpsertSubscriptionSubscriptionsForTopic(t *testing.T) { + testStoreUpsertSubscriptionSubscriptionsForTopic(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreUpsertSubscriptionSubscriberIPLimitReached(t *testing.T) { + testStoreUpsertSubscriptionSubscriberIPLimitReached(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreUpsertSubscriptionUpdateTopics(t *testing.T) { + testStoreUpsertSubscriptionUpdateTopics(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreUpsertSubscriptionUpdateFields(t *testing.T) { + testStoreUpsertSubscriptionUpdateFields(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreRemoveByUserIDMultiple(t *testing.T) { + testStoreRemoveByUserIDMultiple(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreRemoveByEndpoint(t *testing.T) { + testStoreRemoveByEndpoint(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreRemoveByUserID(t *testing.T) { + testStoreRemoveByUserID(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreRemoveByUserIDEmpty(t *testing.T) { + testStoreRemoveByUserIDEmpty(t, newTestPostgresStore(t)) +} + +func TestPostgresStoreExpiryWarningSent(t *testing.T) { + store := newTestPostgresStore(t) + testStoreExpiryWarningSent(t, store, store.SetSubscriptionUpdatedAt) +} + +func TestPostgresStoreExpiring(t *testing.T) { + store := newTestPostgresStore(t) + testStoreExpiring(t, store, store.SetSubscriptionUpdatedAt) +} + +func TestPostgresStoreRemoveExpired(t *testing.T) { + store := newTestPostgresStore(t) + testStoreRemoveExpired(t, store, store.SetSubscriptionUpdatedAt) +} diff --git a/webpush/sqlite.go b/webpush/store_sqlite.go similarity index 100% rename from webpush/sqlite.go rename to webpush/store_sqlite.go diff --git a/webpush/store_sqlite_test.go b/webpush/store_sqlite_test.go new file mode 100644 index 00000000..b01ca55d --- /dev/null +++ b/webpush/store_sqlite_test.go @@ -0,0 +1,63 @@ +package webpush_test + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + "heckel.io/ntfy/v2/webpush" +) + +func newTestSQLiteStore(t *testing.T) *webpush.SQLiteStore { + store, err := webpush.NewSQLiteStore(filepath.Join(t.TempDir(), "webpush.db"), "") + require.Nil(t, err) + t.Cleanup(func() { store.Close() }) + return store +} + +func TestSQLiteStoreUpsertSubscriptionSubscriptionsForTopic(t *testing.T) { + testStoreUpsertSubscriptionSubscriptionsForTopic(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreUpsertSubscriptionSubscriberIPLimitReached(t *testing.T) { + testStoreUpsertSubscriptionSubscriberIPLimitReached(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreUpsertSubscriptionUpdateTopics(t *testing.T) { + testStoreUpsertSubscriptionUpdateTopics(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreUpsertSubscriptionUpdateFields(t *testing.T) { + testStoreUpsertSubscriptionUpdateFields(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreRemoveByUserIDMultiple(t *testing.T) { + testStoreRemoveByUserIDMultiple(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreRemoveByEndpoint(t *testing.T) { + testStoreRemoveByEndpoint(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreRemoveByUserID(t *testing.T) { + testStoreRemoveByUserID(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreRemoveByUserIDEmpty(t *testing.T) { + testStoreRemoveByUserIDEmpty(t, newTestSQLiteStore(t)) +} + +func TestSQLiteStoreExpiryWarningSent(t *testing.T) { + store := newTestSQLiteStore(t) + testStoreExpiryWarningSent(t, store, store.SetSubscriptionUpdatedAt) +} + +func TestSQLiteStoreExpiring(t *testing.T) { + store := newTestSQLiteStore(t) + testStoreExpiring(t, store, store.SetSubscriptionUpdatedAt) +} + +func TestSQLiteStoreRemoveExpired(t *testing.T) { + store := newTestSQLiteStore(t) + testStoreRemoveExpired(t, store, store.SetSubscriptionUpdatedAt) +} diff --git a/webpush/store_test.go b/webpush/store_test.go index 9f1c7adc..fe2e28f3 100644 --- a/webpush/store_test.go +++ b/webpush/store_test.go @@ -12,7 +12,7 @@ import ( const testWebPushEndpoint = "https://updates.push.services.mozilla.com/wpush/v1/AAABBCCCDDEEEFFF" -func testStoreUpsertSubscription_SubscriptionsForTopic(t *testing.T, store webpush.Store) { +func testStoreUpsertSubscriptionSubscriptionsForTopic(t *testing.T, store webpush.Store) { require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"test-topic", "mytopic"})) subs, err := store.SubscriptionsForTopic("test-topic") @@ -29,7 +29,7 @@ func testStoreUpsertSubscription_SubscriptionsForTopic(t *testing.T, store webpu require.Equal(t, subs[0].Endpoint, subs2[0].Endpoint) } -func testStoreUpsertSubscription_SubscriberIPLimitReached(t *testing.T, store webpush.Store) { +func testStoreUpsertSubscriptionSubscriberIPLimitReached(t *testing.T, store webpush.Store) { // Insert 10 subscriptions with the same IP address for i := 0; i < 10; i++ { endpoint := fmt.Sprintf(testWebPushEndpoint+"%d", i) @@ -46,7 +46,7 @@ func testStoreUpsertSubscription_SubscriberIPLimitReached(t *testing.T, store we require.Nil(t, store.UpsertSubscription(testWebPushEndpoint+"99", "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("9.9.9.9"), []string{"test-topic", "mytopic"})) } -func testStoreUpsertSubscription_UpdateTopics(t *testing.T, store webpush.Store) { +func testStoreUpsertSubscriptionUpdateTopics(t *testing.T, store webpush.Store) { // Insert subscription with two topics, and another with one topic require.Nil(t, store.UpsertSubscription(testWebPushEndpoint+"0", "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1", "topic2"})) require.Nil(t, store.UpsertSubscription(testWebPushEndpoint+"1", "auth-key", "p256dh-key", "", netip.MustParseAddr("9.9.9.9"), []string{"topic1"})) @@ -75,7 +75,51 @@ func testStoreUpsertSubscription_UpdateTopics(t *testing.T, store webpush.Store) require.Len(t, subs, 0) } -func testStoreRemoveSubscriptionsByEndpoint(t *testing.T, store webpush.Store) { +func testStoreUpsertSubscriptionUpdateFields(t *testing.T, store webpush.Store) { + // Insert a subscription + require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1"})) + + subs, err := store.SubscriptionsForTopic("topic1") + require.Nil(t, err) + require.Len(t, subs, 1) + require.Equal(t, "auth-key", subs[0].Auth) + require.Equal(t, "p256dh-key", subs[0].P256dh) + require.Equal(t, "u_1234", subs[0].UserID) + + // Re-upsert the same endpoint with different auth, p256dh, and userID + require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "new-auth", "new-p256dh", "u_5678", netip.MustParseAddr("1.2.3.4"), []string{"topic1"})) + + subs, err = store.SubscriptionsForTopic("topic1") + require.Nil(t, err) + require.Len(t, subs, 1) + require.Equal(t, testWebPushEndpoint, subs[0].Endpoint) + require.Equal(t, "new-auth", subs[0].Auth) + require.Equal(t, "new-p256dh", subs[0].P256dh) + require.Equal(t, "u_5678", subs[0].UserID) +} + +func testStoreRemoveByUserIDMultiple(t *testing.T, store webpush.Store) { + // Insert two subscriptions for u_1234 and one for u_5678 + require.Nil(t, store.UpsertSubscription(testWebPushEndpoint+"0", "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1"})) + require.Nil(t, store.UpsertSubscription(testWebPushEndpoint+"1", "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1"})) + require.Nil(t, store.UpsertSubscription(testWebPushEndpoint+"2", "auth-key", "p256dh-key", "u_5678", netip.MustParseAddr("9.9.9.9"), []string{"topic1"})) + + subs, err := store.SubscriptionsForTopic("topic1") + require.Nil(t, err) + require.Len(t, subs, 3) + + // Remove all subscriptions for u_1234 + require.Nil(t, store.RemoveSubscriptionsByUserID("u_1234")) + + // Only u_5678's subscription should remain + subs, err = store.SubscriptionsForTopic("topic1") + require.Nil(t, err) + require.Len(t, subs, 1) + require.Equal(t, testWebPushEndpoint+"2", subs[0].Endpoint) + require.Equal(t, "u_5678", subs[0].UserID) +} + +func testStoreRemoveByEndpoint(t *testing.T, store webpush.Store) { // Insert subscription with two topics require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1", "topic2"})) subs, err := store.SubscriptionsForTopic("topic1") @@ -89,7 +133,7 @@ func testStoreRemoveSubscriptionsByEndpoint(t *testing.T, store webpush.Store) { require.Len(t, subs, 0) } -func testStoreRemoveSubscriptionsByUserID(t *testing.T, store webpush.Store) { +func testStoreRemoveByUserID(t *testing.T, store webpush.Store) { // Insert subscription with two topics require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1", "topic2"})) subs, err := store.SubscriptionsForTopic("topic1") @@ -103,11 +147,11 @@ func testStoreRemoveSubscriptionsByUserID(t *testing.T, store webpush.Store) { require.Len(t, subs, 0) } -func testStoreRemoveSubscriptionsByUserID_Empty(t *testing.T, store webpush.Store) { +func testStoreRemoveByUserIDEmpty(t *testing.T, store webpush.Store) { require.Equal(t, webpush.ErrWebPushUserIDCannotBeEmpty, store.RemoveSubscriptionsByUserID("")) } -func testStoreMarkExpiryWarningSent(t *testing.T, store webpush.Store, setUpdatedAt func(endpoint string, updatedAt int64) error) { +func testStoreExpiryWarningSent(t *testing.T, store webpush.Store, setUpdatedAt func(endpoint string, updatedAt int64) error) { // Insert subscription with two topics require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1", "topic2"})) @@ -129,7 +173,7 @@ func testStoreMarkExpiryWarningSent(t *testing.T, store webpush.Store, setUpdate require.Len(t, subs, 0) } -func testStoreSubscriptionsExpiring(t *testing.T, store webpush.Store, setUpdatedAt func(endpoint string, updatedAt int64) error) { +func testStoreExpiring(t *testing.T, store webpush.Store, setUpdatedAt func(endpoint string, updatedAt int64) error) { // Insert subscription with two topics require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1", "topic2"})) subs, err := store.SubscriptionsForTopic("topic1") @@ -149,7 +193,7 @@ func testStoreSubscriptionsExpiring(t *testing.T, store webpush.Store, setUpdate require.Equal(t, testWebPushEndpoint, subs[0].Endpoint) } -func testStoreRemoveExpiredSubscriptions(t *testing.T, store webpush.Store, setUpdatedAt func(endpoint string, updatedAt int64) error) { +func testStoreRemoveExpired(t *testing.T, store webpush.Store, setUpdatedAt func(endpoint string, updatedAt int64) error) { // Insert subscription with two topics require.Nil(t, store.UpsertSubscription(testWebPushEndpoint, "auth-key", "p256dh-key", "u_1234", netip.MustParseAddr("1.2.3.4"), []string{"topic1", "topic2"})) subs, err := store.SubscriptionsForTopic("topic1")