import { render, screen } from '@testing-library/react'; import React from 'react'; import { AnnotationCustomSections } from './AnnotationCustomSections'; describe('', () => { it('renders text annotations under section groups', () => { render( , ); expect(screen.getByRole('heading', { name: 'deployment details' })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: 'support' })).toBeInTheDocument(); expect(screen.getByText('owner name')).toBeInTheDocument(); expect(screen.getByText('Delivery Platform')).toBeInTheDocument(); expect(screen.getByText('contact')).toBeInTheDocument(); expect(screen.getByText('On call')).toBeInTheDocument(); }); it('sanitizes HTML annotations while enforcing rel on targeted links', () => { const { container } = render( RunbookDashboard', })} resource={resource()} />, ); const links = screen.getAllByRole('link'); expect(links).toHaveLength(2); links.forEach((link) => { expect(link).toHaveAttribute('target', '_blank'); expect(link).toHaveAttribute('rel', 'noopener noreferrer'); expect(link).not.toHaveAttribute('onclick'); }); expect(screen.getByRole('link', { name: 'Runbook' })).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Dashboard' })).toBeInTheDocument(); expect(container.querySelector('[target="dashboard"]')).not.toBeInTheDocument(); expect(container.querySelector('script')).not.toBeInTheDocument(); }); it('escapes interpolated resource values in HTML annotations', () => { const { container } = render( Owner: {{ displayName }}', })} resource={resource({ displayName: 'Evil', })} />, ); expect(screen.getByText('Owner:')).toBeInTheDocument(); expect(container).toHaveTextContent('Evil'); expect(container.querySelector('a[href="https://evil.example"]')).not.toBeInTheDocument(); }); it('interpolates path placeholders against resource and manifest values', () => { render( , ); expect(screen.getByText('frontend in production from frontend-manifest')).toBeInTheDocument(); }); it('leaves non-path expression placeholders unresolved', () => { render( 'frontend', })} />, ); expect(screen.getByText('{{ displayName | uppercase }} {{ getDisplayName() }}')).toBeInTheDocument(); }); it('leaves prototype-chain path placeholders unresolved', () => { const { container } = render( , ); const text = container.textContent || ''; expect(text).toContain( '{{ constructor }} {{ resource.constructor }} {{ resource["constructor"] }} {{ resource.__proto__ }} {{ resource.prototype }} frontend', ); expect(text).not.toContain('function Object'); expect(text).not.toContain('[object Object]'); }); it('treats inherited function path values as missing', () => { const { container } = render( , ); const text = container.textContent || ''; expect(text).toContain('before after frontend'); expect(text).not.toContain('function toString'); expect(text).not.toContain('[native code]'); }); it('strips target attributes from sanitized non-anchor elements', () => { const { container } = render( ContainerRunbook', })} resource={resource()} />, ); const content = screen.getByText('Container'); const link = screen.getByRole('link', { name: 'Runbook' }); expect(content).not.toHaveAttribute('target'); expect(link).toHaveAttribute('target', '_blank'); expect(link).toHaveAttribute('rel', 'noopener noreferrer'); expect(container.querySelector('div[target]')).not.toBeInTheDocument(); }); it('renders text entries before HTML entries within the same section', () => { const { container } = render( Runbook', 'runbook.details.spinnaker.io/summary': 'Read this first', })} resource={resource()} />, ); const sectionText = container.querySelector('.content-body')?.textContent || ''; expect(sectionText.indexOf('Read this first')).toBeLessThan(sectionText.indexOf('Runbook')); }); }); const manifestWithAnnotations = (annotations: { [key: string]: string }) => ({ metadata: { name: 'frontend-manifest', annotations, }, }); const resource = (overrides: any = {}) => ({ apiVersion: 'apps/v1', displayName: 'frontend', kind: 'Deployment', namespace: 'default', ...overrides, } as any);