freeipa/ipatests/test_webui/test_netgroup.py
Michal Reznik 8d508b8e95 ui_tests: extend test_selinuxusermap.py suite
Extend test_selinuxusermap.py suite with new test cases. Details in
the ticket.

We also modify "add_table_associations" to handle "cancel" and
"negative" in the way other methods works.

Lastly, we start using dialog_btn=None to test keyboard confirmation
as we did use it incorrectly with "Negative=True" where it was already
confirmed by "click".

Added tests:

addselinuxusermap_MLS_singlelevel
addselinuxusermap_cancel
addselinuxusermap_disabledhbacrule
addselinuxusermap_MLS_range
addselinuxusermap_MCS_range
addselinuxusermap_MCS_commas
addselinuxusermap_MLS_singlevalue
addselinuxusermap_multiple
addandeditselinuxusermap
selinuxusermap_undo
selinuxusermap_refresh
selinuxusermap_reset
selinuxusermap_update
selinuxusermap_backlink_cancel
selinuxusermap_backlink_reset
selinuxusermap_backlink_update
selinuxusermap_deletemultiple
add_user_selinuxusermap_cancel
add_host_selinuxusermap_cancel
add_hostgroup_selinuxusermap_cancel
selinuxusermap_requiredfield
selinuxusermap_duplicate
selinuxusermap_nonexistinguser
selinuxusermap_invalidusersyntaxMCS
selinuxusermap_invalidusersyntaxMLS
add_usernegative_selinuxusermap
selinuxusermap_addNegativeHBACrule
selinuxusermap_search
selinuxusermap_searchnegative
selinuxusermap_disablemultiple
selinuxusermap_enablemultiple
selinuxusermap_deleteNegativeHBACrule
add_selinuxusermap_adder_dialog_bug910463
delete_selinuxusermap_deleter_dialog_bug910463

https://pagure.io/freeipa/issue/7544

Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
2018-05-18 12:17:54 +02:00

371 lines
13 KiB
Python

