@@ -689,4 +689,130 @@ await client.CompletePkceLoginAsync(new PkceCompleteRequest
689689 It . IsAny < CancellationToken > ( ) ) ,
690690 Times . Once ) ;
691691 }
692+
693+ [ Fact ]
694+ public async Task CompletePkce_Should_Throw_When_Request_Null ( )
695+ {
696+ var client = CreateFlowClient ( ) ;
697+ Func < Task > act = async ( ) => await client . CompletePkceLoginAsync ( null ! ) ;
698+ await act . Should ( ) . ThrowAsync < ArgumentNullException > ( ) ;
699+ }
700+
701+ [ Fact ]
702+ public async Task CompletePkce_Should_Throw_When_Pkce_Disabled ( )
703+ {
704+ var options = Options . Create ( new UAuthClientOptions
705+ {
706+ Pkce = new UAuthClientPkceLoginFlowOptions
707+ {
708+ Enabled = false
709+ }
710+ } ) ;
711+
712+ var client = new UAuthFlowClient (
713+ Mock . Of < IUAuthRequestClient > ( ) ,
714+ Mock . Of < IUAuthClientEvents > ( ) ,
715+ Mock . Of < IClientDeviceProvider > ( ) ,
716+ Mock . Of < IReturnUrlProvider > ( ) ,
717+ options ,
718+ new UAuthClientDiagnostics ( ) ) ;
719+
720+ Func < Task > act = async ( ) => await client . CompletePkceLoginAsync ( new PkceCompleteRequest
721+ {
722+ AuthorizationCode = "code" ,
723+ CodeVerifier = "verifier" ,
724+ ReturnUrl = "/home" ,
725+ Identifier = "user" ,
726+ Secret = "pass" } ) ;
727+
728+ await act . Should ( ) . ThrowAsync < InvalidOperationException > ( ) ;
729+ }
730+
731+ [ Fact ]
732+ public async Task LogoutUserDevice_Should_Call_Admin_Endpoint ( )
733+ {
734+ var mock = new Mock < IUAuthRequestClient > ( ) ;
735+
736+ mock . Setup ( x => x . SendJsonAsync ( It . IsAny < string > ( ) , It . IsAny < object > ( ) ) )
737+ . ReturnsAsync ( new UAuthTransportResult
738+ {
739+ Ok = true ,
740+ Status = 200 ,
741+ Body = JsonSerializer . SerializeToElement ( new RevokeResult ( ) )
742+ } ) ;
743+
744+ var client = CreateFlowClient ( mock ) ;
745+ var userKey = UserKey . FromString ( "user-1" ) ;
746+ await client . LogoutUserDeviceAsync ( userKey , new LogoutDeviceRequest ( ) { ChainId = SessionChainId . New ( ) } ) ;
747+ mock . Verify ( x => x . SendJsonAsync ( $ "/auth/admin/users/{ userKey . Value } /logout-device", It . IsAny < object > ( ) ) , Times . Once ) ;
748+ }
749+
750+ [ Fact ]
751+ public async Task LogoutMyOtherDevices_Should_Call_Correct_Endpoint ( )
752+ {
753+ var mock = new Mock < IUAuthRequestClient > ( ) ;
754+
755+ mock . Setup ( x => x . SendJsonAsync ( It . IsAny < string > ( ) , It . IsAny < object > ( ) ) )
756+ . ReturnsAsync ( new UAuthTransportResult
757+ {
758+ Ok = true ,
759+ Status = 200
760+ } ) ;
761+
762+ var client = CreateFlowClient ( mock ) ;
763+ await client . LogoutMyOtherDevicesAsync ( ) ;
764+ mock . Verify ( x => x . SendJsonAsync ( "/auth/me/logout-others" , null ) , Times . Once ) ;
765+ }
766+
767+ [ Fact ]
768+ public async Task LogoutUserOtherDevices_Should_Call_Admin_Endpoint ( )
769+ {
770+ var mock = new Mock < IUAuthRequestClient > ( ) ;
771+
772+ mock . Setup ( x => x . SendJsonAsync ( It . IsAny < string > ( ) , It . IsAny < object > ( ) ) )
773+ . ReturnsAsync ( new UAuthTransportResult
774+ {
775+ Ok = true ,
776+ Status = 200
777+ } ) ;
778+
779+ var client = CreateFlowClient ( mock ) ;
780+ var userKey = UserKey . FromString ( "user-1" ) ;
781+ await client . LogoutUserOtherDevicesAsync ( userKey , new LogoutOtherDevicesRequest ( ) { CurrentChainId = SessionChainId . New ( ) } ) ;
782+ mock . Verify ( x => x . SendJsonAsync ( $ "/auth/admin/users/{ userKey . Value } /logout-others", It . IsAny < object > ( ) ) , Times . Once ) ;
783+ }
784+
785+ [ Fact ]
786+ public async Task LogoutAllUserDevices_Should_Call_Admin_Endpoint ( )
787+ {
788+ var mock = new Mock < IUAuthRequestClient > ( ) ;
789+
790+ mock . Setup ( x => x . SendJsonAsync ( It . IsAny < string > ( ) , It . IsAny < object > ( ) ) )
791+ . ReturnsAsync ( new UAuthTransportResult
792+ {
793+ Ok = true ,
794+ Status = 200
795+ } ) ;
796+
797+ var client = CreateFlowClient ( mock ) ;
798+ var userKey = UserKey . FromString ( "user-1" ) ;
799+ await client . LogoutAllUserDevicesAsync ( userKey ) ;
800+ mock . Verify ( x => x . SendJsonAsync ( $ "/auth/admin/users/{ userKey . Value } /logout-all", null ) , Times . Once ) ;
801+ }
802+
803+ [ Fact ]
804+ public void UAuthClient_Should_Expose_FlowClient ( )
805+ {
806+ var flow = Mock . Of < IFlowClient > ( ) ;
807+
808+ var client = new UAuthClient (
809+ flow ,
810+ Mock . Of < ISessionClient > ( ) ,
811+ Mock . Of < IUserClient > ( ) ,
812+ Mock . Of < IUserIdentifierClient > ( ) ,
813+ Mock . Of < ICredentialClient > ( ) ,
814+ Mock . Of < IAuthorizationClient > ( ) ) ;
815+
816+ client . Flows . Should ( ) . Be ( flow ) ;
817+ }
692818}
0 commit comments