33import { act } from 'react' ;
44import { cleanup , fireEvent , render , screen , waitFor , within } from '@testing-library/react' ;
55import { afterEach , describe , expect , it , vi } from 'vitest' ;
6+ import type { SkillSummary } from '@open-design/contracts' ;
67
78vi . mock ( '../../src/components/home-hero/PlaceholderCarousel' , ( ) => ( {
89 PlaceholderCarousel : ( ) => null ,
@@ -25,6 +26,7 @@ import { requestHomeChip } from '../../src/runtime/home-intent';
2526import {
2627 createPluginAuthoringHandoff ,
2728 createPluginUseHandoff ,
29+ createSkillUseHandoff ,
2830 PLUGIN_AUTHORING_DEFAULT_GOAL ,
2931 PLUGIN_AUTHORING_PROMPT ,
3032} from '../../src/components/home-hero/plugin-authoring' ;
@@ -139,6 +141,21 @@ const HIDDEN_DEFAULT_PLUGIN = {
139141 } ,
140142} ;
141143
144+ const INDUSTRIAL_PRODUCT_DESIGN_SKILL : SkillSummary = {
145+ id : 'industrial-product-design' ,
146+ name : 'Industrial Product Design' ,
147+ description : 'Generate evidence-aware industrial product design directions.' ,
148+ triggers : [ 'industrial design' ] ,
149+ mode : 'design-system' ,
150+ previewType : 'markdown' ,
151+ designSystemRequired : false ,
152+ defaultFor : [ ] ,
153+ upstream : null ,
154+ hasBody : true ,
155+ examplePrompt : 'Develop three industrial design directions for an air purifier.' ,
156+ aggregatesExamples : false ,
157+ } ;
158+
142159// The Prototype chip binds to the bundled `example-web-prototype`
143160// plugin (which ships its own seed + layouts + checklist) instead of
144161// the generic od-new-generation router. Mirror that here so the
@@ -933,6 +950,44 @@ describe('HomeView prompt handoff', () => {
933950 } ) ) ;
934951 } ) ;
935952
953+ it ( 'submits an explicitly selected skill without the hidden default plugin' , async ( ) => {
954+ const fetchMock = vi . fn < typeof fetch > ( async ( url ) => {
955+ if ( typeof url === 'string' && url === '/api/plugins' ) {
956+ return new Response ( JSON . stringify ( { plugins : [ HIDDEN_DEFAULT_PLUGIN ] } ) , {
957+ status : 200 ,
958+ headers : { 'content-type' : 'application/json' } ,
959+ } ) ;
960+ }
961+ throw new Error ( `unexpected fetch ${ url } ` ) ;
962+ } ) ;
963+ vi . stubGlobal ( 'fetch' , fetchMock ) ;
964+ const onSubmit = vi . fn ( ) ;
965+
966+ render (
967+ < HomeView
968+ projects = { [ ] }
969+ skills = { [ INDUSTRIAL_PRODUCT_DESIGN_SKILL ] }
970+ onSubmit = { onSubmit }
971+ onOpenProject = { ( ) => undefined }
972+ onViewAllProjects = { ( ) => undefined }
973+ promptHandoff = { createSkillUseHandoff ( 12 , INDUSTRIAL_PRODUCT_DESIGN_SKILL ) }
974+ /> ,
975+ ) ;
976+
977+ await waitFor ( ( ) => {
978+ expect ( screen . getByTestId ( 'home-hero-active-skill' ) . textContent )
979+ . toContain ( 'Industrial Product Design' ) ;
980+ } ) ;
981+ fireEvent . click ( screen . getByTestId ( 'home-hero-submit' ) ) ;
982+
983+ expect ( onSubmit ) . toHaveBeenCalledWith ( expect . objectContaining ( {
984+ prompt : 'Develop three industrial design directions for an air purifier.' ,
985+ pluginId : null ,
986+ skillId : 'industrial-product-design' ,
987+ appliedPluginSnapshotId : null ,
988+ } ) ) ;
989+ } ) ;
990+
936991 it ( 'falls back to od-new-generation when od-plugin-authoring is not registered yet' , async ( ) => {
937992 const fetchMock = vi . fn < typeof fetch > ( async ( url ) => {
938993 if ( typeof url === 'string' && url === '/api/plugins' ) {
0 commit comments