Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 111 additions & 1 deletion src/app/xapian/searchservice.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { MatLegacySnackBarModule as MatSnackBarModule } from '@angular/material/

import { MessageListService } from '../rmmapi/messagelist.service';
import { XapianAPI } from '@runboxcom/runbox-searchindex/rmmxapianapi';
import { firstValueFrom } from 'rxjs';
import { AsyncSubject, BehaviorSubject, Subject, of, firstValueFrom } from 'rxjs';
import { xapianLoadedSubject } from './xapianwebloader';
import { PostMessageAction } from './messageactions';

Expand Down Expand Up @@ -328,3 +328,113 @@ describe('SearchService', () => {
FS.unmount('/' + localdir);
});
});

describe('SearchService.getDocData cache', () => {

let searchService: SearchService;
let mockApi: any;
let mockModule: { documenttermlistresult: string[] };

beforeEach(() => {
mockModule = { documenttermlistresult: [] };
(window as any).Module = mockModule;
(window as any).FS = {
syncfs: (_populate: boolean, cb: () => void) => cb(),
};

const RealWorker = (window as any).Worker;
(window as any).Worker = class {
postMessage() {}
onmessage: any = null;
onerror: any = null;
terminate() {}
addEventListener() {}
};

searchService = new SearchService(
{
me: new AsyncSubject(),
messageFlagChangeSubject: new Subject(),
getMessageContents: () => of({ status: 'success', text: { text: '' } }),
deleteCachedMessageContents: () => {},
} as any,
{} as any,
{} as any,
{} as any,
{
folderListSubject: new BehaviorSubject([]),
refreshFolderList: () => Promise.resolve([]),
searchservice: new AsyncSubject(),
} as any,
);

(window as any).Worker = RealWorker;

mockApi = {
getDocumentData: jasmine.createSpy().and.returnValue('Q123\tsender@test.com\tTest Subject'),
documentXTermList: jasmine.createSpy(),
reloadXapianDatabase: jasmine.createSpy(),
};
searchService.api = mockApi;
searchService.messageTextCache = new Map([[123, 'preview text']]);
});

afterEach(() => {
delete (window as any).Module;
delete (window as any).FS;
});

it('returns fresh seen flag after index reload', () => {
mockModule.documenttermlistresult = [];
const before = searchService.getDocData(1);
expect(before.seen).toBeFalsy();

mockModule.documenttermlistresult = ['XFseen'];
searchService.indexUpdatedSubject.next(undefined);

const after = searchService.getDocData(1);
expect(after.seen).toBe(true);
});

it('returns fresh flagged flag after index reload', () => {
mockModule.documenttermlistresult = [];
const before = searchService.getDocData(1);
expect(before.flagged).toBeFalsy();

mockModule.documenttermlistresult = ['XFflagged'];
searchService.indexUpdatedSubject.next(undefined);

const after = searchService.getDocData(1);
expect(after.flagged).toBe(true);
});

it('reflects multiple flag changes in one reload', () => {
mockModule.documenttermlistresult = [];
searchService.getDocData(1);

mockModule.documenttermlistresult = ['XFseen', 'XFflagged'];
searchService.indexUpdatedSubject.next(undefined);

const after = searchService.getDocData(1);
expect(after.seen).toBe(true);
expect(after.flagged).toBe(true);
});

it('still caches between calls when no reload happened', () => {
mockModule.documenttermlistresult = [];
searchService.getDocData(1);
expect(mockApi.getDocumentData).toHaveBeenCalledTimes(1);

searchService.getDocData(1);
expect(mockApi.getDocumentData).toHaveBeenCalledTimes(1);
});

it('does fresh lookup for a different docid without reload', () => {
mockModule.documenttermlistresult = [];
searchService.getDocData(1);
expect(mockApi.getDocumentData).toHaveBeenCalledTimes(1);

searchService.getDocData(2);
expect(mockApi.getDocumentData).toHaveBeenCalledTimes(2);
});
});
3 changes: 3 additions & 0 deletions src/app/xapian/searchservice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ export class SearchService {
// console.log(FS.stat(`${this.partitionsdir}/${f}`));
// });
this.api.reloadXapianDatabase();
// Invalidate the single-doc cache so getDocData reads fresh data
// from the reloaded database instead of returning stale values
this.currentXapianDocId = null;
this.indexReloadedSubject.next(undefined);
});
});
Expand Down
Loading