Files

168 lines
8.6 KiB
Markdown

---
phase: "13"
plan: "02"
subsystem: frontend-tests
tags: [tdd, red, frontend, cloud, queue, health, preview, store]
depends_on:
requires:
- "13-01"
provides:
- "13-02"
affects:
- "frontend/src/components/storage/StorageBrowser.vue"
- "frontend/src/views/CloudFolderView.vue"
- "frontend/src/stores/cloudConnections.js"
- "frontend/src/components/settings/SettingsCloudTab.vue"
tech_stack:
added: []
patterns:
- "Red-test-first: failing tests define D-01..D-18 behavior before implementation"
- "Backend-typed conflict/error bodies: frontend never guesses conflict kind"
- "No window.open() invariant: all cloud open/preview routes through authorized backend"
- "No-probe-on-navigation: health checks fire after failures, not on browse"
- "Health-state store centralization: single translation for browser and Settings"
key_files:
created:
- "frontend/src/components/storage/__tests__/StorageBrowser.cloud-queue.test.js"
- "frontend/src/views/__tests__/CloudFolderOpenPreview.test.js"
- "frontend/src/components/settings/__tests__/SettingsCloudTab.health.test.js"
modified:
- "frontend/src/views/__tests__/CloudFolderView.test.js"
- "frontend/src/stores/__tests__/cloudConnections.test.js"
- "frontend/src/views/__tests__/CloudFolderRenderedFlow.test.js"
decisions:
- "Backend-authored conflict/error bodies (kind + reason codes) rather than Vue-side guessing"
- "file-open event must trigger authorized API call, never window.open() to provider URL"
- "Upload queue is array of typed queue items; conflicts/errors pause whole queue explicitly"
- "Health state map in store is single truth for browser compact status and Settings diagnostics"
- "no-probe-on-navigation is a hard invariant: testCloudConnection not called during browse"
- "Google Drive broader scope consent copy is a test-locked requirement (T-13-09)"
metrics:
duration: "~30 minutes"
completed: "2026-06-22"
tasks_completed: 2
tasks_total: 2
files_created: 3
files_modified: 3
status: complete
---
# Phase 13 Plan 02: Frontend Red Tests for Cloud Queue, Health, and Preview Summary
**One-liner:** Created 42 red frontend tests covering shared cloud upload queue with backend-typed conflict/error dialogs, authorized open/preview with no raw provider URLs, health-state store centralization, reconnect-preserves-stale-metadata, and no-probe-on-navigation invariant.
## Tasks Completed
| Task | Name | Commit | Files |
|------|------|--------|-------|
| 1 | Add red shared-browser tests for queue, preview, and fallback download | 514925b | StorageBrowser.cloud-queue.test.js (new), CloudFolderOpenPreview.test.js (new), CloudFolderView.test.js (extended) |
| 2 | Add red store and health-flow tests for reconnect, broader Google consent, and no navigation probe | 8923ed5 | SettingsCloudTab.health.test.js (new), cloudConnections.test.js (extended), CloudFolderRenderedFlow.test.js (extended) |
## Test Results (RED State Confirmed)
All 42 new tests fail against the current implementation as required for TDD:
| Suite | New Tests | Failing (RED) | Passing |
|-------|-----------|---------------|---------|
| StorageBrowser.cloud-queue.test.js | 18 | 13 | 5 |
| CloudFolderOpenPreview.test.js | 8 | 7 | 1 |
| CloudFolderView.test.js (extensions) | 3 | 1 | 2 |
| SettingsCloudTab.health.test.js | 12 | 10 | 2 |
| cloudConnections.test.js (extensions) | 14 | 7 | 7 |
| CloudFolderRenderedFlow.test.js (extensions) | 4 | 4 | 0 |
| **Total** | **59** | **42** | **17** |
Existing 54 passing tests (Phase 12.1 suites) remain unaffected.
## What These Tests Lock
### Task 1: Queue and preview behavior (D-01, D-02, D-03, D-04, D-18, T-13-07, T-13-08)
**StorageBrowser.cloud-queue.test.js:**
- Sequential upload queue emits array (not single File), forwarded via `uploadQueue` prop
- `paused_conflict` state renders conflict dialog with exactly 4 actions: Keep both / Replace / Skip / Cancel all
- Conflict dialog shows backend-authored `existing_name`, not frontend-guessed text
- Each conflict action emits `upload-queue-resolve` with typed `action` field
- `paused_error` state renders error dialog with Retry / Skip / Cancel all (no conflict choices)
- Error dialog shows backend error message verbatim
- Remaining queued items remain visible in `upload-queue-list` while dialog is shown
- No `window.open()` for cloud file open — must emit `file-open` event
- `file-open` payload carries `provider_item_id`, no raw `https://` URLs
- Unsupported formats emit `file-download-fallback` or `file-open` (never `window.open`)
- No parallel `data-test="cloud-only-grid"` in the browser component
**CloudFolderOpenPreview.test.js:**
- `file-open` event triggers `api.openCloudFile(connectionId, provider_item_id)` — not `window.open()`
- `openCloudFile` arguments must not contain raw `https://` provider URLs
- Office/docx and Google Workspace files route to authorized backend (not native preview)
- No Google Docs/OneDrive URL opened via `window.open()`
- Backend `preview_url` is DocuVault-relative; no provider URLs in rendered HTML
- View handles `file-open` itself; must NOT re-emit it to parent router
- No anchor element click hack during PDF preview
**CloudFolderView.test.js extensions:**
- No HTML table or `cloud-only-grid` in thin view
- `uploadQueue` prop forwarded to StorageBrowser as array
- Upload event from browser handled as queue operation (not immediate single-file upload)
### Task 2: Health-state, reconnect, consent, and no-probe (D-12..D-17, T-13-06, T-13-09)
**SettingsCloudTab.health.test.js:**
- Renders a Test connection button for active connections
- Renders a Reconnect button for REQUIRES_REAUTH connections
- Shows error detail beyond a generic status badge
- Clicking Test calls `testConnection(connectionId)`
- DEGRADED connection shows actionable warning without triggering disconnect confirmation
- Disconnect confirmation dialog does not appear automatically on mount
- Disconnect button click does NOT immediately call `store.disconnect()` — confirmation required
- Disconnect confirmation copy states provider files are untouched
- Google Drive connect/reconnect copy explicitly mentions broader storage access (not just `drive.file`)
- `gdrive-scope-notice` or `gdrive-consent-copy` data-test element must exist
- `credentials_enc`, `access_token`, `refresh_token` never appear in rendered HTML
**cloudConnections.test.js extensions:**
- Store exposes `connectionHealth` or `healthState` field
- `setConnectionHealth('conn-1', {state: 'requires_reauth'})` stores actionable health state
- `setConnectionHealth` distinguishes `degraded` from `requires_reauth`
- Ordinary browse does NOT call `testCloudConnection` (no-probe-on-navigation)
- `handleHealthFailure` schedules a health retest (sets `pendingHealthRetest` flag)
- `markReconnectRefreshPending` sets a pending folder refresh flag
- `markReconnecting` preserves `browseItems` and sets freshness to `stale`/`reconnecting`
- `fetchConnections` marks connections with null health for testing
**CloudFolderRenderedFlow.test.js extensions:**
- Warning freshness renders both cached items AND a health/reconnect banner
- A Reconnect button is accessible inside the browser (not only in Settings)
- `requires_reauth` freshness renders reauthentication prompt; cached items remain visible
- Folder-navigate does not call `testCloudConnection` as a side effect
## Deviations from Plan
None — plan executed exactly as written. The test failures are the intended RED state for a TDD plan.
## Threat Mitigations Locked by Tests
| Threat ID | Category | Mitigation |
|-----------|----------|------------|
| T-13-06 | Tampering | `cloudConnections.test.js` requires no background health probe on navigation |
| T-13-07 | Information Disclosure | `CloudFolderOpenPreview.test.js` forbids `window.open()` and raw provider URLs |
| T-13-08 | Repudiation | `StorageBrowser.cloud-queue.test.js` requires explicit pause/resume and backend-typed choices |
| T-13-09 | Spoofing | `SettingsCloudTab.health.test.js` requires explicit broader Google scope consent copy |
## Stub Inventory
No stubs that prevent plan goals: all test files are pure red test specifications. No implementation code was created in this plan.
## Self-Check: PASSED
| Check | Result |
|-------|--------|
| frontend/src/components/storage/__tests__/StorageBrowser.cloud-queue.test.js | FOUND |
| frontend/src/views/__tests__/CloudFolderOpenPreview.test.js | FOUND |
| frontend/src/components/settings/__tests__/SettingsCloudTab.health.test.js | FOUND |
| .planning/phases/13-virtual-local-cloud-operations/13-02-SUMMARY.md | FOUND |
| Commit 514925b (task 1) | FOUND |
| Commit 8923ed5 (task 2) | FOUND |
| 42 red tests confirmed | VERIFIED |
| 54 existing tests still passing | VERIFIED |