@@ -78,7 +78,7 @@ public function setUp(): void {
7878 $ this ->appConfig = $ this ->createMock (IAppConfig::class);
7979 }
8080
81- private function getService (): RequestSignatureService {
81+ private function getService (? SequentialSigningService $ sequentialSigningService = null ): RequestSignatureService {
8282 return new RequestSignatureService (
8383 $ this ->l10n ,
8484 $ this ->identifyMethodService ,
@@ -95,7 +95,7 @@ private function getService(): RequestSignatureService {
9595 $ this ->client ,
9696 $ this ->docMdpHandler ,
9797 $ this ->loggerInterface ,
98- $ this ->sequentialSigningService ,
98+ $ sequentialSigningService ?? $ this ->sequentialSigningService ,
9999 $ this ->appConfig ,
100100 );
101101 }
@@ -245,4 +245,78 @@ public static function dataSaveVisibleElements():array {
245245 [[['uid ' => 1 ], ['uid ' => 1 ]]],
246246 ];
247247 }
248+
249+ /**
250+ * Test that parallel flow correctly sets ABLE_TO_SIGN status for all signers
251+ * even when frontend sends status 0 (DRAFT) for individual signers,
252+ * as long as file status is ABLE_TO_SIGN (1)
253+ */
254+ public function testParallelFlowIgnoresSignerDraftStatusWhenFileIsAbleToSign (): void {
255+ $ sequentialSigningService = $ this ->createMock (SequentialSigningService::class);
256+ $ sequentialSigningService
257+ ->method ('isOrderedNumericFlow ' )
258+ ->willReturn (false ); // Parallel flow
259+
260+ // File status is ABLE_TO_SIGN (1)
261+ $ fileStatus = \OCA \Libresign \Db \File::STATUS_ABLE_TO_SIGN ;
262+
263+ // Signer status is DRAFT (0) - as sent by frontend
264+ $ signerStatus = \OCA \Libresign \Enum \SignRequestStatus::DRAFT ->value ;
265+
266+ $ result = self ::invokePrivate (
267+ $ this ->getService ($ sequentialSigningService ),
268+ 'determineInitialStatus ' ,
269+ [
270+ 1 , // signingOrder
271+ $ fileStatus ,
272+ $ signerStatus ,
273+ null , // currentStatus
274+ null , // fileId
275+ ]
276+ );
277+
278+ // In parallel flow with ABLE_TO_SIGN file status, signer should be ABLE_TO_SIGN
279+ $ this ->assertEquals (
280+ \OCA \Libresign \Enum \SignRequestStatus::ABLE_TO_SIGN ,
281+ $ result ,
282+ 'Parallel flow should set all signers to ABLE_TO_SIGN when file status is ABLE_TO_SIGN '
283+ );
284+ }
285+
286+ /**
287+ * Test that ordered flow respects signing order when file is ABLE_TO_SIGN
288+ */
289+ public function testOrderedFlowRespectsSigningOrderWhenFileIsAbleToSign (): void {
290+ $ sequentialSigningService = $ this ->createMock (SequentialSigningService::class);
291+ $ sequentialSigningService
292+ ->method ('isOrderedNumericFlow ' )
293+ ->willReturn (true ); // Ordered flow
294+
295+ $ fileStatus = \OCA \Libresign \Db \File::STATUS_ABLE_TO_SIGN ;
296+ $ signerStatus = \OCA \Libresign \Enum \SignRequestStatus::DRAFT ->value ;
297+
298+ // First signer (order 1) should be ABLE_TO_SIGN
299+ $ result1 = self ::invokePrivate (
300+ $ this ->getService ($ sequentialSigningService ),
301+ 'determineInitialStatus ' ,
302+ [1 , $ fileStatus , $ signerStatus , null , null ]
303+ );
304+ $ this ->assertEquals (
305+ \OCA \Libresign \Enum \SignRequestStatus::ABLE_TO_SIGN ,
306+ $ result1 ,
307+ 'First signer in ordered flow should be ABLE_TO_SIGN '
308+ );
309+
310+ // Second signer (order 2) should remain DRAFT
311+ $ result2 = self ::invokePrivate (
312+ $ this ->getService ($ sequentialSigningService ),
313+ 'determineInitialStatus ' ,
314+ [2 , $ fileStatus , $ signerStatus , null , null ]
315+ );
316+ $ this ->assertEquals (
317+ \OCA \Libresign \Enum \SignRequestStatus::DRAFT ,
318+ $ result2 ,
319+ 'Second signer in ordered flow should remain DRAFT until first signs '
320+ );
321+ }
248322}
0 commit comments