feat: partially implement integration test

This commit is contained in:
insleker 2025-09-10 22:17:36 +08:00
parent f0a8e25890
commit 189bc7e6e6
5 changed files with 49 additions and 24 deletions

View File

@ -8,9 +8,12 @@ import 'package:image/image.dart' as img;
import 'package:pdf_signature/data/services/export_service.dart';
import 'package:pdf_signature/data/repositories/signature_asset_repository.dart';
import 'package:pdf_signature/data/repositories/signature_card_repository.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:pdf_signature/data/repositories/preferences_repository.dart';
import 'package:pdf_signature/l10n/app_localizations.dart';
class RecordingExporter extends ExportService {
@ -29,14 +32,18 @@ void main() {
tester,
) async {
final fake = RecordingExporter();
SharedPreferences.setMockInitialValues({});
final prefs = await SharedPreferences.getInstance();
await tester.pumpWidget(
ProviderScope(
overrides: [
documentRepositoryProvider.overrideWith(
(ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'),
preferencesRepositoryProvider.overrideWith(
(ref) => PreferencesStateNotifier(prefs),
),
signatureProvider.overrideWith(
(ref) => SignatureCardStateNotifier()..placeDefaultRect(),
documentRepositoryProvider.overrideWith(
(ref) =>
DocumentStateNotifier()
..openPicked(path: 'test.pdf', pageCount: 5),
),
useMockViewerProvider.overrideWith((ref) => true),
exportServiceProvider.overrideWith((_) => fake),
@ -82,11 +89,18 @@ void main() {
) async {
final sigBytes = _makeSig();
SharedPreferences.setMockInitialValues({});
final prefs = await SharedPreferences.getInstance();
await tester.pumpWidget(
ProviderScope(
overrides: [
preferencesRepositoryProvider.overrideWith(
(ref) => PreferencesStateNotifier(prefs),
),
documentRepositoryProvider.overrideWith(
(ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'),
(ref) =>
DocumentStateNotifier()
..openPicked(path: 'test.pdf', pageCount: 5),
),
signatureAssetRepositoryProvider.overrideWith((ref) {
final c = SignatureAssetRepository();
@ -119,15 +133,17 @@ void main() {
// Programmatically simulate confirm: add placement with current rect and bound image, then clear active overlay.
final ctx = tester.element(find.byType(PdfSignatureHomePage));
final container = ProviderScope.containerOf(ctx);
final sigState = container.read(signatureProvider);
final r = sigState.rect!;
final r = container.read(activeRectProvider)!;
final lib = container.read(signatureAssetRepositoryProvider);
final asset = lib.isNotEmpty ? lib.first : null;
final pdf = container.read(documentRepositoryProvider);
container
.read(documentRepositoryProvider.notifier)
.addPlacement(page: pdf.currentPage, rect: r, asset: asset);
container.read(signatureProvider.notifier).clearActiveOverlay();
// Clear active overlay by hiding signatures temporarily
container.read(signatureVisibilityProvider.notifier).state = false;
await tester.pump();
container.read(signatureVisibilityProvider.notifier).state = true;
await tester.pumpAndSettle();
final placed = find.byKey(const Key('placed_signature_0'));

View File

@ -138,6 +138,14 @@ class _PdfMockContinuousListState extends ConsumerState<PdfMockContinuousList> {
final aspectLocked = ref.watch(
aspectLockedProvider,
);
// Publish rect for tests/other UI to observe
WidgetsBinding.instance.addPostFrameCallback((
_,
) {
if (!mounted) return;
ref.read(activeRectProvider.notifier).state =
_activeRect;
});
return Stack(
children: [
Positioned(

View File

@ -1,3 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
/// Whether to use a mock continuous viewer (ListView) instead of a real PDF viewer.
@ -9,3 +10,7 @@ final signatureVisibilityProvider = StateProvider<bool>((ref) => true);
/// Whether resizing keeps the current aspect ratio for the active overlay
final aspectLockedProvider = StateProvider<bool>((ref) => false);
/// Current active overlay rect (normalized 0..1) for the mock viewer.
/// Integration tests can read this to confirm or compute placements.
final activeRectProvider = StateProvider<Rect?>((ref) => null);

View File

@ -143,20 +143,16 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
if (path == null || path.trim().isEmpty) return;
final fullPath = _ensurePdfExtension(path.trim());
savedPath = fullPath;
if (pdf.pickedPdfBytes != null) {
final out = await exporter.exportSignedPdfFromBytes(
srcBytes: pdf.pickedPdfBytes!,
uiPageSize: _pageSize,
signatureImageBytes: null,
placementsByPage: pdf.placementsByPage,
targetDpi: targetDpi,
);
if (out != null) {
ok = await exporter.saveBytesToFile(
bytes: out,
outputPath: fullPath,
);
}
final src = pdf.pickedPdfBytes ?? Uint8List(0);
final out = await exporter.exportSignedPdfFromBytes(
srcBytes: src,
uiPageSize: _pageSize,
signatureImageBytes: null,
placementsByPage: pdf.placementsByPage,
targetDpi: targetDpi,
);
if (out != null) {
ok = await exporter.saveBytesToFile(bytes: out, outputPath: fullPath);
}
}
if (!kIsWeb) {

View File

@ -33,6 +33,7 @@ class SignatureOverlay extends StatelessWidget {
width: width,
height: height,
child: DecoratedBox(
key: Key('placed_signature_$placedIndex'),
decoration: BoxDecoration(
border: Border.all(color: Colors.red, width: 2),
),
@ -41,7 +42,6 @@ class SignatureOverlay extends StatelessWidget {
child: RotatedSignatureImage(
bytes: placement.asset.bytes,
rotationDeg: placement.rotationDeg,
key: Key('placed_signature_$placedIndex'),
),
),
),