@@ -18,6 +18,7 @@ import {
1818 openStoredWorkspaceContextById ,
1919 seedLocalWorkspaceContexts ,
2020} from './github-pr-drawer/github-pr-drawer.helpers.js'
21+ import { selectWorkspacesRepositoryFilter } from './github-pr-drawer/github-pr-drawer.helpers.js'
2122
2223test ( 'PR/BYOT controls are visible and chat stays hidden until token connect' , async ( {
2324 page,
@@ -418,6 +419,191 @@ test('Local workspace can be renamed from Workspaces drawer', async ({ page }) =
418419 . toBe ( renamedTitle )
419420} )
420421
422+ test ( 'Active Local non-PR workspace can be renamed from Workspaces drawer' , async ( {
423+ page,
424+ } ) => {
425+ const activeWorkspaceId = 'active_local_workspace_rename_allowed'
426+ const originalTitle = 'Active local rename original title'
427+ const renamedTitle = 'Active local rename updated title'
428+
429+ await waitForAppReady ( page )
430+
431+ await seedLocalWorkspaceContexts ( page , [
432+ {
433+ id : activeWorkspaceId ,
434+ repo : '' ,
435+ workspaceScope : 'local' ,
436+ head : 'feat/active-local-rename-allowed' ,
437+ prTitle : originalTitle ,
438+ prContextState : 'inactive' ,
439+ prNumber : null ,
440+ tabs : [
441+ {
442+ id : 'component' ,
443+ path : 'src/component.tsx' ,
444+ language : 'tsx' ,
445+ role : 'component' ,
446+ content : 'export const App = () => <main>active local rename allowed</main>' ,
447+ order : 0 ,
448+ source : 'workspace' ,
449+ dirty : false ,
450+ } ,
451+ ] ,
452+ activeTabId : 'component' ,
453+ } ,
454+ ] )
455+
456+ await page . reload ( )
457+ await waitForAppReady ( page )
458+
459+ const workspacesToggle = page . getByRole ( 'button' , {
460+ name : 'Workspaces' ,
461+ exact : true ,
462+ } )
463+ await workspacesToggle . click ( )
464+
465+ const workspaceSelect = page . getByLabel ( 'Stored workspace' )
466+ const renameButton = page . getByRole ( 'button' , { name : 'Rename' , exact : true } )
467+ await expect ( renameButton ) . toBeVisible ( )
468+
469+ await expect ( workspaceSelect ) . toHaveValue ( activeWorkspaceId )
470+ await expect ( renameButton ) . toBeEnabled ( )
471+
472+ page . once ( 'dialog' , async dialog => {
473+ expect ( dialog . type ( ) ) . toBe ( 'prompt' )
474+ expect ( dialog . defaultValue ( ) ) . toBe ( originalTitle )
475+ await dialog . accept ( renamedTitle )
476+ } )
477+
478+ await renameButton . click ( )
479+ await expect ( page . locator ( '#workspaces-status' ) ) . toContainText ( 'Renamed workspace.' )
480+
481+ const records = await getAllWorkspaceRecords ( page )
482+ const renamedRecord = records . find ( record => record ?. id === activeWorkspaceId )
483+
484+ expect ( renamedRecord ) . toBeTruthy ( )
485+ expect ( typeof renamedRecord ?. prTitle === 'string' ? renamedRecord . prTitle : '' ) . toBe (
486+ renamedTitle ,
487+ )
488+
489+ const selectedLabelText = await page
490+ . locator ( '#workspaces-select option:checked' )
491+ . textContent ( )
492+ expect ( String ( selectedLabelText ?? '' ) . trim ( ) ) . toBe ( renamedTitle )
493+ await expect ( page . locator ( '#workspace-context-status' ) ) . toContainText ( renamedTitle )
494+ } )
495+
496+ test ( 'Active Local workspace with active PR context and null PR number cannot be renamed from Workspaces drawer' , async ( {
497+ page,
498+ } ) => {
499+ const activeWorkspaceId = 'active_local_workspace_rename_blocked_pr_associated'
500+
501+ await waitForAppReady ( page )
502+
503+ await seedLocalWorkspaceContexts ( page , [
504+ {
505+ id : activeWorkspaceId ,
506+ repo : '' ,
507+ workspaceScope : 'local' ,
508+ head : 'feat/active-local-rename-blocked' ,
509+ prTitle : 'PR-associated local workspace' ,
510+ prContextState : 'active' ,
511+ prNumber : null ,
512+ tabs : [
513+ {
514+ id : 'component' ,
515+ path : 'src/component.tsx' ,
516+ language : 'tsx' ,
517+ role : 'component' ,
518+ content : 'export const App = () => <main>active local rename blocked</main>' ,
519+ order : 0 ,
520+ source : 'workspace' ,
521+ dirty : false ,
522+ } ,
523+ ] ,
524+ activeTabId : 'component' ,
525+ } ,
526+ ] )
527+
528+ await page . reload ( )
529+ await waitForAppReady ( page )
530+
531+ const workspacesToggle = page . getByRole ( 'button' , {
532+ name : 'Workspaces' ,
533+ exact : true ,
534+ } )
535+ await workspacesToggle . click ( )
536+
537+ const workspaceSelect = page . getByLabel ( 'Stored workspace' )
538+ const renameButton = page . getByRole ( 'button' , { name : 'Rename' , exact : true } )
539+ await expect ( renameButton ) . toBeVisible ( )
540+
541+ await expect ( workspaceSelect ) . toHaveValue ( activeWorkspaceId )
542+ await expect ( renameButton ) . toBeDisabled ( )
543+ } )
544+
545+ test ( 'Repository-scoped workspace cannot be renamed from Workspaces drawer' , async ( {
546+ page,
547+ } ) => {
548+ const repositoryFullName = 'knightedcodemonkey/develop'
549+ const repositoryWorkspaceId = 'repository_workspace_rename_blocked'
550+
551+ await waitForAppReady ( page )
552+
553+ await seedLocalWorkspaceContexts ( page , [
554+ {
555+ id : repositoryWorkspaceId ,
556+ repo : repositoryFullName ,
557+ workspaceScope : 'repository' ,
558+ head : 'feat/repository-rename-blocked' ,
559+ prTitle : 'Repository scoped workspace' ,
560+ prContextState : 'inactive' ,
561+ prNumber : null ,
562+ tabs : [
563+ {
564+ id : 'component' ,
565+ path : 'src/component.tsx' ,
566+ language : 'tsx' ,
567+ role : 'component' ,
568+ content : 'export const App = () => <main>repository rename blocked</main>' ,
569+ order : 0 ,
570+ source : 'workspace' ,
571+ dirty : false ,
572+ } ,
573+ ] ,
574+ activeTabId : 'component' ,
575+ } ,
576+ ] )
577+
578+ await page . route ( 'https://api.github.com/user/repos**' , async route => {
579+ await route . fulfill ( {
580+ status : 200 ,
581+ contentType : 'application/json' ,
582+ body : JSON . stringify ( [
583+ {
584+ id : 11 ,
585+ owner : { login : 'knightedcodemonkey' } ,
586+ name : 'develop' ,
587+ full_name : repositoryFullName ,
588+ default_branch : 'main' ,
589+ permissions : { push : true } ,
590+ } ,
591+ ] ) ,
592+ } )
593+ } )
594+
595+ await page . reload ( )
596+ await waitForAppReady ( page )
597+ await connectByotWithSingleRepo ( page )
598+ await selectWorkspacesRepositoryFilter ( page , repositoryFullName )
599+
600+ const workspaceSelect = page . getByLabel ( 'Stored workspace' )
601+ const renameButton = page . getByRole ( 'button' , { name : 'Rename' , exact : true } )
602+
603+ await expect ( workspaceSelect ) . toHaveValue ( repositoryWorkspaceId )
604+ await expect ( renameButton ) . toBeHidden ( )
605+ } )
606+
421607test ( 'chat stays usable after opening a Local workspace with PAT connected' , async ( {
422608 page,
423609} ) => {
0 commit comments