1+ import { LOOPS_FLAG } from "@posthog/shared" ;
12import { ANALYTICS_EVENTS } from "@posthog/shared/analytics-events" ;
23import { Theme } from "@radix-ui/themes" ;
34import { act , render , screen } from "@testing-library/react" ;
@@ -9,8 +10,9 @@ type CapturedDragEvent = {
910 canceled ?: boolean ;
1011} ;
1112
12- const { track, dndCapture } = vi . hoisted ( ( ) => ( {
13+ const { track, dndCapture, featureFlags } = vi . hoisted ( ( ) => ( {
1314 track : vi . fn ( ) ,
15+ featureFlags : new Map < string , boolean > ( ) ,
1416 dndCapture : { } as {
1517 onDragStart ?: ( event : CapturedDragEvent ) => void ;
1618 onDragOver ?: ( event : CapturedDragEvent ) => void ;
@@ -19,6 +21,9 @@ const { track, dndCapture } = vi.hoisted(() => ({
1921} ) ) ;
2022
2123vi . mock ( "@posthog/ui/shell/analytics" , ( ) => ( { track } ) ) ;
24+ vi . mock ( "@posthog/ui/features/feature-flags/useFeatureFlag" , ( ) => ( {
25+ useFeatureFlag : ( key : string ) => featureFlags . get ( key ) ?? true ,
26+ } ) ) ;
2227vi . mock ( "@dnd-kit/react" , ( ) => ( {
2328 DragDropProvider : ( {
2429 onDragStart,
@@ -45,32 +50,13 @@ vi.mock("@dnd-kit/react/sortable", () => ({
4550 } ) ,
4651} ) ) ;
4752
48- import {
49- CUSTOMIZABLE_NAV_ITEM_IDS ,
50- type CustomizableNavItemId ,
51- } from "@posthog/ui/features/sidebar/constants" ;
5253import { useSidebarStore } from "@posthog/ui/features/sidebar/sidebarStore" ;
53- import { CustomizeSidebarDialog } from "./CustomizeSidebarDialog" ;
54+ import { CustomizeSidebarSettings } from "./CustomizeSidebarDialog" ;
5455
55- function availability (
56- overrides : Partial < Record < CustomizableNavItemId , boolean > > = { } ,
57- ) {
58- return {
59- ...( Object . fromEntries (
60- CUSTOMIZABLE_NAV_ITEM_IDS . map ( ( id ) => [ id , true ] ) ,
61- ) as Record < CustomizableNavItemId , boolean > ) ,
62- ...overrides ,
63- } ;
64- }
65-
66- function renderDialog ( available = availability ( ) ) {
56+ function renderSettings ( ) {
6757 return render (
6858 < Theme >
69- < CustomizeSidebarDialog
70- open
71- onOpenChange = { vi . fn ( ) }
72- available = { available }
73- />
59+ < CustomizeSidebarSettings />
7460 </ Theme > ,
7561 ) ;
7662}
@@ -107,132 +93,129 @@ function rowLabels() {
10793 . map ( ( checkbox ) => checkbox . closest ( "label" ) ?. textContent ) ;
10894}
10995
110- describe ( "CustomizeSidebarDialog " , ( ) => {
96+ describe ( "CustomizeSidebarSettings " , ( ) => {
11197 beforeEach ( ( ) => {
11298 track . mockReset ( ) ;
99+ featureFlags . clear ( ) ;
113100 useSidebarStore . setState ( { navItemOverrides : { } , navItemOrder : [ ] } ) ;
114101 } ) ;
115102
103+ it ( "omits items whose features are unavailable" , ( ) => {
104+ featureFlags . set ( LOOPS_FLAG , false ) ;
105+
106+ renderSettings ( ) ;
107+
108+ expect (
109+ screen . queryByRole ( "checkbox" , { name : "Loops" } ) ,
110+ ) . not . toBeInTheDocument ( ) ;
111+ } ) ;
112+
116113 it ( "unchecking a visible item demotes it and tracks the change" , async ( ) => {
117114 const user = userEvent . setup ( ) ;
118- renderDialog ( ) ;
115+ renderSettings ( ) ;
119116
120- await user . click ( screen . getByRole ( "checkbox" , { name : "MCP servers " } ) ) ;
117+ await user . click ( screen . getByRole ( "checkbox" , { name : "Command Center " } ) ) ;
121118
122- expect ( useSidebarStore . getState ( ) . navItemOverrides [ "mcp-servers " ] ) . toBe (
119+ expect ( useSidebarStore . getState ( ) . navItemOverrides [ "command-center " ] ) . toBe (
123120 false ,
124121 ) ;
125122 expect ( track ) . toHaveBeenCalledWith ( ANALYTICS_EVENTS . SIDEBAR_CUSTOMIZED , {
126- item : "mcp_servers " ,
123+ item : "command_center " ,
127124 visible : false ,
128125 } ) ;
129126 } ) ;
130127
131128 it ( "checking a hidden item promotes it and tracks the change" , async ( ) => {
132129 const user = userEvent . setup ( ) ;
133- renderDialog ( ) ;
130+ useSidebarStore . setState ( { navItemOverrides : { inbox : false } } ) ;
131+ renderSettings ( ) ;
134132
135- await user . click ( screen . getByRole ( "checkbox" , { name : "Search " } ) ) ;
133+ await user . click ( screen . getByRole ( "checkbox" , { name : "Inbox " } ) ) ;
136134
137- expect ( useSidebarStore . getState ( ) . navItemOverrides . search ) . toBe ( true ) ;
135+ expect ( useSidebarStore . getState ( ) . navItemOverrides . inbox ) . toBe ( true ) ;
138136 expect ( track ) . toHaveBeenCalledWith ( ANALYTICS_EVENTS . SIDEBAR_CUSTOMIZED , {
139- item : "search " ,
137+ item : "inbox " ,
140138 visible : true ,
141139 } ) ;
142140 } ) ;
143141
144- it ( "omits items marked unavailable" , ( ) => {
145- renderDialog ( availability ( { loops : false } ) ) ;
146-
147- expect (
148- screen . queryByRole ( "checkbox" , { name : "Loops" } ) ,
149- ) . not . toBeInTheDocument ( ) ;
150- expect (
151- screen . getByRole ( "checkbox" , { name : "Configure" } ) ,
152- ) . toBeInTheDocument ( ) ;
153- } ) ;
154-
155142 it ( "renders rows in the stored order" , ( ) => {
156- useSidebarStore . setState ( { navItemOrder : [ "configure" , "search " ] } ) ;
157- renderDialog ( ) ;
143+ useSidebarStore . setState ( { navItemOrder : [ "configure" , "inbox " ] } ) ;
144+ renderSettings ( ) ;
158145
159- expect ( rowLabels ( ) . slice ( 0 , 2 ) ) . toEqual ( [ "Configure" , "Search " ] ) ;
146+ expect ( rowLabels ( ) . slice ( 0 , 2 ) ) . toEqual ( [ "Configure" , "Inbox " ] ) ;
160147 } ) ;
161148
162149 it ( "previews on dragover and persists only on drop" , ( ) => {
163- renderDialog ( ) ;
150+ renderSettings ( ) ;
164151
165- dragStart ( "skills " ) ;
166- dragOver ( "skills " , "search " ) ;
152+ dragStart ( "loops " ) ;
153+ dragOver ( "loops " , "inbox " ) ;
167154
168- expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Skills " ) ;
155+ expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Loops " ) ;
169156 expect ( useSidebarStore . getState ( ) . navItemOrder ) . toEqual ( [ ] ) ;
170157 expect ( track ) . not . toHaveBeenCalled ( ) ;
171158
172- dragEnd ( "skills " ) ;
159+ dragEnd ( "loops " ) ;
173160
174161 expect ( useSidebarStore . getState ( ) . navItemOrder ) . toEqual ( [
175- "skills" ,
176- "search" ,
177- "inbox" ,
178- "agents" ,
179162 "loops" ,
180- "mcp-servers " ,
163+ "inbox " ,
181164 "command-center" ,
182165 "contexts" ,
183166 "activity" ,
184167 "configure" ,
185168 ] ) ;
186169 expect ( track ) . toHaveBeenCalledWith ( ANALYTICS_EVENTS . SIDEBAR_REORDERED , {
187- item : "skills " ,
170+ item : "loops " ,
188171 to_index : 0 ,
189172 } ) ;
190173 } ) ;
191174
192175 it ( "ignores a repeated dragover for the same source and target" , ( ) => {
193- renderDialog ( ) ;
176+ renderSettings ( ) ;
194177
195- dragStart ( "skills " ) ;
196- dragOver ( "skills " , "search " ) ;
197- dragOver ( "skills " , "search " ) ;
178+ dragStart ( "loops " ) ;
179+ dragOver ( "loops " , "inbox " ) ;
180+ dragOver ( "loops " , "inbox " ) ;
198181
199- expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Skills " ) ;
182+ expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Loops " ) ;
200183
201- dragEnd ( "skills " ) ;
184+ dragEnd ( "loops " ) ;
202185
203- expect ( useSidebarStore . getState ( ) . navItemOrder [ 0 ] ) . toBe ( "skills " ) ;
186+ expect ( useSidebarStore . getState ( ) . navItemOrder [ 0 ] ) . toBe ( "loops " ) ;
204187 } ) ;
205188
206189 it ( "a canceled drag drops the preview and leaves the store untouched" , ( ) => {
207- renderDialog ( ) ;
190+ renderSettings ( ) ;
208191
209- dragStart ( "skills " ) ;
210- dragOver ( "skills " , "search " ) ;
211- dragEnd ( "skills " , { cancel : true } ) ;
192+ dragStart ( "loops " ) ;
193+ dragOver ( "loops " , "inbox " ) ;
194+ dragEnd ( "loops " , { cancel : true } ) ;
212195
213- expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Search " ) ;
196+ expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Inbox " ) ;
214197 expect ( useSidebarStore . getState ( ) . navItemOrder ) . toEqual ( [ ] ) ;
215198 expect ( track ) . not . toHaveBeenCalled ( ) ;
216199 } ) ;
217200
218201 it ( "a drop without movement neither persists nor tracks" , ( ) => {
219- renderDialog ( ) ;
202+ renderSettings ( ) ;
220203
221- dragStart ( "skills " ) ;
222- dragEnd ( "skills " ) ;
204+ dragStart ( "loops " ) ;
205+ dragEnd ( "loops " ) ;
223206
224207 expect ( useSidebarStore . getState ( ) . navItemOrder ) . toEqual ( [ ] ) ;
225208 expect ( track ) . not . toHaveBeenCalled ( ) ;
226209 } ) ;
227210
228211 it ( "reset clears the stored order back to the default" , async ( ) => {
229212 const user = userEvent . setup ( ) ;
230- useSidebarStore . setState ( { navItemOrder : [ "loops" , "search " ] } ) ;
231- renderDialog ( ) ;
213+ useSidebarStore . setState ( { navItemOrder : [ "loops" , "inbox " ] } ) ;
214+ renderSettings ( ) ;
232215
233216 await user . click ( screen . getByRole ( "button" , { name : "Reset" } ) ) ;
234217
235218 expect ( useSidebarStore . getState ( ) . navItemOrder ) . toEqual ( [ ] ) ;
236- expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Search " ) ;
219+ expect ( rowLabels ( ) [ 0 ] ) . toBe ( "Inbox " ) ;
237220 } ) ;
238221} ) ;
0 commit comments