| |
@@ -5,6 +5,7 @@
|
| |
import logging
|
| |
from unittest.mock import MagicMock, patch
|
| |
|
| |
+ from fedora_messaging.message import Message
|
| |
from journal_to_fedora_messaging_messages.ipa import IpaGroupRemoveMemberV1
|
| |
import pytest
|
| |
|
| |
@@ -36,6 +37,11 @@
|
| |
)
|
| |
|
| |
|
| |
+ @pytest.fixture
|
| |
+ def topic_message():
|
| |
+ return Message
|
| |
+
|
| |
+
|
| |
class TestAcceptTopic:
|
| |
"""
|
| |
Test class for `toddler.plugins.cleaning_packager_groups.CleanPackagerGroups.accepts_topic`
|
| |
@@ -56,6 +62,7 @@
|
| |
"org.fedoraproject.*.ipa.group_remove_member.v1",
|
| |
"org.fedoraproject.prod.ipa.group_remove_member.v1",
|
| |
"org.fedoraproject.stg.ipa.group_remove_member.v1",
|
| |
+ "org.fedoraproject.*.toddlers.trigger.clean_packagers_groups",
|
| |
],
|
| |
)
|
| |
def test_accepts_topic_valid(self, topic, toddler):
|
| |
@@ -72,9 +79,20 @@
|
| |
|
| |
def setup_method(self):
|
| |
"""Initialize toddler."""
|
| |
+ self._ipa_patcher = patch(
|
| |
+ "toddlers.plugins.cleaning_packager_groups.ipalib.api"
|
| |
+ )
|
| |
+ mock_api = self._ipa_patcher.start()
|
| |
+ mock_api.bootstrap.return_value = None
|
| |
+ mock_api.load_plugins.return_value = None
|
| |
+ mock_api.finalize.return_value = None
|
| |
+
|
| |
self.toddler_cls = cleaning_packager_groups.CleanPackagerGroups()
|
| |
self.toddler_cls._ipa_session = MagicMock()
|
| |
|
| |
+ def teardown_method(self):
|
| |
+ self._ipa_patcher.stop()
|
| |
+
|
| |
@patch("toddlers.utils.pagure.set_pagure")
|
| |
def test_not_packager_group(
|
| |
self, mock_set_pagure, group_remove_member_message, caplog
|
| |
@@ -112,11 +130,15 @@
|
| |
"Distgit groups found: ['group1', 'group2']",
|
| |
"User lenkaseg was removed from packager group, removing from "
|
| |
"packager-related groups as well.",
|
| |
+ "Removing user lenkaseg from distgit group packager",
|
| |
"User lenkaseg removed from distgit group: packager",
|
| |
"Fetching groups user lenkaseg is member of in ipa:",
|
| |
"Ipa groups: ['group1', 'group3']",
|
| |
"User lenkaseg should be removed from following groups: ['group1']",
|
| |
- "User lenkaseg removed from ipa group: group1",
|
| |
+ "User lenkaseg is not a sponsor of ipa group group1, skipping sponsor removal",
|
| |
+ "Removing user lenkaseg from members of ipa group group1",
|
| |
+ "User lenkaseg removed from members of ipa group group1",
|
| |
+ "Removing user lenkaseg from distgit group group1",
|
| |
"User lenkaseg removed from distgit group: group1",
|
| |
),
|
| |
),
|
| |
@@ -137,6 +159,7 @@
|
| |
"Distgit groups found: ['group1', 'group2']",
|
| |
"User lenkaseg was removed from packager group, removing from "
|
| |
"packager-related groups as well.",
|
| |
+ "Removing user lenkaseg from distgit group packager",
|
| |
"User lenkaseg removed from distgit group: packager",
|
| |
"Fetching groups user lenkaseg is member of in ipa:",
|
| |
"Ipa groups: ['group3', 'group4']",
|
| |
@@ -152,6 +175,7 @@
|
| |
"Distgit groups found: ['group1', 'group2']",
|
| |
"User lenkaseg was removed from packager group, removing from "
|
| |
"packager-related groups as well.",
|
| |
+ "Removing user lenkaseg from distgit group packager",
|
| |
"User lenkaseg removed from distgit group: packager",
|
| |
"Fetching groups user lenkaseg is member of in ipa:",
|
| |
"Ipa groups: []",
|
| |
@@ -186,6 +210,23 @@
|
| |
mock_pagure.return_value = mock_pagure_obj
|
| |
|
| |
self.toddler_cls._ipa_session.Command.user_show.return_value = ipa_groups
|
| |
+
|
| |
+ # Mock group_show for the first test case where IPA removal should happen
|
| |
+ if distgit_groups == ["group1", "group2"] and ipa_groups == {
|
| |
+ "result": {"memberof_group": ["group1", "group3"]}
|
| |
+ }:
|
| |
+ self.toddler_cls._ipa_session.Command.group_show.return_value = {
|
| |
+ "result": {"member_user": ["lenkaseg"], "membermanager_user": []}
|
| |
+ }
|
| |
+ self.toddler_cls._ipa_session.Command.group_remove_member.return_value = {
|
| |
+ "completed": 1
|
| |
+ }
|
| |
+ else:
|
| |
+ # For other test cases, user is not in IPA group
|
| |
+ self.toddler_cls._ipa_session.Command.group_show.return_value = {
|
| |
+ "result": {"member_user": [], "membermanager_user": []}
|
| |
+ }
|
| |
+
|
| |
caplog.set_level(logging.INFO)
|
| |
config = {
|
| |
"pagure_url": "https://example.io",
|
| |
@@ -198,19 +239,23 @@
|
| |
assert recorded_messages == messages
|
| |
|
| |
@pytest.mark.parametrize(
|
| |
- "ipa_remove_member,error,message_1,message_2",
|
| |
+ "ipa_remove_member,error,messages",
|
| |
(
|
| |
(
|
| |
Exception,
|
| |
None,
|
| |
- "User lenkaseg removed from distgit group: group1",
|
| |
- "Error while removing user lenkaseg from ipa group group1",
|
| |
+ (
|
| |
+ "User lenkaseg removed from distgit group: group1",
|
| |
+ "Error while removing user lenkaseg from ipa group group1",
|
| |
+ ),
|
| |
),
|
| |
(
|
| |
None,
|
| |
PagureError,
|
| |
- "Error while removing user lenkaseg from distgit group group1",
|
| |
- "User lenkaseg removed from ipa group: group1",
|
| |
+ (
|
| |
+ "Error while removing user lenkaseg from distgit group group1",
|
| |
+ "User lenkaseg removed from members of ipa group group1",
|
| |
+ ),
|
| |
),
|
| |
),
|
| |
ids=("ipa_error", "distgit_error"),
|
| |
@@ -221,8 +266,7 @@
|
| |
mock_set_pagure,
|
| |
ipa_remove_member,
|
| |
error,
|
| |
- message_1,
|
| |
- message_2,
|
| |
+ messages,
|
| |
group_remove_member_message,
|
| |
caplog,
|
| |
):
|
| |
@@ -236,9 +280,20 @@
|
| |
"result": {"memberof_group": ["group1", "group3"]}
|
| |
}
|
| |
|
| |
- self.toddler_cls._ipa_session.Command.group_remove_member.side_effect = (
|
| |
- ipa_remove_member
|
| |
- )
|
| |
+ self.toddler_cls._ipa_session.Command.group_show.return_value = {
|
| |
+ "result": {"member_user": ["lenkaseg"], "membermanager_user": []}
|
| |
+ }
|
| |
+
|
| |
+ if ipa_remove_member:
|
| |
+ self.toddler_cls._ipa_session.Command.group_remove_member.side_effect = (
|
| |
+ ipa_remove_member
|
| |
+ )
|
| |
+ else:
|
| |
+ # Return successful result when no IPA error is expected
|
| |
+ self.toddler_cls._ipa_session.Command.group_remove_member.return_value = {
|
| |
+ "completed": 1
|
| |
+ }
|
| |
+ self.toddler_cls._ipa_session.Command.group_remove_member.side_effect = None
|
| |
|
| |
caplog.set_level(logging.INFO)
|
| |
config = {
|
| |
@@ -252,5 +307,419 @@
|
| |
self.toddler_cls._ipa_session.Command.user_show.assert_called_with(
|
| |
uid="lenkaseg"
|
| |
)
|
| |
- assert caplog.records[-1].message == message_1
|
| |
- assert caplog.records[-2].message == message_2
|
| |
+ for message in messages:
|
| |
+ assert message in [r.message for r in caplog.records]
|
| |
+
|
| |
+ @pytest.mark.parametrize(
|
| |
+ "ipa_output,expected_logs",
|
| |
+ [
|
| |
+ (
|
| |
+ {"completed": 1},
|
| |
+ [
|
| |
+ "User lenkaseg removed from members of ipa group group1",
|
| |
+ "User lenkaseg removed from distgit group: group1",
|
| |
+ ],
|
| |
+ ),
|
| |
+ (
|
| |
+ {"completed": 0},
|
| |
+ [
|
| |
+ "Removing user lenkaseg from members of ipa group group1 was not "
|
| |
+ "successful, output:",
|
| |
+ "User lenkaseg removed from distgit group: group1",
|
| |
+ ],
|
| |
+ ),
|
| |
+ ],
|
| |
+ ids=[
|
| |
+ "user_removal_successful",
|
| |
+ "user_removal_failed",
|
| |
+ ],
|
| |
+ )
|
| |
+ def test_process_removal_ipa_output_scenarios(
|
| |
+ self, ipa_output, expected_logs, caplog
|
| |
+ ):
|
| |
+ """
|
| |
+ Assert correct behaviour of ipa_session.Command.group_remove_member() output.
|
| |
+ """
|
| |
+ self.toddler_cls._ipa_session.Command.group_remove_member.return_value = (
|
| |
+ ipa_output
|
| |
+ )
|
| |
+
|
| |
+ self.toddler_cls._ipa_session.Command.user_show.return_value = {
|
| |
+ "result": {"memberof_group": ["group1", "group3"]}
|
| |
+ }
|
| |
+
|
| |
+ self.toddler_cls._ipa_session.Command.group_show.return_value = {
|
| |
+ "result": {"member_user": ["lenkaseg"], "membermanager_user": []}
|
| |
+ }
|
| |
+
|
| |
+ self.toddler_cls.dist_git = MagicMock()
|
| |
+ self.toddler_cls.dist_git.remove_member_from_group.return_value = None
|
| |
+
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ user = "lenkaseg"
|
| |
+ group = "packager"
|
| |
+ distgit_groups = ["group1", "group2"]
|
| |
+
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls._process_removal(config, user, group, distgit_groups)
|
| |
+
|
| |
+ # Verify expected log messages
|
| |
+ for expected_log in expected_logs:
|
| |
+ assert expected_log in caplog.text
|
| |
+
|
| |
+ # Verify IPA calls
|
| |
+ self.toddler_cls._ipa_session.Command.group_remove_member.assert_called_once_with(
|
| |
+ cn="group1", user=user
|
| |
+ )
|
| |
+
|
| |
+ # Verify distgit removal was called (both initial and intersection)
|
| |
+ self.toddler_cls.dist_git.remove_member_from_group.assert_any_call(user, group)
|
| |
+ self.toddler_cls.dist_git.remove_member_from_group.assert_any_call(
|
| |
+ user, "group1"
|
| |
+ )
|
| |
+
|
| |
+ @patch(
|
| |
+ "toddlers.plugins.cleaning_packager_groups.CleanPackagerGroups.find_and_remove"
|
| |
+ )
|
| |
+ def test_error_initializing_ipa_session(self, find_and_remove, caplog):
|
| |
+ """
|
| |
+ If an error occurs initializing IPA session, logs error and stops.
|
| |
+ """
|
| |
+ self.toddler_cls._ipa_session.__enter__.side_effect = Exception(
|
| |
+ "IPA connection failed"
|
| |
+ )
|
| |
+ config = {
|
| |
+ "watched_groups": ["packager"],
|
| |
+ "dist_git_url": "http://example.com/pagure",
|
| |
+ "dist_git_token": "dummy-token",
|
| |
+ }
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+
|
| |
+ # This should raise the exception and not call find_and_remove
|
| |
+ with pytest.raises(Exception, match="IPA connection failed"):
|
| |
+ self.toddler_cls.process(
|
| |
+ config, Message(topic="toddlers.trigger.clean_packagers_groups")
|
| |
+ )
|
| |
+
|
| |
+
|
| |
+ class TestFindAndRemove:
|
| |
+ """
|
| |
+ Test class for
|
| |
+ `toddler.plugins.cleaning_packager_groups.CleanPackagerGroups.find_and_remove`
|
| |
+ method
|
| |
+ """
|
| |
+
|
| |
+ def setup_method(self):
|
| |
+ # Patch the IPA API to prevent bootstrap() already called error
|
| |
+ self._ipa_patcher = patch(
|
| |
+ "toddlers.plugins.cleaning_packager_groups.ipalib.api"
|
| |
+ )
|
| |
+ mock_api = self._ipa_patcher.start()
|
| |
+ mock_api.bootstrap.return_value = None
|
| |
+ mock_api.load_plugins.return_value = None
|
| |
+ mock_api.finalize.return_value = None
|
| |
+
|
| |
+ self.toddler_cls = cleaning_packager_groups.CleanPackagerGroups()
|
| |
+ self.mock_distgit = MagicMock()
|
| |
+ self.mock_ipa_session = MagicMock()
|
| |
+ self.toddler_cls.dist_git = self.mock_distgit
|
| |
+ self.toddler_cls._ipa_session = self.mock_ipa_session
|
| |
+
|
| |
+ def teardown_method(self):
|
| |
+ self._ipa_patcher.stop()
|
| |
+
|
| |
+ @patch("toddlers.utils.pagure.set_pagure")
|
| |
+ def test_topic_playtime_call(self, mock_set_pagure, topic_message, caplog):
|
| |
+ """
|
| |
+ Assert that if the group in the message is not "packager", plugin stops.
|
| |
+ """
|
| |
+ self.toddler_cls.find_and_remove = MagicMock()
|
| |
+ topic_message.topic = (
|
| |
+ "org.fedoraproject.stg.toddlers.trigger.clean_packagers_groups"
|
| |
+ )
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ config = {
|
| |
+ "pagure_url": "https://pagure.io",
|
| |
+ "pagure_stg": "https://stg.pagure.io",
|
| |
+ "watched_groups": ["packager"],
|
| |
+ }
|
| |
+ self.toddler_cls.process(config, topic_message)
|
| |
+ self.toddler_cls.find_and_remove.assert_called_once()
|
| |
+
|
| |
+ def test_all_members_are_packager_members(self, caplog):
|
| |
+ """
|
| |
+ If all distgit group members are IPA packager members, no removal occurs.
|
| |
+ """
|
| |
+ self.mock_distgit.get_all_groups.return_value = ["group1"]
|
| |
+ self.mock_distgit.get_group_members.return_value = ["lenkaseg", "samyak"]
|
| |
+ self.mock_ipa_session.Command.group_show.return_value = {
|
| |
+ "result": {
|
| |
+ "member_user": ["lenkaseg", "samyak"],
|
| |
+ "membermanager_user": ["lenkaseg", "samyak"],
|
| |
+ }
|
| |
+ }
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+ assert "No members to remove from group group1" in caplog.text
|
| |
+ self.mock_distgit.remove_member_from_group.assert_not_called()
|
| |
+
|
| |
+ def test_some_members_not_packager_members(self, caplog):
|
| |
+ """
|
| |
+ If some distgit group members are not IPA packager members, they are removed.
|
| |
+ """
|
| |
+ self.mock_distgit.get_all_groups.return_value = ["group1"]
|
| |
+ self.mock_distgit.get_group_members.return_value = [
|
| |
+ "lenkaseg",
|
| |
+ "samyak",
|
| |
+ "aurelien",
|
| |
+ ]
|
| |
+ self.mock_ipa_session.Command.group_show.return_value = {
|
| |
+ "result": {"member_user": ["lenkaseg"], "membermanager_user": ["aurelien"]}
|
| |
+ }
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+ assert (
|
| |
+ "Found 1 members to remove from distgit and IPA group group1" in caplog.text
|
| |
+ )
|
| |
+ # Only samyak should be removed since lenkaseg is a member and aurelien is a sponsor
|
| |
+ self.mock_distgit.remove_member_from_group.assert_any_call("samyak", "group1")
|
| |
+ assert self.mock_distgit.remove_member_from_group.call_count == 1
|
| |
+
|
| |
+ def test_no_distgit_groups(self, caplog):
|
| |
+ """
|
| |
+ If no distgit groups are found, nothing happens.
|
| |
+ """
|
| |
+ self.mock_distgit.get_all_groups.return_value = []
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+
|
| |
+ expected_logs = [
|
| |
+ "Starting find_and_remove process",
|
| |
+ "Found 0 distgit groups",
|
| |
+ "Found 0 unique packagers (members and sponsors) in IPA packager groups",
|
| |
+ "Completed find_and_remove process",
|
| |
+ ]
|
| |
+ for expected_log in expected_logs:
|
| |
+ assert expected_log in caplog.text
|
| |
+
|
| |
+ self.mock_distgit.get_group_members.assert_not_called()
|
| |
+
|
| |
+ def test_error_fetching_distgit_groups(self, caplog):
|
| |
+ """
|
| |
+ If an error occurs fetching distgit groups, logs error and stops.
|
| |
+ """
|
| |
+ self.mock_distgit.get_all_groups.side_effect = PagureError("fail")
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+ assert "Failed to get distgit groups: fail" in caplog.text
|
| |
+ self.mock_distgit.get_group_members.assert_not_called()
|
| |
+
|
| |
+ def test_error_fetching_group_members(self, caplog):
|
| |
+ """
|
| |
+ If an error occurs fetching distgit group members, logs error and stops.
|
| |
+ """
|
| |
+ self.mock_distgit.get_all_groups.return_value = ["group1"]
|
| |
+ self.mock_distgit.get_group_members.return_value = []
|
| |
+ self.mock_ipa_session.Command.group_show.return_value = {
|
| |
+ "result": {"member_user": ["lenkaseg"]}
|
| |
+ }
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.DEBUG)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+ assert "No group members found in distgit group group1" in caplog.text
|
| |
+ self.mock_distgit.remove_member_from_group.assert_not_called()
|
| |
+
|
| |
+ def test_error_fetching_ipa_group_members(self, caplog):
|
| |
+ """
|
| |
+ If an error occurs fetching IPA group members, logs error and continues.
|
| |
+ """
|
| |
+ self.mock_distgit.get_all_groups.return_value = ["group1"]
|
| |
+ self.mock_ipa_session.Command.group_show.side_effect = Exception(
|
| |
+ "IPA group fetch failed"
|
| |
+ )
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+ assert (
|
| |
+ "Failed to get members of IPA group packager: IPA group fetch failed"
|
| |
+ in caplog.text
|
| |
+ )
|
| |
+ # Should still complete the process despite the error
|
| |
+ assert "Completed find_and_remove process" in caplog.text
|
| |
+
|
| |
+ @pytest.mark.parametrize(
|
| |
+ "output,sponsor_removal_exception,expected_log_message",
|
| |
+ [
|
| |
+ (
|
| |
+ {"completed": 1},
|
| |
+ None,
|
| |
+ "User lenkaseg removed from members of ipa group group1",
|
| |
+ ),
|
| |
+ (
|
| |
+ {"completed": 0},
|
| |
+ None,
|
| |
+ "Removing user lenkaseg from members of ipa group group1 was not "
|
| |
+ "successful, output:",
|
| |
+ ),
|
| |
+ (
|
| |
+ None,
|
| |
+ Exception("ipa removal failed"),
|
| |
+ "Error while removing user lenkaseg from ipa group group1",
|
| |
+ ),
|
| |
+ (
|
| |
+ None,
|
| |
+ None,
|
| |
+ "Error while removing user lenkaseg from members of ipa group group1, no output",
|
| |
+ ),
|
| |
+ ],
|
| |
+ ids=[
|
| |
+ "ipa_user_removal_successful",
|
| |
+ "ipa_user_removal_failed",
|
| |
+ "ipa_removal_exception",
|
| |
+ "ipa_removal_no_output",
|
| |
+ ],
|
| |
+ )
|
| |
+ def test_sponsor_removal_scenarios(
|
| |
+ self,
|
| |
+ output,
|
| |
+ sponsor_removal_exception,
|
| |
+ expected_log_message,
|
| |
+ caplog,
|
| |
+ ):
|
| |
+ self.mock_distgit.get_all_groups.return_value = ["group1"]
|
| |
+ self.mock_distgit.get_group_members.return_value = ["lenkaseg"]
|
| |
+
|
| |
+ # Mock the packager groups check (for find_and_remove) - user is NOT a valid packager
|
| |
+ # This will be called when checking if user should be removed from distgit groups
|
| |
+ def mock_group_show_side_effect(cn):
|
| |
+ if cn == "packager": # This is the watched group
|
| |
+ return {"result": {"member_user": [], "membermanager_user": []}}
|
| |
+ elif cn == "group1": # This is the specific group for IPA removal
|
| |
+ return {
|
| |
+ "result": {"member_user": ["lenkaseg"], "membermanager_user": []}
|
| |
+ }
|
| |
+ else:
|
| |
+ return {"result": {"member_user": [], "membermanager_user": []}}
|
| |
+
|
| |
+ self.mock_ipa_session.Command.group_show.side_effect = (
|
| |
+ mock_group_show_side_effect
|
| |
+ )
|
| |
+
|
| |
+ if not output and sponsor_removal_exception:
|
| |
+ self.mock_ipa_session.Command.group_remove_member.side_effect = (
|
| |
+ sponsor_removal_exception
|
| |
+ )
|
| |
+ self.mock_ipa_session.Command.group_remove_member_manager.side_effect = (
|
| |
+ sponsor_removal_exception
|
| |
+ )
|
| |
+ else:
|
| |
+ group_remove_output = output
|
| |
+ self.mock_ipa_session.Command.group_remove_member.return_value = (
|
| |
+ group_remove_output
|
| |
+ )
|
| |
+ self.mock_ipa_session.Command.group_remove_member_manager.return_value = (
|
| |
+ group_remove_output
|
| |
+ )
|
| |
+ if not sponsor_removal_exception:
|
| |
+ self.mock_ipa_session.Command.group_remove_member.side_effect = None
|
| |
+ self.mock_ipa_session.Command.group_remove_member_manager.side_effect = (
|
| |
+ None
|
| |
+ )
|
| |
+
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+
|
| |
+ if expected_log_message:
|
| |
+ assert expected_log_message in caplog.text
|
| |
+
|
| |
+ @pytest.mark.parametrize(
|
| |
+ "user_as_sponsor,sponsor_removal_output,expected_logs",
|
| |
+ [
|
| |
+ (
|
| |
+ True,
|
| |
+ {"completed": 1},
|
| |
+ [
|
| |
+ "Removing user testuser from sponsors of ipa group group1",
|
| |
+ "User testuser removed from sponsors of ipa group group1",
|
| |
+ ],
|
| |
+ ),
|
| |
+ (
|
| |
+ True,
|
| |
+ {"completed": 0},
|
| |
+ [
|
| |
+ "Removing user testuser from sponsors of ipa group group1",
|
| |
+ "Removing user testuser from sponsors of ipa group group1 "
|
| |
+ "was not successful, output:",
|
| |
+ ],
|
| |
+ ),
|
| |
+ (
|
| |
+ False,
|
| |
+ None,
|
| |
+ [
|
| |
+ "User testuser is not a sponsor of ipa group group1, skipping sponsor removal",
|
| |
+ ],
|
| |
+ ),
|
| |
+ ],
|
| |
+ ids=[
|
| |
+ "sponsor_removal_successful",
|
| |
+ "sponsor_removal_failed",
|
| |
+ "user_not_sponsor",
|
| |
+ ],
|
| |
+ )
|
| |
+ def test_sponsor_removal_scenarios_direct(
|
| |
+ self,
|
| |
+ user_as_sponsor,
|
| |
+ sponsor_removal_output,
|
| |
+ expected_logs,
|
| |
+ caplog,
|
| |
+ ):
|
| |
+ """
|
| |
+ Test sponsor removal scenarios for _remove_from_ipa method (lines 165-166).
|
| |
+ """
|
| |
+ self.mock_distgit.get_all_groups.return_value = ["group1"]
|
| |
+ self.mock_distgit.get_group_members.return_value = ["testuser"]
|
| |
+
|
| |
+ # Set up group_show mock to indicate user sponsor status
|
| |
+ if user_as_sponsor:
|
| |
+ sponsors = ["testuser"]
|
| |
+ else:
|
| |
+ sponsors = []
|
| |
+
|
| |
+ def mock_group_show_side_effect(cn):
|
| |
+ if cn == "packager": # User is NOT a valid packager, so needs removal
|
| |
+ return {"result": {"member_user": [], "membermanager_user": []}}
|
| |
+ elif cn == "group1": # This is where we test sponsor status
|
| |
+ return {"result": {"member_user": [], "membermanager_user": sponsors}}
|
| |
+ else:
|
| |
+ return {"result": {"member_user": [], "membermanager_user": []}}
|
| |
+
|
| |
+ self.mock_ipa_session.Command.group_show.side_effect = (
|
| |
+ mock_group_show_side_effect
|
| |
+ )
|
| |
+
|
| |
+ # Set up sponsor removal mock
|
| |
+ if sponsor_removal_output:
|
| |
+ self.mock_ipa_session.Command.group_remove_member_manager.return_value = (
|
| |
+ sponsor_removal_output
|
| |
+ )
|
| |
+
|
| |
+ config = {"watched_groups": ["packager"]}
|
| |
+ caplog.set_level(logging.INFO)
|
| |
+ self.toddler_cls.find_and_remove(config)
|
| |
+
|
| |
+ # Check that all expected log messages are present
|
| |
+ for expected_log in expected_logs:
|
| |
+ assert expected_log in caplog.text
|
| |
+
|
| |
+ # Verify the appropriate IPA calls were made
|
| |
+ if user_as_sponsor:
|
| |
+ self.mock_ipa_session.Command.group_remove_member_manager.assert_called_once_with(
|
| |
+ cn="group1", user="testuser"
|
| |
+ )
|
| |
+ else:
|
| |
+ self.mock_ipa_session.Command.group_remove_member_manager.assert_not_called()
|
| |