|
| 1 | +/* OverviewPage.unlimited.test.tsx — exercises the storage-tile unlimited (∞) |
| 2 | + * branch. No tier in plans.yaml has an unlimited object-storage cap today, so |
| 3 | + * the only way to reach the `storageUnlimited ? '∞'` path (and cover that line) |
| 4 | + * is to mock the per-tier limit helper to return -1. This guarantees the tile |
| 5 | + * renders ∞ honestly if a future tier ever sets storage_storage_mb: -1. */ |
| 6 | + |
| 7 | +import { describe, it, expect, afterEach, vi } from 'vitest' |
| 8 | +import { render, cleanup, waitFor } from '@testing-library/react' |
| 9 | +import { MemoryRouter } from 'react-router-dom' |
| 10 | + |
| 11 | +const listResourcesMock = vi.fn().mockResolvedValue({ ok: true, items: [], total: 0 }) |
| 12 | +const fetchActivityMock = vi.fn().mockResolvedValue({ ok: true, items: [] }) |
| 13 | +const listDeploymentsMock = vi.fn().mockResolvedValue({ ok: true, items: [], total: 0 }) |
| 14 | + |
| 15 | +vi.mock('../api', async () => { |
| 16 | + const actual = await vi.importActual<typeof import('../api')>('../api') |
| 17 | + return { |
| 18 | + ...actual, |
| 19 | + listResources: (...a: unknown[]) => listResourcesMock(...a), |
| 20 | + fetchActivity: (...a: unknown[]) => fetchActivityMock(...a), |
| 21 | + listDeployments: (...a: unknown[]) => listDeploymentsMock(...a), |
| 22 | + } |
| 23 | +}) |
| 24 | + |
| 25 | +vi.mock('../hooks/useDashboardCtx', () => ({ useDashboardCtx: vi.fn() })) |
| 26 | + |
| 27 | +// Force the object-storage cap to -1 (unlimited) for this suite only. |
| 28 | +vi.mock('../lib/planLimits', async () => { |
| 29 | + const actual = await vi.importActual<typeof import('../lib/planLimits')>('../lib/planLimits') |
| 30 | + return { |
| 31 | + ...actual, |
| 32 | + objectStorageLimitGBFor: () => -1, |
| 33 | + } |
| 34 | +}) |
| 35 | + |
| 36 | +import { OverviewPage } from './OverviewPage' |
| 37 | +import { useDashboardCtx } from '../hooks/useDashboardCtx' |
| 38 | + |
| 39 | +afterEach(() => { |
| 40 | + cleanup() |
| 41 | + vi.clearAllMocks() |
| 42 | +}) |
| 43 | + |
| 44 | +describe('Overview object-storage tile — unlimited (∞) branch', () => { |
| 45 | + it('renders "∞" in the tile label when the tier object cap is -1', async () => { |
| 46 | + vi.mocked(useDashboardCtx).mockReturnValue({ |
| 47 | + me: { user: { id: 'u', email: 'e', tier: 'team' }, team: { id: 't', slug: 's', name: 's', tier: 'team' } }, |
| 48 | + meErr: null, |
| 49 | + meLoading: false, |
| 50 | + env: 'production', |
| 51 | + envs: ['production'], |
| 52 | + counts: { resources: 0, deployments: 0, vault: 0, team: 1 }, |
| 53 | + resources: [], |
| 54 | + } as never) |
| 55 | + |
| 56 | + const { container } = render( |
| 57 | + <MemoryRouter> |
| 58 | + <OverviewPage /> |
| 59 | + </MemoryRouter>, |
| 60 | + ) |
| 61 | + await waitFor(() => expect(listResourcesMock).toHaveBeenCalled()) |
| 62 | + |
| 63 | + const tiles = Array.from(container.querySelectorAll('.stat .k')) |
| 64 | + const objTile = tiles.find((k) => (k.textContent ?? '').includes('object storage')) |
| 65 | + expect(objTile).toBeTruthy() |
| 66 | + expect(objTile!.textContent).toContain('∞') |
| 67 | + // sub-line also reflects unlimited |
| 68 | + await waitFor(() => { |
| 69 | + expect(container.textContent).toContain('unlimited · team tier') |
| 70 | + }) |
| 71 | + }) |
| 72 | +}) |
0 commit comments