feat: partially implement integration test
This commit is contained in:
parent
f0a8e25890
commit
189bc7e6e6
|
|
@ -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/services/export_service.dart';
|
||||||
|
|
||||||
import 'package:pdf_signature/data/repositories/signature_asset_repository.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/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_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';
|
import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class RecordingExporter extends ExportService {
|
class RecordingExporter extends ExportService {
|
||||||
|
|
@ -29,14 +32,18 @@ void main() {
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
final fake = RecordingExporter();
|
final fake = RecordingExporter();
|
||||||
|
SharedPreferences.setMockInitialValues({});
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
ProviderScope(
|
ProviderScope(
|
||||||
overrides: [
|
overrides: [
|
||||||
documentRepositoryProvider.overrideWith(
|
preferencesRepositoryProvider.overrideWith(
|
||||||
(ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'),
|
(ref) => PreferencesStateNotifier(prefs),
|
||||||
),
|
),
|
||||||
signatureProvider.overrideWith(
|
documentRepositoryProvider.overrideWith(
|
||||||
(ref) => SignatureCardStateNotifier()..placeDefaultRect(),
|
(ref) =>
|
||||||
|
DocumentStateNotifier()
|
||||||
|
..openPicked(path: 'test.pdf', pageCount: 5),
|
||||||
),
|
),
|
||||||
useMockViewerProvider.overrideWith((ref) => true),
|
useMockViewerProvider.overrideWith((ref) => true),
|
||||||
exportServiceProvider.overrideWith((_) => fake),
|
exportServiceProvider.overrideWith((_) => fake),
|
||||||
|
|
@ -82,11 +89,18 @@ void main() {
|
||||||
) async {
|
) async {
|
||||||
final sigBytes = _makeSig();
|
final sigBytes = _makeSig();
|
||||||
|
|
||||||
|
SharedPreferences.setMockInitialValues({});
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
ProviderScope(
|
ProviderScope(
|
||||||
overrides: [
|
overrides: [
|
||||||
|
preferencesRepositoryProvider.overrideWith(
|
||||||
|
(ref) => PreferencesStateNotifier(prefs),
|
||||||
|
),
|
||||||
documentRepositoryProvider.overrideWith(
|
documentRepositoryProvider.overrideWith(
|
||||||
(ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'),
|
(ref) =>
|
||||||
|
DocumentStateNotifier()
|
||||||
|
..openPicked(path: 'test.pdf', pageCount: 5),
|
||||||
),
|
),
|
||||||
signatureAssetRepositoryProvider.overrideWith((ref) {
|
signatureAssetRepositoryProvider.overrideWith((ref) {
|
||||||
final c = SignatureAssetRepository();
|
final c = SignatureAssetRepository();
|
||||||
|
|
@ -119,15 +133,17 @@ void main() {
|
||||||
// Programmatically simulate confirm: add placement with current rect and bound image, then clear active overlay.
|
// Programmatically simulate confirm: add placement with current rect and bound image, then clear active overlay.
|
||||||
final ctx = tester.element(find.byType(PdfSignatureHomePage));
|
final ctx = tester.element(find.byType(PdfSignatureHomePage));
|
||||||
final container = ProviderScope.containerOf(ctx);
|
final container = ProviderScope.containerOf(ctx);
|
||||||
final sigState = container.read(signatureProvider);
|
final r = container.read(activeRectProvider)!;
|
||||||
final r = sigState.rect!;
|
|
||||||
final lib = container.read(signatureAssetRepositoryProvider);
|
final lib = container.read(signatureAssetRepositoryProvider);
|
||||||
final asset = lib.isNotEmpty ? lib.first : null;
|
final asset = lib.isNotEmpty ? lib.first : null;
|
||||||
final pdf = container.read(documentRepositoryProvider);
|
final pdf = container.read(documentRepositoryProvider);
|
||||||
container
|
container
|
||||||
.read(documentRepositoryProvider.notifier)
|
.read(documentRepositoryProvider.notifier)
|
||||||
.addPlacement(page: pdf.currentPage, rect: r, asset: asset);
|
.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();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
final placed = find.byKey(const Key('placed_signature_0'));
|
final placed = find.byKey(const Key('placed_signature_0'));
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,14 @@ class _PdfMockContinuousListState extends ConsumerState<PdfMockContinuousList> {
|
||||||
final aspectLocked = ref.watch(
|
final aspectLocked = ref.watch(
|
||||||
aspectLockedProvider,
|
aspectLockedProvider,
|
||||||
);
|
);
|
||||||
|
// Publish rect for tests/other UI to observe
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((
|
||||||
|
_,
|
||||||
|
) {
|
||||||
|
if (!mounted) return;
|
||||||
|
ref.read(activeRectProvider.notifier).state =
|
||||||
|
_activeRect;
|
||||||
|
});
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
/// Whether to use a mock continuous viewer (ListView) instead of a real PDF viewer.
|
/// 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
|
/// Whether resizing keeps the current aspect ratio for the active overlay
|
||||||
final aspectLockedProvider = StateProvider<bool>((ref) => false);
|
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);
|
||||||
|
|
|
||||||
|
|
@ -143,20 +143,16 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
|
||||||
if (path == null || path.trim().isEmpty) return;
|
if (path == null || path.trim().isEmpty) return;
|
||||||
final fullPath = _ensurePdfExtension(path.trim());
|
final fullPath = _ensurePdfExtension(path.trim());
|
||||||
savedPath = fullPath;
|
savedPath = fullPath;
|
||||||
if (pdf.pickedPdfBytes != null) {
|
final src = pdf.pickedPdfBytes ?? Uint8List(0);
|
||||||
final out = await exporter.exportSignedPdfFromBytes(
|
final out = await exporter.exportSignedPdfFromBytes(
|
||||||
srcBytes: pdf.pickedPdfBytes!,
|
srcBytes: src,
|
||||||
uiPageSize: _pageSize,
|
uiPageSize: _pageSize,
|
||||||
signatureImageBytes: null,
|
signatureImageBytes: null,
|
||||||
placementsByPage: pdf.placementsByPage,
|
placementsByPage: pdf.placementsByPage,
|
||||||
targetDpi: targetDpi,
|
targetDpi: targetDpi,
|
||||||
);
|
);
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
ok = await exporter.saveBytesToFile(
|
ok = await exporter.saveBytesToFile(bytes: out, outputPath: fullPath);
|
||||||
bytes: out,
|
|
||||||
outputPath: fullPath,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ class SignatureOverlay extends StatelessWidget {
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
child: DecoratedBox(
|
child: DecoratedBox(
|
||||||
|
key: Key('placed_signature_$placedIndex'),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(color: Colors.red, width: 2),
|
border: Border.all(color: Colors.red, width: 2),
|
||||||
),
|
),
|
||||||
|
|
@ -41,7 +42,6 @@ class SignatureOverlay extends StatelessWidget {
|
||||||
child: RotatedSignatureImage(
|
child: RotatedSignatureImage(
|
||||||
bytes: placement.asset.bytes,
|
bytes: placement.asset.bytes,
|
||||||
rotationDeg: placement.rotationDeg,
|
rotationDeg: placement.rotationDeg,
|
||||||
key: Key('placed_signature_$placedIndex'),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue