88
99namespace OCA \Libresign \Tests \Unit \Migration ;
1010
11- require_once __DIR__ . '/../../../../lib/Migration/Version18001Date20260320000000.php ' ;
12-
1311use OCA \Libresign \AppInfo \Application ;
1412use OCA \Libresign \Migration \Version18001Date20260320000000 ;
1513use OCA \Libresign \Service \Policy \Provider \Footer \FooterPolicyValue ;
14+ use OCA \Libresign \Service \Policy \Provider \SignatureText \SignatureTextPolicy ;
1615use OCP \Exceptions \AppConfigTypeConflictException ;
1716use OCP \IAppConfig ;
1817use OCP \Migration \IOutput ;
2221final class Version18001Date20260320000000Test extends TestCase {
2322 private IAppConfig &MockObject $ appConfig ;
2423
24+ #[\Override]
2525 protected function setUp (): void {
2626 parent ::setUp ();
2727 $ this ->appConfig = $ this ->createMock (IAppConfig::class);
2828 }
2929
3030 public function testMigratesLegacyFooterSettingsIntoStructuredPayload (): void {
3131 $ this ->appConfig
32- ->expects ($ this ->exactly (7 ))
3332 ->method ('getValueString ' )
3433 ->willReturnMap ([
3534 [Application::APP_ID , 'add_footer ' , '' , '1 ' ],
@@ -38,6 +37,15 @@ public function testMigratesLegacyFooterSettingsIntoStructuredPayload(): void {
3837 [Application::APP_ID , 'footer_template_is_default ' , '' , '0 ' ],
3938 [Application::APP_ID , 'docmdp_level ' , '' , '' ],
4039 [Application::APP_ID , 'groups_request_sign ' , '' , '' ],
40+ [Application::APP_ID , 'policy.signature_flow.system ' , '' , '' ],
41+ [Application::APP_ID , 'signature_flow ' , '' , '' ],
42+ [Application::APP_ID , 'template_font_size ' , '' , '' ],
43+ [Application::APP_ID , 'signature_width ' , '' , '' ],
44+ [Application::APP_ID , 'signature_height ' , '' , '' ],
45+ [Application::APP_ID , 'signature_font_size ' , '' , '' ],
46+ [Application::APP_ID , 'signature_render_mode ' , '' , '' ],
47+ [Application::APP_ID , 'collect_metadata ' , '' , '' ],
48+ [Application::APP_ID , 'identification_documents ' , '' , '' ],
4149 [Application::APP_ID , 'identify_methods ' , '' , '' ],
4250 ]);
4351
@@ -46,9 +54,8 @@ public function testMigratesLegacyFooterSettingsIntoStructuredPayload(): void {
4654 $ this ->appConfig
4755 ->expects ($ this ->once ())
4856 ->method ('deleteKey ' )
49- ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deletedKeys ): bool {
57+ ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deletedKeys ): void {
5058 $ deletedKeys [] = [$ app , $ key ];
51- return true ;
5259 });
5360
5461 $ this ->appConfig
@@ -75,7 +82,6 @@ public function testMigratesLegacyFooterSettingsIntoStructuredPayload(): void {
7582
7683 public function testReadsLegacyBooleanWhenAddFooterHasTypedBoolValue (): void {
7784 $ this ->appConfig
78- ->expects ($ this ->exactly (7 ))
7985 ->method ('getValueString ' )
8086 ->willReturnCallback (static function (string $ app , string $ key , string $ default ): string {
8187 if ($ app !== Application::APP_ID ) {
@@ -102,6 +108,18 @@ public function testReadsLegacyBooleanWhenAddFooterHasTypedBoolValue(): void {
102108 return '' ;
103109 }
104110
111+ if ($ key === 'policy.signature_flow.system ' || $ key === 'signature_flow ' ) {
112+ return '' ;
113+ }
114+
115+ if ($ key === 'collect_metadata ' || $ key === 'identification_documents ' ) {
116+ return '' ;
117+ }
118+
119+ if (in_array ($ key , ['template_font_size ' , 'signature_width ' , 'signature_height ' , 'signature_font_size ' , 'signature_render_mode ' ], true )) {
120+ return '' ;
121+ }
122+
105123 if ($ key === 'groups_request_sign ' ) {
106124 return '' ;
107125 }
@@ -120,9 +138,8 @@ public function testReadsLegacyBooleanWhenAddFooterHasTypedBoolValue(): void {
120138 $ this ->appConfig
121139 ->expects ($ this ->once ())
122140 ->method ('deleteKey ' )
123- ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deletedKeys ): bool {
141+ ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deletedKeys ): void {
124142 $ deletedKeys [] = [$ app , $ key ];
125- return true ;
126143 });
127144
128145 $ this ->appConfig
@@ -172,9 +189,8 @@ public function testMigratesGroupsRequestSignFromTypedArrayToCanonicalString():
172189 $ this ->appConfig
173190 ->expects ($ this ->exactly (2 ))
174191 ->method ('deleteKey ' )
175- ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deletedKeys ): bool {
192+ ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deletedKeys ): void {
176193 $ deletedKeys [] = [$ app , $ key ];
177- return true ;
178194 });
179195
180196 $ this ->appConfig
@@ -193,4 +209,211 @@ public function testMigratesGroupsRequestSignFromTypedArrayToCanonicalString():
193209
194210 self ::assertContains ([Application::APP_ID , 'groups_request_sign ' ], $ deletedKeys );
195211 }
212+
213+ public function testMigratesSignatureTextFloatSettingsFromLegacyStrings (): void {
214+ $ this ->appConfig
215+ ->method ('getValueString ' )
216+ ->willReturnMap ([
217+ [Application::APP_ID , 'add_footer ' , '' , '' ],
218+ [Application::APP_ID , 'write_qrcode_on_footer ' , '' , '' ],
219+ [Application::APP_ID , 'validation_site ' , '' , '' ],
220+ [Application::APP_ID , 'footer_template_is_default ' , '' , '' ],
221+ [Application::APP_ID , 'collect_metadata ' , '' , '' ],
222+ [Application::APP_ID , 'identification_documents ' , '' , '' ],
223+ [Application::APP_ID , 'docmdp_level ' , '' , '' ],
224+ [Application::APP_ID , 'groups_request_sign ' , '' , '' ],
225+ [Application::APP_ID , 'policy.signature_flow.system ' , '' , '' ],
226+ [Application::APP_ID , 'signature_flow ' , '' , '' ],
227+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_TEMPLATE_FONT_SIZE , '' , '11.5 ' ],
228+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_WIDTH , '' , '350 ' ],
229+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_HEIGHT , '' , '100.25 ' ],
230+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_FONT_SIZE , '' , '18 ' ],
231+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_RENDER_MODE , '' , 'default ' ],
232+ [Application::APP_ID , 'identify_methods ' , '' , '' ],
233+ ]);
234+
235+ $ deleted = [];
236+ $ this ->appConfig
237+ ->method ('deleteKey ' )
238+ ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deleted ): void {
239+ $ deleted [] = [$ app , $ key ];
240+ });
241+
242+ $ savedFloats = [];
243+ $ this ->appConfig
244+ ->method ('setValueFloat ' )
245+ ->willReturnCallback (static function (string $ app , string $ key , float $ value ) use (&$ savedFloats ): bool {
246+ $ savedFloats [$ key ] = $ value ;
247+ return true ;
248+ });
249+
250+ $ savedStrings = [];
251+ $ this ->appConfig
252+ ->method ('setValueString ' )
253+ ->willReturnCallback (static function (string $ app , string $ key , string $ value ) use (&$ savedStrings ): bool {
254+ $ savedStrings [$ key ] = $ value ;
255+ return true ;
256+ });
257+
258+ $ migration = new Version18001Date20260320000000 ($ this ->appConfig );
259+ $ migration ->preSchemaChange ($ this ->createMock (IOutput::class), static fn () => null , []);
260+
261+ self ::assertSame (11.5 , $ savedFloats [SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_TEMPLATE_FONT_SIZE ]);
262+ self ::assertSame (350.0 , $ savedFloats [SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_WIDTH ]);
263+ self ::assertSame (100.25 , $ savedFloats [SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_HEIGHT ]);
264+ self ::assertSame (18.0 , $ savedFloats [SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_FONT_SIZE ]);
265+ self ::assertContains ([Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_TEMPLATE_FONT_SIZE ], $ deleted );
266+ self ::assertContains ([Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_WIDTH ], $ deleted );
267+ self ::assertContains ([Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_HEIGHT ], $ deleted );
268+ self ::assertContains ([Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_FONT_SIZE ], $ deleted );
269+ self ::assertArrayNotHasKey (SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_RENDER_MODE , $ savedStrings );
270+ }
271+
272+ public function testNormalizesSignatureTextRenderModeToCanonicalPolicyValue (): void {
273+ $ this ->appConfig
274+ ->method ('getValueString ' )
275+ ->willReturnMap ([
276+ [Application::APP_ID , 'add_footer ' , '' , '' ],
277+ [Application::APP_ID , 'write_qrcode_on_footer ' , '' , '' ],
278+ [Application::APP_ID , 'validation_site ' , '' , '' ],
279+ [Application::APP_ID , 'footer_template_is_default ' , '' , '' ],
280+ [Application::APP_ID , 'collect_metadata ' , '' , '' ],
281+ [Application::APP_ID , 'identification_documents ' , '' , '' ],
282+ [Application::APP_ID , 'docmdp_level ' , '' , '' ],
283+ [Application::APP_ID , 'groups_request_sign ' , '' , '' ],
284+ [Application::APP_ID , 'policy.signature_flow.system ' , '' , '' ],
285+ [Application::APP_ID , 'signature_flow ' , '' , '' ],
286+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_TEMPLATE_FONT_SIZE , '' , '' ],
287+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_WIDTH , '' , '' ],
288+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_HEIGHT , '' , '' ],
289+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_FONT_SIZE , '' , '' ],
290+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_RENDER_MODE , '' , 'GRAPHIC_AND_DESCRIPTION ' ],
291+ [Application::APP_ID , 'identify_methods ' , '' , '' ],
292+ ]);
293+
294+ $ deleted = [];
295+
296+ $ this ->appConfig
297+ ->method ('deleteKey ' )
298+ ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deleted ): void {
299+ $ deleted [] = [$ app , $ key ];
300+ });
301+
302+ $ renderModeWasNormalized = false ;
303+ $ this ->appConfig
304+ ->method ('setValueString ' )
305+ ->willReturnCallback (static function (string $ app , string $ key , string $ value ) use (&$ renderModeWasNormalized ): bool {
306+ if ($ key === SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_RENDER_MODE ) {
307+ TestCase::assertSame (Application::APP_ID , $ app );
308+ TestCase::assertSame ('default ' , $ value );
309+ $ renderModeWasNormalized = true ;
310+ }
311+ return true ;
312+ });
313+
314+ $ savedFloats = [];
315+ $ this ->appConfig
316+ ->method ('setValueFloat ' )
317+ ->willReturnCallback (static function (string $ app , string $ key , float $ value ) use (&$ savedFloats ): bool {
318+ $ savedFloats [$ key ] = $ value ;
319+ return true ;
320+ });
321+
322+ $ migration = new Version18001Date20260320000000 ($ this ->appConfig );
323+ $ migration ->preSchemaChange ($ this ->createMock (IOutput::class), static fn () => null , []);
324+
325+ self ::assertTrue ($ renderModeWasNormalized );
326+ self ::assertContains ([Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_RENDER_MODE ], $ deleted );
327+ self ::assertSame ([], $ savedFloats );
328+ }
329+
330+ public function testMigratesPendingBooleanPoliciesFromLegacyStrings (): void {
331+ $ this ->appConfig
332+ ->method ('getValueString ' )
333+ ->willReturnMap ([
334+ [Application::APP_ID , 'add_footer ' , '' , '' ],
335+ [Application::APP_ID , 'write_qrcode_on_footer ' , '' , '' ],
336+ [Application::APP_ID , 'validation_site ' , '' , '' ],
337+ [Application::APP_ID , 'footer_template_is_default ' , '' , '' ],
338+ [Application::APP_ID , 'collect_metadata ' , '' , '1 ' ],
339+ [Application::APP_ID , 'identification_documents ' , '' , 'false ' ],
340+ [Application::APP_ID , 'docmdp_level ' , '' , '' ],
341+ [Application::APP_ID , 'groups_request_sign ' , '' , '' ],
342+ [Application::APP_ID , 'policy.signature_flow.system ' , '' , '' ],
343+ [Application::APP_ID , 'signature_flow ' , '' , '' ],
344+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_TEMPLATE_FONT_SIZE , '' , '' ],
345+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_WIDTH , '' , '' ],
346+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_HEIGHT , '' , '' ],
347+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_FONT_SIZE , '' , '' ],
348+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_RENDER_MODE , '' , '' ],
349+ [Application::APP_ID , 'identify_methods ' , '' , '' ],
350+ ]);
351+
352+ $ savedBools = [];
353+ $ this ->appConfig
354+ ->method ('setValueBool ' )
355+ ->willReturnCallback (static function (string $ app , string $ key , bool $ value ) use (&$ savedBools ): bool {
356+ $ savedBools [$ key ] = $ value ;
357+ return true ;
358+ });
359+
360+ $ deleted = [];
361+ $ this ->appConfig
362+ ->method ('deleteKey ' )
363+ ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deleted ): void {
364+ $ deleted [] = [$ app , $ key ];
365+ });
366+
367+ $ migration = new Version18001Date20260320000000 ($ this ->appConfig );
368+ $ migration ->preSchemaChange ($ this ->createMock (IOutput::class), static fn () => null , []);
369+
370+ self ::assertSame (true , $ savedBools ['collect_metadata ' ]);
371+ self ::assertSame (false , $ savedBools ['identification_documents ' ]);
372+ self ::assertContains ([Application::APP_ID , 'collect_metadata ' ], $ deleted );
373+ self ::assertContains ([Application::APP_ID , 'identification_documents ' ], $ deleted );
374+ }
375+
376+ public function testMigratesLegacySignatureFlowKeyToSystemPolicyKey (): void {
377+ $ this ->appConfig
378+ ->method ('getValueString ' )
379+ ->willReturnMap ([
380+ [Application::APP_ID , 'add_footer ' , '' , '' ],
381+ [Application::APP_ID , 'write_qrcode_on_footer ' , '' , '' ],
382+ [Application::APP_ID , 'validation_site ' , '' , '' ],
383+ [Application::APP_ID , 'footer_template_is_default ' , '' , '' ],
384+ [Application::APP_ID , 'collect_metadata ' , '' , '' ],
385+ [Application::APP_ID , 'identification_documents ' , '' , '' ],
386+ [Application::APP_ID , 'docmdp_level ' , '' , '' ],
387+ [Application::APP_ID , 'groups_request_sign ' , '' , '' ],
388+ [Application::APP_ID , 'policy.signature_flow.system ' , '' , '' ],
389+ [Application::APP_ID , 'signature_flow ' , '' , '2 ' ],
390+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_TEMPLATE_FONT_SIZE , '' , '' ],
391+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_WIDTH , '' , '' ],
392+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_HEIGHT , '' , '' ],
393+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_SIGNATURE_FONT_SIZE , '' , '' ],
394+ [Application::APP_ID , SignatureTextPolicy::SYSTEM_APP_CONFIG_KEY_RENDER_MODE , '' , '' ],
395+ [Application::APP_ID , 'identify_methods ' , '' , '' ],
396+ ]);
397+
398+ $ savedStrings = [];
399+ $ this ->appConfig
400+ ->method ('setValueString ' )
401+ ->willReturnCallback (static function (string $ app , string $ key , string $ value ) use (&$ savedStrings ): bool {
402+ $ savedStrings [$ key ] = $ value ;
403+ return true ;
404+ });
405+
406+ $ deleted = [];
407+ $ this ->appConfig
408+ ->method ('deleteKey ' )
409+ ->willReturnCallback (static function (string $ app , string $ key ) use (&$ deleted ): void {
410+ $ deleted [] = [$ app , $ key ];
411+ });
412+
413+ $ migration = new Version18001Date20260320000000 ($ this ->appConfig );
414+ $ migration ->preSchemaChange ($ this ->createMock (IOutput::class), static fn () => null , []);
415+
416+ self ::assertSame ('ordered_numeric ' , $ savedStrings ['policy.signature_flow.system ' ]);
417+ self ::assertContains ([Application::APP_ID , 'signature_flow ' ], $ deleted );
418+ }
196419}
0 commit comments