Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
5.1 kB · 126 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127package statedb
import ( "testing"
"github.com/stretchr/testify/require")
// TestNotificationRepoDIDPreserved guards against the regression where// re-registering a push token without a repoDID wiped out the existing// association. CreateNotification used to DB.Save() the row, which issues a// full-row UPDATE and blanked repo_did whenever the client re-registered// before its OAuth session had restored, silently dropping the device from// follower livestream blasts.func TestNotificationRepoDIDPreserved(t *testing.T) { WithAllDatabases(t, func(state *StatefulDB) { const token = "device-token-1" const didA = "did:plc:aaaa" const didB = "did:plc:bbbb"
// Initial registration while logged in associates the DID. require.NoError(t, state.CreateNotification(token, didA, NotificationTypeFirebase)) tokens, err := state.GetManyNotificationTokens([]string{didA}) require.NoError(t, err) require.Equal(t, []string{token}, tokens)
// Re-registration without a DID (e.g. before the OAuth session has // restored) must NOT clobber the existing association. require.NoError(t, state.CreateNotification(token, "", NotificationTypeFirebase)) tokens, err = state.GetManyNotificationTokens([]string{didA}) require.NoError(t, err) require.Equal(t, []string{token}, tokens, "repo_did was wiped by a DID-less re-registration")
// ...and it must not have duplicated the row (token is the primary key). nots, err := state.ListNotifications() require.NoError(t, err) require.Len(t, nots, 1)
// Re-registering with a different DID replaces the association. require.NoError(t, state.CreateNotification(token, didB, NotificationTypeFirebase)) tokens, err = state.GetManyNotificationTokens([]string{didB}) require.NoError(t, err) require.Equal(t, []string{token}, tokens) tokens, err = state.GetManyNotificationTokens([]string{didA}) require.NoError(t, err) require.Empty(t, tokens, "old DID association should be replaced") })}
// TestNotificationAnonymousThenAssociated covers a token that first registers// with no DID (anonymous) and later gets associated once the user logs in,// without creating a duplicate row.func TestNotificationAnonymousThenAssociated(t *testing.T) { WithAllDatabases(t, func(state *StatefulDB) { const token = "device-token-2" const did = "did:plc:cccc"
// Anonymous registration: the row exists but has no association yet. require.NoError(t, state.CreateNotification(token, "", NotificationTypeFirebase)) tokens, err := state.GetManyNotificationTokens([]string{did}) require.NoError(t, err) require.Empty(t, tokens) nots, err := state.ListNotifications() require.NoError(t, err) require.Len(t, nots, 1)
// Once logged in, the association is set without adding a new row. require.NoError(t, state.CreateNotification(token, did, NotificationTypeFirebase)) tokens, err = state.GetManyNotificationTokens([]string{did}) require.NoError(t, err) require.Equal(t, []string{token}, tokens) nots, err = state.ListNotifications() require.NoError(t, err) require.Len(t, nots, 1) })}
// TestNotificationTypeAndDelete covers the Type column (firebase vs web) and// the DeleteNotification path used when a web client unsubscribes.func TestNotificationTypeAndDelete(t *testing.T) { WithAllDatabases(t, func(state *StatefulDB) { const did = "did:plc:dddd" const fbToken = "firebase-token-1" const webToken = `{"endpoint":"https://push.example/abc","keys":{"p256dh":"x","auth":"y"}}`
// Register one firebase and one web subscription for the same user. require.NoError(t, state.CreateNotification(fbToken, did, NotificationTypeFirebase)) require.NoError(t, state.CreateNotification(webToken, did, NotificationTypeWeb))
// GetManyNotifications returns both rows with their types intact. nots, err := state.GetManyNotifications([]string{did}) require.NoError(t, err) require.Len(t, nots, 2)
byType := map[NotificationType]Notification{} for _, n := range nots { byType[n.Type] = n } require.Contains(t, byType, NotificationTypeFirebase) require.Contains(t, byType, NotificationTypeWeb) require.Equal(t, fbToken, byType[NotificationTypeFirebase].Token) require.Equal(t, webToken, byType[NotificationTypeWeb].Token)
// An empty type defaults to firebase. require.NoError(t, state.CreateNotification("defaulted-token", did, "")) nots, err = state.GetManyNotifications([]string{did}) require.NoError(t, err) var defaulted Notification for _, n := range nots { if n.Token == "defaulted-token" { defaulted = n } } require.Equal(t, NotificationTypeFirebase, defaulted.Type, "empty type should default to firebase")
// DeleteNotification removes the row; deleting a missing row is not an error. require.NoError(t, state.DeleteNotification(webToken)) nots, err = state.GetManyNotifications([]string{did}) require.NoError(t, err) require.Len(t, nots, 2, "web token should be gone, leaving firebase + defaulted") for _, n := range nots { require.NotEqual(t, webToken, n.Token) } require.NoError(t, state.DeleteNotification("never-existed")) })}