11/**
22 * @vitest -environment jsdom
33 *
4- * A surface's own landing must not change the conversation it fronts. Failure modes: Home's
5- * Assistant sharing Search's unsent question, a new chat losing its Search address, the landing
6- * outliving the first turn, a restored chat entry flashing the dashboard's skeleton, and a caller
7- * without a landing (the extension, Search) seeing any of it.
4+ * Transient states a browser run cannot hold still. Failure modes: the landing rendering before the
5+ * session arrives, and a restored chat entry flashing the dashboard while the router takes over.
86 */
97import { act , type ReactNode } from 'react'
108import { authClientMock , authClientMockFns } from '@sim/testing/mocks/auth-client.mock'
@@ -24,12 +22,10 @@ import {
2422import { NuqsTestingAdapter } from 'nuqs/adapters/testing'
2523import { createRoot , type Root } from 'react-dom/client'
2624import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
27- import { useMothershipDraftsStore } from '@/stores/mothership-drafts/store'
2825
2926const mocks = vi . hoisted ( ( ) => ( {
3027 chat : vi . fn ( ) ,
3128 composer : vi . fn ( ) ,
32- send : vi . fn ( ) ,
3329} ) )
3430vi . mock ( '@/app/workspace/[workspaceId]/providers/feature-flags-provider' , ( ) => ( {
3531 useFeatureFlag : ( ) => false ,
@@ -78,9 +74,6 @@ import {
7874 type OrganizationLandingSlot ,
7975} from '@/app/o/[organizationId]/components/organization-conversation'
8076
81- const SEARCH_DRAFT = 'reader:organization:organization-a:search-assistant'
82- const HOME_DRAFT = 'reader:organization:organization-a:home-assistant'
83-
8477const landing = {
8578 fallback : < div > Dashboard skeleton</ div > ,
8679 render : ( { requestMode, composer, shortcuts } : OrganizationLandingSlot ) => (
@@ -101,17 +94,10 @@ async function render(element: ReactNode) {
10194 } )
10295}
10396
104- function composerProps ( ) {
105- const call = mocks . composer . mock . lastCall
106- if ( ! call ) throw new Error ( 'Composer has not rendered' )
107- return call [ 0 ]
108- }
109-
11097beforeEach ( ( ) => {
11198 vi . stubGlobal ( 'IS_REACT_ACT_ENVIRONMENT' , true )
11299 reactQueryMockFns . mockUseQuery . mockReturnValue ( createQueryResultMock ( ) )
113100 reactQueryMockFns . mockUseMutation . mockReturnValue ( createMutationResultMock ( ) )
114- useMothershipDraftsStore . setState ( { drafts : { } } )
115101 nextNavigationMockFns . mockUsePathname . mockReturnValue ( '/o/organization-a/home' )
116102 authClientMockFns . mockUseSession . mockReturnValue ( { data : { user : { id : 'reader' } } } )
117103 organizationProviderMockFns . mockUseOrganizationContext . mockReturnValue ( {
@@ -121,7 +107,7 @@ beforeEach(() => {
121107 canBuild : false ,
122108 viewer : { isAdmin : false , canUseSearchMcp : true } ,
123109 } )
124- mocks . chat . mockReturnValue ( { messages : [ ] , resources : [ ] , sendMessage : mocks . send } )
110+ mocks . chat . mockReturnValue ( { messages : [ ] , resources : [ ] , sendMessage : vi . fn ( ) } )
125111 mocks . composer . mockReturnValue ( < div > Question composer</ div > )
126112 container = document . createElement ( 'div' )
127113 document . body . appendChild ( container )
@@ -134,69 +120,6 @@ afterEach(async () => {
134120} )
135121
136122describe ( 'an Assistant conversation on a surface with its own landing' , ( ) => {
137- it ( 'hands its composer and the Assistant shortcuts to the surface’s landing, in place of the default heading' , async ( ) => {
138- await render (
139- < OrganizationConversation
140- requestMode = 'assistant'
141- draftId = 'home-assistant'
142- landing = { landing }
143- />
144- )
145- expect ( container . textContent ) . toContain ( 'Dashboard for assistant' )
146- expect ( container . textContent ) . toContain ( 'Question composer' )
147- expect ( container . querySelector ( '[data-testid="shortcuts"]' ) ?. textContent ) . toBe (
148- 'Legacy get started'
149- )
150- expect ( container . querySelector ( 'h1' ) ) . toBeNull ( )
151- } )
152-
153- it ( 'keeps its unsent question apart from Search’s Assistant, in both directions' , async ( ) => {
154- useMothershipDraftsStore . getState ( ) . setDraft ( SEARCH_DRAFT , { text : 'Asked from Search' } )
155- await render (
156- < OrganizationConversation
157- requestMode = 'assistant'
158- draftId = 'home-assistant'
159- landing = { landing }
160- />
161- )
162- expect ( composerProps ( ) . value ) . toBe ( '' )
163- await act ( async ( ) => composerProps ( ) . onChange ( 'Asked from Home' ) )
164- const { drafts } = useMothershipDraftsStore . getState ( )
165- expect ( drafts [ HOME_DRAFT ] ?. text ) . toBe ( 'Asked from Home' )
166- expect ( drafts [ SEARCH_DRAFT ] ?. text ) . toBe ( 'Asked from Search' )
167- } )
168-
169- it ( 'addresses a new chat under Search, in the Assistant view' , async ( ) => {
170- await render (
171- < OrganizationConversation
172- requestMode = 'assistant'
173- draftId = 'home-assistant'
174- landing = { landing }
175- />
176- )
177- const [ , chatId , options ] = mocks . chat . mock . lastCall ?? [ ]
178- expect ( chatId ) . toBeUndefined ( )
179- expect ( options . requestMode ) . toBe ( 'assistant' )
180- expect ( options . getChatUrl ( 'chat-1' ) ) . toBe ( '/o/organization-a/search/chat/chat-1?mode=assistant' )
181- } )
182-
183- it ( 'gives way to today’s conversation view at the first turn' , async ( ) => {
184- mocks . chat . mockReturnValue ( {
185- messages : [ { id : 'turn' } ] ,
186- resources : [ ] ,
187- sendMessage : mocks . send ,
188- } )
189- await render (
190- < OrganizationConversation
191- requestMode = 'assistant'
192- draftId = 'home-assistant'
193- landing = { landing }
194- />
195- )
196- expect ( container . textContent ) . toContain ( 'Conversation view' )
197- expect ( container . textContent ) . not . toContain ( 'Dashboard for' )
198- } )
199-
200123 it ( 'holds the surface’s fallback until the session arrives' , async ( ) => {
201124 authClientMockFns . mockUseSession . mockReturnValue ( { data : null } )
202125 await render ( < OrganizationConversation requestMode = 'assistant' landing = { landing } /> )
@@ -209,13 +132,3 @@ describe('an Assistant conversation on a surface with its own landing', () => {
209132 expect ( container . textContent ) . toBe ( '' )
210133 } )
211134} )
212-
213- describe ( 'a conversation without a landing' , ( ) => {
214- it ( 'keeps today’s landing and Search’s draft key' , async ( ) => {
215- useMothershipDraftsStore . getState ( ) . setDraft ( SEARCH_DRAFT , { text : 'Asked from Search' } )
216- await render ( < OrganizationConversation requestMode = 'assistant' /> )
217- expect ( container . querySelector ( 'h1' ) ?. textContent ) . toBe ( 'Search Acme' )
218- expect ( container . textContent ) . toContain ( 'Legacy get started' )
219- expect ( composerProps ( ) . value ) . toBe ( 'Asked from Search' )
220- } )
221- } )
0 commit comments