fix(web): restore asset update events in asset viewer (#26845)

This commit is contained in:
Michel Heusschen
2026-03-11 13:46:29 +01:00
committed by GitHub
parent 9fc32b6f7a
commit 9fc6fbc373
2 changed files with 84 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
import { getAnimateMock } from '$lib/__mocks__/animate.mock';
import { getResizeObserverMock } from '$lib/__mocks__/resize-observer.mock';
import { preferences as preferencesStore, resetSavedUser, user as userStore } from '$lib/stores/user.store';
import { renderWithTooltips } from '$tests/helpers';
import { updateAsset } from '@immich/sdk';
import { assetFactory } from '@test-data/factories/asset-factory';
import { preferencesFactory } from '@test-data/factories/preferences-factory';
import { userAdminFactory } from '@test-data/factories/user-factory';
import { fireEvent, waitFor } from '@testing-library/svelte';
import AssetViewer from './asset-viewer.svelte';
vi.mock('$lib/managers/feature-flags-manager.svelte', () => ({
featureFlagsManager: {
init: vi.fn(),
loadFeatureFlags: vi.fn(),
value: { smartSearch: true, trash: true },
} as never,
}));
vi.mock('$lib/stores/ocr.svelte', () => ({
ocrManager: {
clear: vi.fn(),
getAssetOcr: vi.fn(),
hasOcrData: false,
showOverlay: false,
},
}));
vi.mock('@immich/sdk', async () => {
const sdk = await vi.importActual<typeof import('@immich/sdk')>('@immich/sdk');
return {
...sdk,
updateAsset: vi.fn(),
};
});
describe('AssetViewer', () => {
beforeAll(() => {
Element.prototype.animate = getAnimateMock();
vi.stubGlobal('ResizeObserver', getResizeObserverMock());
});
afterEach(() => {
resetSavedUser();
vi.clearAllMocks();
});
afterAll(() => {
vi.restoreAllMocks();
});
it('updates the top bar favorite action after pressing favorite', async () => {
const ownerId = 'owner-id';
const user = userAdminFactory.build({ id: ownerId });
const asset = assetFactory.build({ ownerId, isFavorite: false, isTrashed: false });
userStore.set(user);
preferencesStore.set(preferencesFactory.build({ cast: { gCastEnabled: false } }));
vi.mocked(updateAsset).mockResolvedValue({ ...asset, isFavorite: true });
const { getByLabelText, queryByLabelText } = renderWithTooltips(AssetViewer, {
cursor: { current: asset },
showNavigation: false,
});
expect(getByLabelText('to_favorite')).toBeInTheDocument();
expect(queryByLabelText('unfavorite')).toBeNull();
await fireEvent.click(getByLabelText('to_favorite'));
await waitFor(() =>
expect(updateAsset).toHaveBeenCalledWith({ id: asset.id, updateAssetDto: { isFavorite: true } }),
);
await waitFor(() => expect(getByLabelText('unfavorite')).toBeInTheDocument());
});
});

View File

@@ -5,6 +5,7 @@
import NextAssetAction from '$lib/components/asset-viewer/actions/next-asset-action.svelte';
import PreviousAssetAction from '$lib/components/asset-viewer/actions/previous-asset-action.svelte';
import AssetViewerNavBar from '$lib/components/asset-viewer/asset-viewer-nav-bar.svelte';
import OnEvents from '$lib/components/OnEvents.svelte';
import { AssetAction, ProjectionType } from '$lib/constants';
import { activityManager } from '$lib/managers/activity-manager.svelte';
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
@@ -142,6 +143,12 @@
}
};
const onAssetUpdate = (updatedAsset: AssetResponseDto) => {
if (asset.id === updatedAsset.id) {
cursor = { ...cursor, current: updatedAsset };
}
};
onMount(() => {
syncAssetViewerOpenClass(true);
unsubscribes.push(
@@ -406,6 +413,7 @@
</script>
<CommandPaletteDefaultProvider name={$t('assets')} actions={[Tag, TagPeople]} />
<OnEvents {onAssetUpdate} />
<svelte:document bind:fullscreenElement />