39 lines
3.8 KiB
TypeScript
39 lines
3.8 KiB
TypeScript
// @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;}
|
||
});
|