@@ -163,7 +163,7 @@ public function testLoadUserPreferenceReturnsLayerFromUserConfig(): void {
163163 ->expects ($ this ->once ())
164164 ->method ('getUserValue ' )
165165 ->with ('john ' , 'policy.signature_flow ' , '' )
166- ->willReturn ('parallel ' );
166+ ->willReturn ('" parallel" ' );
167167
168168 $ source = $ this ->getSource ();
169169 $ layer = $ source ->loadUserPreference ('signature_flow ' , PolicyContext::fromUserId ('john ' ));
@@ -177,12 +177,49 @@ public function testSaveUserPreferenceNormalizesAndPersistsUserConfigValue(): vo
177177 $ this ->appConfig
178178 ->expects ($ this ->once ())
179179 ->method ('setUserValue ' )
180- ->with ('john ' , 'policy.signature_flow ' , 'ordered_numeric ' );
180+ ->with ('john ' , 'policy.signature_flow ' , '" ordered_numeric" ' );
181181
182182 $ source = $ this ->getSource ();
183183 $ source ->saveUserPreference ('signature_flow ' , PolicyContext::fromUserId ('john ' ), 'ordered_numeric ' );
184184 }
185185
186+ public function testLoadUserPolicyReturnsExplicitAssignedLayerFromUserConfig (): void {
187+ $ this ->appConfig
188+ ->expects ($ this ->once ())
189+ ->method ('getUserValue ' )
190+ ->with ('john ' , 'policy.signature_flow.assigned ' , '' )
191+ ->willReturn ('{"value":"ordered_numeric","allowChildOverride":false} ' );
192+
193+ $ source = $ this ->getSource ();
194+ $ layer = $ source ->loadUserPolicy ('signature_flow ' , PolicyContext::fromUserId ('john ' ));
195+
196+ $ this ->assertNotNull ($ layer );
197+ $ this ->assertSame ('user_policy ' , $ layer ->getScope ());
198+ $ this ->assertSame ('ordered_numeric ' , $ layer ->getValue ());
199+ $ this ->assertFalse ($ layer ->isAllowChildOverride ());
200+ $ this ->assertSame (['ordered_numeric ' ], $ layer ->getAllowedValues ());
201+ }
202+
203+ public function testSaveUserPolicyPersistsAssignedUserPayload (): void {
204+ $ this ->appConfig
205+ ->expects ($ this ->once ())
206+ ->method ('setUserValue ' )
207+ ->with ('john ' , 'policy.signature_flow.assigned ' , '{"value":"ordered_numeric","allowChildOverride":true} ' );
208+
209+ $ source = $ this ->getSource ();
210+ $ source ->saveUserPolicy ('signature_flow ' , PolicyContext::fromUserId ('john ' ), 'ordered_numeric ' , true );
211+ }
212+
213+ public function testClearUserPolicyDeletesAssignedUserConfig (): void {
214+ $ this ->appConfig
215+ ->expects ($ this ->once ())
216+ ->method ('deleteUserValue ' )
217+ ->with ('john ' , 'policy.signature_flow.assigned ' );
218+
219+ $ source = $ this ->getSource ();
220+ $ source ->clearUserPolicy ('signature_flow ' , PolicyContext::fromUserId ('john ' ));
221+ }
222+
186223 public function testClearUserPreferenceDeletesUserConfig (): void {
187224 $ this ->appConfig
188225 ->expects ($ this ->once ())
@@ -628,7 +665,7 @@ public function testLoadAllUserPreferencesReturnsMappedLayersFromDatabase(): voi
628665
629666 $ dbResult = $ this ->createMock (IResult::class);
630667 $ dbResult ->method ('fetchAssociative ' )->willReturnOnConsecutiveCalls (
631- ['configkey ' => 'policy.signature_flow ' , 'configvalue ' => 'parallel ' ],
668+ ['configkey ' => 'policy.signature_flow ' , 'configvalue ' => '" parallel" ' ],
632669 false ,
633670 );
634671 $ dbResult ->expects ($ this ->once ())->method ('closeCursor ' );
@@ -727,7 +764,7 @@ public function testLoadAllRuleCountsAggregatesGroupAndUserCounts(): void {
727764
728765 $ dbResult = $ this ->createMock (IResult::class);
729766 $ dbResult ->method ('fetchAssociative ' )->willReturnOnConsecutiveCalls (
730- ['configkey ' => 'policy.signature_flow ' , 'user_count ' => '3 ' ],
767+ ['configkey ' => 'policy.signature_flow.assigned ' , 'user_count ' => '3 ' ],
731768 false ,
732769 );
733770 $ dbResult ->expects ($ this ->once ())->method ('closeCursor ' );
0 commit comments