import pytest import demistomock as demisto from IAMApiModule import * from Salesforce_IAM import Client, IAMUserProfile, create_user_command, get_user_command, update_user_command def mock_client(): client = Client( demisto_params={}, base_url="base_url", conn_client_id="client_id", conn_client_secret="client_secret", conn_username="", conn_password="password", ok_codes=(200, 201, 204), verify=True, proxy=True, ) return client create_inp_schme = { "username": "test@palo.com", "Email": "test@palo.com", "LastName": "haim", "FirstName": "test", "Alias": "a", "TimeZoneSidKey": "Asia/Tokyo", "LocaleSidKey": "en_US", "EmailEncodingKey": "ISO-8859-1", "ProfileId": "00e4K000001GgCL", "LanguageLocaleKey": "en_US", } demisto.callingContext = {"context": {"IntegrationInstance": "Test", "IntegrationBrand": "Test"}} SALESFORCE_GET_USER_OUTPUT = { "Email": "TestID@networks.com", "Username": "TestID@networks.com", "FirstName": "test", "Id": "12345", "IsActive": "true", } SALESFORCE_CREATE_USER_OUTPUT = {"id": "12345", "success": True} def get_outputs_from_user_profile(user_profile): entry_context = user_profile.to_entry() outputs = entry_context.get("Contents") return outputs def test_create_user_command(mocker): args = {"user-profile": {"email": "mock@mock.com"}} mocker.patch.object(Client, "get_access_token_", return_value="") client = mock_client() mocker.patch.object(IAMUserProfile, "map_object", return_value={}) mocker.patch.object(client, "create_user", return_value=SALESFORCE_CREATE_USER_OUTPUT) mocker.patch.object(client, "get_user_id_and_activity_by_mail", return_value=(None, None)) iam_user_profile = create_user_command(client, args, "mapper_out", True, True, True) outputs = get_outputs_from_user_profile(iam_user_profile) assert outputs.get("action") == IAMActions.CREATE_USER assert outputs.get("success") is True assert outputs.get("active") is True assert outputs.get("id") == "12345" def test_get_user_command__existing_user(mocker): args = {"user-profile": {"email": "mock@mock.com"}} mocker.patch.object(Client, "get_access_token_", return_value="") client = mock_client() mocker.patch.object(client, "get_user", return_value=SALESFORCE_GET_USER_OUTPUT) mocker.patch.object(client, "get_user_id_and_activity_by_mail", return_value=("id", None)) mocker.patch.object(IAMUserProfile, "update_with_app_data", return_value={}) iam_user_profile = get_user_command(client, args, "mapper_in", "mapper_out") outputs = get_outputs_from_user_profile(iam_user_profile) assert outputs.get("action") == IAMActions.GET_USER assert outputs.get("success") is True assert outputs.get("active") is True assert outputs.get("id") == "12345" assert outputs.get("username") == "TestID@networks.com" def test_get_user_command__non_existing_user(mocker): args = {"user-profile": {"email": "mock@mock.com"}} mocker.patch.object(Client, "get_access_token_", return_value="") client = mock_client() mocker.patch.object(client, "get_user_id_and_activity_by_mail", return_value=(None, None)) mocker.patch.object(client, "get_user", return_value={}) iam_user_profile = get_user_command(client, args, "mapper_in", "mapper_out") outputs = get_outputs_from_user_profile(iam_user_profile) assert outputs.get("action") == IAMActions.GET_USER assert outputs.get("success") is False assert outputs.get("errorCode") == IAMErrors.USER_DOES_NOT_EXIST[0] assert outputs.get("errorMessage") == IAMErrors.USER_DOES_NOT_EXIST[1] def test_create_user_command__user_already_exists(mocker): args = {"user-profile": {"email": "mock@mock.com"}} mocker.patch.object(Client, "get_access_token_", return_value="") client = mock_client() mocker.patch.object(client, "get_user_id_and_activity_by_mail", return_value=("mock@mock.com", "")) mocker.patch.object(client, "update_user", return_value="") iam_user_profile = create_user_command(client, args, "mapper_out", True, True, True) outputs = get_outputs_from_user_profile(iam_user_profile) assert outputs.get("action") == IAMActions.UPDATE_USER assert outputs.get("success") is True def test_update_user_command__non_existing_user(mocker): args = {"user-profile": {"email": "mock@mock.com"}} mocker.patch.object(Client, "get_access_token_", return_value="") client = mock_client() mocker.patch.object(client, "get_user_id_and_activity_by_mail", return_value=(None, None)) mocker.patch.object(IAMUserProfile, "map_object", return_value={}) mocker.patch.object(client, "create_user", return_value=SALESFORCE_CREATE_USER_OUTPUT) iam_user_profile = update_user_command( client, args, "mapper_out", is_command_enabled=True, is_enable_enabled=True, is_create_user_enabled=True, create_if_not_exists=True, ) outputs = get_outputs_from_user_profile(iam_user_profile) assert outputs.get("action") == IAMActions.CREATE_USER assert outputs.get("success") is True assert outputs.get("active") is True assert outputs.get("id") == "12345" def test_update_user_command__command_is_disabled(mocker): args = {"user-profile": {"email": "mock@mock.com"}} mocker.patch.object(Client, "get_access_token_", return_value="") client = mock_client() mocker.patch.object(client, "get_user_id_and_activity_by_mail", return_value=(None, None)) mocker.patch.object(IAMUserProfile, "map_object", return_value={}) mocker.patch.object(client, "update_user") user_profile = update_user_command( client, args, "mapper_out", is_command_enabled=False, is_enable_enabled=False, is_create_user_enabled=False, create_if_not_exists=False, ) outputs = get_outputs_from_user_profile(user_profile) assert outputs.get("action") == IAMActions.UPDATE_USER assert outputs.get("success") is True assert outputs.get("skipped") is True assert outputs.get("reason") == "Command is disabled." # ===================== UCP Tests ===================== def test_client_init_skips_token_when_ucp_enabled(mocker): """When UCP auth is enabled, Client.__init__ should NOT call get_access_token_ and self.token should remain None.""" mocker.patch("Salesforce_IAM.should_use_ucp_auth", return_value=True) spy = mocker.patch.object(Client, "get_access_token_", return_value="fake_token") client = Client( demisto_params={}, base_url="base_url", conn_client_id="", conn_client_secret="", conn_username="", conn_password="", ok_codes=(200, 201, 204), verify=True, proxy=True, ) spy.assert_not_called() assert client.token is None def test_client_init_gets_token_when_ucp_disabled(mocker): """When UCP auth is disabled (default), Client.__init__ should call get_access_token_ and self.token should have the returned value.""" mocker.patch("Salesforce_IAM.should_use_ucp_auth", return_value=False) mocker.patch.object(Client, "get_access_token_", return_value="my_token") client = Client( demisto_params={}, base_url="base_url", conn_client_id="client_id", conn_client_secret="client_secret", conn_username="user", conn_password="password", ok_codes=(200, 201, 204), verify=True, proxy=True, ) Client.get_access_token_.assert_called_once() assert client.token == "my_token" def test_main_skips_credential_extraction_when_ucp_enabled(mocker): """When UCP is enabled, main() should skip credential extraction from params and pass empty strings to Client constructor.""" from Salesforce_IAM import main mocker.patch("Salesforce_IAM.should_use_ucp_auth", return_value=True) mocker.patch.object( demisto, "params", return_value={ "url": "https://test.salesforce.com/", "insecure": False, "proxy": False, }, ) mocker.patch.object(demisto, "command", return_value="test-module") mocker.patch.object(demisto, "args", return_value={}) mock_client_constructor = mocker.patch("Salesforce_IAM.Client") mocker.patch("Salesforce_IAM.test_module", return_value="ok") mocker.patch("Salesforce_IAM.return_results") main() call_kwargs = mock_client_constructor.call_args assert call_kwargs[1]["conn_client_id"] == "" assert call_kwargs[1]["conn_client_secret"] == "" assert call_kwargs[1]["conn_username"] == "" assert call_kwargs[1]["conn_password"] == "" def test_main_extracts_credentials_when_ucp_disabled(mocker): """When UCP is disabled, main() should extract credentials from params.""" from Salesforce_IAM import main mocker.patch("Salesforce_IAM.should_use_ucp_auth", return_value=False) mocker.patch.object( demisto, "params", return_value={ "url": "https://test.salesforce.com/", "credentials": {"identifier": "myuser", "password": "mypass"}, "credentials_consumer": {"identifier": "my_client_id", "password": "my_client_secret"}, "insecure": False, "proxy": False, }, ) mocker.patch.object(demisto, "command", return_value="test-module") mocker.patch.object(demisto, "args", return_value={}) mock_client_constructor = mocker.patch("Salesforce_IAM.Client") mocker.patch("Salesforce_IAM.test_module", return_value="ok") mocker.patch("Salesforce_IAM.return_results") main() call_kwargs = mock_client_constructor.call_args assert call_kwargs[1]["conn_client_id"] == "my_client_id" assert call_kwargs[1]["conn_client_secret"] == "my_client_secret" assert call_kwargs[1]["conn_username"] == "myuser" assert call_kwargs[1]["conn_password"] == "mypass" def test_main_errors_on_missing_consumer_keys_when_ucp_disabled(mocker): """When UCP is disabled and consumer key/secret are missing, main() should call return_error. In production, return_error calls sys.exit(0), so we simulate that with SystemExit side_effect.""" from Salesforce_IAM import main mocker.patch("Salesforce_IAM.should_use_ucp_auth", return_value=False) mocker.patch.object( demisto, "params", return_value={ "url": "https://test.salesforce.com/", "credentials": {"identifier": "myuser", "password": "mypass"}, "insecure": False, "proxy": False, }, ) mocker.patch.object(demisto, "command", return_value="test-module") mocker.patch.object(demisto, "args", return_value={}) mock_return_error = mocker.patch("Salesforce_IAM.return_error", side_effect=SystemExit(0)) with pytest.raises(SystemExit): main() mock_return_error.assert_called_once_with("Consumer Key and Consumer Secret must be provided.") def test_existing_commands_work_with_ucp_enabled(mocker): """When UCP is enabled, commands like get_user_command should still work. The client.token will be None but _http_request handles UCP auth injection.""" mocker.patch("Salesforce_IAM.should_use_ucp_auth", return_value=True) client = Client( demisto_params={}, base_url="base_url", conn_client_id="", conn_client_secret="", conn_username="", conn_password="", ok_codes=(200, 201, 204), verify=True, proxy=True, ) assert client.token is None args = {"user-profile": {"email": "mock@mock.com"}} mocker.patch.object(client, "get_user", return_value=SALESFORCE_GET_USER_OUTPUT) mocker.patch.object(client, "get_user_id_and_activity_by_mail", return_value=("id", None)) mocker.patch.object(IAMUserProfile, "update_with_app_data", return_value={}) iam_user_profile = get_user_command(client, args, "mapper_in", "mapper_out") outputs = get_outputs_from_user_profile(iam_user_profile) assert outputs.get("action") == IAMActions.GET_USER assert outputs.get("success") is True assert outputs.get("active") is True assert outputs.get("id") == "12345" assert outputs.get("username") == "TestID@networks.com"