Skip to content

Commit 844e7bf

Browse files
author
Nivedithaa Mahendran
committed
update
1 parent 9f7f3a5 commit 844e7bf

2 files changed

Lines changed: 73 additions & 49 deletions

File tree

src/mas/devops/users.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ def get_user(self, user_id):
217217
# Get MAXADMIN API key for authentication
218218
maxadmin_manage_api_key = self.create_or_get_manage_api_key_for_user(MASUserUtils.MAXADMIN, temporary=True)
219219

220+
# First request: Query to find user and get resource_id from href
220221
url = f"{self.manage_api_url_internal}/maximo/api/os/masperuser"
221222
querystring = {
222223
"lean": 1,
@@ -233,39 +234,40 @@ def get_user(self, user_id):
233234
cert=self.manage_internal_client_pem_file_path,
234235
verify=self.manage_internal_ca_pem_file_path
235236
)
236-
user_info = response.json()
237237
self.logger.info(f"GET {url} returned {response.status_code}")
238238
self.logger.info(f"Response: {response.text}")
239-
self.logger.info(f"Response json: {response.json}")
240-
241-
# Parse resource_id from user_info for version >= 9.1
242-
if Version(self.mas_version) >= Version('9.1') and user_info:
243-
# Check if user_info has member array with href
244-
if "member" in user_info and len(user_info["member"]) > 0:
245-
href = user_info["member"][0].get("href", "")
246-
# Extract resource_id from href (e.g., "api/os/masperuser/<resource_id>")
247-
if href and "/" in href:
248-
resource_id = href.split("/")[-1]
249-
self.logger.info(f"Extracted resource_id: {resource_id} from user_info")
250239

251-
url = f"{self.manage_api_url_internal}/maximo/api/os/masperuser"
240+
user_info = response.json()
241+
self.logger.info(f"Response json: {user_info}")
242+
243+
# Parse resource_id from user_info
244+
if user_info and "member" in user_info and len(user_info["member"]) > 0:
245+
href = user_info["member"][0].get("href", "")
246+
# Extract resource_id from href (e.g., "api/os/masperuser/<resource_id>")
247+
if href and "/" in href:
248+
resource_id = href.split("/")[-1]
249+
self.logger.info(f"Extracted resource_id: {resource_id} from user_info")
250+
251+
# Second request: Get full user details using resource_id
252+
url = f"{self.manage_api_url_internal}/maximo/api/os/masperuser/"
253+
querystring = {
254+
"lean": 1,
255+
"oslc.where": f"personid=\"{user_id}\"",
256+
"oslc.select": "personid,displayname"
257+
}
252258
headers = {
253259
"Accept": "application/json",
254260
"apikey": maxadmin_manage_api_key["apikey"]
255261
}
256-
querystring = {
257-
"lean": 1,
258-
"oslc.where": f"userid=\"{user_id}\""
259-
}
260262
response = requests.get(
261263
url,
262264
headers=headers,
265+
params=querystring,
263266
cert=self.manage_internal_client_pem_file_path,
264267
verify=self.manage_internal_ca_pem_file_path
265268
)
266269
self.logger.info(f"GET {url} returned {response.status_code}")
267270
self.logger.info(f"Response: {response.text}")
268-
self.logger.info(f"Response json: {response.json}")
269271
else:
270272
# For earlier versions, use the Core API v3/users endpoint
271273
url = f"{self.mas_api_url_internal}/v3/users/{user_id}"

test/src/test_users.py

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -219,20 +219,18 @@ def mock_get_user(requests_mock, user_id, json, status_code, mock_manage_api_key
219219
additional_matcher=lambda req: additional_matcher(req, cert=PEM_PATH)
220220
)
221221

