77
88declare (strict_types=1 );
99
10+ use OCA \UserOIDC \Db \User ;
1011use OCA \UserOIDC \Db \UserMapper ;
1112use OCA \UserOIDC \Service \LocalIdService ;
1213use OCP \AppFramework \Db \DoesNotExistException ;
@@ -39,7 +40,7 @@ public function setUp(): void {
3940 $ this ->db = $ this ->createMock (IDBConnection::class);
4041 $ this ->userMapper = $ this ->getMockBuilder (UserMapper::class)
4142 ->setConstructorArgs ([$ this ->db , $ this ->idService , $ this ->config ])
42- ->onlyMethods (['getUser ' , 'insert ' ])
43+ ->onlyMethods (['getUser ' , 'getByProviderAndSub ' , ' insert ' , ' update ' ])
4344 ->getMock ();
4445 }
4546
@@ -67,6 +68,10 @@ public static function dataCreate(): array {
6768
6869 #[DataProvider('dataCreate ' )]
6970 public function testCreate (int $ providerId , string $ sub , string $ generatedId , bool $ id4me , string $ expected ): void {
71+ $ this ->userMapper ->expects (self ::once ())
72+ ->method ('getByProviderAndSub ' )
73+ ->willThrowException (new DoesNotExistException ('No user ' ));
74+
7075 $ this ->idService ->expects (self ::once ())->method ('getId ' )->with ($ providerId , $ sub , $ id4me )->willReturn ($ generatedId );
7176
7277 $ this ->userMapper ->expects (self ::once ())
@@ -78,7 +83,84 @@ public function testCreate(int $providerId, string $sub, string $generatedId, bo
7883 ->willReturnCallback (function ($ arg ) {
7984 return $ arg ;
8085 });
86+ $ this ->userMapper ->expects (self ::never ())->method ('update ' );
87+
88+ $ user = $ this ->userMapper ->getOrCreate ($ providerId , $ sub , $ id4me );
89+ Assert::assertEquals ($ expected , $ user ->getUserId ());
90+ Assert::assertSame ($ providerId , $ user ->getProviderId ());
91+ Assert::assertSame ($ sub , $ user ->getSub ());
92+ }
93+
94+ public function testCreateHashesOverlongSub (): void {
95+ $ longSub = str_repeat ('a ' , 300 );
96+
97+ $ this ->userMapper ->expects (self ::once ())
98+ ->method ('getByProviderAndSub ' )
99+ ->willThrowException (new DoesNotExistException ('No user ' ));
100+
101+ $ this ->idService ->expects (self ::once ())->method ('getId ' )->willReturn ('short-user-id ' );
102+
103+ $ this ->userMapper ->expects (self ::once ())
104+ ->method ('getUser ' )
105+ ->willThrowException (new DoesNotExistException ('No user ' ));
106+
107+ $ this ->userMapper ->expects (self ::once ())
108+ ->method ('insert ' )
109+ ->willReturnCallback (function ($ arg ) {
110+ return $ arg ;
111+ });
112+
113+ $ user = $ this ->userMapper ->getOrCreate (1 , $ longSub );
114+ Assert::assertSame (hash ('sha256 ' , $ longSub ), $ user ->getSub ());
115+ }
116+
117+ public function testGetOrCreateBackfillsExistingUserWithoutStableIdentifier (): void {
118+ // simulates an account provisioned before provider_id/sub existed:
119+ // not found by that pair yet, but its computed uid already exists
120+ $ existing = new User ();
121+ $ existing ->setUserId ('existing-user ' );
122+ $ existing ->setDisplayName ('Existing User ' );
123+
124+ $ this ->userMapper ->expects (self ::once ())
125+ ->method ('getByProviderAndSub ' )
126+ ->willThrowException (new DoesNotExistException ('No user ' ));
127+
128+ $ this ->idService ->expects (self ::once ())->method ('getId ' )->willReturn ('existing-user ' );
129+
130+ $ this ->userMapper ->expects (self ::once ())
131+ ->method ('getUser ' )
132+ ->willReturn ($ existing );
133+
134+ $ this ->userMapper ->expects (self ::once ())
135+ ->method ('update ' )
136+ ->willReturnCallback (function ($ arg ) {
137+ return $ arg ;
138+ });
139+ $ this ->userMapper ->expects (self ::never ())->method ('insert ' );
140+
141+ $ user = $ this ->userMapper ->getOrCreate (5 , 'the-sub ' );
142+ Assert::assertSame (5 , $ user ->getProviderId ());
143+ Assert::assertSame ('the-sub ' , $ user ->getSub ());
144+ }
145+
146+ public function testGetOrCreateReturnsExistingUserByProviderAndSubWithoutComputingAUid (): void {
147+ $ existing = new User ();
148+ $ existing ->setUserId ('existing-user ' );
149+ $ existing ->setDisplayName ('Existing User ' );
150+ $ existing ->setProviderId (5 );
151+ $ existing ->setSub ('the-sub ' );
152+
153+ $ this ->userMapper ->expects (self ::once ())
154+ ->method ('getByProviderAndSub ' )
155+ ->with (5 , 'the-sub ' )
156+ ->willReturn ($ existing );
157+
158+ $ this ->idService ->expects (self ::never ())->method ('getId ' );
159+ $ this ->userMapper ->expects (self ::never ())->method ('getUser ' );
160+ $ this ->userMapper ->expects (self ::never ())->method ('update ' );
161+ $ this ->userMapper ->expects (self ::never ())->method ('insert ' );
81162
82- Assert::assertEquals ($ expected , $ this ->userMapper ->getOrCreate ($ providerId , $ sub , $ id4me )->getUserId ());
163+ $ user = $ this ->userMapper ->getOrCreate (5 , 'the-sub ' );
164+ Assert::assertSame ($ existing , $ user );
83165 }
84166}
0 commit comments