@@ -1282,6 +1282,107 @@ def test_get_lms_user_activation_link(
12821282 if expected_link is None :
12831283 self .assertTrue (mock_logger .error .called or mock_logger .exception .called )
12841284
1285+ @ddt .data (
1286+ # list response, user linked → returns enterprise user record
1287+ {
1288+ 'mock_user_accounts' : [{'id' : TEST_USER_ID }],
1289+ 'enterprise_results' : [TEST_USER_RECORD ],
1290+ 'expected_result' : TEST_USER_RECORD ,
1291+ 'expect_enterprise_called' : True ,
1292+ },
1293+ # empty list → None, no enterprise call
1294+ {
1295+ 'mock_user_accounts' : [],
1296+ 'enterprise_results' : None ,
1297+ 'expected_result' : None ,
1298+ 'expect_enterprise_called' : False ,
1299+ },
1300+ # None → None, no enterprise call
1301+ {
1302+ 'mock_user_accounts' : None ,
1303+ 'enterprise_results' : None ,
1304+ 'expected_result' : None ,
1305+ 'expect_enterprise_called' : False ,
1306+ },
1307+ # user has account but is not linked to this enterprise → None
1308+ {
1309+ 'mock_user_accounts' : [{'id' : TEST_USER_ID }],
1310+ 'enterprise_results' : [],
1311+ 'expected_result' : None ,
1312+ 'expect_enterprise_called' : True ,
1313+ },
1314+ # list entry missing 'id' → None, no enterprise call
1315+ {
1316+ 'mock_user_accounts' : [{'email' : 'someone@example.com' }],
1317+ 'enterprise_results' : None ,
1318+ 'expected_result' : None ,
1319+ 'expect_enterprise_called' : False ,
1320+ },
1321+ )
1322+ @ddt .unpack
1323+ @mock .patch ('enterprise_access.apps.api_client.base_oauth.OAuthAPIClient' )
1324+ def test_get_enterprise_learner_by_email (
1325+ self ,
1326+ mock_oauth_client ,
1327+ mock_user_accounts ,
1328+ enterprise_results ,
1329+ expected_result ,
1330+ expect_enterprise_called ,
1331+ ):
1332+ """
1333+ Verify get_enterprise_learner_by_email resolves an email to an enterprise user record,
1334+ returning None when the learner has no account, no matching ID, or is not linked.
1335+ HTTP errors from either LMS call propagate to the caller.
1336+ """
1337+ learner_email = 'test@example.com'
1338+
1339+ if enterprise_results is not None :
1340+ mock_oauth_client .return_value .get .return_value = MockResponse (
1341+ {'results' : enterprise_results }, 200
1342+ )
1343+
1344+ client = LmsApiClient ()
1345+ with mock .patch .object (client , 'get_lms_user_account' , return_value = mock_user_accounts ) as mock_get_account :
1346+ result = client .get_enterprise_learner_by_email (str (TEST_ENTERPRISE_UUID ), learner_email )
1347+
1348+ self .assertEqual (result , expected_result )
1349+ mock_get_account .assert_called_once_with (email = learner_email )
1350+ if expect_enterprise_called :
1351+ mock_oauth_client .return_value .get .assert_called_once_with (
1352+ client .enterprise_learner_endpoint ,
1353+ params = {'enterprise_customer_uuid' : str (TEST_ENTERPRISE_UUID ), 'user_ids' : TEST_USER_ID },
1354+ timeout = settings .LMS_CLIENT_TIMEOUT ,
1355+ )
1356+ else :
1357+ mock_oauth_client .return_value .get .assert_not_called ()
1358+
1359+ @mock .patch ('enterprise_access.apps.api_client.base_oauth.OAuthAPIClient' )
1360+ def test_get_enterprise_learner_by_email_account_http_error (self , mock_oauth_client ):
1361+ """
1362+ HTTPError from get_lms_user_account propagates to the caller instead of being swallowed.
1363+ This ensures calling Celery tasks retry rather than silently proceeding.
1364+ """
1365+ client = LmsApiClient ()
1366+ with mock .patch .object (
1367+ client , 'get_lms_user_account' , side_effect = requests .exceptions .HTTPError ('500' )
1368+ ):
1369+ with self .assertRaises (requests .exceptions .HTTPError ):
1370+ client .get_enterprise_learner_by_email (str (TEST_ENTERPRISE_UUID ), 'test@example.com' )
1371+ mock_oauth_client .return_value .get .assert_not_called ()
1372+
1373+ @mock .patch ('enterprise_access.apps.api_client.base_oauth.OAuthAPIClient' )
1374+ def test_get_enterprise_learner_by_email_enterprise_http_error (self , mock_oauth_client ):
1375+ """
1376+ HTTPError from the enterprise-learner endpoint propagates to the caller.
1377+ This ensures calling Celery tasks retry on LMS 5xx rather than treating
1378+ the failure as 'not linked' and proceeding to create_pending_enterprise_users.
1379+ """
1380+ mock_oauth_client .return_value .get .return_value = MockResponse (None , 503 )
1381+ client = LmsApiClient ()
1382+ with mock .patch .object (client , 'get_lms_user_account' , return_value = [{'id' : TEST_USER_ID }]):
1383+ with self .assertRaises (requests .exceptions .HTTPError ):
1384+ client .get_enterprise_learner_by_email (str (TEST_ENTERPRISE_UUID ), 'test@example.com' )
1385+
12851386
12861387class TestLmsUserApiClient (TestCase ):
12871388 """
0 commit comments