222-
# Second request: If status is 200 and json is a dict (not a callback) with member array, mock the resource_id GET
223-
if status_code == 200 and json and isinstance(json, dict) and "member" in json and len(json["member"]) > 0:
224-
href = json["member"][0].get("href", "")
225-
if href and "/" in href:
226-
resource_id = href.split("/")[-1]
227-
requests_mock.get(
228-
f"{MANAGE_API_URL}/maximo/api/os/masperuser/{resource_id}",
229-
request_headers={"apikey": mock_manage_api_key["apikey"]},
230-
json=json,
231-
status_code=status_code,
232-
additional_matcher=lambda req: additional_matcher(req, cert=PEM_PATH)
233-
)
222+
# Second request: Mock the query-based request with personid
223+
# This matches the actual implementation at line 258-275 in users.py
224+
# Always mock this for version >= 9.1, regardless of status_code
225+
manage_personid_mock = requests_mock.get(
226+
f"{MANAGE_API_URL}/maximo/api/os/masperuser/?lean=1&oslc.where=personid%3D%22{user_id}%22&oslc.select=personid%2Cdisplayname",
227+
request_headers={"apikey": mock_manage_api_key["apikey"]},
228+
json=json,
229+
status_code=status_code,
230+
additional_matcher=lambda req: additional_matcher(req, cert=PEM_PATH)
231+
)
234232

235-
return core_mock, manage_query_mock
233+
return core_mock, manage_query_mock, manage_personid_mock
236234

237235

238236
def mock_get_user_200(requests_mock, user_id, mock_manage_api_key):
@@ -361,7 +359,7 @@ def test_mas_workspace_application_ids(user_utils, requests_mock):
361359

362360
def test_get_user_exists(user_utils, requests_mock, mock_manage_api_key):
363361
user_id = "user1"
364-
get_core, get_manage = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
362+
get_core, get_manage, get_manage_personid = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
365363
resource_id, user_data = user_utils.get_user(user_id)
366364
assert user_data["id"] == user_id
367365
assert user_data["displayName"] == user_id
@@ -383,7 +381,7 @@ def test_get_user_exists(user_utils, requests_mock, mock_manage_api_key):
383381

384382
def test_get_user_notfound(user_utils, requests_mock, mock_manage_api_key):
385383
user_id = "user1"
386-
get_core, get_manage = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
384+
get_core, get_manage, get_manage_personid = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
387385
resource_id, user_data = user_utils.get_user(user_id)
388386
assert resource_id is None
389387
assert user_data is None
@@ -399,7 +397,7 @@ def test_get_user_notfound(user_utils, requests_mock, mock_manage_api_key):
399397

400398
def test_get_user_error(user_utils, requests_mock, mock_manage_api_key):
401399
user_id = "user1"
402-
get_core, get_manage = mock_get_user_500(requests_mock, user_id, mock_manage_api_key)
400+
get_core, get_manage, get_manage_personid = mock_get_user_500(requests_mock, user_id, mock_manage_api_key)
403401
with pytest.raises(Exception):
404402
user_utils.get_user(user_id)
405403

@@ -414,7 +412,7 @@ def test_get_user_error(user_utils, requests_mock, mock_manage_api_key):
414412

415413
def test_get_or_create_user_exists(user_utils, requests_mock, mock_manage_api_key):
416414
user_id = "user1"
417-
get_core, get_manage = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
415+
get_core, get_manage, get_manage_personid = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
418416

