Skip to content

Commit 938cb1a

Browse files
Gerry-Cerndiocas
authored andcommitted
Refactor EmbedActions component to conditionally post messages based on embed mode. Update tests to ensure correct message posting behavior and add checks for file selection in embed mode.
1 parent da82075 commit 938cb1a

8 files changed

Lines changed: 110 additions & 14 deletions

File tree

packages/web-app-files/src/components/EmbedActions/EmbedActions.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ export default defineComponent({
152152
JSON.stringify(routeToContextQuery(unref(router.currentRoute)))
153153
)
154154
})
155+
} else {
156+
// TODO: adjust type to embedModeLocationPickMessageData later (breaking)
157+
postMessage<Resource[]>('owncloud-embed:select', resources)
155158
}
156-
157-
// TODO: adjust type to embedModeLocationPickMessageData later (breaking)
158-
postMessage<Resource[]>('owncloud-embed:select', resources)
159159
} finally {
160160
signing.value = false
161161
}

packages/web-app-files/tests/unit/components/EmbedActions/EmbedActions.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { FileAction, useEmbedMode, useFileActionsCreateLink } from '@ownclouders
99
import { mock } from 'vitest-mock-extended'
1010
import { ref } from 'vue'
1111
import { Resource } from '@ownclouders/web-client'
12+
import { flushPromises } from '@vue/test-utils'
1213

