@@ -160,6 +160,102 @@ suite('DeepnoteTreeDataProvider', () => {
160160 } ) ;
161161 } ) ;
162162
163+ suite ( 'loading state' , ( ) => {
164+ test ( 'should show loading item on first getChildren call' , async ( ) => {
165+ const children = await provider . getChildren ( ) ;
166+
167+ assert . isArray ( children ) ;
168+ assert . strictEqual ( children . length , 1 ) ;
169+ assert . strictEqual ( children [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
170+ assert . strictEqual ( children [ 0 ] . contextValue , 'loading' ) ;
171+ } ) ;
172+
173+ test ( 'should create loading item with correct properties' , async ( ) => {
174+ const children = await provider . getChildren ( ) ;
175+ const loadingItem = children [ 0 ] ;
176+
177+ assert . strictEqual ( loadingItem . type , DeepnoteTreeItemType . Loading ) ;
178+ assert . strictEqual ( loadingItem . label , 'Scanning for Deepnote projects...' ) ;
179+ assert . strictEqual ( loadingItem . collapsibleState , 0 ) ; // TreeItemCollapsibleState.None
180+ assert . strictEqual ( loadingItem . data , null ) ;
181+ assert . isDefined ( loadingItem . iconPath ) ;
182+ } ) ;
183+
184+ test ( 'should not show loading item after initial scan completes' , async ( ) => {
185+ const firstChildren = await provider . getChildren ( ) ;
186+ assert . strictEqual ( firstChildren . length , 1 ) ;
187+ assert . strictEqual ( firstChildren [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
188+
189+ // Wait for the scan to complete - give it time to finish
190+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
191+
192+ const secondChildren = await provider . getChildren ( ) ;
193+ assert . isArray ( secondChildren ) ;
194+
195+ if ( secondChildren . length > 0 ) {
196+ assert . notStrictEqual ( secondChildren [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
197+ }
198+ } ) ;
199+
200+ test ( 'should reset loading state on refresh' , async ( ) => {
201+ const firstChildren = await provider . getChildren ( ) ;
202+ assert . strictEqual ( firstChildren [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
203+
204+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
205+
206+ const afterScan = await provider . getChildren ( ) ;
207+ if ( afterScan . length > 0 ) {
208+ assert . notStrictEqual ( afterScan [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
209+ }
210+
211+ // Call refresh to reset state, should show loading again
212+ provider . refresh ( ) ;
213+ const afterRefresh = await provider . getChildren ( ) ;
214+ assert . isArray ( afterRefresh ) ;
215+ assert . strictEqual ( afterRefresh . length , 1 ) ;
216+ assert . strictEqual ( afterRefresh [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
217+ } ) ;
218+
219+ test ( 'should handle multiple concurrent getChildren calls during initial scan' , async ( ) => {
220+ const promise1 = provider . getChildren ( ) ;
221+ const promise2 = provider . getChildren ( ) ;
222+ const promise3 = provider . getChildren ( ) ;
223+
224+ const [ children1 , children2 , children3 ] = await Promise . all ( [ promise1 , promise2 , promise3 ] ) ;
225+
226+ // All should return loading item
227+ assert . strictEqual ( children1 . length , 1 ) ;
228+ assert . strictEqual ( children1 [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
229+
230+ assert . strictEqual ( children2 . length , 1 ) ;
231+ assert . strictEqual ( children2 [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
232+
233+ assert . strictEqual ( children3 . length , 1 ) ;
234+ assert . strictEqual ( children3 [ 0 ] . type , DeepnoteTreeItemType . Loading ) ;
235+ } ) ;
236+
237+ test ( 'should not show loading item when called with parent element' , async ( ) => {
238+ const mockProjectItem = new DeepnoteTreeItem (
239+ DeepnoteTreeItemType . ProjectFile ,
240+ {
241+ filePath : '/workspace/project.deepnote' ,
242+ projectId : 'project-123'
243+ } ,
244+ mockProject ,
245+ 1 // TreeItemCollapsibleState.Collapsed
246+ ) ;
247+
248+ // Even during initial scan, should not show loading for children of a project
249+ const children = await provider . getChildren ( mockProjectItem ) ;
250+
251+ assert . isArray ( children ) ;
252+
253+ children . forEach ( ( child ) => {
254+ assert . notStrictEqual ( child . type , DeepnoteTreeItemType . Loading ) ;
255+ } ) ;
256+ } ) ;
257+ } ) ;
258+
163259 suite ( 'integration scenarios' , ( ) => {
164260 test ( 'should maintain independence between multiple providers' , ( ) => {
165261 const provider1 = new DeepnoteTreeDataProvider ( ) ;
0 commit comments