feat(audit): free-text search, JSONL export of the view, labeled dev reset
Some checks failed
Security / Security check (push) Failing after 1s
Some checks failed
Security / Security check (push) Failing after 1s
- search field over flow/step/module/error/detail/project/id backs
the list and the export ('current view' semantics); match logic
is a top-level function with unit tests
- export writes one JSON object per line via the save dialog; the
CLI stays the canonical WORM-grade export
- the bare trash icon on the audit toolbar read as 'delete
evidence' (security-auditor finding) — the dev-only reset now
sits in a labeled overflow menu next to the export action
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
0e53572589
commit
5aa69104e7
7 changed files with 273 additions and 7 deletions
49
test/audit_filter_test.dart
Normal file
49
test/audit_filter_test.dart
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// Free-text audit search — the match function behind the audit
|
||||
// page's search field and JSONL export ("current view" semantics).
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:chain_studio/data/hub.dart';
|
||||
import 'package:chain_studio/pages/audit.dart';
|
||||
|
||||
AuditEvent _event({
|
||||
String type = 'step.completed',
|
||||
String? flow,
|
||||
String? step,
|
||||
String? module,
|
||||
String? error,
|
||||
String? detail,
|
||||
String project = '',
|
||||
}) {
|
||||
return AuditEvent(
|
||||
eventId: 'evt-1',
|
||||
timestamp: DateTime.utc(2026, 7, 18),
|
||||
type: type,
|
||||
flowName: flow,
|
||||
stepId: step,
|
||||
moduleName: module,
|
||||
error: error,
|
||||
detail: detail,
|
||||
project: project,
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
test('matches on every displayed field, case-insensitive', () {
|
||||
expect(matchesAuditQuery(_event(flow: 'Rechnungslauf'), 'rechnung'), isTrue);
|
||||
expect(matchesAuditQuery(_event(step: 'extract'), 'extract'), isTrue);
|
||||
expect(matchesAuditQuery(_event(module: 'debug.echo'), 'echo'), isTrue);
|
||||
expect(matchesAuditQuery(_event(error: 'Timeout nach 30s'), 'timeout'),
|
||||
isTrue);
|
||||
expect(matchesAuditQuery(_event(detail: '{"anchor":"tsa"}'), 'anchor'),
|
||||
isTrue);
|
||||
expect(matchesAuditQuery(_event(project: 'stromnetz'), 'strom'), isTrue);
|
||||
expect(matchesAuditQuery(_event(), 'evt-1'), isTrue);
|
||||
expect(matchesAuditQuery(_event(), 'step.'), isTrue);
|
||||
});
|
||||
|
||||
test('rejects non-matching queries and null fields', () {
|
||||
expect(matchesAuditQuery(_event(), 'nichtvorhanden'), isFalse);
|
||||
expect(matchesAuditQuery(_event(flow: null, error: null), 'flow'), isFalse);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue