fix: prevent premature queued message auto-send
Only auto-send queued messages after an active session becomes idle Avoid treating missing initial status as safe to send Add coverage for queue auto-send status transitions
This commit is contained in:
@@ -27,7 +27,23 @@ mock.module('@/sync/session-ui-store', () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { buildQueuedAutoSendPayload, sendQueuedAutoSendPayload } from './useQueuedMessageAutoSend';
|
import {
|
||||||
|
buildQueuedAutoSendPayload,
|
||||||
|
sendQueuedAutoSendPayload,
|
||||||
|
shouldDispatchQueuedAutoSend,
|
||||||
|
} from './useQueuedMessageAutoSend';
|
||||||
|
|
||||||
|
describe('shouldDispatchQueuedAutoSend', () => {
|
||||||
|
test('dispatches only after an active session becomes idle', () => {
|
||||||
|
expect(shouldDispatchQueuedAutoSend('busy', 'idle')).toBe(true);
|
||||||
|
expect(shouldDispatchQueuedAutoSend('retry', 'idle')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('does not dispatch when idle is only first seen or status is missing', () => {
|
||||||
|
expect(shouldDispatchQueuedAutoSend(undefined, 'idle')).toBe(false);
|
||||||
|
expect(shouldDispatchQueuedAutoSend('idle', 'idle')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('buildQueuedAutoSendPayload', () => {
|
describe('buildQueuedAutoSendPayload', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -106,6 +106,14 @@ const resolveSessionSendConfig = (sessionId: string) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const shouldDispatchQueuedAutoSend = (
|
||||||
|
previousStatusType: SessionStatusType | undefined,
|
||||||
|
currentStatusType: SessionStatusType,
|
||||||
|
): boolean => {
|
||||||
|
return (previousStatusType === 'busy' || previousStatusType === 'retry')
|
||||||
|
&& currentStatusType === 'idle';
|
||||||
|
};
|
||||||
|
|
||||||
export function useQueuedMessageAutoSend(enabledOrOptions?: boolean | { enabled?: boolean }) {
|
export function useQueuedMessageAutoSend(enabledOrOptions?: boolean | { enabled?: boolean }) {
|
||||||
const enabled = typeof enabledOrOptions === 'boolean' ? enabledOrOptions : (enabledOrOptions?.enabled ?? true);
|
const enabled = typeof enabledOrOptions === 'boolean' ? enabledOrOptions : (enabledOrOptions?.enabled ?? true);
|
||||||
const queuedMessages = useMessageQueueStore((state) => state.queuedMessages);
|
const queuedMessages = useMessageQueueStore((state) => state.queuedMessages);
|
||||||
@@ -183,12 +191,8 @@ export function useQueuedMessageAutoSend(enabledOrOptions?: boolean | { enabled?
|
|||||||
queueEntries.forEach(([sessionId, queue]) => {
|
queueEntries.forEach(([sessionId, queue]) => {
|
||||||
const currentStatusType = (statusRecord[sessionId]?.type ?? 'idle') as SessionStatusType;
|
const currentStatusType = (statusRecord[sessionId]?.type ?? 'idle') as SessionStatusType;
|
||||||
const previousStatusType = previousStatusRef.current.get(sessionId);
|
const previousStatusType = previousStatusRef.current.get(sessionId);
|
||||||
const becameIdle =
|
|
||||||
(previousStatusType === 'busy' || previousStatusType === 'retry')
|
|
||||||
&& currentStatusType === 'idle';
|
|
||||||
const firstSeenIdle = previousStatusType === undefined && currentStatusType === 'idle';
|
|
||||||
|
|
||||||
if (queue.length > 0 && (becameIdle || firstSeenIdle)) {
|
if (queue.length > 0 && shouldDispatchQueuedAutoSend(previousStatusType, currentStatusType)) {
|
||||||
void dispatchSessionQueue(sessionId, queue);
|
void dispatchSessionQueue(sessionId, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user