diff --git a/cypress/component/CreatorYAMLView.cy.tsx b/cypress/component/CreatorYAMLView.cy.tsx index a1dc1fba..b5863db5 100644 --- a/cypress/component/CreatorYAMLView.cy.tsx +++ b/cypress/component/CreatorYAMLView.cy.tsx @@ -363,8 +363,7 @@ spec: cy.contains('button', 'Load Sample Template').click(); // Wait for Monaco to update and verify key template fields - cy.contains('apiVersion: console.openshift.io/v1', { timeout: 5000 }).should('be.visible'); - cy.contains('kind: QuickStarts').should('be.visible'); + cy.contains('kind: QuickStarts', { timeout: 5000 }).should('be.visible'); cy.contains('name: sample-interactive-quickstart').should('be.visible'); cy.contains('version: 0.1').should('be.visible'); cy.contains('displayName: Sample Interactive QuickStart').should('be.visible'); diff --git a/jest.config.js b/jest.config.js index 4c79597e..718a9993 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,4 @@ -const transformIgnorePatterns = ['node_modules/(?!(uuid)/)']; +const transformIgnorePatterns = ['node_modules/(?!(uuid|yaml)/)']; /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { diff --git a/src/Creator.tsx b/src/Creator.tsx index 87aa5bbc..c205d9e3 100644 --- a/src/Creator.tsx +++ b/src/Creator.tsx @@ -238,6 +238,11 @@ const CreatorInternal = ({ onChangeCurrentStage={setCurrentStage} resetCreator={resetCreator} files={files} + quickStart={quickStart} + currentBundles={bundles} + currentTags={tags} + currentKind={rawKind} + onChangeKindDirect={setRawKind} /> diff --git a/src/components/creator/CreatorWizard.tsx b/src/components/creator/CreatorWizard.tsx index e6c82964..aa5d47cb 100644 --- a/src/components/creator/CreatorWizard.tsx +++ b/src/components/creator/CreatorWizard.tsx @@ -36,6 +36,7 @@ import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome' import { downloadFile } from '@redhat-cloud-services/frontend-components-utilities/helpers'; import SimpleButton from '../SimpleButton'; import DdfNumberInput from '../DdfNumberInput'; +import { ExtendedQuickstart } from '../../utils/fetchQuickstarts'; import { NAME_BUNDLES, NAME_DESCRIPTION, @@ -66,6 +67,11 @@ export type CreatorWizardProps = { filterData: FilterData; onChangeTags: (tags: { [kind: string]: string[] }) => void; onChangeMetadataTags: (tags: Array<{ kind: string; value: string }>) => void; + quickStart?: ExtendedQuickstart; + currentBundles?: string[]; + currentTags?: { [kind: string]: string[] }; + currentKind?: ItemKind | null; + onChangeKindDirect?: (kind: ItemKind | null) => void; }; type ViewMode = 'wizard' | 'creator'; @@ -312,11 +318,43 @@ const CreatorWizard = ({ onChangeMetadataTags, files, filterData, + quickStart, + currentBundles, + currentTags, + currentKind, + onChangeKindDirect, }: CreatorWizardProps) => { const chrome = useChrome(); const [viewMode, setViewMode] = useState('wizard'); const schema = useMemo(() => makeSchema(chrome, filterData), []); + // Derive initialValues from shared state so wizard ↔ YAML stays in sync. + // FormRenderer is conditionally rendered (unmounted in YAML mode), so it + // picks up fresh initialValues each time the user switches back to wizard. + const initialValues = useMemo(() => { + if (!quickStart) return undefined; + return { + [NAME_KIND]: currentKind || undefined, + [NAME_BUNDLES]: currentBundles, + [NAME_TAGS]: currentTags, + [NAME_TITLE]: quickStart.spec.displayName || '', + [NAME_DESCRIPTION]: quickStart.spec.description || '', + [NAME_DURATION]: quickStart.spec.durationMinutes, + [NAME_URL]: quickStart.spec.link?.href, + [NAME_PREREQUISITES]: quickStart.spec.prerequisites, + [NAME_PANEL_INTRODUCTION]: quickStart.spec.introduction, + [NAME_TASK_TITLES]: quickStart.spec.tasks?.map((t) => t.title || '') || [ + '', + ], + [NAME_TASKS_ARRAY]: quickStart.spec.tasks?.map((t) => ({ + description: t.description, + enable_work_check: !!t.review, + work_check_instructions: t.review?.instructions, + work_check_help: t.review?.failedTaskHelp, + })), + }; + }, [quickStart, currentKind, currentBundles, currentTags]); + // Update stage when switching to creator mode to show preview const handleViewModeChange = (newMode: ViewMode) => { setViewMode(newMode); @@ -368,6 +406,7 @@ const CreatorWizard = ({ {}} schema={schema} + initialValues={initialValues} componentMapper={componentMapper} > {({ formFields }) => ( @@ -409,6 +448,10 @@ const CreatorWizard = ({ onChangeBundles={onChangeBundles} onChangeTags={onChangeTags} onChangeMetadataTags={onChangeMetadataTags} + onChangeKind={onChangeKindDirect} + quickStart={quickStart} + currentBundles={currentBundles} + currentTags={currentTags} /> )} diff --git a/src/components/creator/CreatorYAMLView.test.tsx b/src/components/creator/CreatorYAMLView.test.tsx new file mode 100644 index 00000000..93b1fc43 --- /dev/null +++ b/src/components/creator/CreatorYAMLView.test.tsx @@ -0,0 +1,635 @@ +import React from 'react'; +import { + act, + fireEvent, + render, + screen, + waitFor, +} from '@testing-library/react'; +import CreatorYAMLView from './CreatorYAMLView'; +import { CreatorWizardContext } from './context'; +import { CreatorFiles } from './types'; +import { DEFAULT_QUICKSTART_YAML } from '../../data/quickstart-templates'; +import { ExtendedQuickstart } from '../../utils/fetchQuickstarts'; + +// Mock downloadFile from frontend-components-utilities +const mockDownloadFile = jest.fn(); +jest.mock( + '@redhat-cloud-services/frontend-components-utilities/helpers', + () => ({ + downloadFile: (...args: unknown[]) => mockDownloadFile(...args), + }) +); + +// Mock Monaco Editor — render a simple textarea that mirrors onChange behavior +jest.mock('@monaco-editor/react', () => { + const MockEditor = ({ + value, + onChange, + }: { + value: string; + onChange: (value: string | undefined) => void; + }) => ( +