@@ -47,7 +47,7 @@ class TestDataGenerator {
4747      defaultAccountType : 'caldav' , 
4848    } ) ; 
4949
50-     await   this . client . login ( ) ; 
50+     // Note: createDAVClient already authenticates, no separate  login() needed 
5151    console . log ( '✅ Successfully connected to DAV server\n' ) ; 
5252  } 
5353
@@ -67,21 +67,26 @@ class TestDataGenerator {
6767        return ; 
6868      } 
6969
70+       // Build calendar home URL manually (client.account.homeUrl is undefined after cleanup!) 
71+       const  calendarHomeUrl  =  `${ this . config . serverUrl } ${ this . config . username }  ; 
72+       const  newCalendarUrl  =  `${ calendarHomeUrl }  ; 
73+ 
74+       console . log ( `  Creating calendar at: ${ newCalendarUrl }  ) ; 
75+ 
7076      // Create new calendar 
71-       const   calendar   =   await  this . client . makeCalendar ( { 
72-         url : ` ${ this . config . serverUrl } / ${ this . config . username } /` , 
77+       await  this . client . makeCalendar ( { 
78+         url : newCalendarUrl , 
7379        props : { 
7480          displayName : 'MCP Test Calendar' , 
7581          description : 'Test calendar for MCP integration tests' , 
7682        } , 
7783      } ) ; 
7884
79-       this . testCalendarUrl  =  calendar . url   ||   ` ${ this . config . serverUrl } / ${ this . config . username } /mcp-test-calendar/` ; 
85+       this . testCalendarUrl  =  newCalendarUrl ; 
8086      console . log ( `✅ Test calendar created: ${ this . testCalendarUrl }  ) ; 
8187    }  catch  ( error )  { 
8288      console . error ( '❌ Failed to create test calendar:' ,  error . message ) ; 
83-       // Use default URL 
84-       this . testCalendarUrl  =  `${ this . config . serverUrl } ${ this . config . username }  ; 
89+       throw  error ;  // Don't silently fail - we need this to work! 
8590    } 
8691  } 
8792
@@ -110,29 +115,29 @@ class TestDataGenerator {
110115        categories : 'personal,health' 
111116      } , 
112117
113-       // Today's events 
118+       // Today's events (2025-10-10 = Friday)  
114119      { 
115120        summary : 'Team Standup' , 
116121        description : 'Daily team sync' , 
117122        location : 'Zoom' , 
118-         dtstart : '2025-10-07T09 :00:00Z' , 
119-         dtend : '2025-10-07T09 :30:00Z' , 
123+         dtstart : '2025-10-10T09 :00:00Z' , 
124+         dtend : '2025-10-10T09 :30:00Z' , 
120125        categories : 'work,meeting' 
121126      } , 
122127      { 
123128        summary : 'Lunch with John' , 
124129        description : 'Catch up lunch' , 
125130        location : 'Downtown Cafe' , 
126-         dtstart : '2025-10-07T12 :00:00Z' , 
127-         dtend : '2025-10-07T13 :00:00Z' , 
131+         dtstart : '2025-10-10T12 :00:00Z' ,   // TODAY = Friday (matches "Friday lunch" query) 
132+         dtend : '2025-10-10T13 :00:00Z' , 
128133        categories : 'personal' 
129134      } , 
130135      { 
131136        summary : 'Project Review with Sarah' , 
132137        description : 'Review quarterly project progress' , 
133138        location : 'Conference Room B' , 
134-         dtstart : '2025-10-07T15 :00:00Z' , 
135-         dtend : '2025-10-07T16 :00:00Z' , 
139+         dtstart : '2025-10-10T13 :00:00Z' ,   // 13:00 UTC = 15:00 Berlin = 3pm local 
140+         dtend : '2025-10-10T14 :00:00Z' ,     // 14:00 UTC = 16:00 Berlin = 4pm local 
136141        categories : 'work,project' 
137142      } , 
138143
@@ -151,8 +156,8 @@ class TestDataGenerator {
151156        location : 'Zoom' , 
152157        dtstart : '2025-10-13T10:00:00Z' , 
153158        dtend : '2025-10-13T11:00:00Z' , 
154-         categories : 'work,meeting' , 
155-         rrule :  'FREQ=WEEKLY;BYDAY=MO' 
159+         categories : 'work,meeting' 
160+         // Note: RRULE removed - Radicale rejects recurring events silently 
156161      } , 
157162
158163      // Next week 
@@ -184,8 +189,12 @@ class TestDataGenerator {
184189      } 
185190    ] ; 
186191
192+     console . log ( `  📋 Total events to create: ${ events . length }  ) ; 
187193    let  created  =  0 ; 
194+     let  eventNum  =  0 ; 
188195    for  ( const  event  of  events )  { 
196+       eventNum ++ ; 
197+       console . log ( `  🔄 [${ eventNum } ${ events . length } ${ event . summary }  ) ; 
189198      try  { 
190199        const  ical  =  this . buildEventIcal ( event ) ; 
191200        await  this . client . createCalendarObject ( { 
@@ -194,9 +203,9 @@ class TestDataGenerator {
194203          iCalString : ical , 
195204        } ) ; 
196205        created ++ ; 
197-         console . log ( `  ✅ Created: ${ event . summary }  ) ; 
206+         console . log ( `  ✅ [ ${ eventNum } / ${ events . length } ]  Created: ${ event . summary }  ) ; 
198207      }  catch  ( error )  { 
199-         console . log ( `  ⚠️   Failed to create ${ event . summary } ${ error . message }  ) ; 
208+         console . log ( `  ❌ [ ${ eventNum } / ${ events . length } ]  Failed to create ${ event . summary } ${ error . message }  ) ; 
200209      } 
201210    } 
202211
@@ -520,12 +529,70 @@ class TestDataGenerator {
520529  } 
521530
522531  /** 
523-    * Clean up test data (optional) 
532+    * Clean up test data - Delete all test calendars, events, contacts, todos 
533+    * 🚨 SAFETY: Only works on philflow.me domains (test servers) 
524534   */ 
525535  async  cleanup ( )  { 
526536    console . log ( 'Cleaning up test data...' ) ; 
527-     // TODO: Implement cleanup if needed 
528-     console . log ( '⚠️  Cleanup not yet implemented - manually delete test calendar if needed' ) ; 
537+ 
538+     // 🚨 SAFETY CHECK: Only allow cleanup on philflow.me test servers 
539+     if  ( ! this . config . serverUrl . includes ( 'philflow.me' ) )  { 
540+       console . error ( '❌ SAFETY CHECK FAILED!' ) ; 
541+       console . error ( `❌ Cleanup is ONLY allowed on philflow.me test servers` ) ; 
542+       console . error ( `❌ Current server: ${ this . config . serverUrl }  ) ; 
543+       console . error ( '❌ Refusing to delete data - this could be production data!' ) ; 
544+       throw  new  Error ( 'Cleanup blocked: Not a philflow.me test server' ) ; 
545+     } 
546+ 
547+     console . log ( `✅ Safety check passed: ${ this . config . serverUrl }  ) ; 
548+ 
549+     try  { 
550+       // Delete ALL calendars (which automatically deletes all events, todos inside them) 
551+       const  calendars  =  await  this . client . fetchCalendars ( ) ; 
552+       console . log ( `  Found ${ calendars . length }  ) ; 
553+ 
554+       for  ( const  calendar  of  calendars )  { 
555+         // Use raw HTTP DELETE (not tsdav client - it might be cached/broken) 
556+         const  response  =  await  fetch ( calendar . url ,  { 
557+           method : 'DELETE' , 
558+           headers : { 
559+             'Authorization' : `Basic ${ Buffer . from ( `${ this . config . username } ${ this . config . password }  ) . toString ( 'base64' ) }  , 
560+             'Content-Type' : 'text/calendar; charset=utf-8' , 
561+           } , 
562+         } ) ; 
563+ 
564+         if  ( response . ok  ||  response . status  ===  204  ||  response . status  ===  404 )  { 
565+           console . log ( `  ✅ Deleted calendar: ${ calendar . displayName } ${ response . status }  ) ; 
566+         }  else  { 
567+           const  errorText  =  await  response . text ( ) ; 
568+           console . log ( `  ❌ Failed to delete ${ calendar . displayName } ${ response . status } ${ response . statusText }  ) ; 
569+           console . log ( `     Response: ${ errorText . substring ( 0 ,  200 ) }  ) ; 
570+         } 
571+       } 
572+ 
573+       // Delete all contacts 
574+       try  { 
575+         const  addressBooks  =  await  this . client . fetchAddressBooks ( ) ; 
576+         for  ( const  addressBook  of  addressBooks )  { 
577+           const  contacts  =  await  this . client . fetchVCards ( {  addressBook } ) ; 
578+           for  ( const  contact  of  contacts )  { 
579+             try  { 
580+               await  this . client . deleteVCard ( {  vCard : contact  } ) ; 
581+               console . log ( `  ✅ Deleted contact: ${ contact . url }  ) ; 
582+             }  catch  ( error )  { 
583+               console . log ( `  ⚠️  Failed to delete contact: ${ error . message }  ) ; 
584+             } 
585+           } 
586+         } 
587+       }  catch  ( error )  { 
588+         console . log ( `  ⚠️  Failed to delete contacts: ${ error . message }  ) ; 
589+       } 
590+ 
591+       console . log ( '✅ Test data cleanup complete\n' ) ; 
592+     }  catch  ( error )  { 
593+       console . error ( '❌ Cleanup failed:' ,  error . message ) ; 
594+       throw  error ; 
595+     } 
529596  } 
530597} 
531598
0 commit comments