Assessor_2.0/tests/workflows/assessment-workflow.test.ts

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');
});
});