84 lines
3.4 KiB
TypeScript
84 lines
3.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { defaultReview } from '../../src/domain/review';
|
|
import { buildDashboardHtml } from '../../src/exports/dashboard-export';
|
|
import { combineDatasets } from '../../src/features/project-import/project-import';
|
|
import { updateReviewState } from '../../src/features/review-workspace/update-review-state';
|
|
import { filterAndSortRecords } from '../../src/features/search-filter/filter-records';
|
|
import { importFile } from '../../src/importers/importer';
|
|
import { createSnapshot, parseSnapshot } from '../../src/persistence/snapshot-store';
|
|
import { genericProfile } from '../../src/profiles/generic/generic-profile';
|
|
|
|
const options = { profiles: [genericProfile] };
|
|
|
|
describe('assessment workflow', () => {
|
|
it('imports, combines, searches, reviews, exports and snapshots multiple files', async () => {
|
|
const csv = [
|
|
'Title;Severity;Status;Asset',
|
|
'Synthetic weak policy;High;Open;dc01',
|
|
'Synthetic legacy protocol;Medium;Closed;server01'
|
|
].join('\n');
|
|
const json = JSON.stringify([
|
|
{ Title: 'Synthetic admin exposure', Severity: 'Critical', Status: 'Open', Asset: 'tenant01' }
|
|
]);
|
|
|
|
const datasets = await Promise.all([
|
|
importFile(new File([csv], 'directory.csv', { type: 'text/csv', lastModified: 1000 }), options),
|
|
importFile(new File([json], 'cloud.json', { type: 'application/json', lastModified: 2000 }), options)
|
|
]);
|
|
const project = combineDatasets(datasets, genericProfile);
|
|
const projectSheet = project.sheets.find(sheet => sheet.isProjectSheet);
|
|
|
|
expect(project.fileSize).toBeGreaterThan(0);
|
|
expect(project.lastModified).toBe(2000);
|
|
expect(projectSheet?.analysis.records).toHaveLength(3);
|
|
expect(projectSheet?.analysis.headers.slice(0, 2)).toEqual(['Source: File', 'Source: Sheet']);
|
|
|
|
const searchResults = filterAndSortRecords(projectSheet, {
|
|
activeProfile: genericProfile,
|
|
search: 'legacy',
|
|
sortColumn: 'all',
|
|
sortDirection: 'desc',
|
|
statusFilter: 'all',
|
|
actionOnly: false,
|
|
reviews: {}
|
|
});
|
|
expect(searchResults.map(record => record.title)).toEqual(['Synthetic legacy protocol']);
|
|
|
|
const selected = searchResults[0];
|
|
const reviewState = updateReviewState({ reviews: {}, actionOnly: false }, selected.id, {
|
|
...defaultReview(),
|
|
include: true,
|
|
status: 'In Bearbeitung',
|
|
priority: 'Hoch',
|
|
owner: 'Security Team',
|
|
nextStep: 'Disable legacy protocol'
|
|
});
|
|
const actionRecords = filterAndSortRecords(projectSheet, {
|
|
activeProfile: genericProfile,
|
|
search: '',
|
|
sortColumn: 'all',
|
|
sortDirection: 'desc',
|
|
statusFilter: 'all',
|
|
actionOnly: true,
|
|
reviews: reviewState.reviews
|
|
});
|
|
|
|
expect(actionRecords.map(record => record.id)).toEqual([selected.id]);
|
|
|
|
const dashboard = buildDashboardHtml(project.fileName, actionRecords.map(record => ({
|
|
record,
|
|
sheetName: projectSheet?.name ?? '',
|
|
review: reviewState.reviews[record.id]
|
|
})));
|
|
expect(dashboard).toContain('Synthetic legacy protocol');
|
|
expect(dashboard).toContain('Security Team');
|
|
expect(dashboard).toContain('Disable legacy protocol');
|
|
|
|
const snapshot = createSnapshot(project, reviewState.reviews);
|
|
const restored = parseSnapshot(JSON.stringify(snapshot));
|
|
|
|
expect(restored?.dataset.fileName).toBe(project.fileName);
|
|
expect(restored?.reviews[selected.id].owner).toBe('Security Team');
|
|
});
|
|
});
|