Skip to content

Commit

Permalink
Improve QTableView update, fix case host spied is None
Browse files Browse the repository at this point in the history
Ref #272 Update Unit Tests
  • Loading branch information
algorys committed Mar 14, 2018
1 parent 9dc0767 commit f6462ed
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 84 deletions.
5 changes: 5 additions & 0 deletions alignak_app/backend/datamanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ def get_item(self, item_type, key, value=None):
if not wanted_item:
wanted_item = next((item for item in items if item.name == key), None)

if not wanted_item:
logger.error(
'Item not found in database[%s]: key=%s, value=%s' % (item_type, key, value)
)

return wanted_item

def update_item_data(self, item_type, item_id, data):
Expand Down
36 changes: 11 additions & 25 deletions alignak_app/qobjects/alignak/problems.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from logging import getLogger

from PyQt5.Qt import QWidget, QIcon, QVBoxLayout, QPushButton, Qt, QLabel, QHBoxLayout, QLineEdit
from PyQt5.Qt import QStandardItemModel, QSortFilterProxyModel

from alignak_app.backend.datamanager import data_manager
from alignak_app.utils.config import settings
Expand All @@ -48,15 +47,13 @@ def __init__(self, parent=None):
super(ProblemsQWidget, self).__init__(parent)
self.setWindowIcon(QIcon(settings.get_image('icon')))
# Fields
self.problem_table = ProblemsQTableView()
self.line_search = QLineEdit()
self.problems_table = ProblemsQTableView()
self.problems_title = QLabel()
self.problems_model = QStandardItemModel()
self.actions_widget = ActionsQWidget()
self.host_btn = QPushButton()
self.spy_btn = QPushButton()
self.spy_widget = None
self.line_search = QLineEdit()
self.original_model = None
self.spy_btn = QPushButton()
self.host_btn = QPushButton()

def initialize(self, spy_widget):
"""
Expand All @@ -75,8 +72,7 @@ def initialize(self, spy_widget):

problem_layout.addWidget(self.get_search_widget())

# self.problem_table.initialize()
problem_layout.addWidget(self.problem_table)
problem_layout.addWidget(self.problems_table)

self.update_problems_data()

Expand All @@ -87,8 +83,8 @@ def update_action_buttons(self):
"""