# Authors:
# Petr Vobornik <pvoborni@redhat.com>
#
# Copyright (C) 2013 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Netgroup tests
"""
from ipatests.test_webui.ui_driver import UI_driver
from ipatests.test_webui.ui_driver import screenshot
import ipatests.test_webui.data_netgroup as netgroup
import ipatests.test_webui.data_user as user
import ipatests.test_webui.data_group as group
import ipatests.test_webui.data_hostgroup as hostgroup
from ipatests.test_webui.test_host import host_tasks, ENTITY as HOST_ENTITY
import pytest
try:
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
except ImportError:
pass
@pytest.mark.tier1
class test_netgroup(UI_driver):
@screenshot
def test_crud(self):
"""
Basic CRUD: netgroup
"""
self.init_app()
self.basic_crud(netgroup.ENTITY, netgroup.DATA)
@screenshot
def test_basic_workflows(self):
"""
add and delete netgroup with various scenarios.
"""
self.init_app()
# add mixed case netgroup name
self.add_record(netgroup.ENTITY, netgroup.DATA_MIXED_CASE)
pkey = netgroup.DATA_MIXED_CASE['pkey'].lower()
self.delete_record(pkey)
# add long netgroup name
self.add_record(netgroup.ENTITY, netgroup.DATA_LONG_NAME, delete=True)
# add single character netgroup name ticket#2671
self.add_record(netgroup.ENTITY, netgroup.DATA_SINGLE_CHAR,
delete=True)
# add netgroup using enter
self.add_record(netgroup.ENTITY, netgroup.DATA, dialog_btn=None)
actions = ActionChains(self.driver)
actions.send_keys(Keys.TAB)
actions.send_keys(Keys.ENTER).perform()
self.wait_for_request(d=0.5)
self.assert_record(netgroup.PKEY)
self.close_notifications()
# delete netgroup using enter
self.select_record(netgroup.PKEY)
self.facet_button_click('remove')
self.wait_for_request()
actions = ActionChains(self.driver)
actions.send_keys(Keys.ENTER).perform()
self.wait_for_request(d=0.5)
self.assert_record(netgroup.PKEY, negative=True)
self.close_all_dialogs()
# delete and cancel
self.add_record(netgroup.ENTITY, netgroup.DATA)
self.select_record(netgroup.PKEY)
self.facet_button_click('remove')
self.dialog_button_click('cancel')
self.assert_record(netgroup.PKEY)
self.select_record(netgroup.PKEY, unselect=True)
self.delete_record(netgroup.PKEY)
# add multiple records using add_and_another button
self.add_record(netgroup.ENTITY, [netgroup.DATA, netgroup.DATA2,
netgroup.DATA3, netgroup.DATA4])
# search record
pkey = netgroup.DATA2['pkey']
self.search_pkey(pkey)
self.assert_record(pkey)
# Negative search
pkey = netgroup.DATA_MIXED_CASE['pkey']
self.search_pkey(pkey)
self.assert_record(pkey, negative=True)
# delete multiple records
records = [netgroup.DATA, netgroup.DATA2, netgroup.DATA3]
self.navigate_to_entity(netgroup.ENTITY)
self.select_multiple_records(records)
self.facet_button_click('remove')
self.dialog_button_click('ok')
# Find and delete
pkey = netgroup.DATA4['pkey']
self.search_pkey(pkey)
self.select_record(pkey)
self.facet_button_click('remove')
self.dialog_button_click('ok')
def search_pkey(self, pkey):
search_field_s = '.search-filter input[name=filter]'
self.fill_text(search_field_s, pkey)
self.action_button_click('find', parent=None)
self.wait_for_request(n=2)
@screenshot
def test_add_netgroup_negative(self):
"""
Negative test for adding netgroup
"""
self.init_app()
# add then cancel
self.add_record(netgroup.ENTITY, netgroup.DATA, dialog_btn='cancel')
# add duplicate
self.add_record(netgroup.ENTITY, netgroup.DATA)
expected_error = 'group with name "%s" already exists' % netgroup.PKEY
self.navigate_to_entity(netgroup.ENTITY)
self.facet_button_click('add')
self.fill_input('cn', netgroup.PKEY)
self.cancel_retry_dialog(expected_error)
self.delete_record(netgroup.PKEY)
# empty netgroup
self.navigate_to_entity(netgroup.ENTITY)
self.facet_button_click('add')
self.dialog_button_click('add')
elem = self.find(".widget[name='cn']")
self.assert_field_validation_required(elem)
self.dialog_button_click('cancel')
# invalid_group_name
expected_error = 'may only include letters, numbers, _, -, and .'
pkey = ';test-gr@up'
self.navigate_to_entity(netgroup.ENTITY)
self.facet_button_click('add')
self.fill_input('cn', pkey)
elem = self.find(".widget[name='cn']")
self.assert_field_validation(expected_error, parent=elem)
self.dialog_button_click('cancel')
def cancel_retry_dialog(self, expected_error):
self.dialog_button_click('add')
dialog = self.get_last_error_dialog()
assert (expected_error in dialog.text)
self.wait_for_request()
# Key press for Retry
actions = ActionChains(self.driver)
actions.send_keys(Keys.ENTER).perform()
self.wait_for_request(n=2)
self.dialog_button_click('cancel')
self.wait_for_request(n=2)
self.dialog_button_click('cancel')
@screenshot
def test_unsaved_changes(self):
"""
verifying unsaved changes dialog ticket#2075
"""
self.init_app()
self.add_record(netgroup.ENTITY, netgroup.DATA8,
dialog_btn='add_and_edit')
mod_description = (netgroup.DATA8['mod'][0][2])
# verifying Cancel button
self.fill_fields(netgroup.DATA8['mod'])
self.click_on_link('Netgroups')
self.assert_dialog()
self.dialog_button_click('cancel')
self.assert_facet_button_enabled('save')
# verifying Revert button
self.click_on_link('Netgroups')
self.assert_dialog()
self.dialog_button_click('revert')
self.navigate_to_record(netgroup.PKEY8)
self.verify_btn_action(mod_description)
# verifying Save button
self.fill_fields(netgroup.DATA8['mod'])
self.click_on_link('Netgroups')
self.assert_dialog()
self.dialog_button_click('save')
self.navigate_to_record(netgroup.PKEY8)
self.verify_btn_action(mod_description, negative=True)
@screenshot
def test_add_and_edit_group(self):
"""
1. add and switch to edit mode
2. verifying Save, Revert, Refresh and Undo button
"""
self.init_app()
# add and edit record
self.add_record(netgroup.ENTITY, netgroup.DATA8,
dialog_btn='add_and_edit')
mod_description = (netgroup.DATA8['mod'][0][2])
# verifying undo button
self.fill_fields(netgroup.DATA8['mod'])
self.undo_click()
self.verify_btn_action(mod_description)
self.wait_for_request(n=2)
# verifying revert button
self.mod_record(netgroup.ENTITY, netgroup.DATA8, facet_btn='revert')
self.wait_for_request()
self.verify_btn_action(mod_description)
self.wait_for_request(n=2)
# verifying refresh button
self.fill_fields(netgroup.DATA8['mod'], undo=True)
self.facet_button_click('refresh')
self.verify_btn_action(mod_description)
self.wait_for_request(n=2)
# verifying Save button
self.mod_record(netgroup.ENTITY, netgroup.DATA8)
self.wait_for_request()
self.verify_btn_action(mod_description, negative=True)
self.wait_for_request(n=2)
# clean up
self.navigate_to_entity(netgroup.ENTITY)
self.delete_record(netgroup.PKEY8)
def undo_click(self):
facet = self.get_facet()
s = ".textarea-widget button[name='undo']"
self._button_click(s, facet)
def verify_btn_action(self, mod_description, negative=False):
"""
camparing current description with modified description
"""
current_description = self.get_field_value("description",
element="textarea")
if negative:
assert current_description == mod_description
else:
assert current_description != mod_description
@screenshot
def test_add_members(self):
"""
Adding members and membersof
"""
self.init_app()
records = [netgroup.DATA, netgroup.DATA2, netgroup.DATA3,
netgroup.DATA4, netgroup.DATA8]
self.add_record(netgroup.ENTITY, records)
# adding netgroup "members"
self.navigate_to_record(netgroup.PKEY2)
self.add_associations([netgroup.PKEY3, netgroup.PKEY4],
'member_netgroup', delete=True, search=True)
# adding netgroup "memberof"
self.add_associations([netgroup.PKEY, netgroup.PKEY8],
'memberof_netgroup', delete=True)
self.delete(netgroup.ENTITY, records)
@screenshot
def test_mod(self):
"""
Mod: netgroup
"""
self.init_app()
host = host_tasks()
host.setup(self.driver, self.config)
self.add_record(netgroup.ENTITY, netgroup.DATA2)
self.add_record(user.ENTITY, user.DATA)
self.add_record(user.ENTITY, user.DATA2, navigate=False)
self.add_record(group.ENTITY, group.DATA)
self.add_record(group.ENTITY, group.DATA2, navigate=False)
self.add_record(HOST_ENTITY, host.data)
self.add_record(HOST_ENTITY, host.data2, navigate=False)
self.add_record(hostgroup.ENTITY, hostgroup.DATA)
self.add_record(hostgroup.ENTITY, hostgroup.DATA2, navigate=False)
self.add_record(netgroup.ENTITY, netgroup.DATA)
self.navigate_to_record(netgroup.PKEY, entity=netgroup.ENTITY)
tables = [
['memberuser_user', [user.PKEY, user.PKEY2], ],
['memberuser_group', [group.PKEY, group.PKEY2], ],
['memberhost_host', [host.pkey, host.pkey2], ],
['memberhost_hostgroup', [hostgroup.PKEY, hostgroup.PKEY2], ],
]
categories = [
'usercategory',
'hostcategory',
]
self.mod_rule_tables(tables, categories, [])
# add associations then cancel
def get_t_vals(t):
table = t[0]
k = t[1]
e = []
if len(t) > 2:
e = t[2]
return table, k, e
for t in tables:
table, keys, _exts = get_t_vals(t)
self.add_table_associations(table, [keys[0]], confirm_btn='cancel')
# verifying members listed as links ticket#2670
self.add_table_associations(table, [keys[0]])
self.wait_for_request(n=2)
self.navigate_to_record(keys[0], table_name=table)
page_pkey = self.get_text('.facet-pkey')
assert keys[0] in page_pkey
self.navigate_to_record(netgroup.PKEY, entity=netgroup.ENTITY)
for cat in categories:
# verifying undo on memberships
self.check_option(cat, 'all')
self.assert_facet_button_enabled('save', enabled=True)
undo = "div[name = %s] > button[name='undo']" % cat
self._button_click(undo, parent=None)
self.assert_facet_button_enabled('save', enabled=False)
# verifying Revert on memberships
self.check_option(cat, 'all')
self.facet_button_click('revert')
self.assert_facet_button_enabled('save', enabled=False)
# verifying refresh on memberships
self.check_option(cat, 'all')
self.facet_button_click('refresh')
self.assert_facet_button_enabled('save', enabled=False)
# cleanup
# -------
self.delete(netgroup.ENTITY, [netgroup.DATA, netgroup.DATA2])
self.delete(user.ENTITY, [user.DATA, user.DATA2])
self.delete(group.ENTITY, [group.DATA, group.DATA2])
self.delete(HOST_ENTITY, [host.data, host.data2])
self.delete(hostgroup.ENTITY, [hostgroup.DATA, hostgroup.DATA2])