Skip to content

Commit

Permalink
add basic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bartoval committed Feb 12, 2025
1 parent e572f41 commit 4a61b6a
Show file tree
Hide file tree
Showing 16 changed files with 538 additions and 78 deletions.
88 changes: 88 additions & 0 deletions __tests__/AlertStatus.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';

import AlertStatus from '../src/console/pages/components/AlertStatus';

const mockUseWatchedSkupperResource = vi.hoisted(() => vi.fn());

vi.mock('../src/console/hooks/useSkupperWatchResource', () => ({
useWatchedSkupperResource: mockUseWatchedSkupperResource
}));

describe('AlertStatus Component', () => {
it('renders nothing when no site data is available', () => {
mockUseWatchedSkupperResource.mockReturnValue({ data: [] });

const { container } = render(<AlertStatus />);

expect(container.firstChild).toBeNull();
});

it('renders configured but not ready warning alert', () => {
mockUseWatchedSkupperResource.mockReturnValue({
data: [
{
isConfigured: true,
isReady: false
}
]
});

render(<AlertStatus />);

const warningAlert = screen.getByTestId('alert-status-warning');
expect(warningAlert).toBeInTheDocument();
expect(warningAlert).toHaveClass('pf-m-warning');
expect(warningAlert).toHaveTextContent(
'The site is Configured: you can create resources, but until the router is ready the effect is not usable'
);
});

it('renders error status danger alert', () => {
mockUseWatchedSkupperResource.mockReturnValue({
data: [
{
status: 'Error'
}
]
});

render(<AlertStatus />);

const dangerAlert = screen.getByTestId('alert-status-danger');
expect(dangerAlert).toBeInTheDocument();
expect(dangerAlert).toHaveClass('pf-m-danger');
expect(dangerAlert).toHaveTextContent(
'There is one or more errors. Please check the conditions on the Details page for more information'
);
});

it('does not render alert when site is configured and ready', () => {
mockUseWatchedSkupperResource.mockReturnValue({
data: [
{
isConfigured: true,
isReady: true
}
]
});

const { container } = render(<AlertStatus />);

expect(container.firstChild).toBeNull();
});

it('does not render alert when site is not configured', () => {
mockUseWatchedSkupperResource.mockReturnValue({
data: [
{
isConfigured: false
}
]
});

const { container } = render(<AlertStatus />);

expect(container.firstChild).toBeNull();
});
});
33 changes: 33 additions & 0 deletions __tests__/App.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';

import App from '../src/console/App';

vi.mock('../src/console/AppContent', () => ({
default: () => <div data-testid="app-content">App Content</div>
}));

vi.mock('../src/console/AppVersionValidator', () => ({
default: ({ children }: { children: React.ReactNode }) => <div data-testid="version-validator">{children}</div>
}));

describe('App', () => {
it('renders app structure correctly', () => {
render(<App />);

expect(screen.getByTestId('query-boundary')).toBeInTheDocument();
expect(screen.getByTestId('version-validator')).toBeInTheDocument();
expect(screen.getByTestId('app-content')).toBeInTheDocument();
});

it('maintains correct component hierarchy', () => {
render(<App />);

const queryBoundary = screen.getByTestId('query-boundary');
const versionValidator = screen.getByTestId('version-validator');
const appContent = screen.getByTestId('app-content');

expect(queryBoundary).toContainElement(versionValidator);
expect(versionValidator).toContainElement(appContent);
});
});
65 changes: 65 additions & 0 deletions __tests__/AppContent.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react';

import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';

import AppContent from '../src/console/AppContent';

const mockUseWatchedSkupperResource = vi.hoisted(() => vi.fn());

vi.mock('../src/console/hooks/useSkupperWatchResource', () => ({
useWatchedSkupperResource: mockUseWatchedSkupperResource
}));

vi.mock('../src/console/core/components/Loading', () => ({
default: function Loading() {
return React.createElement('div', { 'data-testid': 'loading' });
}
}));

vi.mock('../src/console/pages/SitePage', () => ({
default: function SitePage({ siteId }: { siteId: string }) {
return React.createElement('div', { 'data-testid': 'site-page', id: siteId });
}
}));

vi.mock('../src/console/pages/CreateSitePage', () => ({
default: function CreateSitePage() {
return React.createElement('div', { 'data-testid': 'create-site' });
}
}));

describe('AppContent', () => {
it('shows loading when not loaded', () => {
mockUseWatchedSkupperResource.mockReturnValue({ loaded: false });
render(<AppContent />);
expect(screen.getByTestId('loading')).toBeInTheDocument();
});

it('shows SitePage when site is configured', () => {
mockUseWatchedSkupperResource.mockReturnValue({
data: [{ isConfigured: true, identity: 'test-id' }],
loaded: true
});
render(<AppContent />);
expect(screen.getByTestId('site-page')).toBeInTheDocument();
});

it('shows SitePage when site has error', () => {
mockUseWatchedSkupperResource.mockReturnValue({
data: [{ hasError: true, identity: 'test-id' }],
loaded: true
});
render(<AppContent />);
expect(screen.getByTestId('site-page')).toBeInTheDocument();
});

it('shows CreateSitePage when site is not configured', () => {
mockUseWatchedSkupperResource.mockReturnValue({
data: [{ isConfigured: false, isReady: false, hasError: false }],
loaded: true
});
render(<AppContent />);
expect(screen.getByTestId('create-site')).toBeInTheDocument();
});
});
29 changes: 29 additions & 0 deletions __tests__/AppValidator.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import AppVersionValidator from '../src/console/AppVersionValidator';

