mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-05 08:06:58 +00:00
Every keyword change sent the message's whole `keywords` map, which the
server takes as a replacement. Opening a message that wasn't in the
loaded list sent `{"$seen": true}` and wiped its star and tags; starring
a listed message sent the list's stale map and reverted keywords another
client had changed since the list loaded.
Keyword changes now go out as `keywords/<name>` patch pointers (`true`
to set, `null` to clear) everywhere:
- mark read/unread, star, pin and tagging in the email store
- spam / not spam, trash-and-read, and the spam undo, which now puts
back only the keywords the action touched
- star, tag and unread from the message viewer
- the offline outbox, whose keyword ops carry a patch and merge per
keyword when coalesced
Ops queued by earlier builds still hold a whole map. They replay as a
patch that only sets the keywords in it (clearing the other half of
`$junk`/`$notjunk`), so an unread or unstar queued before the update is
lost but nothing gets erased. The list and the offline cache apply the
same patch locally instead of overwriting their keyword maps.
27 lines
1.0 KiB
TypeScript
27 lines
1.0 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { applyKeywordPatch, revertKeywordPatch } from '../keyword-patch';
|
|
|
|
describe('applyKeywordPatch', () => {
|
|
it('sets and clears only the keywords the patch names', () => {
|
|
const before = { $seen: true, $flagged: true, '$label:work': true };
|
|
expect(applyKeywordPatch(before, { $seen: null, $pinned: true, $flagged: false })).toEqual({
|
|
'$label:work': true,
|
|
$pinned: true,
|
|
});
|
|
expect(before).toEqual({ $seen: true, $flagged: true, '$label:work': true });
|
|
});
|
|
|
|
it('starts from nothing when the message has no keywords yet', () => {
|
|
expect(applyKeywordPatch(undefined, { $seen: true })).toEqual({ $seen: true });
|
|
});
|
|
});
|
|
|
|
describe('revertKeywordPatch', () => {
|
|
it('restores each touched keyword to its original value and nothing else', () => {
|
|
expect(revertKeywordPatch(
|
|
{ $junk: true, $notjunk: null, $seen: true },
|
|
{ $notjunk: true, $flagged: true },
|
|
)).toEqual({ $junk: null, $notjunk: true, $seen: null });
|
|
});
|
|
});
|