[MNT-25413] ADW - First login after a clear cache does not show the s… (#11318)

This commit is contained in:
dominikiwanekhyland
2025-10-31 16:03:23 +01:00
committed by GitHub
parent 4feba2f304
commit 4acda3b09b
2 changed files with 140 additions and 104 deletions
@@ -57,7 +57,6 @@ describe('SavedSearchesService', () => {
});
service = TestBed.inject(SavedSearchesService);
authService = TestBed.inject(AuthenticationService);
spyOn(service.nodesApi, 'getNode').and.callFake(() => Promise.resolve({ entry: { id: testNodeId } } as NodeEntry));
spyOn(service.nodesApi, 'getNodeContent').and.callFake(() => createBlob());
spyOn(service.nodesApi, 'deleteNode').and.callFake(() => Promise.resolve());
spyOn(service.preferencesApi, 'getPreference').and.callFake(() =>
@@ -72,106 +71,140 @@ describe('SavedSearchesService', () => {
localStorage.removeItem(LOCAL_STORAGE_KEY);
});
it('should retrieve saved searches from the preferences API', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.callFake(() => 'true');
service.init();
service.getSavedSearches().subscribe((searches) => {
expect(localStorage.getItem).toHaveBeenCalledWith(LOCAL_STORAGE_KEY);
expect(service.preferencesApi.getPreference).toHaveBeenCalledWith('-me-', 'saved-searches');
expect(searches.length).toBe(2);
expect(searches[0].name).toBe('Search 1');
expect(searches[1].name).toBe('Search 2');
done();
describe('Saved searches retrieval and migration', () => {
beforeEach(() => {
spyOn(service.nodesApi, 'getNode').and.callFake(() => Promise.resolve({ entry: { id: testNodeId } } as NodeEntry));
});
});
it('should retrieve saved searches from the preferences API', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.callFake(() => 'true');
service.init();
it('should automatically migrate saved searches if config.json file exists', (done) => {
spyOn(localStorage, 'setItem');
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
service.getSavedSearches().subscribe((searches) => {
expect(service.nodesApi.getNode).toHaveBeenCalledWith('-my-', { relativePath: 'config.json' });
expect(service.nodesApi.getNodeContent).toHaveBeenCalledWith(testNodeId);
expect(localStorage.setItem).toHaveBeenCalledWith(LOCAL_STORAGE_KEY, 'true');
expect(service.preferencesApi.updatePreference).toHaveBeenCalledWith('-me-', 'saved-searches', SAVED_SEARCHES_CONTENT);
expect(service.nodesApi.deleteNode).toHaveBeenCalledWith(testNodeId, { permanent: true });
expect(searches.length).toBe(2);
done();
});
});
it('should save a new search', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.callFake(() => 'true');
const newSearch = { name: 'Search 3', description: 'Description 3', encodedUrl: 'url3' };
service.init();
service.saveSearch(newSearch).subscribe(() => {
expect(service.preferencesApi.updatePreference).toHaveBeenCalledWith('-me-', 'saved-searches', jasmine.any(String));
expect(service.savedSearches$).toBeDefined();
done();
});
});
it('should emit initial saved searches on subscription', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.returnValue('true');
service.init();
service.savedSearches$.pipe().subscribe((searches) => {
expect(searches.length).toBe(2);
expect(searches[0].name).toBe('Search 1');
expect(service.preferencesApi.getPreference).toHaveBeenCalledWith('-me-', 'saved-searches');
done();
});
service.getSavedSearches().subscribe();
});
it('should emit updated saved searches after saving a new search', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.callFake(() => 'true');
const newSearch = { name: 'Search 3', description: 'Description 3', encodedUrl: 'url3' };
service.init();
service.saveSearch(newSearch).subscribe(() => {
service.savedSearches$.subscribe((searches) => {
expect(searches.length).toBe(3);
expect(searches[2].name).toBe('Search 2');
expect(service.preferencesApi.updatePreference).toHaveBeenCalledWith('-me-', 'saved-searches', jasmine.any(String));
done();
});
});
});
it('should edit a search', (done) => {
const updatedSearch = { name: 'Search 3', description: 'Description 3', encodedUrl: 'url3', order: 0 };
prepareDefaultMock();
service.editSavedSearch(updatedSearch).subscribe(() => {
service.savedSearches$.subscribe((searches) => {
service.getSavedSearches().subscribe((searches) => {
expect(localStorage.getItem).toHaveBeenCalledWith(LOCAL_STORAGE_KEY);
expect(service.preferencesApi.getPreference).toHaveBeenCalledWith('-me-', 'saved-searches');
expect(searches.length).toBe(2);
expect(searches[0].name).toBe('Search 3');
expect(searches[0].order).toBe(0);
expect(searches[0].name).toBe('Search 1');
expect(searches[1].name).toBe('Search 2');
expect(searches[1].order).toBe(1);
done();
});
});
it('should automatically migrate saved searches if config.json file exists', (done) => {
spyOn(localStorage, 'setItem');
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
service.getSavedSearches().subscribe((searches) => {
expect(service.nodesApi.getNode).toHaveBeenCalledWith('-my-', { relativePath: 'config.json' });
expect(service.nodesApi.getNodeContent).toHaveBeenCalledWith(testNodeId);
expect(localStorage.setItem).toHaveBeenCalledWith(LOCAL_STORAGE_KEY, 'true');
expect(service.preferencesApi.updatePreference).toHaveBeenCalledWith('-me-', 'saved-searches', SAVED_SEARCHES_CONTENT);
expect(service.nodesApi.deleteNode).toHaveBeenCalledWith(testNodeId, { permanent: true });
expect(searches.length).toBe(2);
done();
});
});
it('should save a new search', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.callFake(() => 'true');
const newSearch = { name: 'Search 3', description: 'Description 3', encodedUrl: 'url3' };
service.init();
service.saveSearch(newSearch).subscribe(() => {
expect(service.preferencesApi.updatePreference).toHaveBeenCalledWith('-me-', 'saved-searches', jasmine.any(String));
expect(service.savedSearches$).toBeDefined();
done();
});
});
it('should emit initial saved searches on subscription', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.returnValue('true');
service.init();
service.savedSearches$.pipe().subscribe((searches) => {
expect(searches.length).toBe(2);
expect(searches[0].name).toBe('Search 1');
expect(service.preferencesApi.getPreference).toHaveBeenCalledWith('-me-', 'saved-searches');
done();
});
service.getSavedSearches().subscribe();
});
it('should emit updated saved searches after saving a new search', (done) => {
spyOn(authService, 'getUsername').and.callFake(() => testUserName);
spyOn(localStorage, 'getItem').and.callFake(() => 'true');
const newSearch = { name: 'Search 3', description: 'Description 3', encodedUrl: 'url3' };
service.init();
service.saveSearch(newSearch).subscribe(() => {
service.savedSearches$.subscribe((searches) => {
expect(searches.length).toBe(3);
expect(searches[2].name).toBe('Search 2');
expect(service.preferencesApi.updatePreference).toHaveBeenCalledWith('-me-', 'saved-searches', jasmine.any(String));
done();
});
});
});
it('should edit a search', (done) => {
const updatedSearch = { name: 'Search 3', description: 'Description 3', encodedUrl: 'url3', order: 0 };
prepareDefaultMock();
service.editSavedSearch(updatedSearch).subscribe(() => {
service.savedSearches$.subscribe((searches) => {
expect(searches.length).toBe(2);
expect(searches[0].name).toBe('Search 3');
expect(searches[0].order).toBe(0);
expect(searches[1].name).toBe('Search 2');
expect(searches[1].order).toBe(1);
done();
});
});
});
it('should delete a search', (done) => {
const searchToDelete = { name: 'Search 1', description: 'Description 1', encodedUrl: 'url1', order: 0 };
prepareDefaultMock();
service.deleteSavedSearch(searchToDelete).subscribe(() => {
service.savedSearches$.subscribe((searches) => {
expect(searches.length).toBe(1);
expect(searches[0].name).toBe('Search 2');
expect(searches[0].order).toBe(0);
done();
});
});
});
});
it('should delete a search', (done) => {
const searchToDelete = { name: 'Search 1', description: 'Description 1', encodedUrl: 'url1', order: 0 };
prepareDefaultMock();
describe('Saved searches error handling', () => {
it('should fallback to preferences API if getting saved searches node ID fails', (done) => {
spyOn(authService, 'getUsername').and.returnValue(testUserName);
spyOn(localStorage, 'getItem').and.returnValue('');
const error = new Error(JSON.stringify({ error: { statusCode: 500 } }));
spyOn(service.nodesApi, 'getNode').and.returnValue(Promise.reject(error));
service.deleteSavedSearch(searchToDelete).subscribe(() => {
service.savedSearches$.subscribe((searches) => {
expect(searches.length).toBe(1);
expect(searches[0].name).toBe('Search 2');
expect(searches[0].order).toBe(0);
service.getSavedSearches().subscribe((searches) => {
expect(service.preferencesApi.getPreference).toHaveBeenCalledWith('-me-', 'saved-searches');
expect(searches.length).toBe(2);
done();
});
});
it('should handle 404 from getNode() by setting migration flag and falling back to preferences API', (done) => {
spyOn(authService, 'getUsername').and.returnValue(testUserName);
spyOn(localStorage, 'getItem').and.returnValue('');
spyOn(localStorage, 'setItem');
const notFoundError = new Error(JSON.stringify({ error: { statusCode: 404 } }));
spyOn(service.nodesApi, 'getNode').and.returnValue(Promise.reject(notFoundError));
service.getSavedSearches().subscribe((searches) => {
expect(localStorage.setItem).toHaveBeenCalledWith(LOCAL_STORAGE_KEY, 'true');
expect(service.preferencesApi.getPreference).toHaveBeenCalledWith('-me-', 'saved-searches');
expect(searches.length).toBe(2);
done();
});
});
@@ -56,7 +56,10 @@ export class SavedSearchesService {
readonly savedSearches$ = new ReplaySubject<SavedSearch[]>(1);
constructor(private readonly apiService: AlfrescoApiService, private readonly authService: AuthenticationService) {}
constructor(
private readonly apiService: AlfrescoApiService,
private readonly authService: AuthenticationService
) {}
init(): void {
this.fetchSavedSearches();
@@ -70,10 +73,7 @@ export class SavedSearchesService {
getSavedSearches(): Observable<SavedSearch[]> {
const savedSearchesMigrated = localStorage.getItem(this.getLocalStorageKey()) ?? '';
if (savedSearchesMigrated === 'true') {
return from(this.preferencesApi.getPreference('-me-', 'saved-searches')).pipe(
map((preference) => JSON.parse(preference.entry.value)),
catchError(() => of([]))
);
return this.getSavedSearchesFromPreferenceApi();
} else {
return this.getSavedSearchesNodeId().pipe(
take(1),
@@ -81,12 +81,10 @@ export class SavedSearchesService {
if (this.savedSearchFileNodeId !== '') {
return this.migrateSavedSearches();
} else {
return from(this.preferencesApi.getPreference('-me-', 'saved-searches')).pipe(
map((preference) => JSON.parse(preference.entry.value)),
catchError(() => of([]))
);
return this.getSavedSearchesFromPreferenceApi();
}
})
}),
catchError(() => this.getSavedSearchesFromPreferenceApi())
);
}
}
@@ -237,10 +235,8 @@ export class SavedSearchesService {
const errorStatusCode = JSON.parse(error.message).error.statusCode;
if (errorStatusCode === 404) {
localStorage.setItem(this.getLocalStorageKey(), 'true');
return '';
} else {
return throwError(() => error);
}
return throwError(() => error);
})
);
}
@@ -271,4 +267,11 @@ export class SavedSearchesService {
})
);
}
private getSavedSearchesFromPreferenceApi(): Observable<SavedSearch[]> {
return from(this.preferencesApi.getPreference('-me-', 'saved-searches')).pipe(
map((preference) => JSON.parse(preference.entry.value)),
catchError(() => of([]))
);
}
}