Skip to content

Commit 0d58ced

Browse files
ppcvoteclaude
andcommitted
test(search): cover the warm restore path as well as the cold start
The two tests added with the fix both drive the cold-start branch. This adds one for the cached branch, where the `finally` used to override the `catch`, so both halves of the change have a test that fails without it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 062f477 commit 0d58ced

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
### Bug Fixes
66

77
* Settle the search index write when an IndexedDB write fails, instead of leaving the promise pending and the search spinner up.
8-
* Disable the search controls and explain why when the search index cannot be built, instead of leaving the spinner running for as long as the page is open.
8+
* Disable the search controls and explain why when the search index cannot be built, instead of leaving the spinner running for as long as the page is open. A failed restore from the cached index is no longer reported as a successful load.
99

1010
## v5.0.0 (2026-08-06)
1111

attack-search/__tests__/search-events.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ describe('search event bindings', () => {
128128
expect(parsingIcon.hide).toHaveBeenCalled();
129129
});
130130

131+
test('a failed restore from the cache is not reported as a successful load', async () => {
132+
await loadIndexWithAFailingWarmRestore();
133+
134+
// The catch used to set the loaded flag false and the finally set it straight back to
135+
// true, so `search` went on to query an index that was never populated.
136+
expect(mockJqueryApis['#search-input'].prop).toHaveBeenCalledWith('disabled', true);
137+
expect(mockJqueryApis['#search-icon'].addClass).toHaveBeenCalledWith('error-icon');
138+
});
139+
131140
test('a failed index build puts the search controls into their unavailable state', async () => {
132141
await loadIndexWithAFailingColdStart();
133142

@@ -159,6 +168,24 @@ async function loadIndexWithAFailingColdStart() {
159168
await new Promise(resolve => setImmediate(resolve));
160169
}
161170

171+
// Load the module on the cached path, with restoring the index from IndexedDB failing.
172+
async function loadIndexWithAFailingWarmRestore() {
173+
const { searchCacheCompatibilityVersion, searchCacheSchemaVersion } = require('../src/settings');
174+
const version = `${searchCacheSchemaVersion}-${searchCacheCompatibilityVersion}`;
175+
176+
global.window = { indexedDB: {} };
177+
global.localStorage.getItem.mockReturnValue(`${global.build_uuid}-search-${version}`);
178+
179+
jest.doMock('../src/search-service.js', () => class {
180+
initializeAsync() {
181+
return Promise.reject(new Error('cached index is unreadable'));
182+
}
183+
});
184+
185+
require('../src/index');
186+
await new Promise(resolve => setImmediate(resolve));
187+
}
188+
162189
function eventsForSelector(selector) {
163190
return mockJqueryCalls
164191
.filter(call => call.selector === selector || call.delegatedSelector === selector)

0 commit comments

Comments
 (0)