import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:marianum_mobile/widget/prosemirror/pm_document_view.dart'; import 'package:marianum_mobile/widget/prosemirror/pm_node.dart'; /// The canonical contract fixtures shared with the backend content validator /// (see fixtures/README.md). Every one must parse into fully-typed nodes (no /// PmUnknown in the content) and render in both themes without throwing. const _fixtures = [ 'callout.json', 'image.json', 'kitchen-sink.json', 'lists.json', 'table.json', 'text-marks.json', ]; Map _loadFixture(String name) { final raw = File( 'test/widget/prosemirror/fixtures/$name', ).readAsStringSync(); return jsonDecode(raw) as Map; } bool _hasUnknown(PmNode node) { if (node is PmUnknown) return true; return node.children.any(_hasUnknown); } Widget _host(PmNode doc, Brightness brightness) => MaterialApp( theme: ThemeData( colorScheme: ColorScheme.fromSeed( seedColor: const Color(0xFF993333), brightness: brightness, ), ), home: Scaffold( body: SingleChildScrollView(child: PmDocumentView(doc: doc)), ), ); void main() { for (final fixture in _fixtures) { test('$fixture parses without any PmUnknown in its content', () { final doc = PmNode.fromJson(_loadFixture(fixture)); // The root `doc` node itself has no dedicated subclass and maps to // PmUnknown by design; assert none of its content nodes are unknown. expect(doc, isA()); expect( doc.children.any(_hasUnknown), isFalse, reason: '$fixture contains an unrecognised node type', ); }); testWidgets('$fixture renders in light + dark without exception', ( tester, ) async { final doc = PmNode.fromJson(_loadFixture(fixture)); await tester.pumpWidget(_host(doc, Brightness.light)); await tester.pump(); expect(tester.takeException(), isNull); await tester.pumpWidget(_host(doc, Brightness.dark)); await tester.pump(); expect(tester.takeException(), isNull); }); } }