From ddb39fd0d5ed151dfd5bb459ab88ec79dd935edb Mon Sep 17 00:00:00 2001 From: dorschs57 Date: Wed, 14 Apr 2021 08:59:18 -0400 Subject: [PATCH] Issue 81 (#82): Removed file chooser * removed file chooser and update System calls * Fixed up Status and colors * fixed tests * fix broken tests * added UI linting to the CI --- .github/workflows/main.yml | 19 +++++++++ .gitignore | 1 + python/.flake8 | 3 ++ python/Pipfile | 1 + python/fapolicy_analyzer/__init__.py | 2 +- python/fapolicy_analyzer/tests/conftest.py | 7 ++++ .../test_ancillary_trust_database_admin.py | 19 +++++---- .../tests/test_confirmation_dialog.py | 2 +- .../tests/test_database_admin_page.py | 9 +++- .../tests/test_system_trust_database_admin.py | 18 ++++---- .../tests/test_trust_file_list.py | 42 +++++-------------- .../ui/ancillary_trust_database_admin.py | 15 ++++--- python/fapolicy_analyzer/ui/configs.py | 4 ++ .../ui/database_admin_page.py | 6 ++- .../ui/system_trust_database_admin.py | 18 +++----- .../fapolicy_analyzer/ui/trust_file_list.py | 39 +++++++---------- python/glade/trust_file_list.glade | 15 +------ 17 files changed, 109 insertions(+), 111 deletions(-) create mode 100644 python/.flake8 create mode 100644 python/fapolicy_analyzer/tests/conftest.py create mode 100644 python/fapolicy_analyzer/ui/configs.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4e4f9cd77..2491fdb37 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -74,6 +74,25 @@ jobs: name: fapolicy-analyzer-package path: ${{ steps.build.outputs.virt_env }}/lib/python3.8/site-packages/fapolicy_analyzer*.egg/ + ui_lint: + name: UI Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install dependencies + id: install_deps + run: | + python -m pip install --upgrade pip + pip install flake8 + - name: Lint with flake8 + run: | + cd python + python -m flake8 ./fapolicy_analyzer + ui_test: name: UI Test Suite needs: py_build diff --git a/.gitignore b/.gitignore index c21e1cd1a..dd6891e14 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ dist .vscode/ +\#*.glade\# *.glade~ .coverage .env diff --git a/python/.flake8 b/python/.flake8 new file mode 100644 index 000000000..8ee2a992e --- /dev/null +++ b/python/.flake8 @@ -0,0 +1,3 @@ +[flake8] +ignore = E402,W503 +max-line-length = 120 diff --git a/python/Pipfile b/python/Pipfile index 1eddfc160..db0778821 100644 --- a/python/Pipfile +++ b/python/Pipfile @@ -27,4 +27,5 @@ allow_prereleases = true [scripts] test = "pipenv run xvfb-run -a pytest -s --cov-report term-missing --cov=ui fapolicy_analyzer/" +lint = "pipenv run flake8 fapolicy_analyzer/" watch-test = "pipenv run xvfb-run -a pytest-watch fapolicy_analyzer/ -- -s" diff --git a/python/fapolicy_analyzer/__init__.py b/python/fapolicy_analyzer/__init__.py index cb3830e35..74ba4bd89 100644 --- a/python/fapolicy_analyzer/__init__.py +++ b/python/fapolicy_analyzer/__init__.py @@ -1 +1 @@ -from .rust import * +from .rust import * # noqa: F401,F403 diff --git a/python/fapolicy_analyzer/tests/conftest.py b/python/fapolicy_analyzer/tests/conftest.py new file mode 100644 index 000000000..77fe6595f --- /dev/null +++ b/python/fapolicy_analyzer/tests/conftest.py @@ -0,0 +1,7 @@ +import pytest +from mocks import mock_System + + +@pytest.fixture(autouse=True) +def widget(mocker): + mocker.patch("ui.database_admin_page.System", return_value=mock_System()) diff --git a/python/fapolicy_analyzer/tests/test_ancillary_trust_database_admin.py b/python/fapolicy_analyzer/tests/test_ancillary_trust_database_admin.py index ab7a7790b..7813e2d07 100644 --- a/python/fapolicy_analyzer/tests/test_ancillary_trust_database_admin.py +++ b/python/fapolicy_analyzer/tests/test_ancillary_trust_database_admin.py @@ -5,13 +5,14 @@ gi.require_version("Gtk", "3.0") from gi.repository import Gtk from unittest.mock import MagicMock -from helpers import delayed_gui_action +from mocks import mock_System from ui.ancillary_trust_database_admin import AncillaryTrustDatabaseAdmin +from ui.configs import Colors @pytest.fixture def widget(): - return AncillaryTrustDatabaseAdmin() + return AncillaryTrustDatabaseAdmin(mock_System()) def test_creates_widget(widget): @@ -20,16 +21,16 @@ def test_creates_widget(widget): def test_status_markup(widget): assert widget._AncillaryTrustDatabaseAdmin__status_markup("T") == ( - "T/U", - "light green", + "T/D/U", + Colors.LIGHT_GREEN, ) - assert widget._AncillaryTrustDatabaseAdmin__status_markup("U") == ( - "T/U", - "gold", + assert widget._AncillaryTrustDatabaseAdmin__status_markup("D") == ( + "T/D/U", + Colors.LIGHT_RED, ) assert widget._AncillaryTrustDatabaseAdmin__status_markup("foo") == ( - "T/U", - "light red", + "T/D/U", + Colors.LIGHT_YELLOW, ) diff --git a/python/fapolicy_analyzer/tests/test_confirmation_dialog.py b/python/fapolicy_analyzer/tests/test_confirmation_dialog.py index 93e038807..e645469cc 100644 --- a/python/fapolicy_analyzer/tests/test_confirmation_dialog.py +++ b/python/fapolicy_analyzer/tests/test_confirmation_dialog.py @@ -22,6 +22,6 @@ def test_trust_database_admin_selection(): dialog = ConfirmDialog("foo").get_content() for expected in [Gtk.ResponseType.YES, Gtk.ResponseType.NO]: button = dialog.get_widget_for_response(expected) - delayed_gui_action(button.clicked) + delayed_gui_action(button.clicked, delay=1) response = dialog.run() assert response == expected diff --git a/python/fapolicy_analyzer/tests/test_database_admin_page.py b/python/fapolicy_analyzer/tests/test_database_admin_page.py index 2d6f5ada1..d81e733ab 100644 --- a/python/fapolicy_analyzer/tests/test_database_admin_page.py +++ b/python/fapolicy_analyzer/tests/test_database_admin_page.py @@ -4,12 +4,17 @@ gi.require_version("Gtk", "3.0") from gi.repository import Gtk +from mocks import mock_System +from helpers import refresh_gui from ui.database_admin_page import DatabaseAdminPage @pytest.fixture -def widget(): - return DatabaseAdminPage() +def widget(mocker): + mocker.patch("ui.database_admin_page.System", return_value=mock_System()) + widget = DatabaseAdminPage() + refresh_gui() + return widget def test_creates_widget(widget): diff --git a/python/fapolicy_analyzer/tests/test_system_trust_database_admin.py b/python/fapolicy_analyzer/tests/test_system_trust_database_admin.py index 754b0a755..4ac050113 100644 --- a/python/fapolicy_analyzer/tests/test_system_trust_database_admin.py +++ b/python/fapolicy_analyzer/tests/test_system_trust_database_admin.py @@ -6,16 +6,13 @@ from gi.repository import Gtk from unittest.mock import MagicMock from mocks import mock_System -from helpers import refresh_gui from ui.system_trust_database_admin import SystemTrustDatabaseAdmin +from ui.configs import Colors @pytest.fixture -def widget(mocker): - mocker.patch("ui.system_trust_database_admin.System", return_value=mock_System()) - widget = SystemTrustDatabaseAdmin() - refresh_gui() - return widget +def widget(): + return SystemTrustDatabaseAdmin(mock_System()) def test_creates_widget(widget): @@ -24,10 +21,13 @@ def test_creates_widget(widget): def test_status_markup(widget): assert widget._SystemTrustDatabaseAdmin__status_markup("T") == ( - "T", - "light green", + "T/D", + Colors.LIGHT_GREEN, + ) + assert widget._SystemTrustDatabaseAdmin__status_markup("foo") == ( + "T/D", + Colors.LIGHT_RED, ) - assert widget._SystemTrustDatabaseAdmin__status_markup("foo") == ("T", "light red") def test_updates_trust_details(widget, mocker): diff --git a/python/fapolicy_analyzer/tests/test_trust_file_list.py b/python/fapolicy_analyzer/tests/test_trust_file_list.py index 40872917a..e023caa5f 100644 --- a/python/fapolicy_analyzer/tests/test_trust_file_list.py +++ b/python/fapolicy_analyzer/tests/test_trust_file_list.py @@ -4,17 +4,11 @@ gi.require_version("Gtk", "3.0") from gi.repository import Gtk -from helpers import refresh_gui -from mocks import mock_System from unittest.mock import MagicMock +from helpers import refresh_gui from ui.trust_file_list import TrustFileList -@pytest.fixture -def patch(mocker): - mocker.patch("ui.trust_file_list.System", return_value=mock_System()) - - @pytest.fixture def trust_func(): return MagicMock( @@ -27,8 +21,8 @@ def trust_func(): @pytest.fixture def widget(trust_func): - widget = TrustFileList(defaultLocation="/foo.db", trust_func=trust_func) - refresh_gui() + widget = TrustFileList(trust_func=trust_func) + refresh_gui(0.2) return widget @@ -36,46 +30,32 @@ def test_creates_widget(widget): assert type(widget.get_content()) is Gtk.Box -def test_sets_defaultLocation(patch): - widget = TrustFileList( - locationAction=Gtk.FileChooserAction.SELECT_FOLDER, defaultLocation="/tmp/foo" - ) - assert ( - widget.databaseFileChooser.get_action() == Gtk.FileChooserAction.SELECT_FOLDER - ) - assert widget.databaseFileChooser.get_filename() == "/tmp/foo" - - -def test_uses_custom_trust_func(patch, trust_func): - widget = TrustFileList(trust_func=trust_func) - widget.databaseFileChooser.set_filename("/foo.db") - refresh_gui() - trust_func.assert_called_with("/foo.db") +def test_uses_custom_trust_func(widget, trust_func): + trust_func.assert_called() -def test_uses_custom_markup_func(patch): +def test_uses_custom_markup_func(trust_func): markup_func = MagicMock(return_value="t") - widget = TrustFileList(markup_func=markup_func) - widget.databaseFileChooser.set_filename("/foo") + TrustFileList(trust_func=trust_func, markup_func=markup_func) refresh_gui(0.2) - markup_func.assert_called_with("trusted") + markup_func.assert_called_with("t") -def test_sorting_path(patch, widget): +def test_sorting_path(widget): trustView = widget.trustView assert ["/tmp/foo", "/tmp/baz"] == [x[1] for x in trustView.get_model()] trustView.get_column(1).clicked() assert ["/tmp/baz", "/tmp/foo"] == [x[1] for x in trustView.get_model()] -def test_sorting_status(patch, widget): +def test_sorting_status(widget): trustView = widget.trustView assert ["u", "t"] == [x[0] for x in trustView.get_model()] trustView.get_column(0).clicked() assert ["t", "u"] == [x[0] for x in trustView.get_model()] -def test_filtering(patch, widget): +def test_filtering(widget): trustView = widget.trustView trustViewFilter = widget.builder.get_object("trustViewSearch") trustViewFilter.set_text("foo") diff --git a/python/fapolicy_analyzer/ui/ancillary_trust_database_admin.py b/python/fapolicy_analyzer/ui/ancillary_trust_database_admin.py index fefde4657..a1631956a 100644 --- a/python/fapolicy_analyzer/ui/ancillary_trust_database_admin.py +++ b/python/fapolicy_analyzer/ui/ancillary_trust_database_admin.py @@ -8,14 +8,17 @@ from .trust_file_details import TrustFileDetails from .confirmation_dialog import ConfirmDialog from .deploy_confirm_dialog import DeployConfirmDialog +from .configs import Colors class AncillaryTrustDatabaseAdmin(UIWidget): - def __init__(self): + def __init__(self, system): super().__init__() self.content = self.builder.get_object("ancillaryTrustDatabaseAdmin") - self.trustFileList = TrustFileList(markup_func=self.__status_markup) + self.trustFileList = TrustFileList( + trust_func=system.ancillary_trust, markup_func=self.__status_markup + ) self.trustFileList.on_file_selection_change += self.on_file_selection_change self.builder.get_object("leftBox").pack_start( self.trustFileList.get_content(), True, True, 0 @@ -29,11 +32,11 @@ def __init__(self): def __status_markup(self, status): s = status.lower() return ( - ("T/U", "light green") + ("T/D/U", Colors.LIGHT_GREEN) if s == "t" - else ("T/U", "gold") - if s == "u" - else ("T/U", "light red") + else ("T/D/U", Colors.LIGHT_RED) + if s == "d" + else ("T/D/U", Colors.LIGHT_YELLOW) ) def get_content(self): diff --git a/python/fapolicy_analyzer/ui/configs.py b/python/fapolicy_analyzer/ui/configs.py new file mode 100644 index 000000000..4e3fd1c3c --- /dev/null +++ b/python/fapolicy_analyzer/ui/configs.py @@ -0,0 +1,4 @@ +class Colors: + LIGHT_RED = "#FF3333" + LIGHT_YELLOW = "#FFFF33" + LIGHT_GREEN = "light green" diff --git a/python/fapolicy_analyzer/ui/database_admin_page.py b/python/fapolicy_analyzer/ui/database_admin_page.py index d4d242a8d..8f02118c1 100644 --- a/python/fapolicy_analyzer/ui/database_admin_page.py +++ b/python/fapolicy_analyzer/ui/database_admin_page.py @@ -2,19 +2,21 @@ gi.require_version("Gtk", "3.0") from gi.repository import Gtk +from fapolicy_analyzer import System from .ancillary_trust_database_admin import AncillaryTrustDatabaseAdmin from .system_trust_database_admin import SystemTrustDatabaseAdmin class DatabaseAdminPage: def __init__(self): + system = System() self.notebook = Gtk.Notebook() self.notebook.append_page( - SystemTrustDatabaseAdmin().get_content(), + SystemTrustDatabaseAdmin(system).get_content(), Gtk.Label(label="System Trust Database"), ) self.notebook.append_page( - AncillaryTrustDatabaseAdmin().get_content(), + AncillaryTrustDatabaseAdmin(system).get_content(), Gtk.Label(label="Ancillary Trust Database"), ) self.notebook.show_all() diff --git a/python/fapolicy_analyzer/ui/system_trust_database_admin.py b/python/fapolicy_analyzer/ui/system_trust_database_admin.py index 59d6677af..bfbf585f5 100644 --- a/python/fapolicy_analyzer/ui/system_trust_database_admin.py +++ b/python/fapolicy_analyzer/ui/system_trust_database_admin.py @@ -1,24 +1,16 @@ -import gi - -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk -from fapolicy_analyzer import System from fapolicy_analyzer.util import fs from .trust_file_list import TrustFileList from .trust_file_details import TrustFileDetails from .ui_widget import UIWidget - -systemDb = "/var/lib/rpm" +from .configs import Colors class SystemTrustDatabaseAdmin(UIWidget): - def __init__(self): + def __init__(self, system): super().__init__() self.trustFileList = TrustFileList( - locationAction=Gtk.FileChooserAction.SELECT_FOLDER, - defaultLocation=systemDb, - trust_func=lambda x: System(None, x, None).system_trust(), + trust_func=system.system_trust, markup_func=self.__status_markup, ) self.trustFileList.on_file_selection_change += self.on_file_selection_change @@ -33,9 +25,9 @@ def __init__(self): def __status_markup(self, status): return ( - ("T", "light green") + ("T/D", Colors.LIGHT_GREEN) if status.lower() == "t" - else ("T", "light red") + else ("T/D", Colors.LIGHT_RED) ) def get_content(self): diff --git a/python/fapolicy_analyzer/ui/trust_file_list.py b/python/fapolicy_analyzer/ui/trust_file_list.py index 524c7d70b..4b68ac5b7 100644 --- a/python/fapolicy_analyzer/ui/trust_file_list.py +++ b/python/fapolicy_analyzer/ui/trust_file_list.py @@ -5,31 +5,18 @@ from threading import Thread from time import sleep from events import Events -from fapolicy_analyzer import System from .ui_widget import UIWidget class TrustFileList(UIWidget, Events): __events__ = "on_file_selection_change" - def __init__( - self, - locationAction=Gtk.FileChooserAction.OPEN, - defaultLocation=None, - trust_func=lambda x: System(None, None, x).ancillary_trust(), - markup_func=None, - ): - + def __init__(self, trust_func, markup_func=None): UIWidget.__init__(self) Events.__init__(self) self.trust_func = trust_func self.markup_func = markup_func - self.databaseFileChooser = self.builder.get_object("databaseFileChooser") - self.databaseFileChooser.set_action(locationAction) - if defaultLocation: - self.databaseFileChooser.set_filename(defaultLocation) - self.trustView = self.builder.get_object("trustView") trustCell = Gtk.CellRendererText() trustCell.set_property("background", "light gray") @@ -49,9 +36,14 @@ def __init__( ) ) - def __get_trust(self, database): + self.__set_loading(True) + thread = Thread(target=self.__get_trust) + thread.daemon = True + thread.start() + + def __get_trust(self): sleep(0.1) - trust = self.trust_func(database) + trust = self.trust_func() trustStore = Gtk.ListStore(str, str, object, str) for i, e in enumerate(trust): @@ -97,10 +89,11 @@ def on_trust_view_selection_changed(self, selection): def on_search_changed(self, search): self.trustViewFilter.refilter() - def on_databaseFileChooser_selection_changed(self, *args): - database = self.databaseFileChooser.get_filename() - if database and self.trust_func: - self.__set_loading(True) - thread = Thread(target=self.__get_trust, args=(database,)) - thread.daemon = True - thread.start() + def on_trustFileList_realize(self, *args): + return + # print("***** on realized") + # if self.trust_func: + # self.__set_loading(True) + # thread = Thread(target=self.__get_trust) + # thread.daemon = True + # thread.start() diff --git a/python/glade/trust_file_list.glade b/python/glade/trust_file_list.glade index 8ae512398..f226ff73d 100644 --- a/python/glade/trust_file_list.glade +++ b/python/glade/trust_file_list.glade @@ -8,20 +8,7 @@ 5 5 vertical - - - True - False - select-folder - - - - - False - True - 0 - - + True