mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 16:14:07 +00:00
fix: say a connection is needed only when offline or the server is down, not at a start while online
This commit is contained in:
@@ -8,7 +8,7 @@ import { DEFAULT_ORGANISATION_POLICY } from '@/lib/admin/organisation-policy';
|
||||
import { setStoreBackend } from '@/lib/store/client/api';
|
||||
import { FakeJmapMail } from '@/lib/store/__tests__/helpers/fake-jmap-mail';
|
||||
import { InProcessStore } from '@/lib/store/__tests__/helpers/in-process-store';
|
||||
import { startOfflineMode, wipeEverything } from '../offline-mode';
|
||||
import { setOfflineNotifier, startOfflineMode, wipeEverything } from '../offline-mode';
|
||||
import { forgetLegacyMove } from '../migrate-legacy';
|
||||
import { useOfflineStore, writeEnabled } from '../state';
|
||||
|
||||
@@ -291,3 +291,27 @@ describe('what the store answers and is told', () => {
|
||||
stop();
|
||||
});
|
||||
});
|
||||
|
||||
describe('saying a connection is needed', () => {
|
||||
it('not while online with the server answering, as at a start with a draft waiting', async () => {
|
||||
const { client, stop } = await ready();
|
||||
const { getOfflineHooks } = await import('@/lib/jmap/offline-hooks');
|
||||
const notices: { kind: string }[] = [];
|
||||
setOfflineNotifier((notice) => notices.push(notice));
|
||||
await getOfflineHooks()?.answer(client, [['Identity/set', { create: { x: { email: 'a@example.org' } } }, '0']]);
|
||||
expect(notices.filter((n) => n.kind.startsWith('refused'))).toEqual([]);
|
||||
stop();
|
||||
});
|
||||
|
||||
it('when offline, once', async () => {
|
||||
const { client, stop } = await ready();
|
||||
const { getOfflineHooks } = await import('@/lib/jmap/offline-hooks');
|
||||
const notices: { kind: string }[] = [];
|
||||
setOfflineNotifier((notice) => notices.push(notice));
|
||||
await offline(async () => {
|
||||
await getOfflineHooks()?.answer(client, [['Identity/set', { create: { x: { email: 'a@example.org' } } }, '0']]);
|
||||
});
|
||||
expect(notices.filter((n) => n.kind === 'refused-other')).toHaveLength(1);
|
||||
stop();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -319,7 +319,12 @@ function hasWholeText(email: { bodyValues?: Record<string, { isTruncated?: boole
|
||||
const NEEDS_SERVER = /^(EmailSubmission|Email\/import|CalendarEvent\/set|ContactCard\/set|AddressBook\/set|Calendar\/set|Mailbox\/set|FileNode\/set|SieveScript\/set|VacationResponse\/set|Identity\/set)/;
|
||||
let lastRefusalNotice = 0;
|
||||
|
||||
function noticeRefused(answered: OfflineResponse | null, methodCalls: OfflineMethodCall[]): void {
|
||||
function noticeRefused(client: OfflineClientRef, answered: OfflineResponse | null, methodCalls: OfflineMethodCall[]): void {
|
||||
// Online, with the server answering: the store only stood in for a moment (a draft
|
||||
// waiting from last time, at a start). The outbox retries by itself; "this needs a
|
||||
// connection" would be wrong.
|
||||
const online = typeof navigator === 'undefined' || navigator.onLine !== false;
|
||||
if (online && !useOfflineStore.getState().downServers.includes(serverKey(client.getServerUrl()))) return;
|
||||
const refusedCall = methodCalls.some(([name, , id]) => NEEDS_SERVER.test(name)
|
||||
&& (!answered || answered.methodResponses.some(([responseName, , responseId]) => responseId === id && responseName === 'error')));
|
||||
const refusedChange = answered?.methodResponses.some(([name, result]) => name === 'Email/set' && result?.notUpdated) ?? false;
|
||||
@@ -382,7 +387,7 @@ const hooks: OfflineHooks = {
|
||||
} catch {
|
||||
// The store couldn't start or lost its owner: as if nothing were kept.
|
||||
}
|
||||
noticeRefused(answered, methodCalls);
|
||||
noticeRefused(client, answered, methodCalls);
|
||||
if (answered && methodCalls.some(([name]) => QUEUEING_METHOD.test(name))) {
|
||||
requestOutboxSync();
|
||||
void refreshQueueState();
|
||||
|
||||
Reference in New Issue
Block a user