From 368e4074fca3793256bf98662a7dc43772948551 Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Fri, 27 Sep 2024 18:33:02 +0300 Subject: [PATCH 1/3] fix: hasTechPreviewTag filter Signed-off-by: Oleksii Orel --- .../Gallery/Entry/__tests__/index.spec.tsx | 29 +++++++++++++++++++ .../EditorSelector/Gallery/Entry/index.tsx | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/__tests__/index.spec.tsx b/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/__tests__/index.spec.tsx index 0a80e2ace..401240010 100644 --- a/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/__tests__/index.spec.tsx +++ b/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/__tests__/index.spec.tsx @@ -67,6 +67,35 @@ describe('Editor Selector Entry', () => { expect(snapshot.toJSON()).toMatchSnapshot(); }); + describe('Tech-Preview labels', () => { + test('should not show without proper tag', () => { + renderComponent( + editorGroup[0].id, + [...editorGroup].map(editor => Object.assign({}, editor, { tags: [] })), + ); + + expect(screen.queryByText('Tech Preview')).toBeNull(); + }); + + test('show if has proper tag "tech-preview"', () => { + renderComponent( + editorGroup[0].id, + [...editorGroup].map(editor => Object.assign({}, editor, { tags: ['tech-preview'] })), + ); + + expect(screen.queryByText('Tech Preview')).not.toBeNull(); + }); + + test('show if has proper tag "Tech-Preview"', () => { + renderComponent( + editorGroup[0].id, + [...editorGroup].map(editor => Object.assign({}, editor, { tags: ['Tech-Preview'] })), + ); + + expect(screen.queryByText('Tech Preview')).not.toBeNull(); + }); + }); + describe('props change', () => { test('sibling editor ID provided later', () => { const { reRenderComponent } = renderComponent(editorGroup[0].id, editorGroup); diff --git a/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx b/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx index 2dc2d0281..0a2b0eab7 100644 --- a/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx +++ b/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx @@ -151,7 +151,7 @@ export class EditorSelectorEntry extends React.PureComponent { ? `data:image/svg+xml;charset=utf-8,${encodeURIComponent(groupIcon)}` : groupIcon; const hasTechPreviewTag = - (activeEditor.tags || []).includes('tech-preview') === true || + (activeEditor.tags || []).map(tag => tag.toLowerCase()).includes('tech-preview') || /idea/i.test(activeEditor.id) === true; const tagsGroup = ( From 600031fa4502a018b82c314f815a2d60bb931456 Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Fri, 27 Sep 2024 18:48:33 +0300 Subject: [PATCH 2/3] fixup! fix: hasTechPreviewTag filter Signed-off-by: Oleksii Orel --- .../src/components/EditorSelector/Gallery/Entry/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx b/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx index 0a2b0eab7..94b16022e 100644 --- a/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx +++ b/packages/dashboard-frontend/src/components/EditorSelector/Gallery/Entry/index.tsx @@ -150,9 +150,9 @@ export class EditorSelectorEntry extends React.PureComponent { groupIconMediatype === 'image/svg+xml' ? `data:image/svg+xml;charset=utf-8,${encodeURIComponent(groupIcon)}` : groupIcon; - const hasTechPreviewTag = - (activeEditor.tags || []).map(tag => tag.toLowerCase()).includes('tech-preview') || - /idea/i.test(activeEditor.id) === true; + const hasTechPreviewTag = (activeEditor.tags || []) + .map(tag => tag.toLowerCase()) + .includes('tech-preview'); const tagsGroup = ( From aac97d8e090c5474b76a1ccbc85cf8de4533bbe4 Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Mon, 30 Sep 2024 12:34:35 +0300 Subject: [PATCH 3/3] fixup! fixup! fix: hasTechPreviewTag filter Signed-off-by: Oleksii Orel --- .../helpers.convertToEditorPlugin.spec.ts | 137 ++++++++++++++++++ .../src/store/Plugins/chePlugins/helpers.ts | 45 ++++++ .../src/store/Plugins/chePlugins/index.ts | 24 +-- 3 files changed, 184 insertions(+), 22 deletions(-) create mode 100644 packages/dashboard-frontend/src/store/Plugins/chePlugins/__tests__/helpers.convertToEditorPlugin.spec.ts create mode 100644 packages/dashboard-frontend/src/store/Plugins/chePlugins/helpers.ts diff --git a/packages/dashboard-frontend/src/store/Plugins/chePlugins/__tests__/helpers.convertToEditorPlugin.spec.ts b/packages/dashboard-frontend/src/store/Plugins/chePlugins/__tests__/helpers.convertToEditorPlugin.spec.ts new file mode 100644 index 000000000..121998c76 --- /dev/null +++ b/packages/dashboard-frontend/src/store/Plugins/chePlugins/__tests__/helpers.convertToEditorPlugin.spec.ts @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2018-2024 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +import common from '@eclipse-che/common'; + +import devfileApi from '@/services/devfileApi'; +import { che } from '@/services/models'; +import { convertToEditorPlugin } from '@/store/Plugins/chePlugins/helpers'; + +describe('convertToEditorPlugin', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('should throw the error', () => { + let editor: devfileApi.Devfile; + let plugin: che.Plugin | undefined; + let errorMessage: string | undefined; + + beforeEach(() => { + plugin = undefined; + errorMessage = undefined; + editor = getEditor(); + }); + + test('if metadata.name is empty', () => { + editor.metadata.name = ''; + + try { + plugin = convertToEditorPlugin(editor); + } catch (e) { + errorMessage = common.helpers.errors.getMessage(e); + } + + expect(plugin).toBeUndefined(); + expect(errorMessage).toBe('Invalid editor metadata'); + }); + + test('if metadata.attributes.version is undefined', () => { + editor.metadata.attributes.version = undefined; + + try { + plugin = convertToEditorPlugin(editor); + } catch (e) { + errorMessage = common.helpers.errors.getMessage(e); + } + + expect(plugin).toBeUndefined(); + expect(errorMessage).toBe('Invalid editor metadata'); + }); + + test('if metadata.attributes.publisher is undefined', () => { + editor.metadata.attributes.publisher = undefined; + + try { + plugin = convertToEditorPlugin(editor); + } catch (e) { + errorMessage = common.helpers.errors.getMessage(e); + } + + expect(plugin).toBeUndefined(); + expect(errorMessage).toBe('Invalid editor metadata'); + }); + }); + + test('returns correct editor plugin', async () => { + const editor = getEditor(); + + const plugin = convertToEditorPlugin(editor); + + expect(plugin).toEqual({ + description: + 'Microsoft Visual Studio Code - Open Source IDE for Eclipse Che - Insiders build', + displayName: 'VS Code - Open Source', + icon: ``, + iconMediatype: 'image/svg+xml', + id: 'che-incubator/che-code/insiders', + links: { + devfile: '', + }, + name: 'che-code', + publisher: 'che-incubator', + tags: ['Tech-Preview'], + type: 'Che Editor', + version: 'insiders', + }); + }); +}); + +function getEditor(): devfileApi.Devfile { + return { + commands: [ + { + apply: { + component: 'che-code-injector', + }, + id: 'init-container-command', + }, + ], + components: [ + { + container: { + command: ['/entrypoint-init-container.sh'], + image: 'quay.io/che-incubator/che-code:insiders', + }, + name: 'che-code-injector', + }, + ], + metadata: { + attributes: { + firstPublicationDate: '2021-10-31', + iconData: + '', + iconMediatype: 'image/svg+xml', + publisher: 'che-incubator', + repository: 'https://github.com/che-incubator/che-code', + title: 'Microsoft Visual Studio Code - Open Source IDE for Eclipse Che - Insiders build', + version: 'insiders', + }, + description: + 'Microsoft Visual Studio Code - Open Source IDE for Eclipse Che - Insiders build', + displayName: 'VS Code - Open Source', + name: 'che-code', + tags: ['Tech-Preview'], + }, + schemaVersion: '2.2.2', + } as devfileApi.Devfile; +} diff --git a/packages/dashboard-frontend/src/store/Plugins/chePlugins/helpers.ts b/packages/dashboard-frontend/src/store/Plugins/chePlugins/helpers.ts new file mode 100644 index 000000000..90982d2c7 --- /dev/null +++ b/packages/dashboard-frontend/src/store/Plugins/chePlugins/helpers.ts @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2024 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +import devfileApi from '@/services/devfileApi'; +import { che } from '@/services/models'; + +/** Convert devfile to editor plugin */ +export function convertToEditorPlugin(editor: devfileApi.Devfile): che.Plugin { + if ( + !editor.metadata?.name || + !editor.metadata.attributes?.version || + !editor.metadata.attributes?.publisher + ) { + throw new Error('Invalid editor metadata'); + } + return { + id: + editor.metadata.attributes.publisher + + '/' + + editor.metadata.name + + '/' + + editor.metadata.attributes.version, + name: editor.metadata.name, + description: editor.metadata.description, + displayName: editor.metadata.displayName, + publisher: editor.metadata.attributes.publisher, + type: 'Che Editor', + tags: editor.metadata.tags, + version: editor.metadata.attributes.version, + links: { + devfile: '', + }, + icon: editor.metadata.attributes.iconData, + iconMediatype: editor.metadata.attributes.iconMediatype, + }; +} diff --git a/packages/dashboard-frontend/src/store/Plugins/chePlugins/index.ts b/packages/dashboard-frontend/src/store/Plugins/chePlugins/index.ts index 7e04c189c..55f9bfe32 100644 --- a/packages/dashboard-frontend/src/store/Plugins/chePlugins/index.ts +++ b/packages/dashboard-frontend/src/store/Plugins/chePlugins/index.ts @@ -16,6 +16,7 @@ import { Action, Reducer } from 'redux'; import { che } from '@/services/models'; import { AppThunk } from '@/store'; import { createObject } from '@/store/helpers'; +import { convertToEditorPlugin } from '@/store/Plugins/chePlugins/helpers'; import * as devWorkspacePlugins from '@/store/Plugins/devWorkspacePlugins'; import { SanityCheckAction } from '@/store/sanityCheckMiddleware'; @@ -57,28 +58,7 @@ export const actionCreators: ActionCreators = { const state = getState(); const editors = state.dwPlugins.cmEditors || []; - const editorsPlugins: che.Plugin[] = editors.map(editor => { - return { - id: - editor.metadata.attributes.publisher + - '/' + - editor.metadata.name + - '/' + - editor.metadata.attributes.version, - name: editor.metadata.name, - description: editor.metadata.description, - displayName: editor.metadata.displayName, - publisher: editor.metadata.attributes.publisher, - type: 'Che Editor', - tags: editor.metadata.attributes.tags, - version: editor.metadata.attributes.version, - links: { - devfile: '', - }, - icon: editor.metadata.attributes.iconData, - iconMediatype: editor.metadata.attributes.iconMediatype, - }; - }); + const editorsPlugins = editors.map(editor => convertToEditorPlugin(editor)); dispatch({ type: 'RECEIVE_PLUGINS', plugins: editorsPlugins,