From c7e88c249e55664916dc3b0ca0897fdffcb8a79c Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Mon, 2 Nov 2026 23:14:22 +0100 Subject: [PATCH] fix: sync the setting that deletes junk mail for good between devices --- .../settings-store-junk-sync.test.ts | 31 +++++++++++++++++++ stores/settings-store.ts | 5 +++ 2 files changed, 36 insertions(+) create mode 100644 stores/__tests__/settings-store-junk-sync.test.ts diff --git a/stores/__tests__/settings-store-junk-sync.test.ts b/stores/__tests__/settings-store-junk-sync.test.ts new file mode 100644 index 000000000..9002a0eb8 --- /dev/null +++ b/stores/__tests__/settings-store-junk-sync.test.ts @@ -0,0 +1,31 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { useSettingsStore } from '../settings-store'; + +// "Permanently delete junk" is a choice on the Message list page; it has to +// reach the server copy like the rest, or another device (or a restore) +// quietly goes back to moving junk to the trash. +describe('settings-store permanentlyDeleteJunk sync', () => { + beforeEach(() => { + useSettingsStore.getState().resetToDefaults(); + }); + + it('is in the snapshot pushed to the server and in a file export', () => { + useSettingsStore.getState().updateSetting('permanentlyDeleteJunk', true); + expect(JSON.parse(useSettingsStore.getState().exportSettings({ forSync: true })).permanentlyDeleteJunk).toBe(true); + expect(JSON.parse(useSettingsStore.getState().exportSettings()).permanentlyDeleteJunk).toBe(true); + }); + + it('comes back from a synced copy', () => { + useSettingsStore.getState().updateSetting('permanentlyDeleteJunk', true); + const blob = useSettingsStore.getState().exportSettings({ forSync: true }); + useSettingsStore.getState().resetToDefaults(); + expect(useSettingsStore.getState().permanentlyDeleteJunk).toBe(false); + expect(useSettingsStore.getState().importSettings(blob)).toBe(true); + expect(useSettingsStore.getState().permanentlyDeleteJunk).toBe(true); + }); + + it('ignores a value that is not a boolean', () => { + expect(useSettingsStore.getState().importSettings(JSON.stringify({ permanentlyDeleteJunk: 'yes' }))).toBe(true); + expect(useSettingsStore.getState().permanentlyDeleteJunk).toBe(false); + }); +}); diff --git a/stores/settings-store.ts b/stores/settings-store.ts index 2427a5965..91e0f66f0 100644 --- a/stores/settings-store.ts +++ b/stores/settings-store.ts @@ -1334,6 +1334,7 @@ export const useSettingsStore = create()( deleteAction: state.deleteAction, returnToListAfterAction: state.returnToListAfterAction, confirmBulkDelete: state.confirmBulkDelete, + permanentlyDeleteJunk: state.permanentlyDeleteJunk, clearSearchOnFolderChange: state.clearSearchOnFolderChange, searchDefaultScope: state.searchDefaultScope, showPreview: state.showPreview, @@ -1635,6 +1636,10 @@ export const useSettingsStore = create()( if (key === 'searchDefaultScope' && !isSearchDefaultScope(settings[key])) { return; } + // Anything but a real true must not turn on deleting junk for good. + if (key === 'permanentlyDeleteJunk' && typeof settings[key] !== 'boolean') { + return; + } if (DEVICE_LOCAL_SETTING_KEYS.has(key)) { return; }