168 lines
8.6 KiB
Markdown
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 |
|