# Get item by UserRole
item = self.problem_table.model().data(
self.problem_table.selectionModel().currentIndex(),
item = self.problems_table.model().data(
self.problems_table.selectionModel().currentIndex(),
Qt.UserRole
)

Expand Down Expand Up @@ -200,8 +196,8 @@ def add_spied_host(self):
"""

# Get item by UserRole
item = self.problem_table.model().data(
self.problem_table.selectionModel().currentIndex(),
item = self.problems_table.model().data(
self.problems_table.selectionModel().currentIndex(),
Qt.UserRole
)

Expand Down Expand Up @@ -236,18 +232,8 @@ def update_problems_data(self):
problems_data['services_nb']
)
)
self.problems_model.setRowCount(len(problems_data['problems']))
self.problems_model.setColumnCount(len(self.problem_table.headers_list))

for row, item in enumerate(problems_data['problems']):
self.problems_model.setItem(row, 0, self.problem_table.get_tableitem(item))
self.problems_model.setItem(row, 1, self.problem_table.get_output_tableitem(item))

proxy_filter = QSortFilterProxyModel()
proxy_filter.setFilterCaseSensitivity(Qt.CaseInsensitive)
proxy_filter.setSourceModel(self.problems_model)
proxy_filter = self.problems_table.update_view(problems_data)
self.line_search.textChanged.connect(proxy_filter.setFilterRegExp)

self.problem_table.initialize(proxy_filter)
self.problems_model.setHorizontalHeaderLabels(self.problem_table.headers_list)
self.problem_table.selectionModel().selectionChanged.connect(self.update_action_buttons)
self.problems_table.selectionModel().selectionChanged.connect(self.update_action_buttons)
59 changes: 39 additions & 20 deletions alignak_app/qobjects/alignak/problems_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
# along with (AlignakApp). If not, see <http://www.gnu.org/licenses/>.

"""
Problems
++++++++
Problems manage creation of QTableView to display problems found in Alignak backend:
Problems Table
++++++++++++++
Problems Table manage creation of QTableView to display problems found in Alignak backend:
* **Hosts**: ``DOWN``, ``UNREACHABLE``
* **Services**: ``WARNING``, ``CRITICAL``, ``UNKNOWN``
Expand All @@ -32,6 +32,7 @@
from logging import getLogger

from PyQt5.Qt import QIcon, QStandardItem, Qt, QAbstractItemView, QSize, QTableView
from PyQt5.Qt import QSortFilterProxyModel, QStandardItemModel

from alignak_app.backend.datamanager import data_manager
from alignak_app.utils.config import settings
Expand All @@ -48,32 +49,19 @@ class ProblemsQTableView(QTableView):
def __init__(self, parent=None):
super(ProblemsQTableView, self).__init__(parent)
self.setWindowIcon(QIcon(settings.get_image('icon')))
# Fields
self.headers_list = [
_('Items in problem'), _('Output')
]

def initialize(self, proxy_filter):
"""
Initialize Problems QTableWidget cells, rows
:param proxy_filter: filter model with QStandardItemModel
:type proxy_filter: PyQt5.Qt.QSortFilterProxyModel
"""

self.setModel(proxy_filter)

self.setObjectName('problems')
self.verticalHeader().hide()
self.verticalHeader().setDefaultSectionSize(40)
self.setColumnWidth(0, 500)
self.setColumnWidth(1, 300)
self.setIconSize(QSize(24, 24))
self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
self.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.horizontalHeader().setStretchLastSection(True)
self.horizontalHeader().setMinimumHeight(40)
self.horizontalHeader().setDefaultAlignment(Qt.AlignCenter)
# Fields
self.headers_list = [
_('Items in problem'), _('Output')
]

def get_tableitem(self, item):
"""
Expand Down Expand Up @@ -140,3 +128,34 @@ def get_item_text(item):
text = _('%s is %s') % (hostname, item.data['ls_state'])

return text

def update_view(self, problems_data):
"""
Update QTableView model and proxy filter
:param problems_data: problems found in database
:type problems_data: dict
:return: proxy filter to connect with line edit
:rtype: QSortFilterProxyModel
"""

problems_model = QStandardItemModel()
problems_model.setRowCount(len(problems_data['problems']))
problems_model.setColumnCount(len(self.headers_list))

for row, item in enumerate(problems_data['problems']):
problems_model.setItem(row, 0, self.get_tableitem(item))
problems_model.setItem(row, 1, self.get_output_tableitem(item))

proxy_filter = QSortFilterProxyModel()
proxy_filter.setFilterCaseSensitivity(Qt.CaseInsensitive)
proxy_filter.setSourceModel(problems_model)

problems_model.setHorizontalHeaderLabels(self.headers_list)

self.setModel(proxy_filter)

self.setColumnWidth(0, 500)
self.setColumnWidth(1, 300)

return proxy_filter
21 changes: 11 additions & 10 deletions alignak_app/qobjects/events/spy.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ def add_spy_host(self, host_id):
if host_id not in self.spied_hosts:
self.spied_hosts.append(host_id)
host = data_manager.get_item('host', '_id', host_id)
item = EventItem()
item.initialize(
'SPY',
_('Host %s is spied by Alignak-app !') % host.name.capitalize()
)
item.host = host.item_id
self.insertItem(0, item)

logger.info('Spy a new host: %s', host.name)
logger.debug('... with id: %s', host_id)
if host:
item = EventItem()
item.initialize(
'SPY',
_('Host %s is spied by Alignak-app !') % host.name.capitalize()
)
item.host = host.item_id
self.insertItem(0, item)

logger.info('Spy a new host: %s', host.name)
logger.debug('... with id: %s', host_id)

def dragMoveEvent(self, event):
"""
Expand Down
4 changes: 2 additions & 2 deletions alignak_app/qobjects/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ def define_hostname(self):
if isinstance(self.sender(), QPushButton):
# From Problems QWidget
item = self.problems_widget.problems_model.item(
self.problems_widget.problem_table.selectionModel().currentIndex().row(),
self.problems_widget.problem_table.selectionModel().currentIndex().column()
self.problems_widget.problems_table.selectionModel().currentIndex().row(),
self.problems_widget.problems_table.selectionModel().currentIndex().column()
).item
if 'service' in item.item_type:
hostname = data_manager.get_item('host', item.data['host']).name
Expand Down
23 changes: 13 additions & 10 deletions test/test_problems_table_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@

import unittest2

from PyQt5.Qt import QSortFilterProxyModel, QStandardItem
from PyQt5.Qt import QStandardItem

from alignak_app.backend.datamanager import data_manager
from alignak_app.items.host import Host
from alignak_app.items.service import Service

from alignak_app.qobjects.alignak.problems_table import ProblemsQTableView


class TestProblemsQTableWidget(unittest2.TestCase):
class TestProblemsQTableView(unittest2.TestCase):
"""
This file test the ProblemsQTableWidget class.
This file test the ProblemsQTableView class.
"""

# Host data test
Expand Down Expand Up @@ -77,16 +78,18 @@ class TestProblemsQTableWidget(unittest2.TestCase):
def test_initialize_tables_problems(self):
"""Initialize ProblemsQTableWidget"""

problems = data_manager.get_problems()
under_test = ProblemsQTableView()
self.assertIsNone(under_test.model())
self.assertIsNone(under_test.selectionModel())

proxy_model_test = QSortFilterProxyModel()
under_test.initialize(proxy_model_test)
under_test.update_view(problems)

self.assertEqual(
['Items in problem', 'Output'],
under_test.headers_list
)
self.assertEqual(0, under_test.model().columnCount())
self.assertIsNotNone(under_test.model())
self.assertIsNotNone(under_test.selectionModel())

self.assertEqual(['Items in problem', 'Output'], under_test.headers_list)
self.assertEqual(2, under_test.model().columnCount())

def test_get_tableitem(self):
"""Get Problems Table Item"""
Expand Down
48 changes: 31 additions & 17 deletions test/test_problems_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@

import unittest2

from PyQt5.Qt import QApplication, QWidget, QItemSelectionModel, QStandardItem, Qt
from PyQt5.Qt import QApplication, QWidget, QItemSelectionModel, Qt

from alignak_app.backend.datamanager import data_manager
from alignak_app.items.host import Host

from alignak_app.qobjects.alignak.problems import ProblemsQWidget
Expand Down Expand Up @@ -55,6 +56,9 @@ class TestProblemsQWidget(unittest2.TestCase):
)
host_list.append(host)

