186f9ef380
Fix getNamespaces() to skip cluster-scoped resources (Namespace: "") that caused Router.createRouteURL to throw TypeError on the Namespaces page. Add Playwright E2E smoke tests with Authentik OIDC auth for CI and K8s token fallback for local dev. Add Gitea Actions E2E workflow, vitest unit test infrastructure, and test-utils fixtures. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
135 lines
3.9 KiB
TypeScript
135 lines
3.9 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
import React from 'react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import { makeAuditData, makeResult } from '../test-utils';
|
|
|
|
// Mock Headlamp lib
|
|
vi.mock('@kinvolk/headlamp-plugin/lib', () => ({
|
|
ApiProxy: { request: vi.fn() },
|
|
}));
|
|
|
|
// Mock Headlamp CommonComponents as thin pass-throughs
|
|
vi.mock('@kinvolk/headlamp-plugin/lib/CommonComponents', () => ({
|
|
Loader: ({ title }: { title: string }) => <div data-testid="loader">{title}</div>,
|
|
SectionBox: ({ title, children }: { title?: string; children?: React.ReactNode }) => (
|
|
<div data-testid="section-box" data-title={title}>
|
|
{children}
|
|
</div>
|
|
),
|
|
SectionHeader: ({ title }: { title: string }) => <div data-testid="section-header">{title}</div>,
|
|
StatusLabel: ({ status, children }: { status: string; children?: React.ReactNode }) => (
|
|
<span data-testid="status-label" data-status={status}>
|
|
{children}
|
|
</span>
|
|
),
|
|
NameValueTable: ({ rows }: { rows: Array<{ name: string; value: React.ReactNode }> }) => (
|
|
<table data-testid="name-value-table">
|
|
<tbody>
|
|
{rows.map(row => (
|
|
<tr key={row.name}>
|
|
<td>{row.name}</td>
|
|
<td>{row.value}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
),
|
|
PercentageCircle: ({ label }: { label: string }) => (
|
|
<div data-testid="percentage-circle">{label}</div>
|
|
),
|
|
PercentageBar: () => <div data-testid="percentage-bar" />,
|
|
}));
|
|
|
|
// Mock the context hook — we'll override per test via mockReturnValue
|
|
const mockUsePolarisDataContext = vi.fn();
|
|
vi.mock('../api/PolarisDataContext', () => ({
|
|
usePolarisDataContext: () => mockUsePolarisDataContext(),
|
|
}));
|
|
|
|
import DashboardView from './DashboardView';
|
|
|
|
describe('DashboardView', () => {
|
|
it('renders loader when loading', () => {
|
|
mockUsePolarisDataContext.mockReturnValue({
|
|
data: null,
|
|
loading: true,
|
|
error: null,
|
|
});
|
|
|
|
render(<DashboardView />);
|
|
expect(screen.getByTestId('loader')).toHaveTextContent('Loading Polaris audit data');
|
|
});
|
|
|
|
it('renders error message when error is set', () => {
|
|
mockUsePolarisDataContext.mockReturnValue({
|
|
data: null,
|
|
loading: false,
|
|
error: 'Access denied (403)',
|
|
});
|
|
|
|
render(<DashboardView />);
|
|
expect(screen.getByText('Access denied (403)')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders score, check distribution, and cluster info with data', () => {
|
|
const data = makeAuditData([
|
|
makeResult({
|
|
Results: {
|
|
c1: {
|
|
ID: 'c1',
|
|
Message: '',
|
|
Details: [],
|
|
Success: true,
|
|
Severity: 'warning',
|
|
Category: 'X',
|
|
},
|
|
c2: {
|
|
ID: 'c2',
|
|
Message: '',
|
|
Details: [],
|
|
Success: false,
|
|
Severity: 'danger',
|
|
Category: 'X',
|
|
},
|
|
},
|
|
}),
|
|
]);
|
|
|
|
mockUsePolarisDataContext.mockReturnValue({
|
|
data,
|
|
loading: false,
|
|
error: null,
|
|
});
|
|
|
|
render(<DashboardView />);
|
|
|
|
// Score circle shows 50%
|
|
expect(screen.getByTestId('percentage-circle')).toHaveTextContent('50%');
|
|
|
|
// Check distribution values
|
|
expect(screen.getByText('Total Checks')).toBeInTheDocument();
|
|
|
|
// Cluster info section (title is in data-title attr of SectionBox)
|
|
const sectionBoxes = screen.getAllByTestId('section-box');
|
|
const clusterInfoBox = sectionBoxes.find(
|
|
el => el.getAttribute('data-title') === 'Cluster Info'
|
|
);
|
|
expect(clusterInfoBox).toBeDefined();
|
|
|
|
// Cluster info values
|
|
expect(screen.getByText('Nodes')).toBeInTheDocument();
|
|
expect(screen.getByText('Pods')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders "No Data" when no data and no error', () => {
|
|
mockUsePolarisDataContext.mockReturnValue({
|
|
data: null,
|
|
loading: false,
|
|
error: null,
|
|
});
|
|
|
|
render(<DashboardView />);
|
|
expect(screen.getByText('No Polaris audit results found.')).toBeInTheDocument();
|
|
});
|
|
});
|