419417
# Mock Core API endpoint for version < 9.1
420418
post_core = requests_mock.post(
@@ -462,7 +460,7 @@ def test_get_or_create_user_exists(user_utils, requests_mock, mock_manage_api_ke
462460

463461
def test_get_or_create_user_notfound(user_utils, requests_mock, mock_manage_api_key):
464462
user_id = "user1"
465-
get_core, get_manage = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
463+
get_core, get_manage, get_manage_personid = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
466464

467465
# Mock Core API endpoint for version < 9.1
468466
post_core = requests_mock.post(
@@ -508,7 +506,7 @@ def test_get_or_create_user_notfound(user_utils, requests_mock, mock_manage_api_
508506

509507
def test_get_or_create_user_error(user_utils, requests_mock, mock_manage_api_key):
510508
user_id = "user1"
511-
get_core, get_manage = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
509+
get_core, get_manage, get_manage_personid = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
512510

513511
# Mock Core API endpoint for version < 9.1
514512
post_core = requests_mock.post(
@@ -606,7 +604,7 @@ def test_update_user_display_name_error(user_utils, requests_mock):
606604
def test_link_user_to_local_idp(user_utils, requests_mock, mock_manage_api_key):
607605
user_id = "user1"
608606
email_password = True
609-
get_core, get_manage = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
607+
get_core, get_manage, get_manage_personid = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
610608

611609
put = requests_mock.put(
612610
f"{MAS_API_URL}/v3/users/{user_id}/idps/local?emailPassword={email_password}",
@@ -630,7 +628,7 @@ def test_link_user_to_local_idp(user_utils, requests_mock, mock_manage_api_key):
630628

631629
def test_link_user_to_local_idp_usernotfound(user_utils, requests_mock, mock_manage_api_key):
632630
user_id = "user1"
633-
get_core, get_manage = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
631+
get_core, get_manage, get_manage_personid = mock_get_user_404(requests_mock, user_id, mock_manage_api_key)
634632
put = requests_mock.put(
635633
f"{MAS_API_URL}/v3/users/{user_id}/idps/local",
636634
additional_matcher=lambda req: additional_matcher(req, json={"idpUserId": user_id})
@@ -652,7 +650,7 @@ def test_link_user_to_local_idp_usernotfound(user_utils, requests_mock, mock_man
652650
def test_link_user_to_local_idp_already_linked(user_utils, requests_mock, mock_manage_api_key):
653651
user_id = "user1"
654652
email_password = True
655-
get_core, get_manage = mock_get_user(
653+
get_core, get_manage, get_manage_personid = mock_get_user(
656654
requests_mock, user_id, {"id": user_id, "identities": {"_local": {}}}, 200, mock_manage_api_key
657655
)
658656

@@ -888,7 +886,7 @@ def test_resync_users(user_utils, requests_mock, mock_manage_api_key):
888886
gets_manage = []
889887
patches = []
890888
for user_id in user_ids:
891-
get_core, get_manage = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
889+
get_core, get_manage, get_manage_personid = mock_get_user_200(requests_mock, user_id, mock_manage_api_key)
892890
gets_core.append(get_core)
893891
gets_manage.append(get_manage)
894892

@@ -930,13 +928,18 @@ def test_check_user_sync(user_utils, requests_mock, mock_manage_api_key):
930928

931929
def json_callback(request, context):
932930
nonlocal attempts
933-
if attempts >= 2:
931+
# For version >= 9.1, each get_user call makes 2 requests, so we need attempts >= 4
932+
# For version < 9.1, each get_user call makes 1 request, so we need attempts >= 2
933+
threshold = 4 if Version(user_utils.mas_version) >= Version('9.1') else 2
934+
if attempts >= threshold:
934935
state = "SUCCESS"
935936
else:
936937
state = "PENDING"
937938
attempts = attempts + 1
939+
resource_id = f"{user_id}_resource_id"
938940
return {
939941
"id": user_id,
942+
"member": [{"href": f"api/os/masperuser/{resource_id}"}],
940943
"applications": {
941944
"other": {
942945
"sync": {
@@ -951,7 +954,7 @@ def json_callback(request, context):
951954
}
952955
}
953956

954-
get_core, get_manage = mock_get_user(
957+
get_core, get_manage, get_manage_personid = mock_get_user(
955958
requests_mock,
956959
user_id,
957960
json_callback,
@@ -962,8 +965,11 @@ def json_callback(request, context):
962965
user_utils.check_user_sync(user_id, application_id, timeout_secs=8, retry_interval_secs=0)
963966

964967
# Check that the correct endpoint was called based on version
968+
# Note: For version >= 9.1, get_user makes 2 requests (query + resource_id GET)
969+
# but we only track the first query request in get_manage mock
965970
if Version(user_utils.mas_version) >= Version('9.1'):
966971
assert get_core.call_count == 0
972+
# Each get_user call makes 2 requests, but we only count the query request
967973
assert get_manage.call_count == 3
968974
else:
969975
assert get_core.call_count == 3
@@ -974,7 +980,7 @@ def test_check_user_sync_timeout(user_utils, requests_mock, mock_manage_api_key)
974980
user_id = "user1"
975981
application_id = "manage"
976982

977-
get_core, get_manage = mock_get_user(
983+
get_core, get_manage, get_manage_personid = mock_get_user(
978984
requests_mock,
979985
user_id,
980986
{
@@ -1019,10 +1025,15 @@ def test_check_user_sync_appstate_notfound(user_utils, requests_mock, mock_manag
10191025

10201026
def json_callback(request, context):
10211027
nonlocal attempts
1022-
if attempts >= 1:
1028+
resource_id = f"{user_id}_resource_id"
1029+
# For version >= 9.1, each get_user call makes 2 requests, so we need attempts >= 2
1030+
# For version < 9.1, each get_user call makes 1 request, so we need attempts >= 1
1031+
threshold = 2 if Version(user_utils.mas_version) >= Version('9.1') else 1
1032+
if attempts >= threshold:
10231033
ret = {
10241034
"id": user_id,
10251035
"displayName": user_id,
1036+
"member": [{"href": f"api/os/masperuser/{resource_id}"}],
10261037
"applications": {
10271038
"other": {
10281039
"sync": {
@@ -1040,6 +1051,7 @@ def json_callback(request, context):
10401051
ret = {
10411052
"id": user_id,
10421053
"displayName": user_id,
1054+
"member": [{"href": f"api/os/masperuser/{resource_id}"}],
10431055
"applications": {
10441056
"other": {
10451057
"sync": {
@@ -1058,7 +1070,7 @@ def json_callback(request, context):
10581070
status_code=200
10591071
)
10601072

1061-
get_core, get_manage = mock_get_user(
1073+
get_core, get_manage, get_manage_personid = mock_get_user(
10621074
requests_mock,
10631075
user_id,
10641076
json_callback,
@@ -1071,7 +1083,9 @@ def json_callback(request, context):
10711083
# Check that the correct endpoint was called based on version
10721084
if Version(user_utils.mas_version) >= Version('9.1'):
10731085
assert get_core.call_count == 0
1086+
# For version >= 9.1, each get_user call makes 2 requests
10741087
assert get_manage.call_count == 3
1088+
assert get_manage_personid.call_count == 3
10751089
else:
10761090
assert get_core.call_count == 3
10771091
assert get_manage.call_count == 0
@@ -1091,10 +1105,15 @@ def test_check_user_sync_appstate_transient_error(user_utils, requests_mock, moc
10911105

10921106
def json_callback(request, context):
10931107
nonlocal attempts
1094-
if attempts >= 1:
1108+
resource_id = f"{user_id}_resource_id"
1109+
# For version >= 9.1, each get_user call makes 2 requests, so we need attempts >= 2
1110+
# For version < 9.1, each get_user call makes 1 request, so we need attempts >= 1
1111+
threshold = 2 if Version(user_utils.mas_version) >= Version('9.1') else 1
1112+
if attempts >= threshold:
10951113
ret = {
10961114
"id": user_id,
10971115
"displayName": user_id,
1116+
"member": [{"href": f"api/os/masperuser/{resource_id}"}],
10981117
"applications": {
10991118
application_id: {
11001119
"sync": {
@@ -1107,6 +1126,7 @@ def json_callback(request, context):
11071126
ret = {
11081127
"id": user_id,
11091128
"displayName": user_id,
1129+
"member": [{"href": f"api/os/masperuser/{resource_id}"}],
11101130
"applications": {
11111131
application_id: {
11121132
"sync": {
@@ -1125,7 +1145,7 @@ def json_callback(request, context):
11251145
status_code=200
11261146
)
11271147

1128-
get_core, get_manage = mock_get_user(
1148+
get_core, get_manage, get_manage_personid = mock_get_user(
11291149
requests_mock,
11301150
user_id,
11311151
json_callback,
@@ -1138,7 +1158,9 @@ def json_callback(request, context):
11381158
# Check that the correct endpoint was called based on version
11391159
if Version(user_utils.mas_version) >= Version('9.1'):
11401160
assert get_core.call_count == 0
1161+
# For version >= 9.1, each get_user call makes 2 requests
11411162
assert get_manage.call_count == 3
1163+
assert get_manage_personid.call_count == 3
11421164
else:
11431165
assert get_core.call_count == 3
11441166
assert get_manage.call_count == 0
@@ -1158,7 +1180,7 @@ def test_check_user_sync_appstate_persistent_error(user_utils, requests_mock, mo
11581180
status_code=200
11591181
)
11601182

1161-
get_core, get_manage = mock_get_user(
1183+
get_core, get_manage, get_manage_personid = mock_get_user(
11621184
requests_mock,
11631185
user_id,
11641186
{

0 commit comments

Comments
 (0)