@@ -1004,6 +1004,62 @@ async def test_client_registration_client_credentials(self, test_client: httpx.A
10041004 client_info = response .json ()
10051005 assert client_info ["grant_types" ] == ["client_credentials" ]
10061006
1007+ @pytest .mark .anyio
1008+ async def test_client_registration_with_additional_response_types (
1009+ self , test_client : httpx .AsyncClient , mock_oauth_provider : MockOAuthProvider
1010+ ):
1011+ """Test that registration accepts additional response_types values alongside 'code'."""
1012+ client_metadata = {
1013+ "redirect_uris" : ["https://client.example.com/callback" ],
1014+ "client_name" : "Test Client" ,
1015+ "grant_types" : ["authorization_code" , "refresh_token" ],
1016+ "response_types" : ["code" , "none" ], # Keycloak-style response with additional value
1017+ }
1018+
1019+ response = await test_client .post ("/register" , json = client_metadata )
1020+ assert response .status_code == 201
1021+ data = response .json ()
1022+
1023+ client = await mock_oauth_provider .get_client (data ["client_id" ])
1024+ assert client is not None
1025+ assert "code" in client .response_types
1026+
1027+ @pytest .mark .anyio
1028+ async def test_client_registration_response_types_without_code (self , test_client : httpx .AsyncClient ):
1029+ """Test that registration rejects response_types that don't include 'code'."""
1030+ client_metadata = {
1031+ "redirect_uris" : ["https://client.example.com/callback" ],
1032+ "client_name" : "Test Client" ,
1033+ "grant_types" : ["authorization_code" , "refresh_token" ],
1034+ "response_types" : ["token" , "none" , "nonsense-string" ],
1035+ }
1036+
1037+ response = await test_client .post ("/register" , json = client_metadata )
1038+ assert response .status_code == 400
1039+ error_data = response .json ()
1040+ assert "error" in error_data
1041+ assert error_data ["error" ] == "invalid_client_metadata"
1042+ assert "response_types must include 'code'" in error_data ["error_description" ]
1043+
1044+ @pytest .mark .anyio
1045+ async def test_client_registration_default_response_types (
1046+ self , test_client : httpx .AsyncClient , mock_oauth_provider : MockOAuthProvider
1047+ ):
1048+ """Test that registration uses default response_types of ['code'] when not specified."""
1049+ client_metadata = {
1050+ "redirect_uris" : ["https://client.example.com/callback" ],
1051+ "client_name" : "Test Client" ,
1052+ "grant_types" : ["authorization_code" , "refresh_token" ],
1053+ # response_types not specified, should default to ["code"]
1054+ }
1055+
1056+ response = await test_client .post ("/register" , json = client_metadata )
1057+ assert response .status_code == 201
1058+ data = response .json ()
1059+
1060+ assert "response_types" in data
1061+ assert data ["response_types" ] == ["code" ]
1062+
10071063
10081064class TestAuthorizeEndpointErrors :
10091065 """Test error handling in the OAuth authorization endpoint."""
0 commit comments