vi.mock('../src/console/pages/ErrorOldSkupperVersionPage', () => ({
default: function ErrorPage() {
return React.createElement('div', { 'data-testid': 'error-page' });
}
}));

describe('AppVersionValidator', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('renders children when version is current', () => {
render(
<AppVersionValidator>
<div data-testid="child">Test Content</div>
</AppVersionValidator>
);

expect(screen.queryByTestId('error-page')).not.toBeInTheDocument();
expect(screen.getByTestId('child')).toBeInTheDocument();
});
});
35 changes: 35 additions & 0 deletions __tests__/ExternalLink.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { render } from '@testing-library/react';
import { describe, it, expect } from 'vitest';

import ExternalLink from '../src/console/core/components/ExternalLink';

describe('ExternalLink Component', () => {
const mockProps = {
href: 'https://example.com',
text: 'Example Link'
};

it('renders the link with correct attributes and content', () => {
const { getByText, getByRole } = render(<ExternalLink {...mockProps} />);

const linkElement = getByRole('link');

expect(linkElement).toHaveAttribute('href', mockProps.href);
expect(linkElement).toHaveAttribute('target', '_blank');
expect(linkElement).toHaveAttribute('rel', 'noopener noreferrer');

const textElement = getByText(mockProps.text);
expect(textElement).toBeTruthy();

const iconElement = linkElement.querySelector('svg');
expect(iconElement).toBeTruthy();
});

it('renders the external link icon correctly', () => {
const { container } = render(<ExternalLink {...mockProps} />);

const iconElement = container.querySelector('svg');
expect(iconElement).toBeTruthy();
expect(iconElement).toBeInstanceOf(SVGSVGElement);
});
});
96 changes: 96 additions & 0 deletions __tests__/InstructionBlock.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';

import InstructionBlock from '../src/console/core/components/InstructionBlock';

const MockExternalLink = vi.hoisted(() =>
vi.fn(({ href, text }) => (
<a href={href} data-testid="external-link">
{text}
</a>
))
);

vi.mock('../src/console/core/components/ExternalLink', () => ({
default: MockExternalLink
}));

describe('InstructionBlock Component', () => {
const baseProps = {
img: '/test-image.png',
title: 'Test Title',
description: 'Test Description'
};

it('renders basic component with required props', () => {
render(<InstructionBlock {...baseProps} />);

const image = screen.getByAltText('Link tutorial');
expect(image).toBeInTheDocument();
expect(image).toHaveAttribute('src', '/test-image.png');

const title = screen.getByRole('heading', { level: 3, name: 'Test Title' });
expect(title).toBeInTheDocument();

const description = screen.getByText('Test Description');
expect(description).toBeInTheDocument();
});

it('renders with two links', () => {
MockExternalLink.mockClear();

const propsWithTwoLinks = {
...baseProps,
link1: 'https://example1.com',
link1Text: 'First Link',
link2: 'https://example2.com',
link2Text: 'Second Link'
};

render(<InstructionBlock {...propsWithTwoLinks} />);

expect(MockExternalLink).toHaveBeenCalledTimes(2);

expect(MockExternalLink.mock.calls[0][0]).toEqual({
href: 'https://example1.com',
text: 'First Link'
});

expect(MockExternalLink.mock.calls[1][0]).toEqual({
href: 'https://example2.com',
text: 'Second Link'
});

const separator = screen.getByText('|');
expect(separator).toBeInTheDocument();

const links = screen.getAllByTestId('external-link');
expect(links).toHaveLength(2);
});

it('renders with additional component', () => {
const TestComponent = function () {
return <div>Additional Component</div>;
};

const propsWithComponent = {
...baseProps,
component: <TestComponent />
};

render(<InstructionBlock {...propsWithComponent} />);

const additionalComponent = screen.getByText('Additional Component');
expect(additionalComponent).toBeInTheDocument();
});

it('renders without links when not provided', () => {
MockExternalLink.mockClear();

render(<InstructionBlock {...baseProps} />);

expect(MockExternalLink).not.toHaveBeenCalled();
const links = screen.queryByTestId('external-link');
expect(links).toBeNull();
});
});
42 changes: 42 additions & 0 deletions __tests__/ProjectEntryTab.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { NamespaceManager } from '@config/db';
import { render } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';

import ProjectEntryTab from '../src/openshift/ProjectEntryTab';

vi.mock('../src/console/config/db', () => ({
NamespaceManager: {
setNamespace: vi.fn()
}
}));

vi.mock('../src/console/App', () => ({
default: vi.fn(() => <div data-testid="mocked-app">Mocked App</div>)
}));

describe('ProjectEntryTab Component', () => {
it('sets namespace when obj is provided', () => {
const mockObj = {
metadata: {
name: 'test-namespace'
}
};

render(<ProjectEntryTab obj={mockObj} />);

expect(NamespaceManager.setNamespace).toHaveBeenCalledWith('test-namespace');
});

it('renders App component', () => {
const mockObj = {
metadata: {
name: 'test-namespace'
}
};

const { getByTestId } = render(<ProjectEntryTab obj={mockObj} />);

const appComponent = getByTestId('mocked-app');
expect(appComponent).toBeInTheDocument();
});
});
Loading

0 comments on commit 4a61b6a

Please sign in to comment.