diff --git a/ansible-runner/project b/ansible-runner/project index 9497aed..774348c 160000 --- a/ansible-runner/project +++ b/ansible-runner/project @@ -1 +1 @@ -Subproject commit 9497aed512ae9bd1d42b088fae748ddc2a24bc9a +Subproject commit 774348c0098b70ad802274abe4603dc6c83fb2b1 diff --git a/tests/test_s3df_posixgroup_ldif.py b/tests/test_s3df_posixgroup_ldif.py new file mode 100644 index 0000000..45a32a6 --- /dev/null +++ b/tests/test_s3df_posixgroup_ldif.py @@ -0,0 +1,69 @@ +""" +Unit tests for the LDIF template generated by the s3df_posixgroup ansible +module (daemon/ansible-runner/project/library/s3df_posixgroup.py). +""" + +import sys +import os +from unittest.mock import Mock + +# Mock the ansible modules imported by s3df_posixgroup +sys.modules['ansible.module_utils.basic'] = Mock() +sys.modules['ansible.module_utils.common.text.converters'] = Mock() + +LIBRARY_PATH = os.path.join( + os.path.dirname(__file__), '..', 'ansible-runner', 'project', 'library' +) +if LIBRARY_PATH not in sys.path: + sys.path.insert(0, LIBRARY_PATH) + +from s3df_posixgroup import _change_membership_template # noqa: E402 + +DN = "cn=sdf-cryoem-cd10,ou=Group,dc=sdf,dc=slac,dc=stanford,dc=edu" + + +def test_single_user_add_produces_one_record(): + tmpl = _change_membership_template(DN, 1234, ["bbammes"], action="add") + + assert tmpl.count("dn: ") == 1 + assert tmpl.count("changetype: modify") == 1 + assert "-" not in tmpl.splitlines() + assert tmpl == ( + f"dn: {DN}\n" + "changetype: modify\n" + "add: memberUid\n" + "memberUid: bbammes" + ) + + +def test_multi_user_add_produces_single_record_with_mod_specs(): + users = ["bbammes", "patrickm", "ppascual", "yanliu10"] + tmpl = _change_membership_template(DN, 1234, users, action="add") + + # Exactly one dn/changetype header, regardless of how many users + assert tmpl.count("dn: ") == 1 + assert tmpl.count("changetype: modify") == 1 + + # One mod-spec per user, separated by "-" (users - 1 separators) + lines = tmpl.splitlines() + assert lines.count("-") == len(users) - 1 + assert lines.count("add: memberUid") == len(users) + for user in users: + assert f"memberUid: {user}" in lines + + # No stray "dn:"/"changetype:" lines after the header (the original bug) + assert lines[0] == f"dn: {DN}" + assert lines[1] == "changetype: modify" + for line in lines[2:]: + assert not line.startswith("dn:") + assert not line.startswith("changetype:") + + +def test_multi_user_delete_uses_delete_action(): + users = ["bbammes", "patrickm"] + tmpl = _change_membership_template(DN, 1234, users, action="delete") + + lines = tmpl.splitlines() + assert lines.count("delete: memberUid") == len(users) + assert lines.count("-") == len(users) - 1 + assert "add: memberUid" not in tmpl