test(13-02): add red store, health-flow, reconnect, and no-probe tests

- SettingsCloudTab.health.test.js: Test/Reconnect/Disconnect per-connection actions,
  explicit confirmation before credential removal, Google Drive broader scope consent
  copy (D-12/D-13/D-15/D-16/D-17/T-13-09)
- cloudConnections.test.js: connectionHealth state map, setConnectionHealth translation,
  degraded vs requires_reauth distinction, pendingHealthRetest after failure, reconnect
  preserves cached items, auto-test after connect, no-probe-on-navigation (D-12..D-15)
- CloudFolderRenderedFlow.test.js: warning+reconnect banner alongside cached items,
  requires_reauth renders actionable prompt, folder-navigate never triggers health probe
  (D-12/D-13/D-14/CONN-02/T-13-06)
This commit is contained in:
curo1305
2026-06-22 18:13:39 +02:00
parent 514925bd4c
commit 8923ed5b3c
3 changed files with 813 additions and 0 deletions
@@ -412,3 +412,154 @@ describe('filenames_render_as_text_not_html', () => {
expect(html).not.toContain('<img src=x onerror=alert(1)>')
})
})
// ── Phase 13 Plan 02: health warning and reconnect state rendered-flow tests ──
// These tests MUST FAIL until Phase 13 health/reconnect UI is implemented.
describe('warning_state_shows_health_banner_while_keeping_items_D14', () => {
it('warning freshness shows a health/reconnect banner alongside cached items', async () => {
/**
* D-12 / D-14: On a warning freshness state, the browser must show BOTH:
* 1. The cached items (stale metadata visible while DocuVault revalidates)
* 2. A health/reconnect banner with compact status and Reconnect action
*
* RED: current StorageBrowser shows a freshness warning text but no actionable
* reconnect affordance within the cloud browser.
*/
api.getCloudFoldersByConnectionId.mockResolvedValue({
items: [ROOT_FOLDER_A, ROOT_FILE_A],
capabilities: null,
freshness: WARNING_FRESHNESS,
})
const wrapper = mount(CloudFolderView, {
global: { stubs: leafStubs },
})
await flushPromises()
const html = wrapper.html()
// Items must still be rendered (stale metadata visible)
expect(html).toContain('Alpha')
expect(html).toContain('report.pdf')
// A health/reconnect UI element must be present
const hasHealthBanner = wrapper.find('[data-test="cloud-health-banner"]').exists()
|| wrapper.find('[data-test="connection-warning"]').exists()
|| wrapper.find('[data-test="reconnect-action"]').exists()
// RED: no health banner with reconnect affordance in the current browser
expect(hasHealthBanner).toBe(true)
})
it('warning state renders a Reconnect button inside the browser, not just a badge', async () => {
/**
* D-12: Compact status plus Reconnect must appear in the cloud browser —
* not just in Settings. The browser must surface actionable reconnect.
*
* RED: current browser shows stale warning text but no Reconnect button.
*/
api.getCloudFoldersByConnectionId.mockResolvedValue({
items: [ROOT_FOLDER_A],
capabilities: null,
freshness: WARNING_FRESHNESS,
})
const wrapper = mount(CloudFolderView, {
global: { stubs: leafStubs },
})
await flushPromises()
// A reconnect action must be accessible within the browser component
const reconnectEl = wrapper.find('[data-test="reconnect-action"]')
|| wrapper.find('button[aria-label="Reconnect"]')
// RED: no reconnect button in browser view
expect(
wrapper.find('[data-test="reconnect-action"]').exists()
|| !!wrapper.findAll('button').find(b => b.text().toLowerCase().includes('reconnect'))
).toBe(true)
})
})
describe('requires_reauth_state_shows_reauthentication_prompt_D14', () => {
it('requires_reauth freshness state shows a reauthentication prompt', async () => {
/**
* D-12 / CONN-02: When a connection requires re-authentication, the browser
* must show a clear reauthentication prompt (not just a generic error).
*
* RED: current rendered flow has no requires_reauth specific UI.
*/
const REAUTH_FRESHNESS = {
refresh_state: 'requires_reauth',
last_refreshed_at: '2026-06-20T10:00:00Z',
error_code: 'token_expired',
error_message: 'Your Google Drive access has expired.',
}
api.getCloudFoldersByConnectionId.mockResolvedValue({
items: [ROOT_FOLDER_A],
capabilities: null,
freshness: REAUTH_FRESHNESS,
})
const wrapper = mount(CloudFolderView, {
global: { stubs: leafStubs },
})
await flushPromises()
// A reauthentication-specific UI element must be rendered
const hasReauthUi = wrapper.find('[data-test="requires-reauth"]').exists()
|| wrapper.find('[data-test="reauth-prompt"]').exists()
|| wrapper.html().toLowerCase().includes('reconnect')
// RED: no reauth-specific UI in the current browser
expect(hasReauthUi).toBe(true)
// Items must still be shown (D-14: cached metadata visible during reauth state)
expect(wrapper.html()).toContain('Alpha')
})
})
describe('no_health_probe_on_folder_navigate_D13', () => {
it('navigating into a subfolder does NOT trigger a separate health API call', async () => {
/**
* D-13: Ordinary folder navigation must never trigger a provider health probe.
* getCloudFoldersByConnectionId is for browse — no side-effect health calls.
*
* RED: a naive implementation could call testCloudConnection on every navigate.
*/
api.getCloudFoldersByConnectionId.mockResolvedValue({
items: [ROOT_FOLDER_A],
capabilities: null,
freshness: FRESH_FRESHNESS,
})
const wrapper = mount(CloudFolderView, {
global: { stubs: leafStubs },
})
await flushPromises()
// Navigate into a subfolder
const storageBrowser = wrapper.findComponent({ name: 'StorageBrowser' })
expect(storageBrowser.exists()).toBe(true)
api.getCloudFoldersByConnectionId.mockResolvedValue({
items: [ROOT_FILE_A],
capabilities: null,
freshness: FRESH_FRESHNESS,
})
await storageBrowser.vm.$emit('folder-navigate', ROOT_FOLDER_A)
await flushPromises()
// Browse API was called for the subfolder — that's expected
expect(api.getCloudFoldersByConnectionId).toHaveBeenCalledTimes(2)
// testCloudConnection (if it exists) must NOT have been called during navigation
const { testCloudConnection } = await import('../../api/client.js')
if (typeof testCloudConnection === 'function') {
expect(testCloudConnection).not.toHaveBeenCalled()
}
// The invariant is: browse calls = exactly N navigations; health calls = 0
})
})