data_manager.update_database('host', [])
data_manager.update_database('service', [])

@classmethod
def setUpClass(cls):
"""Create QApplication"""
Expand All @@ -69,13 +73,13 @@ def test_initialize(self):
under_test = ProblemsQWidget()

self.assertIsNotNone(under_test.layout)
self.assertTrue(under_test.problem_table)
self.assertTrue(under_test.problems_table)
self.assertTrue(under_test.problems_title)

under_test.initialize(None)

self.assertIsNotNone(under_test.layout)
self.assertTrue(under_test.problem_table)
self.assertTrue(under_test.problems_table)
self.assertTrue(under_test.problems_title)

self.assertEqual('itemtitle', under_test.problems_title.objectName())
Expand All @@ -90,30 +94,40 @@ def test_get_problems_widget_title(self):
self.assertIsInstance(under_test, QWidget)

def test_add_spy_host(self):
"""Add Psy Host from Problems QWidget"""
"""Add Spy Host from Problems QWidget"""

data_manager.update_database('host', [])
data_manager.update_database('service', [])

under_test = ProblemsQWidget()
spy_widget_test = SpyQWidget()
spy_widget_test.initialize()
under_test.initialize(spy_widget_test)

# Set a current QStandardItem
tableitem_test = QStandardItem()
tableitem_test.setData(self.host_list[0], Qt.UserRole)
under_test.problems_model.setItem(0, 0, tableitem_test)
# Update view with problems
under_test.problems_table.update_view({'problems': [self.host_list[8]]})

# Make this QStandardItem as current index
index_test = under_test.problem_table.model().index(0, 0)
under_test.problem_table.selectionModel().select(index_test, QItemSelectionModel.Select)
under_test.problem_table.setCurrentIndex(index_test)
index_test = under_test.problems_table.model().index(0, 0)
under_test.problems_table.selectionModel().setCurrentIndex(
index_test,
QItemSelectionModel.SelectCurrent
)

self.assertFalse(under_test.spy_widget.spy_list_widget.spied_hosts)

item = under_test.problems_table.model().data(
under_test.problems_table.selectionModel().currentIndex(),
Qt.UserRole
)

under_test.add_spied_host()

# Assert host has been spied
self.assertTrue(under_test.spy_widget.spy_list_widget.spied_hosts)
# "_id8" is inside "spied_hosts"
self.assertTrue(
self.host_list[0].item_id in under_test.spy_widget.spy_list_widget.spied_hosts
self.host_list[8].item_id in under_test.spy_widget.spy_list_widget.spied_hosts
)

def test_update_problems_data(self):
Expand All @@ -124,11 +138,11 @@ def test_update_problems_data(self):
spy_widget_test.initialize()
under_test.initialize(spy_widget_test)

host_tableitem_test = under_test.problems_model.item(0, 0)
output_tableitem_test = under_test.problems_model.item(0, 1)
model_test = under_test.problems_table.model()
select_model_test = under_test.problems_table.selectionModel()

under_test.update_problems_data()

# Assert Table items and QWidgets have changed
self.assertNotEqual(host_tableitem_test, under_test.problems_model.item(0, 0))
self.assertNotEqual(output_tableitem_test, under_test.problems_model.item(0, 1))
# Assert Table models have changed
self.assertNotEqual(model_test, under_test.problems_table.model())
self.assertNotEqual(select_model_test, under_test.problems_table.selectionModel())

0 comments on commit f6462ed

Please sign in to comment.