Skip to content

Commit 2aec7fc

Browse files
CopilotSubterrane
andcommitted
Fix type validation errors for manager_user_id and get_auth_factors
- Add field validator to convert integer manager_user_id to string - Update get_auth_factors return type from single object to List - Add comprehensive tests for both fixes Co-authored-by: Subterrane <[email protected]>
1 parent 72dbcd8 commit 2aec7fc

File tree

4 files changed

+123
-4
lines changed

4 files changed

+123
-4
lines changed

onelogin/api/multi_factor_authentication_api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ def generate_otp_with_http_info(self, user_id : Annotated[StrictInt, Field(...,
684684
_request_auth=_params.get('_request_auth'))
685685

686686
@validate_call
687-
def get_auth_factors(self, user_id : Annotated[StrictInt, Field(..., description="Set to the id of the user that you want to return.")], **kwargs) -> GetAuthFactors200Response: # noqa: E501
687+
def get_auth_factors(self, user_id : Annotated[StrictInt, Field(..., description="Set to the id of the user that you want to return.")], **kwargs) -> List[GetAuthFactors200Response]: # noqa: E501
688688
"""Get User Factors # noqa: E501
689689
690690
Get a user\\'s available authentication factors # noqa: E501
@@ -705,7 +705,7 @@ def get_auth_factors(self, user_id : Annotated[StrictInt, Field(..., description
705705
:return: Returns the result object.
706706
If the method is called asynchronously,
707707
returns the request thread.
708-
:rtype: GetAuthFactors200Response
708+
:rtype: List[GetAuthFactors200Response]
709709
"""
710710
kwargs['_return_http_data_only'] = True
711711
if '_preload_content' in kwargs:
@@ -747,7 +747,7 @@ def get_auth_factors_with_http_info(self, user_id : Annotated[StrictInt, Field(.
747747
:return: Returns the result object.
748748
If the method is called asynchronously,
749749
returns the request thread.
750-
:rtype: tuple(GetAuthFactors200Response, status_code(int), headers(HTTPHeaderDict))
750+
:rtype: tuple(List[GetAuthFactors200Response], status_code(int), headers(HTTPHeaderDict))
751751
"""
752752

753753
_params = locals()
@@ -802,7 +802,7 @@ def get_auth_factors_with_http_info(self, user_id : Annotated[StrictInt, Field(.
802802
_auth_settings = ['OAuth2'] # noqa: E501
803803

804804
_response_types_map = {
805-
'200': "GetAuthFactors200Response",
805+
'200': "List[GetAuthFactors200Response]",
806806
'401': "AltErr",
807807
}
808808

onelogin/models/user.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ def status_validate_enum(cls, value):
8181
raise ValueError("must be one of enum values (0, 1, 2, 3, 4, 5, 7, 8)")
8282
return value
8383

84+
@field_validator('manager_user_id', mode='before')
85+
@classmethod
86+
def manager_user_id_to_string(cls, value):
87+
"""Converts manager_user_id to string if it's an integer"""
88+
if value is None:
89+
return value
90+
if isinstance(value, int):
91+
return str(value)
92+
return value
93+
8494
"""Pydantic configuration"""
8595
model_config = {
8696
"validate_by_name": True,

test/test_get_auth_factors_fix.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# coding: utf-8
2+
3+
"""
4+
OneLogin API
5+
6+
OpenAPI Specification for OneLogin # noqa: E501
7+
8+
The version of the OpenAPI document: 3.1.1
9+
Generated by OpenAPI Generator (https://openapi-generator.tech)
10+
11+
Do not edit the class manually.
12+
"""
13+
14+
15+
import unittest
16+
import datetime
17+
18+
import onelogin
19+
from onelogin.models.get_auth_factors200_response import GetAuthFactors200Response
20+
from onelogin.rest import ApiException
21+
22+
23+
class TestGetAuthFactorsFix(unittest.TestCase):
24+
"""Test case for get_auth_factors return type fix"""
25+
26+
def setUp(self):
27+
pass
28+
29+
def tearDown(self):
30+
pass
31+
32+
def test_get_auth_factors_list_response(self):
33+
"""
34+
Test that GetAuthFactors200Response can be deserialized from a list.
35+
This test validates the fix where API returns a list of factors
36+
but model expected a single object.
37+
"""
38+
# Example response data from API (a list of factors)
39+
factors_data = [
40+
{
41+
"factor_id": 3098,
42+
"name": "OneLogin SMS",
43+
"auth_factor_name": "OneLogin SMS"
44+
},
45+
{
46+
"factor_id": 3099,
47+
"name": "YubiKey",
48+
"auth_factor_name": "YubiKey"
49+
}
50+
]
51+
52+
# Each item in the list should be deserializable as GetAuthFactors200Response
53+
factors = [GetAuthFactors200Response.from_dict(factor_data) for factor_data in factors_data]
54+
55+
self.assertEqual(len(factors), 2)
56+
self.assertEqual(factors[0].factor_id, 3098)
57+
self.assertEqual(factors[0].name, "OneLogin SMS")
58+
self.assertEqual(factors[1].factor_id, 3099)
59+
self.assertEqual(factors[1].name, "YubiKey")
60+
61+
def test_single_auth_factor_from_dict(self):
62+
"""
63+
Test that a single auth factor can be created from dict.
64+
"""
65+
factor_data = {
66+
"factor_id": 3098,
67+
"name": "OneLogin SMS",
68+
"auth_factor_name": "OneLogin SMS"
69+
}
70+
71+
factor = GetAuthFactors200Response.from_dict(factor_data)
72+
self.assertEqual(factor.factor_id, 3098)
73+
self.assertEqual(factor.name, "OneLogin SMS")
74+
self.assertEqual(factor.auth_factor_name, "OneLogin SMS")
75+
76+
def test_auth_factor_with_optional_fields(self):
77+
"""
78+
Test that auth factor works with optional fields.
79+
"""
80+
factor_data = {
81+
"factor_id": 3098
82+
# name and auth_factor_name are optional
83+
}
84+
85+
factor = GetAuthFactors200Response.from_dict(factor_data)
86+
self.assertEqual(factor.factor_id, 3098)
87+
self.assertIsNone(factor.name)
88+
self.assertIsNone(factor.auth_factor_name)
89+
90+
91+
if __name__ == '__main__':
92+
unittest.main()

test/test_user_manager_user_id_fix.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,23 @@ def test_manager_user_id_with_string_value(self):
4747
self.assertEqual(user.manager_user_id, "252462756")
4848
self.assertIsInstance(user.manager_user_id, str)
4949

50+
def test_manager_user_id_with_integer_value(self):
51+
"""
52+
Test that manager_user_id accepts integer values and converts them to string.
53+
This test validates the fix where API sometimes returns manager_user_id as integer.
54+
"""
55+
user_data = {
56+
"id": 123,
57+
"username": "testuser",
58+
"email": "[email protected]",
59+
"manager_user_id": 252462756 # Integer value as sometimes returned by API
60+
}
61+
62+
# This should work without validation errors and convert to string
63+
user = User.from_dict(user_data)
64+
self.assertEqual(user.manager_user_id, "252462756")
65+
self.assertIsInstance(user.manager_user_id, str)
66+
5067
def test_manager_user_id_with_none_value(self):
5168
"""
5269
Test that manager_user_id accepts None values.

0 commit comments

Comments
 (0)