Assessor_2.0/tests/features/results-header-actions.test...

39 lines
3.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// @vitest-environment jsdom
import { act, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { expect, it, vi } from 'vitest';
import { FloatingResultsWindow } from '../../src/features/linked-results/FloatingResultsWindow';
import { makeSheet } from '../../src/importers/sheet-factory';
vi.mock('../../src/app/AppProvider', () => ({useOptionalApp:()=>undefined}));
vi.mock('../../src/features/related-findings/RelatedFindings',()=>({RelatedFindingRing:({record}:{record:{id:string}})=>record.id==='grouped'?<button className="related-finding-ring is-inline" aria-label="Synthetic group"><span/></button>:null}));
it.each(['light','dark'])('keeps title and actions separate with a stable optional group slot through minimize/restore (%s)',async theme=>{
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT',true);vi.stubGlobal('ResizeObserver',class{observe(){}disconnect(){}});
document.documentElement.dataset.theme=theme;
const record=makeSheet('Synthetic',[['Name'],['Evidence']],'','synthetic.csv').analysis.records[0];
const before=JSON.stringify(record);const bookmark=vi.fn(),open=vi.fn(),close=vi.fn();
const host=document.createElement('div');document.body.append(host);const root=createRoot(host);
const long='Unexpected principal with metadata edit permission on a GPO linked to a critical AD container '.repeat(8);
function Example(){const [minimized,setMinimized]=useState(true);return <>{['grouped','ungrouped'].map((id,index)=><FloatingResultsWindow key={id} id={id} title={`Results (${index+1}) – ${index?long:'SMBv1 is enabled on Domain Controllers'}`} finding={{...record,id}} sheets={[]} color="" zIndex={1} offset={index*40} search="" minimized={minimized} onToggleMinimize={()=>setMinimized(value=>!value)} onActivate={()=>{}} onClose={close} onToggleBookmark={bookmark} onOpenRecord={open}/>)}</>}
try{
await act(async()=>root.render(<Example/>));
const windows=()=>[...host.querySelectorAll('.results-window')];
for(const node of windows()){
expect(node.querySelector('.results-window-actions .results-window-related-slot')).not.toBeNull();
expect(node.querySelector('.results-window-head > .related-finding-ring')).toBeNull();
expect(node.querySelector('.results-window-actions')?.lastElementChild?.classList.contains('results-window-close')).toBe(true);
expect(node.querySelector('.results-window-close')?.previousElementSibling?.classList.contains('results-window-related-slot')).toBe(true);
}
expect(windows()[0].querySelector('.results-window-related-slot button')).not.toBeNull();
expect(windows()[1].querySelector('.results-window-related-slot')?.children).toHaveLength(0);
expect(windows()[1].querySelector('.results-window-name')?.getAttribute('title')).toBe(long.trim());
await act(async()=>windows()[1].querySelector<HTMLButtonElement>('.results-window-bookmark')!.click());expect(bookmark).toHaveBeenCalledOnce();
await act(async()=>windows()[1].querySelector<HTMLButtonElement>('.results-window-action')!.click());expect(open).toHaveBeenCalledOnce();
await act(async()=>windows()[1].querySelector<HTMLButtonElement>('.results-window-toggle')!.click());
expect(windows().every(node=>!node.classList.contains('is-minimized'))).toBe(true);
expect(windows().every(node=>node.querySelector('.results-window-actions')?.lastElementChild?.classList.contains('results-window-close'))).toBe(true);
expect(windows()[0].querySelector('.results-window-related-slot button')).not.toBeNull();
await act(async()=>windows()[1].querySelector<HTMLButtonElement>('.results-window-close')!.click());expect(close).toHaveBeenCalledOnce();
expect(JSON.stringify(record)).toBe(before);
}finally{await act(async()=>root.unmount());host.remove();vi.unstubAllGlobals();delete document.documentElement.dataset.theme;}
});