1314
vi.mock('@ownclouders/web-pkg', async (importOriginal) => ({
1415
...(await importOriginal<any>()),
@@ -46,8 +47,10 @@ describe('EmbedActions', () => {
4647
const { wrapper, mocks } = getWrapper({ selectedIds: ['1'] })
4748

4849
await wrapper.find(selectors.btnSelect).trigger('click')
50+
await flushPromises()
4951

5052
expect(mocks.postMessageMock).toHaveBeenCalledWith('owncloud-embed:select', [{ id: '1' }])
53+
expect(mocks.postMessageMock).toHaveBeenCalledTimes(1)
5154
})
5255

5356
it('should enable select action when embedTarget is set to location', () => {
@@ -63,8 +66,10 @@ describe('EmbedActions', () => {
6366
})
6467

6568
await wrapper.find(selectors.btnSelect).trigger('click')
69+
await flushPromises()
6670

6771
expect(mocks.postMessageMock).toHaveBeenCalledWith('owncloud-embed:select', [{ id: '1' }])
72+
expect(mocks.postMessageMock).toHaveBeenCalledTimes(1)
6873
})
6974
it('should display the file name input when chooseFileName is configured', () => {
7075
const { wrapper } = getWrapper({
@@ -91,6 +96,7 @@ describe('EmbedActions', () => {
9196
})
9297

9398
await wrapper.find(selectors.btnSelect).trigger('click')
99+
await flushPromises()
94100

95101
expect(mocks.postMessageMock).toHaveBeenCalledWith('owncloud-embed:select', {
96102
fileName: 'file.txt',
@@ -100,6 +106,7 @@ describe('EmbedActions', () => {
100106
contextRouteQuery: {}
101107
}
102108
})
109+
expect(mocks.postMessageMock).toHaveBeenCalledTimes(1)
103110
})
104111
})
105112

@@ -177,6 +184,7 @@ function getWrapper(
177184
mock<ReturnType<typeof useEmbedMode>>({
178185
isLocationPicker: ref(isLocationPicker),
179186
isFilePicker: ref(isFilePicker),
187+
isInlineAttach: ref(false),
180188
chooseFileName: ref(chooseFileName),
181189
chooseFileNameSuggestion: ref('file.txt'),
182190
postMessage: postMessageMock

packages/web-pkg/src/components/CreateLinkModal.vue

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -278,15 +278,15 @@ export default defineComponent({
278278
'owncloud-embed:share',
279279
(succeeded as PromiseFulfilledResult<LinkShare>[]).map(({ value }) => value.webUrl)
280280
)
281+
// Always emit new event with objects, include password only when copyPassword is enabled
282+
postMessage<Array<{ url: string; password?: string }>>(
283+
'owncloud-embed:share-links',
284+
(succeeded as PromiseFulfilledResult<LinkShare>[]).map(({ value }) => ({
285+
url: value.webUrl,
286+
...(options.copyPassword && { password: password.value })
287+
}))
288+
)
281289
}
282-
// Always emit new event with objects, include password only when copyPassword is enabled
283-
postMessage<Array<{ url: string; password?: string }>>(
284-
'owncloud-embed:share-links',
285-
(succeeded as PromiseFulfilledResult<LinkShare>[]).map(({ value }) => ({
286-
url: value.webUrl,
287-
...(options.copyPassword && { password: password.value })
288-
}))
289-
)
290290
291291
const userFacingErrors: Error[] = []
292292
const failed = result.filter(({ status }) => status === 'rejected')

packages/web-pkg/src/components/FilesList/ResourceTiles.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ export default defineComponent({
299299
return action.route({ space, resources: [resource] })
300300
}
301301
const emitTileClick = (resource: Resource) => {
302-
if (unref(isEmbedModeEnabled) && unref(isFilePicker)) {
302+
if (unref(isEmbedModeEnabled) && unref(isFilePicker) && !resource.isFolder) {
303303
return postMessage<embedModeFilePickMessageData>('owncloud-embed:file-pick', {
304304
resource: JSON.parse(JSON.stringify(resource)),
305305
locationQuery: JSON.parse(JSON.stringify(routeToContextQuery(unref(router.currentRoute))))

packages/web-pkg/tests/unit/components/CreateLinkModal.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,36 @@ describe('CreateLinkModal', () => {
114114
const { addLink } = useSharesStore()
115115
vi.mocked(addLink).mockResolvedValue(link)
116116
await wrapper.vm.onConfirm()
117+
expect(mocks.postMessageMock).toHaveBeenCalledTimes(2)
117118
expect(mocks.postMessageMock).toHaveBeenCalledWith('owncloud-embed:share', [link.webUrl])
119+
expect(mocks.postMessageMock).toHaveBeenCalledWith('owncloud-embed:share-links', [
120+
{ url: link.webUrl }
121+
])
122+
})
123+
it('does not emit embed share events when not in embed mode', async () => {
124+
const resources = [mock<Resource>({ isFolder: false })]
125+
const { wrapper, mocks } = getWrapper({ resources, embedModeEnabled: false })
126+
const link = mock<LinkShare>({ webUrl: 'someurl' })
127+
128+
const { addLink } = useSharesStore()
129+
vi.mocked(addLink).mockResolvedValue(link)
130+
await wrapper.vm.onConfirm()
131+
132+
expect(mocks.postMessageMock).not.toHaveBeenCalled()
133+
})
134+
it('includes password in share-links event when copyPassword is enabled', async () => {
135+
const resources = [mock<Resource>({ isFolder: false })]
136+
const { wrapper, mocks } = getWrapper({ resources, embedModeEnabled: true })
137+
const link = mock<LinkShare>({ webUrl: 'someurl' })
138+
139+
const { addLink } = useSharesStore()
140+
vi.mocked(addLink).mockResolvedValue(link)
141+
wrapper.vm.password.value = 'secret'
142+
await wrapper.vm.onConfirm({ copyPassword: true })
143+
144+
expect(mocks.postMessageMock).toHaveBeenCalledWith('owncloud-embed:share-links', [
145+
{ url: link.webUrl, password: 'secret' }
146+
])
118147
})
119148
it('shows error messages for links that failed to be created', async () => {
120149
const consoleMock = vi.fn(() => undefined)

packages/web-pkg/tests/unit/components/FilesList/ResourceTiles.spec.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import ResourceTiles from '../../../../src/components/FilesList/ResourceTiles.vu
33
import { sortFields } from '../../../../src/helpers/ui/resourceTiles'
44
import { Resource, ResourceIndicator, SpaceResource } from '@ownclouders/web-client'
55
import { mock } from 'vitest-mock-extended'
6-
import { ComponentPublicInstance, computed } from 'vue'
6+
import { ComponentPublicInstance, computed, ref } from 'vue'
77
import { extractDomSelector } from '@ownclouders/web-client'
88
import { useCanBeOpenedWithSecureView } from '../../../../src/composables/resources'
99
import { displayPositionedDropdown } from '../../../../src/helpers/contextMenuDropdown'
@@ -81,6 +81,7 @@ describe('ResourceTiles component', () => {
8181
const originalGetElementById = document.getElementById
8282
const originalGetComputedStyle = window.getComputedStyle
8383
beforeEach(() => {
84+
mockUseEmbedMode.mockReturnValue({ isEnabled: computed(() => false) })
8485
const mockElement = {
8586
clientWidth: 800
8687
} as HTMLElement
@@ -145,6 +146,44 @@ describe('ResourceTiles component', () => {
145146
await wrapper.find('.oc-tiles-item .oc-resource-name').trigger('click')
146147
expect(wrapper.emitted().fileClick).toBeUndefined()
147148
})
149+
150+
it('posts file-pick message when embed file picker mode is enabled and a file is clicked', async () => {
151+
const postMessageMock = vi.fn()
152+
mockUseEmbedMode.mockReturnValue({
153+
isEnabled: ref(true),
154+
isFilePicker: ref(true),
155+
postMessage: postMessageMock
156+
})
157+
const { wrapper } = getWrapper({ props: { resources } })
158+
await wrapper.find('.oc-tiles-item .oc-resource-name').trigger('click')
159+
160+
expect(postMessageMock).toHaveBeenCalledWith(
161+
'owncloud-embed:file-pick',
162+
expect.objectContaining({
163+
resource: expect.objectContaining({ name: 'forest.jpg' })
164+
})
165+
)
166+
})
167+
168+
it('does not post file-pick message when embed file picker mode is enabled and a folder is clicked', async () => {
169+
const postMessageMock = vi.fn()
170+
mockUseEmbedMode.mockReturnValue({
171+
isEnabled: ref(true),
172+
isFilePicker: ref(true),
173+
postMessage: postMessageMock
174+
})
175+
const folderResource = {
176+
...resources[0],
177+
id: 'folder',
178+
name: 'docs',
179+
isFolder: true,
180+
type: 'folder'
181+
}
182+
const { wrapper } = getWrapper({ props: { resources: [folderResource] } })
183+
await wrapper.findComponent({ name: 'resource-tile' }).trigger('click')
184+
185+
expect(postMessageMock).not.toHaveBeenCalled()
186+
})
148187
})
149188

150189
it('emits update:selectedIds event on resource selection and sets the selection', () => {

packages/web-runtime/src/container/bootstrap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ const getEmbedConfigFromQuery = (
121121

122122
const delegateAuthenticationOrigin = getQueryParam('embed-delegate-authentication-origin')
123123

124-
if (delegateAuthentication) {
124+
if (delegateAuthenticationOrigin) {
125125
config.delegateAuthenticationOrigin = delegateAuthenticationOrigin
126126
}
127127

packages/web-runtime/tests/unit/container/bootstrap.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,26 @@ describe('announceConfiguration', () => {
220220
expect(configStore.options.defaultLanguage).toStrictEqual('de')
221221
})
222222

223+
it('should set delegateAuthenticationOrigin from URL query when param is present without delegateAuthentication', async () => {
224+
Object.defineProperty(window, 'location', {
225+
value: {
226+
search: '?embed-delegate-authentication-origin=https://parent.test'
227+
},
228+
writable: true
229+
})
230+
vi.spyOn(global, 'fetch').mockResolvedValue(
231+
mock<Response>({
232+
status: 200,
233+
json: () => Promise.resolve({ theme: '', server: '', options: {} })
234+
})
235+
)
236+
const configStore = useConfigStore()
237+
await announceConfiguration({ path: '/config.json', configStore })
238+
expect(configStore.options.embed.delegateAuthenticationOrigin).toStrictEqual(
239+
'https://parent.test'
240+
)
241+
})
242+
223243
it('should fallback to navigator language as default language when lang in URL query does not match supported languages', async () => {
224244
Object.defineProperty(window, 'location', {
225245
value: {

0 commit comments

Comments
 (0)