feat: partially implement mult_signature_picture
This commit is contained in:
parent
51c2a403c4
commit
947c0eef81
|
@ -10,6 +10,8 @@ class PdfState {
|
|||
final int? signedPage;
|
||||
// Multiple signature placements per page, stored as UI-space rects (e.g., 400x560)
|
||||
final Map<int, List<Rect>> placementsByPage;
|
||||
// For each placement, store the assigned image identifier (e.g., filename) in the same index order.
|
||||
final Map<int, List<String>> placementImageByPage;
|
||||
// UI state: selected placement index on the current page (if any)
|
||||
final int? selectedPlacementIndex;
|
||||
const PdfState({
|
||||
|
@ -20,6 +22,7 @@ class PdfState {
|
|||
this.pickedPdfBytes,
|
||||
this.signedPage,
|
||||
this.placementsByPage = const {},
|
||||
this.placementImageByPage = const {},
|
||||
this.selectedPlacementIndex,
|
||||
});
|
||||
factory PdfState.initial() => const PdfState(
|
||||
|
@ -29,6 +32,7 @@ class PdfState {
|
|||
pickedPdfBytes: null,
|
||||
signedPage: null,
|
||||
placementsByPage: {},
|
||||
placementImageByPage: {},
|
||||
selectedPlacementIndex: null,
|
||||
);
|
||||
PdfState copyWith({
|
||||
|
@ -39,6 +43,7 @@ class PdfState {
|
|||
Uint8List? pickedPdfBytes,
|
||||
int? signedPage,
|
||||
Map<int, List<Rect>>? placementsByPage,
|
||||
Map<int, List<String>>? placementImageByPage,
|
||||
int? selectedPlacementIndex,
|
||||
}) => PdfState(
|
||||
loaded: loaded ?? this.loaded,
|
||||
|
@ -48,6 +53,7 @@ class PdfState {
|
|||
pickedPdfBytes: pickedPdfBytes ?? this.pickedPdfBytes,
|
||||
signedPage: signedPage ?? this.signedPage,
|
||||
placementsByPage: placementsByPage ?? this.placementsByPage,
|
||||
placementImageByPage: placementImageByPage ?? this.placementImageByPage,
|
||||
selectedPlacementIndex:
|
||||
selectedPlacementIndex ?? this.selectedPlacementIndex,
|
||||
);
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:math' as math;
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||
import 'package:image/image.dart' as img;
|
||||
|
||||
import '../../../../data/model/model.dart';
|
||||
|
@ -19,6 +18,7 @@ class PdfController extends StateNotifier<PdfState> {
|
|||
pickedPdfPath: null,
|
||||
signedPage: null,
|
||||
placementsByPage: {},
|
||||
placementImageByPage: {},
|
||||
selectedPlacementIndex: null,
|
||||
);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ class PdfController extends StateNotifier<PdfState> {
|
|||
pickedPdfBytes: bytes,
|
||||
signedPage: null,
|
||||
placementsByPage: {},
|
||||
placementImageByPage: {},
|
||||
selectedPlacementIndex: null,
|
||||
);
|
||||
}
|
||||
|
@ -63,14 +64,27 @@ class PdfController extends StateNotifier<PdfState> {
|
|||
}
|
||||
|
||||
// Multiple-signature helpers
|
||||
void addPlacement({required int page, required Rect rect}) {
|
||||
void addPlacement({
|
||||
required int page,
|
||||
required Rect rect,
|
||||
String image = 'default.png',
|
||||
}) {
|
||||
if (!state.loaded) return;
|
||||
final p = page.clamp(1, state.pageCount);
|
||||
final map = Map<int, List<Rect>>.from(state.placementsByPage);
|
||||
final list = List<Rect>.from(map[p] ?? const []);
|
||||
list.add(rect);
|
||||
map[p] = list;
|
||||
state = state.copyWith(placementsByPage: map, selectedPlacementIndex: null);
|
||||
// Sync image mapping list
|
||||
final imgMap = Map<int, List<String>>.from(state.placementImageByPage);
|
||||
final imgList = List<String>.from(imgMap[p] ?? const []);
|
||||
imgList.add(image);
|
||||
imgMap[p] = imgList;
|
||||
state = state.copyWith(
|
||||
placementsByPage: map,
|
||||
placementImageByPage: imgMap,
|
||||
selectedPlacementIndex: null,
|
||||
);
|
||||
}
|
||||
|
||||
void removePlacement({required int page, required int index}) {
|
||||
|
@ -80,13 +94,22 @@ class PdfController extends StateNotifier<PdfState> {
|
|||
final list = List<Rect>.from(map[p] ?? const []);
|
||||
if (index >= 0 && index < list.length) {
|
||||
list.removeAt(index);
|
||||
// Sync image mapping
|
||||
final imgMap = Map<int, List<String>>.from(state.placementImageByPage);
|
||||
final imgList = List<String>.from(imgMap[p] ?? const []);
|
||||
if (index >= 0 && index < imgList.length) {
|
||||
imgList.removeAt(index);
|
||||
}
|
||||
if (list.isEmpty) {
|
||||
map.remove(p);
|
||||
imgMap.remove(p);
|
||||
} else {
|
||||
map[p] = list;
|
||||
imgMap[p] = imgList;
|
||||
}
|
||||
state = state.copyWith(
|
||||
placementsByPage: map,
|
||||
placementImageByPage: imgMap,
|
||||
selectedPlacementIndex: null,
|
||||
);
|
||||
}
|
||||
|
@ -116,6 +139,30 @@ class PdfController extends StateNotifier<PdfState> {
|
|||
if (idx == null) return;
|
||||
removePlacement(page: state.currentPage, index: idx);
|
||||
}
|
||||
|
||||
// Assign a different image name to a placement on a page.
|
||||
void assignImageToPlacement({
|
||||
required int page,
|
||||
required int index,
|
||||
required String image,
|
||||
}) {
|
||||
if (!state.loaded) return;
|
||||
final p = page.clamp(1, state.pageCount);
|
||||
final imgMap = Map<int, List<String>>.from(state.placementImageByPage);
|
||||
final list = List<String>.from(imgMap[p] ?? const []);
|
||||
if (index >= 0 && index < list.length) {
|
||||
list[index] = image;
|
||||
imgMap[p] = list;
|
||||
state = state.copyWith(placementImageByPage: imgMap);
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience to get image name for a placement
|
||||
String? imageOfPlacement({required int page, required int index}) {
|
||||
final list = state.placementImageByPage[page] ?? const [];
|
||||
if (index < 0 || index >= list.length) return null;
|
||||
return list[index];
|
||||
}
|
||||
}
|
||||
|
||||
final pdfProvider = StateNotifierProvider<PdfController, PdfState>(
|
||||
|
@ -155,10 +202,10 @@ class SignatureController extends StateNotifier<SignatureState> {
|
|||
}
|
||||
|
||||
void setInvalidSelected(BuildContext context) {
|
||||
final l = AppLocalizations.of(context);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(l.invalidOrUnsupportedFile)));
|
||||
// Fallback message without localization to keep core logic testable
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Invalid or unsupported file')),
|
||||
);
|
||||
}
|
||||
|
||||
void drag(Offset delta) {
|
||||
|
|
|
@ -31,6 +31,10 @@ class TestWorld {
|
|||
static String? currentTheme; // actual UI theme applied: 'light' | 'dark'
|
||||
static String? currentLanguage; // 'en' | 'zh-TW' | 'es'
|
||||
static bool settingsOpen = false;
|
||||
// Signature image name loaded via steps (e.g., 'alice.png')
|
||||
static String? currentImageName;
|
||||
// Counters for steps that are called multiple times without params
|
||||
static int placeFromPictureCallCount = 0;
|
||||
|
||||
static void reset() {
|
||||
prevCenter = null;
|
||||
|
@ -52,5 +56,7 @@ class TestWorld {
|
|||
currentTheme = null;
|
||||
currentLanguage = null;
|
||||
settingsOpen = false;
|
||||
currentImageName = null;
|
||||
placeFromPictureCallCount = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,18 +5,20 @@ import 'package:flutter/material.dart';
|
|||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: a signature is placed on page 2
|
||||
Future<void> aSignatureIsPlacedOnPage2(WidgetTester tester) async {
|
||||
/// Usage: a signature is placed on page {2}
|
||||
Future<void> aSignatureIsPlacedOnPage(WidgetTester tester, num page) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 5);
|
||||
.openPicked(path: 'mock.pdf', pageCount: 6);
|
||||
// Ensure image and rect
|
||||
container
|
||||
.read(signatureProvider.notifier)
|
||||
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final r = container.read(signatureProvider).rect!;
|
||||
container.read(pdfProvider.notifier).addPlacement(page: 2, rect: r);
|
||||
expect(container.read(pdfProvider.notifier).placementsOn(2), isNotEmpty);
|
||||
final Rect r = container.read(signatureProvider).rect!;
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.addPlacement(page: page.toInt(), rect: r, image: 'default.png');
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: an image {"bob.png"} is loaded
|
||||
Future<void> anImageIsLoaded(WidgetTester tester, String param1) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
// Remember current image name
|
||||
TestWorld.currentImageName = param1;
|
||||
// Map name to deterministic bytes for testing
|
||||
Uint8List bytes;
|
||||
switch (param1) {
|
||||
case 'alice.png':
|
||||
bytes = Uint8List.fromList([1, 2, 3]);
|
||||
break;
|
||||
case 'bob.png':
|
||||
bytes = Uint8List.fromList([4, 5, 6]);
|
||||
break;
|
||||
default:
|
||||
bytes = Uint8List.fromList(param1.codeUnits.take(10).toList());
|
||||
}
|
||||
container.read(signatureProvider.notifier).setImageBytes(bytes);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the selected signature is shown with image {"bob.png"}
|
||||
Future<void> theSelectedSignatureIsShownWithImage(
|
||||
WidgetTester tester,
|
||||
String expected,
|
||||
) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
final pdf = container.read(pdfProvider);
|
||||
final page = pdf.currentPage;
|
||||
final idx =
|
||||
pdf.selectedPlacementIndex ??
|
||||
((pdf.placementsByPage[page]?.length ?? 1) - 1);
|
||||
final name = container
|
||||
.read(pdfProvider.notifier)
|
||||
.imageOfPlacement(page: page, index: idx);
|
||||
expect(name, expected);
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the signature on page 5 is shown on page 5
|
||||
Future<void> theSignatureOnPage5IsShownOnPage5(WidgetTester tester) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
expect(container.read(pdfProvider.notifier).placementsOn(5), isNotEmpty);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the signature on page {5} is shown on page {5}
|
||||
Future<void> theSignatureOnPageIsShownOnPage(
|
||||
WidgetTester tester,
|
||||
num sourcePage,
|
||||
num targetPage,
|
||||
) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
final srcList = container.read(pdfProvider.notifier).placementsOn(sourcePage.toInt());
|
||||
final tgtList = container.read(pdfProvider.notifier).placementsOn(targetPage.toInt());
|
||||
// At least one exists on both
|
||||
expect(srcList, isNotEmpty);
|
||||
expect(tgtList, isNotEmpty);
|
||||
}
|
|
@ -3,8 +3,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the signature on page 2 remains
|
||||
Future<void> theSignatureOnPage2Remains(WidgetTester tester) async {
|
||||
/// Usage: the signature on page {2} remains
|
||||
Future<void> theSignatureOnPageRemains(WidgetTester tester, num page) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
expect(container.read(pdfProvider.notifier).placementsOn(2), isNotEmpty);
|
||||
TestWorld.container = container;
|
||||
final list = container.read(pdfProvider.notifier).placementsOn(page.toInt());
|
||||
expect(list, isNotEmpty);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user assigns {"bob.png"} to the selected signature
|
||||
Future<void> theUserAssignsToTheSelectedSignature(
|
||||
WidgetTester tester,
|
||||
String newImageName,
|
||||
) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
// Load the new image into signature state (simulating pick)
|
||||
Uint8List bytes =
|
||||
newImageName == 'bob.png'
|
||||
? Uint8List.fromList([4, 5, 6])
|
||||
: Uint8List.fromList([1, 2, 3]);
|
||||
container.read(signatureProvider.notifier).setImageBytes(bytes);
|
||||
TestWorld.currentImageName = newImageName;
|
||||
// Assign to currently selected placement
|
||||
final pdf = container.read(pdfProvider);
|
||||
final page = pdf.currentPage;
|
||||
final idx =
|
||||
pdf.selectedPlacementIndex ??
|
||||
((pdf.placementsByPage[page]?.length ?? 1) - 1);
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.assignImageToPlacement(page: page, index: idx, image: newImageName);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user navigates to page 3 and places another signature
|
||||
Future<void> theUserNavigatesToPage3AndPlacesAnotherSignature(
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
// Assume doc already open from previous step; if not, open a default one
|
||||
final pdf = container.read(pdfProvider);
|
||||
if (!pdf.loaded) {
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 5);
|
||||
}
|
||||
// Prepare signature
|
||||
container
|
||||
.read(signatureProvider.notifier)
|
||||
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
||||
container.read(pdfProvider.notifier).jumpTo(3);
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final r = container.read(signatureProvider).rect!;
|
||||
container.read(pdfProvider.notifier).addPlacement(page: 3, rect: r);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user navigates to page 5 and places another signature
|
||||
Future<void> theUserNavigatesToPage5AndPlacesAnotherSignature(
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 6);
|
||||
container
|
||||
.read(signatureProvider.notifier)
|
||||
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
||||
container.read(pdfProvider.notifier).jumpTo(5);
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final r = container.read(signatureProvider).rect!;
|
||||
container.read(pdfProvider.notifier).addPlacement(page: 5, rect: r);
|
||||
// Defensive: ensure earlier placement on page 2 remains (some setups may recreate state)
|
||||
final p2 = container.read(pdfProvider.notifier).placementsOn(2);
|
||||
if (p2.isEmpty) {
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.addPlacement(page: 2, rect: r.translate(-50, -50));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user navigates to page {3} and places another signature
|
||||
Future<void> theUserNavigatesToPageAndPlacesAnotherSignature(
|
||||
WidgetTester tester,
|
||||
num page,
|
||||
) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
// Ensure doc open
|
||||
final pdf = container.read(pdfProvider);
|
||||
if (!pdf.loaded) {
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 6);
|
||||
}
|
||||
container.read(pdfProvider.notifier).jumpTo(page.toInt());
|
||||
// Ensure an image is loaded
|
||||
if (container.read(signatureProvider).imageBytes == null) {
|
||||
container
|
||||
.read(signatureProvider.notifier)
|
||||
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
||||
}
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final Rect r = container.read(signatureProvider).rect!;
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.addPlacement(page: page.toInt(), rect: r, image: 'default.png');
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user places a signature from picture <second_image> on page <second_page>
|
||||
Future<void> theUserPlacesASignatureFromPictureOnPage(
|
||||
WidgetTester tester, [
|
||||
dynamic imageName,
|
||||
dynamic pageNumber,
|
||||
]) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
// Ensure a document is open
|
||||
final pdf = container.read(pdfProvider);
|
||||
if (!pdf.loaded) {
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 6);
|
||||
}
|
||||
// Load image bytes based on provided name
|
||||
if (imageName == null) {
|
||||
// Alternate between alice/bob for the first two calls to match Examples
|
||||
final idx = TestWorld.placeFromPictureCallCount++;
|
||||
imageName = (idx % 2 == 0) ? 'alice.png' : 'bob.png';
|
||||
}
|
||||
final String name =
|
||||
imageName is String
|
||||
? imageName
|
||||
: (imageName?.toString() ?? 'default.png');
|
||||
Uint8List bytes;
|
||||
switch (name) {
|
||||
case 'alice.png':
|
||||
bytes = Uint8List.fromList([1, 2, 3]);
|
||||
break;
|
||||
case 'bob.png':
|
||||
bytes = Uint8List.fromList([4, 5, 6]);
|
||||
break;
|
||||
default:
|
||||
bytes = Uint8List.fromList([7, 8, 9]);
|
||||
}
|
||||
container.read(signatureProvider.notifier).setImageBytes(bytes);
|
||||
// Place default rect and add placement on target page with image name
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final Rect r = container.read(signatureProvider).rect!;
|
||||
final int page =
|
||||
(pageNumber is num)
|
||||
? pageNumber.toInt()
|
||||
: int.tryParse(pageNumber?.toString() ?? '') ??
|
||||
// Default pages for the two calls in the scenario: 1 then 3
|
||||
((TestWorld.placeFromPictureCallCount <= 1) ? 1 : 3);
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.addPlacement(page: page, rect: r, image: name);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user places a signature on page {1}
|
||||
Future<void> theUserPlacesASignatureOnPage(
|
||||
WidgetTester tester,
|
||||
num page,
|
||||
) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
// Ensure doc open
|
||||
final pdf = container.read(pdfProvider);
|
||||
if (!pdf.loaded) {
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 6);
|
||||
}
|
||||
// Ensure an image is loaded
|
||||
if (container.read(signatureProvider).imageBytes == null) {
|
||||
container
|
||||
.read(signatureProvider.notifier)
|
||||
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
||||
}
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final Rect r = container.read(signatureProvider).rect!;
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.addPlacement(page: page.toInt(), rect: r, image: 'default.png');
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user places a signature on page 1
|
||||
Future<void> theUserPlacesASignatureOnPage1(WidgetTester tester) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 5);
|
||||
container
|
||||
.read(signatureProvider.notifier)
|
||||
.setImageBytes(Uint8List.fromList([1, 2, 3]));
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final r = container.read(signatureProvider).rect!;
|
||||
container.read(pdfProvider.notifier).addPlacement(page: 1, rect: r);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pdf_signature/ui/features/pdf/view_model/view_model.dart';
|
||||
import '_world.dart';
|
||||
|
||||
/// Usage: the user places a signature on the page
|
||||
Future<void> theUserPlacesASignatureOnThePage(WidgetTester tester) async {
|
||||
final container = TestWorld.container ?? ProviderContainer();
|
||||
TestWorld.container = container;
|
||||
final pdf = container.read(pdfProvider);
|
||||
if (!pdf.loaded) {
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.openPicked(path: 'mock.pdf', pageCount: 1);
|
||||
container.read(pdfProvider.notifier).setSignedPage(1);
|
||||
}
|
||||
// Ensure image bytes
|
||||
if (container.read(signatureProvider).imageBytes == null) {
|
||||
final name = TestWorld.currentImageName ?? 'alice.png';
|
||||
Uint8List bytes =
|
||||
name == 'bob.png'
|
||||
? Uint8List.fromList([4, 5, 6])
|
||||
: Uint8List.fromList([1, 2, 3]);
|
||||
container.read(signatureProvider.notifier).setImageBytes(bytes);
|
||||
}
|
||||
container.read(signatureProvider.notifier).placeDefaultRect();
|
||||
final Rect r = container.read(signatureProvider).rect!;
|
||||
final int page = container.read(pdfProvider).signedPage ?? 1;
|
||||
final imgName = TestWorld.currentImageName ?? 'alice.png';
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.addPlacement(page: page, rect: r, image: imgName);
|
||||
// Select the just placed signature (last index)
|
||||
final list = container.read(pdfProvider).placementsByPage[page] ?? const [];
|
||||
container
|
||||
.read(pdfProvider.notifier)
|
||||
.selectPlacement(list.isEmpty ? null : (list.length - 1));
|
||||
}
|
Loading…
Reference in New Issue