| # Verifying the Google Calendar connection end-to-end |
|
|
| > **Private-Space gotcha (the OAuth popup 404):** while the Space is private, |
| > `*.hf.space` URLs answer Hugging Face's 404 page for any request that lacks |
| > the signed access cookie. The app viewed EMBEDDED on huggingface.co |
| > authenticates its iframe with a short-lived signed URL, but the OAuth POPUP |
| > is a separate top-level window β when the subdomain cookie is missing or |
| > expired, **Connect opens a 404**. Fix: always open |
| > `https://paretooptimal-offgridschedula.hf.space` directly in its own tab |
| > (the redirect re-mints the cookie for the whole subdomain), then connect |
| > from there. Making the Space public would remove this entirely, at the cost |
| > of the deployed source tree becoming publicly browsable β deliberately NOT |
| > done (2026-06-12). |
| |
| Two layers of verification exist: |
| |
| 1. **In-app, automatic** β on every page load, `wireGcal()` round-trips the stored |
| token to `POST /oauth2/check`, which makes one real (scope-compatible) Google |
| API call. The Step 2a row and the export-bar badge upgrade from |
| "β connected" to **"β connected Β· verified"** when Google answers; a |
| *definitive* rejection (revoked/invalid token) clears the stored token and |
| flips everything to "not connected". Transient problems (OAuth env unset, |
| network down, `SERVE=gradio` mode where FastAPI routes aren't served) never |
| destroy the token β the UI just stays at the local shape-check state. |
| 2. **Scripted E2E** β `scripts/verify_gcal_e2e.py` proves the whole chain: |
| agent-extracted event β real push β API readback (title/location/start/ |
| reminder) β cleanup. |
|
|
| ## Browser loop (manual) |
|
|
| 1. Run locally with OAuth configured: |
| ``` |
| set GOOGLE_OAUTH_CLIENT_ID=... # a Google Cloud OAuth "Web application" client |
| set GOOGLE_OAUTH_CLIENT_SECRET=... |
| set SERVE=uvicorn |
| python app.py |
| ``` |
| 2. Open http://localhost:7860, switch to **βοΈ Online**, open Step 2a |
| **"π Connect your calendar"** β click **Connect** on the Google row β |
| consent in the popup. The row flips to "β connected", then upgrades to |
| **"β connected Β· verified"** within ~1s (the `/oauth2/check` round-trip). |
| 3. Paste the appointment text (the CANON sample in `tests/test_agent.py`) β |
| **Run the agents** β the export toolbar appears with the badge |
| **"Google: β connected Β· verified"** next to the three buttons. |
| 4. Click **Add to Google Calendar** β the status line shows the created event |
| link; open it: *Mon Jun 22 2026, 10:15β11:00, 112A West 72nd Street, |
| New York, NY 10023*, 60-minute reminder. |
| 5. **Reload the page** β still verified, no re-prompt (the acceptance test for |
| "never asks again"). |
|
|
| ### Negative paths |
|
|
| - Revoke access at https://myaccount.google.com/permissions β reload β the |
| check is definitive: token is cleared, every surface shows "not connected". |
| - Unset the OAuth env vars (or kill the network) β reload β stays at plain |
| "β connected" β transient failures never log the user out. |
| - Click **disconnect** in Step 2a β flips everywhere instantly. |
|
|
| ## Scripted loop |
|
|
| One-time: after connecting in the browser, copy the `gcal_token` value from |
| DevTools β Application β Local Storage into a file (e.g. `tok.json` β it's |
| gitignored territory; don't commit it). |
|
|
| ``` |
| python scripts/verify_gcal_e2e.py --token-file tok.json --check-only # liveness only |
| python scripts/verify_gcal_e2e.py --token-file tok.json # full E2E |
| ``` |
|
|
| The full run pushes the CANON event with a nonce in the title (`[e2e-xxxxxx]`), |
| reads it back through the API, asserts summary/location/start-instant/reminder, |
| and deletes it (use `--keep` to inspect it in the calendar first). Exit code 0 |
| = all checks passed. |
|
|