#!/usr/bin/env python3
"""
TEST 11: Email-Only Test (NO Calendar Invite)
This test sends ONLY the invitation email to the external participant.
It does NOT confirm the booking, so NO calendar events should be created.
Expected result:
- External receives 1 email with 3 proposed slots + booking link
- NO calendar invite should be received
- Organizer's calendar stays CLEAN (no events)
- Internal attendees' calendars stay CLEAN (no events)
To confirm the booking later (simulate external user confirming):
- Manually call confirm_booking() or use the booking page
"""
import asyncio
import sys
from datetime import datetime, timedelta
from src.mcp_servers.mcp_client import MCPClient
# Configuration
MCP_SERVER_URL = "http://localhost:8001"
# Test accounts (approved for testing)
INTERNAL_ATTENDEE = "giovanni.albero@infocert.it"
EXTERNAL_EMAIL = "filippo.savarese@gmail.com"
EXTERNAL_NAME = "Filippo External"
async def main():
print("π TEST 11: Email-Only Test (NO Calendar Invite)")
print("=" * 60)
print()
client = MCPClient(MCP_SERVER_URL)
session_id = None
try:
# Step 1: Get authenticated user (organizer)
print("π STEP 1: Get Authenticated User (Organizer)")
print("-" * 60)
auth_result = await client.get_authenticated_user()
organizer = auth_result['user']
print(f"β
Organizer: {organizer['displayName']} ({organizer['mail']})")
print()
# Step 2: Find available slots
print("π STEP 2: Find Available Meeting Times")
print("-" * 60)
print(f" Checking availability for:")
print(f" β’ {organizer['mail']} (organizer)")
print(f" β’ {INTERNAL_ATTENDEE} (internal)")
print()
slots = await client.find_meeting_times(
attendees=[organizer['mail'], INTERNAL_ATTENDEE],
duration_minutes=30
)
if not slots:
print(f"β No available slots found")
return
print(f"β
Found {len(slots)} available slots")
for idx, slot in enumerate(slots[:3], 1):
print(f" {idx}. {slot['start']} β {slot['end']}")
print()
# Step 3: Create booking session
print("π STEP 3: Create Hybrid Booking Session")
print("-" * 60)
session_result = await client.create_booking_session(
organizer_email=organizer['mail'],
organizer_name=organizer['displayName'],
external_email=EXTERNAL_EMAIL,
external_name=EXTERNAL_NAME,
internal_attendees=[
{
"email": INTERNAL_ATTENDEE,
"name": "Giovanni Albero"
}
],
proposed_slots=slots[:3],
meeting_subject="TEST 11 - Email Only (NO Calendar Invite)"
)
if not session_result or 'session_id' not in session_result:
print(f"β Failed to create session: {session_result}")
return
session_id = session_result['session_id']
booking_url = session_result['booking_url']
print(f"β
Session created:")
print(f" Session ID: {session_id}")
print(f" Booking URL: {booking_url}")
print()
# Step 4: Send invitation email (ONLY EMAIL, NO CALENDAR EVENT!)
print("π STEP 4: Send Invitation Email")
print("-" * 60)
print("β οΈ IMPORTANT: This sends ONLY an email, NO calendar event!")
print()
invite_result = await client.send_booking_invitation(
session_id=session_id
)
if not invite_result or not invite_result.get('success'):
print(f"β Failed to send invitation: {invite_result}")
return
print(f"β
Invitation email sent to: {EXTERNAL_EMAIL}")
print(f" Sent at: {invite_result.get('sent_at')}")
print()
# Step 5: Verify calendar stays clean
print("π STEP 5: Verify Calendar Stays Clean")
print("-" * 60)
print("β
NO calendar events created yet!")
print("β
Organizer's calendar: CLEAN")
print("β
Internal attendees' calendars: CLEAN")
print()
# Step 6: What the external user should receive
print("π STEP 6: What External User Receives")
print("-" * 60)
print(f"π§ 1 EMAIL to {EXTERNAL_EMAIL}:")
print(f" Subject: Meeting Invitation: TEST 11 - Email Only (NO Calendar Invite)")
print(f" Content:")
print(f" β’ Message from {organizer['displayName']}")
print(f" β’ 3 proposed time slots")
print(f" β’ Button: 'Select Your Preferred Time'")
print(f" β’ Link to booking page: {booking_url}")
print()
print("β NO CALENDAR INVITE RECEIVED (text/calendar)")
print("β NO .ics FILE ATTACHED")
print("β NO TEAMS MEETING LINK YET")
print()
# Step 7: Instructions for confirmation
print("=" * 60)
print("π― TEST COMPLETE - STOPPED BEFORE CONFIRMATION")
print("=" * 60)
print()
print("β
What happened:")
print(" 1. Found available slots for organizer + internal")
print(" 2. Created booking session")
print(" 3. Sent email to external participant")
print(" 4. NO calendar events created")
print()
print("π§ External user should have received:")
print(" β’ 1 HTML email with 3 proposed slots")
print(" β’ NO calendar invite")
print()
print("π
Calendars should be:")
print(f" β’ {organizer['displayName']}: CLEAN (no events)")
print(f" β’ {INTERNAL_ATTENDEE}: CLEAN (no events)")
print(f" β’ {EXTERNAL_EMAIL}: CLEAN (no events)")
print()
print("-" * 60)
print("π To confirm the booking (simulate external user):")
print("-" * 60)
print()
print("Option A: Use the booking page")
print(f" 1. Open: {booking_url}")
print(f" 2. Select a time slot")
print(f" 3. Click 'Confirm Booking'")
print()
print("Option B: Call API manually")
print(" python -c \"")
print(" import asyncio")
print(" from src.mcp_servers.mcp_client import MCPClient")
print(" async def confirm():")
print(f" client = MCPClient('{MCP_SERVER_URL}')")
print(" result = await client.call_action('bookings', 'confirm_hybrid_booking', {")
print(f" 'session_id': '{session_id}',")
print(" 'selected_slot_index': 0")
print(" })")
print(" print(result)")
print(" asyncio.run(confirm())")
print(" \"")
print()
print("-" * 60)
print("β οΈ AFTER CONFIRMATION:")
print("-" * 60)
print(" β’ Calendar event created for ALL 3 participants")
print(" β’ Teams meeting link included")
print(" β’ Microsoft sends calendar invites to all")
print(" β’ Calendars updated with confirmed event")
print()
print("=" * 60)
print(f"π Session ID for reference: {session_id}")
print("=" * 60)
except Exception as e:
print(f"\nβ ERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())