From abcec01fbc9736aa7f745b04fdb072962ea8e648 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 8 Oct 2026 12:38:22 +0200 Subject: [PATCH 1/4] fix: update the sidebar preview when switching to a resource with the same mdate --- .../SideBar/Details/FileDetails.vue | 3 ++- .../SideBar/Details/FileDetails.spec.ts | 21 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue b/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue index 026ddf50e85..bdd4a522928 100644 --- a/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue +++ b/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue @@ -365,8 +365,9 @@ const capitalizedTimestamp = computed(() => { return upperFirst(displayDate) }) +// TODO: ... or simply watch etag instead? watch( - () => unref(resource)?.mdate, + [() => unref(resource)?.id, () => unref(resource)?.mdate], async () => { if (unref(resource)) { preview.value = await loadPreview({ diff --git a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts index 32412b35f53..a8cc5976bb2 100644 --- a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts +++ b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts @@ -7,11 +7,13 @@ import { RouteLocation } from '@opencloud-eu/web-test-helpers' import { mock, mockDeep } from 'vitest-mock-extended' +import { ref, Ref } from 'vue' import { SpaceResource } from '@opencloud-eu/web-client' import { AncestorMetaData, ImageDimension, ProcessorType } from '@opencloud-eu/web-pkg' import { User } from '@opencloud-eu/web-client/graph/generated' const getResourceMock = ({ + id = '1', type = 'file', mimeType = 'image/jpeg', tags = [], @@ -23,7 +25,7 @@ const getResourceMock = ({ sharedBy = undefined } = {}) => mock({ - id: '1', + id, type, isFolder: type === 'folder', isInVault: false, @@ -87,6 +89,21 @@ describe('Details SideBar Panel', () => { expect.anything() ) }) + it('loads the preview of another resource with the same modification date', async () => { + const resource = ref(getResourceMock({ id: '1' })) + const { mocks, wrapper } = createWrapper({ resource }) + await wrapper.vm.$nextTick() + await wrapper.vm.$nextTick() + resource.value = getResourceMock({ id: '2' }) + await wrapper.vm.$nextTick() + await wrapper.vm.$nextTick() + expect(mocks.$previewService.loadPreview).toHaveBeenLastCalledWith( + expect.objectContaining({ resource: expect.objectContaining({ id: '2' }) }), + expect.anything(), + expect.anything(), + expect.anything() + ) + }) }) describe('status indicators', () => { it('show if given on non-public page', () => { @@ -216,7 +233,7 @@ function createWrapper({ versions = [], tagsEnabled = true }: { - resource?: Resource + resource?: Resource | Ref isPublicLinkContext?: boolean ancestorMetaData?: AncestorMetaData user?: User From 610c76642a0bc76be91014c3141c4a38df982eac Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 8 Oct 2026 12:45:46 +0200 Subject: [PATCH 2/4] test: swap the resource in the sidebar preview test without changing the test helper --- .../SideBar/Details/FileDetails.spec.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts index a8cc5976bb2..5c959b62bed 100644 --- a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts +++ b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts @@ -7,13 +7,12 @@ import { RouteLocation } from '@opencloud-eu/web-test-helpers' import { mock, mockDeep } from 'vitest-mock-extended' -import { ref, Ref } from 'vue' +import { reactive } from 'vue' import { SpaceResource } from '@opencloud-eu/web-client' import { AncestorMetaData, ImageDimension, ProcessorType } from '@opencloud-eu/web-pkg' import { User } from '@opencloud-eu/web-client/graph/generated' const getResourceMock = ({ - id = '1', type = 'file', mimeType = 'image/jpeg', tags = [], @@ -25,7 +24,7 @@ const getResourceMock = ({ sharedBy = undefined } = {}) => mock({ - id, + id: '1', type, isFolder: type === 'folder', isInVault: false, @@ -90,13 +89,17 @@ describe('Details SideBar Panel', () => { ) }) it('loads the preview of another resource with the same modification date', async () => { - const resource = ref(getResourceMock({ id: '1' })) + const resource = reactive({ ...getResourceMock() }) as Resource const { mocks, wrapper } = createWrapper({ resource }) await wrapper.vm.$nextTick() await wrapper.vm.$nextTick() - resource.value = getResourceMock({ id: '2' }) + expect(mocks.$previewService.loadPreview).toHaveBeenCalledTimes(1) + + resource.id = '2' await wrapper.vm.$nextTick() await wrapper.vm.$nextTick() + + expect(mocks.$previewService.loadPreview).toHaveBeenCalledTimes(2) expect(mocks.$previewService.loadPreview).toHaveBeenLastCalledWith( expect.objectContaining({ resource: expect.objectContaining({ id: '2' }) }), expect.anything(), @@ -233,7 +236,7 @@ function createWrapper({ versions = [], tagsEnabled = true }: { - resource?: Resource | Ref + resource?: Resource isPublicLinkContext?: boolean ancestorMetaData?: AncestorMetaData user?: User From 339748ea5d295e4bfd210fcc1517dc9645f76be3 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 8 Oct 2026 13:04:25 +0200 Subject: [PATCH 3/4] fix: watch the etag to reload the sidebar preview --- .../src/components/SideBar/Details/FileDetails.vue | 3 +-- .../unit/components/SideBar/Details/FileDetails.spec.ts | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue b/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue index bdd4a522928..feb22a8e1c5 100644 --- a/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue +++ b/packages/web-app-files/src/components/SideBar/Details/FileDetails.vue @@ -365,9 +365,8 @@ const capitalizedTimestamp = computed(() => { return upperFirst(displayDate) }) -// TODO: ... or simply watch etag instead? watch( - [() => unref(resource)?.id, () => unref(resource)?.mdate], + () => unref(resource)?.etag, async () => { if (unref(resource)) { preview.value = await loadPreview({ diff --git a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts index 5c959b62bed..b91aa7f7fa5 100644 --- a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts +++ b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts @@ -88,20 +88,20 @@ describe('Details SideBar Panel', () => { expect.anything() ) }) - it('loads the preview of another resource with the same modification date', async () => { - const resource = reactive({ ...getResourceMock() }) as Resource + it('loads the preview again when the etag changes but the modification date stays the same', async () => { + const resource = reactive({ ...getResourceMock(), etag: '1' }) as Resource const { mocks, wrapper } = createWrapper({ resource }) await wrapper.vm.$nextTick() await wrapper.vm.$nextTick() expect(mocks.$previewService.loadPreview).toHaveBeenCalledTimes(1) - resource.id = '2' + resource.etag = '2' await wrapper.vm.$nextTick() await wrapper.vm.$nextTick() expect(mocks.$previewService.loadPreview).toHaveBeenCalledTimes(2) expect(mocks.$previewService.loadPreview).toHaveBeenLastCalledWith( - expect.objectContaining({ resource: expect.objectContaining({ id: '2' }) }), + expect.objectContaining({ resource: expect.objectContaining({ etag: '2' }) }), expect.anything(), expect.anything(), expect.anything() From 74d60b1f5a61a569e4ea2a840c949aedb848cdf8 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 8 Oct 2026 13:05:33 +0200 Subject: [PATCH 4/4] test: use descriptive etags in the sidebar preview test --- .../unit/components/SideBar/Details/FileDetails.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts index b91aa7f7fa5..3216e4274ce 100644 --- a/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts +++ b/packages/web-app-files/tests/unit/components/SideBar/Details/FileDetails.spec.ts @@ -89,19 +89,19 @@ describe('Details SideBar Panel', () => { ) }) it('loads the preview again when the etag changes but the modification date stays the same', async () => { - const resource = reactive({ ...getResourceMock(), etag: '1' }) as Resource + const resource = reactive({ ...getResourceMock(), etag: 'initial-etag' }) as Resource const { mocks, wrapper } = createWrapper({ resource }) await wrapper.vm.$nextTick() await wrapper.vm.$nextTick() expect(mocks.$previewService.loadPreview).toHaveBeenCalledTimes(1) - resource.etag = '2' + resource.etag = 'changed-etag' await wrapper.vm.$nextTick() await wrapper.vm.$nextTick() expect(mocks.$previewService.loadPreview).toHaveBeenCalledTimes(2) expect(mocks.$previewService.loadPreview).toHaveBeenLastCalledWith( - expect.objectContaining({ resource: expect.objectContaining({ etag: '2' }) }), + expect.objectContaining({ resource: expect.objectContaining({ etag: 'changed-etag' }) }), expect.anything(), expect.anything(), expect.anything()