From bdbb8f5e81d57543e56f1949f18ac9d2245c70e4 Mon Sep 17 00:00:00 2001 From: Pavel Novotny Date: Thu, 26 Feb 2026 10:07:43 +0100 Subject: [PATCH] hostgroup nonadmin viewer read (#20875) hostgroups: new test for non-admin viewer role Verifies: SAT-38451 New test for bug "Non-admin users on Satellite with viewer role, unable to see the hostgroup." Ensure that non-admin user with viewer role can see hostgroup created by admin user. Also added new `UserFactory` class to help with more reusable user fixtures. (cherry picked from commit 0da20aba3a316b090dff2355ba0b152b2a213a94) --- pytest_fixtures/component/hostgroup.py | 7 ++++ pytest_fixtures/component/user_role.py | 50 +++++++++++++++++++++----- tests/foreman/ui/test_hostgroup.py | 38 ++++++++++++++++++++ 3 files changed, 86 insertions(+), 9 deletions(-) diff --git a/pytest_fixtures/component/hostgroup.py b/pytest_fixtures/component/hostgroup.py index a71c74a8e2e..c2e12111b80 100644 --- a/pytest_fixtures/component/hostgroup.py +++ b/pytest_fixtures/component/hostgroup.py @@ -10,6 +10,13 @@ def module_hostgroup(module_target_sat): return module_target_sat.api.HostGroup().create() +@pytest.fixture(scope='module') +def module_hostgroup_with_org_loc(module_target_sat, module_org, module_location): + return module_target_sat.api.HostGroup( + organization=[module_org], location=[module_location] + ).create() + + @pytest.fixture(scope='class') def class_hostgroup(class_target_sat, class_org, class_location): """Create a hostgroup linked to specific org and location created at the class scope""" diff --git a/pytest_fixtures/component/user_role.py b/pytest_fixtures/component/user_role.py index 99b6a8492c2..7d78ae88572 100644 --- a/pytest_fixtures/component/user_role.py +++ b/pytest_fixtures/component/user_role.py @@ -1,7 +1,31 @@ -from fauxfactory import gen_alphanumeric, gen_string +from fauxfactory import gen_alphanumeric import pytest +class UserFactory: + """Helper class for more complex operations with users that can be reused in fixtures.""" + + @staticmethod + def create_user(target_sat, **params): + """Create and return a user object. Set the password if not specified. + Args: + target_sat: Satellite object + params: parameters passed to the User object + Returns: + User object + """ + params.setdefault('password', gen_alphanumeric()) + user = target_sat.api.User(**params).create() + user.password = params['password'] + return user + + +@pytest.fixture(scope='session') +def viewer_role(session_target_sat): + """Viewer role.""" + return session_target_sat.api.Role().search(query={'search': 'name="Viewer"'})[0] + + @pytest.fixture(scope='class') def class_user_password(): """Generate a random password for a user, and capture it so a test has access to it""" @@ -26,19 +50,27 @@ def module_user(module_target_sat, module_org, module_location): @pytest.fixture(scope='module') -def default_viewer_role(module_target_sat, module_org, default_location): +def default_viewer_role(module_target_sat, module_org, default_location, viewer_role): """Custom user with viewer role for tests validating visibility of entities or fields created by some other user. Created only when accessed, unlike `module_user`. """ - viewer_role = module_target_sat.api.Role().search(query={'search': 'name="Viewer"'})[0] - custom_password = gen_string('alphanumeric') - custom_user = module_target_sat.api.User( + return UserFactory.create_user( + target_sat=module_target_sat, admin=False, default_organization=module_org, location=[default_location], organization=[module_org], role=[viewer_role], - password=custom_password, - ).create() - custom_user.password = custom_password - return custom_user + ) + + +@pytest.fixture(scope='module') +def module_user_viewer(module_target_sat, module_org, module_location, viewer_role): + """Non-admin user with Viewer role.""" + return UserFactory.create_user( + target_sat=module_target_sat, + admin=False, + location=[module_location], + organization=[module_org], + role=[viewer_role], + ) diff --git a/tests/foreman/ui/test_hostgroup.py b/tests/foreman/ui/test_hostgroup.py index a2b57a90cf8..4860cdb8655 100644 --- a/tests/foreman/ui/test_hostgroup.py +++ b/tests/foreman/ui/test_hostgroup.py @@ -370,3 +370,41 @@ def test_positive_clone_host_groups( assert target_sat.api.HostGroup().search(query={'search': f'name={clone_hg_name}'}) session.hostgroup.delete(clone_hg_name) assert not target_sat.api.HostGroup().search(query={'search': f'name={clone_hg_name}'}) + + +def test_positive_non_admin_viewer_role_read( + test_name, + module_target_sat, + module_org, + module_location, + module_hostgroup_with_org_loc, + module_user_viewer, +): + """Verify that a non-admin user with Viewer role assigned is able to see a host group created by admin user. + + :ID: c4f5e236-0bfb-11f1-acba-000c29a0e355 + + :CaseImportance: High + + :Setup: + 1. Create new host group as admin. + 2. Create new non-admin user with Viewer role assigned. + + :Steps: + 1. Log in as the user with Viewer role and go to the Configure->Host Groups page. + + :ExpectedResults: The page is displayed correctly, i.e., no error is shown. User sees the host group in the list. + + :Verifies: SAT-38451 + + :CustomerScenario: true + """ + with module_target_sat.ui_session( + test_name, module_user_viewer.login, module_user_viewer.password + ) as session: + session.organization.select(org_name=module_org.name) + session.location.select(loc_name=module_location.name) + assert ( + session.hostgroup.search(module_hostgroup_with_org_loc.name)[0]['Name'] + == module_hostgroup_with_org_loc.name + )