fix: drop mobile notification stream on cleanup (#2887)

This commit is contained in:
Neil 2026-05-30 20:17:45 -07:00 committed by GitHub
parent ed3c88b0ff
commit be2dfe4bac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 1 deletions

View File

@ -0,0 +1,36 @@
import { describe, expect, it, vi } from 'vitest'
import { subscribeToDesktopNotifications } from './mobile-notifications'
import type { RpcClient } from '../transport/rpc-client'
vi.mock('expo-notifications', () => ({
AndroidImportance: { HIGH: 'high' },
setNotificationChannelAsync: vi.fn(),
getPermissionsAsync: vi.fn(),
requestPermissionsAsync: vi.fn(),
scheduleNotificationAsync: vi.fn()
}))
vi.mock('react-native', () => ({
Platform: { OS: 'ios' }
}))
vi.mock('../storage/preferences', () => ({
loadPushNotificationsEnabled: vi.fn()
}))
describe('subscribeToDesktopNotifications', () => {
it('drops the local stream when disposed before the desktop returns ready', () => {
const unsubscribeStream = vi.fn()
const client = {
subscribe: vi.fn(() => unsubscribeStream),
getState: vi.fn(() => 'connected'),
sendRequest: vi.fn()
} as unknown as RpcClient
const unsubscribe = subscribeToDesktopNotifications(client, 'host-1')
unsubscribe()
expect(unsubscribeStream).toHaveBeenCalledTimes(1)
expect(client.sendRequest).not.toHaveBeenCalled()
})
})

View File

@ -114,8 +114,10 @@ export function subscribeToDesktopNotifications(client: RpcClient, hostId: strin
// unmount races with disconnect). sendRequest rejects immediately on a
// closed client — swallow it since server-side cleanup happens via
// connection-close anyway.
// Always drop the local stream first; readiness can race unmount and we
// must not retain the callback while waiting for a subscription id.
unsubscribeStream()
if (subscriptionId) {
unsubscribeStream()
unsubscribeServer(subscriptionId)
}
}