...
 
Commits (4)
......@@ -7,4 +7,5 @@ pycodestyle>=2.5.0
pylint>=2.3.1
pytest>=4.6.2
pytest-cov>=2.7.1
pytest-mock>=1.11.0
requests_mock>=1.6.0
......@@ -11,20 +11,20 @@ from gi.repository import Gdk, Gio, GLib, Gtk
from briar.api.api import Api
from briar.gtk.define import APPLICATION_ID, APPLICATION_NAME
from briar.gtk.define import BRIAR_HEADLESS_JAR
from briar.gtk.define import APPLICATION_STYLING, BRIAR_HEADLESS_JAR
from briar.gtk.window import Window
class Application(Gtk.Application):
def __init__(self):
Application._set_application_name()
Application._set_application_name(APPLICATION_NAME)
super().__init__(application_id=APPLICATION_ID)
# pylint: disable=arguments-differ
def do_startup(self):
Gtk.Application.do_startup(self)
Application._setup_styling()
Application._setup_styling(APPLICATION_STYLING)
self._setup_api()
# pylint: disable=arguments-differ
......@@ -38,14 +38,13 @@ class Application(Gtk.Application):
Gio.Application.quit(self)
@staticmethod
def _set_application_name():
GLib.set_application_name(APPLICATION_NAME)
GLib.set_prgname(APPLICATION_NAME)
def _set_application_name(name):
GLib.set_application_name(name)
GLib.set_prgname(name)
@staticmethod
def _setup_styling():
css_provider_file = Gio.File.new_for_uri(
"resource:///app/briar/gtk/ui/application.css")
def _setup_styling(styling):
css_provider_file = Gio.File.new_for_uri(styling)
css_provider = Gtk.CssProvider()
css_provider.load_from_file(css_provider_file)
......
......@@ -6,20 +6,22 @@ from gi.repository import GLib, Gtk
from briar.api.models.private_chat import PrivateChat
from briar.gtk.container import Container
from briar.gtk.define import App
from briar.gtk.define import APP
class ChatContainer(Container):
CONTAINER_UI = "/app/briar/gtk/ui/chat.ui"
def __init__(self, contact_id):
super().__init__()
self._api = App().api
self._api = APP().api
self._contact_id = contact_id
self._setup_view()
self._load_content()
def _setup_view(self):
self.builder.add_from_resource("/app/briar/gtk/ui/chat.ui")
self.builder.add_from_resource(self.CONTAINER_UI)
self.add(self.builder.get_object("chat"))
self.builder.connect_signals(self)
chat_entry = self.builder.get_object("chat_entry")
......
......@@ -6,19 +6,21 @@ from gi.repository import GLib, Gtk
from briar.api.models.contacts import Contacts
from briar.gtk.container import Container
from briar.gtk.define import App
from briar.gtk.define import APP
class MainContainer(Container):
CONTAINER_UI = "/app/briar/gtk/ui/main.ui"
def __init__(self):
super().__init__()
self._api = App().api
self._api = APP().api
self._setup_view()
self._load_content()
def _setup_view(self):
self.builder.add_from_resource("/app/briar/gtk/ui/main.ui")
self.builder.add_from_resource(self.CONTAINER_UI)
self.add(self.builder.get_object("contacts_list"))
self.builder.connect_signals(self)
......@@ -36,4 +38,4 @@ class MainContainer(Container):
# pylint: disable=unused-argument
@staticmethod
def _contact_clicked(widget, contact_id):
GLib.idle_add(App().window.open_private_chat, contact_id)
GLib.idle_add(APP().window.open_private_chat, contact_id)
......@@ -5,14 +5,17 @@
from gi.repository import GLib
from briar.gtk.container import Container
from briar.gtk.define import App
from briar.gtk.define import APP
class StartupContainer(Container):
SETUP_UI = "/app/briar/gtk/ui/main.ui"
LOGIN_UI = "/app/briar/gtk/ui/login.ui"
def __init__(self):
super().__init__()
self._api = App().api
self._api = APP().api
self._setup_view()
# pylint: disable=unused-argument
......@@ -39,17 +42,17 @@ class StartupContainer(Container):
def _setup_view(self):
self.set_hexpand(True)
self.set_vexpand(True)
if not App().api.has_account():
self.builder.add_from_resource("/app/briar/gtk/ui/setup.ui")
if not APP().api.has_account():
self.builder.add_from_resource(self.SETUP_UI)
self.add(self.builder.get_object("setup"))
else:
self.builder.add_from_resource("/app/briar/gtk/ui/login.ui")
self.builder.add_from_resource(self.LOGIN_UI)
self.add(self.builder.get_object("login"))
self.builder.connect_signals(self)
@staticmethod
def _startup_completed(succeeded):
if succeeded:
GLib.idle_add(App().window.on_startup_completed)
GLib.idle_add(APP().window.on_startup_completed)
return
print("Startup failed")
......@@ -10,6 +10,7 @@ from gi.repository import Gio
APPLICATION_ID = "app.briar.gtk"
APPLICATION_NAME = "Briar"
APPLICATION_STYLING = "resource:///app/briar/gtk/ui/application.css"
BRIAR_HEADLESS_JAR = "/app/briar/briar-headless.jar"
App = Gio.Application.get_default # pylint: disable=invalid-name
APP = Gio.Application.get_default
......@@ -8,16 +8,17 @@
from gi.repository import Gtk
from briar.gtk.define import APPLICATION_NAME
class Toolbar(Gtk.HeaderBar):
TOOLBAR_UI = "/app/briar/gtk/ui/toolbar_start.ui"
def __init__(self):
super().__init__()
self._builder = Gtk.Builder()
self._builder.add_from_resource("/app/briar/gtk/ui/toolbar_start.ui")
toolbar_start = self._builder.get_object("toolbar_start")
self.set_title("Briar")
self.pack_start(toolbar_start)
self._setup_builder()
self._setup_toolbar()
def show_back_button(self, show, callback=None):
back_button = self._builder.get_object("back_button")
......@@ -28,3 +29,13 @@ class Toolbar(Gtk.HeaderBar):
raise Exception("Callback needed when showing back button")
back_button.show()
back_button.connect("clicked", callback)
def _setup_builder(self):
self._builder = Gtk.Builder()
def _setup_toolbar(self):
self.set_title(APPLICATION_NAME)
self._builder.add_from_resource(self.TOOLBAR_UI)
toolbar_start = self._builder.get_object("toolbar_start")
self.pack_start(toolbar_start)
......@@ -7,7 +7,7 @@ from gi.repository import Gtk
from briar.gtk.containers.chat import ChatContainer
from briar.gtk.containers.main import MainContainer
from briar.gtk.containers.startup import StartupContainer
from briar.gtk.define import App, APPLICATION_ID, APPLICATION_NAME
from briar.gtk.define import APP, APPLICATION_ID, APPLICATION_NAME
from briar.gtk.toolbar import Toolbar
......@@ -28,7 +28,7 @@ class Window(Gtk.ApplicationWindow):
return self._toolbar
def _initialize_gtk_application_window(self):
Gtk.ApplicationWindow.__init__(self, application=App(),
Gtk.ApplicationWindow.__init__(self, application=APP(),
title=APPLICATION_NAME,
icon_name=APPLICATION_ID)
......
# Copyright (c) 2019 Nico Alt
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
from unittest.mock import Mock
from briar.api.api import Api
from briar.gtk.application import Application
from briar.gtk.define import APPLICATION_NAME, APPLICATION_STYLING
from briar.gtk.define import BRIAR_HEADLESS_JAR
from briar.gtk.window import Window
def test_do_startup(mocker):
do_startup_mock = mocker.patch("gi.repository.Gtk.Application.do_startup")
_setup_styling_mock = mocker.patch(
"briar.gtk.application.Application._setup_styling")
_setup_api_mock = mocker.patch(
"briar.gtk.application.Application._setup_api")
Application().do_startup()
do_startup_mock.assert_called_once()
_setup_styling_mock.assert_called_once_with(APPLICATION_STYLING)
_setup_api_mock.assert_called_once()
def test_do_activate(mocker):
_setup_window_mock = mocker.patch(
"briar.gtk.application.Application._setup_window")
Application().do_activate()
_setup_window_mock.assert_called_once()
def test_quit(mocker):
api_mock = mocker.patch("briar.api.api.Api")
api_stop_mock = mocker.patch("briar.api.api.Api.stop")
window_mock = mocker.patch("briar.gtk.window.Window")
window_hide_mock = mocker.patch("briar.gtk.window.Window.hide")
quit_mock = mocker.patch("gi.repository.Gio.Application.quit")
application = Application()
application.api = api_mock
application.window = window_mock
application.quit()
api_stop_mock.assert_called_once()
window_hide_mock.assert_called_once()
quit_mock.assert_called_once()
def test_set_application_name(mocker):
set_application_name_mock = mocker.patch(
"gi.repository.GLib.set_application_name")
set_prgname_mock = mocker.patch("gi.repository.GLib.set_prgname")
name_mock = "Mock"
Application._set_application_name(name_mock)
set_application_name_mock.assert_called_once_with(name_mock)
set_prgname_mock.assert_called_once_with(name_mock)
def test_set_application_name_implicit(mocker):
set_application_name_mock = mocker.patch(
"gi.repository.GLib.set_application_name")
set_prgname_mock = mocker.patch("gi.repository.GLib.set_prgname")
Application()
set_application_name_mock.assert_called_once_with(APPLICATION_NAME)
set_prgname_mock.assert_called_once_with(APPLICATION_NAME)
def test_setup_styling(mocker):
new_for_uri_mock = mocker.patch("gi.repository.Gio.File.new_for_uri")
load_from_file_mock = mocker.patch(
"gi.repository.Gtk.CssProvider.load_from_file")
get_default_mock = mocker.patch("gi.repository.Gdk.Screen.get_default")
add_provider_for_screen_mock = mocker.patch(
"gi.repository.Gtk.StyleContext.add_provider_for_screen")
Application._setup_styling(APPLICATION_STYLING)
new_for_uri_mock.assert_called_with(APPLICATION_STYLING)
load_from_file_mock.assert_called_once()
get_default_mock.assert_called_once()
add_provider_for_screen_mock.assert_called_once()
def test_setup_api(mocker):
application = Application()
assert not hasattr(application, "api")
application._setup_api()
assert isinstance(application.api, Api)
assert application.api._command == ["java", "-jar", BRIAR_HEADLESS_JAR]
def test_setup_window(mocker):
mocker.patch("briar.gtk.window.Window.__init__").return_value = None
window_show_mock = mocker.patch("briar.gtk.window.Window.show")
window_present_mock = mocker.patch("briar.gtk.window.Window.present")
Application()._setup_window()
window_show_mock.assert_called_once()
window_present_mock.assert_called_once()
def test_setup_window_has_attribute(mocker):
mocker.patch("briar.gtk.window.Window.__init__").return_value = None
window_mock = Mock()
application = Application()
application.window = window_mock
application._setup_window()
window_mock.show.assert_not_called()
window_mock.present.assert_called_once()
def test_setup_window_has_none_attribute(mocker):
mocker.patch("briar.gtk.window.Window.__init__").return_value = None
window_show_mock = mocker.patch("briar.gtk.window.Window.show")
window_present_mock = mocker.patch("briar.gtk.window.Window.present")
application = Application()
application.window = None
application._setup_window()
window_show_mock.assert_called_once()
window_present_mock.assert_called_once()
# Copyright (c) 2019 Nico Alt
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
from gi.repository import Gio
from briar.gtk.define import App
def test_app():
assert App == Gio.Application.get_default
# Copyright (c) 2019 Nico Alt
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
import pytest
from unittest.mock import Mock
from briar.gtk.toolbar import Toolbar
def test_show_back_button(mocker):
get_object_mock = mocker.patch("gi.repository.Gtk.Builder.get_object")
back_button_mock = get_object_mock.return_value
callback = Mock()
mocker.patch("briar.gtk.toolbar.Toolbar._setup_toolbar")
Toolbar().show_back_button(True, callback)
get_object_mock.assert_called_once_with("back_button")
back_button_mock.hide.assert_not_called()
back_button_mock.show.assert_called_once()
back_button_mock.connect.assert_called_once()
def test_show_back_button_without_callback(mocker):
get_object_mock = mocker.patch("gi.repository.Gtk.Builder.get_object")
back_button_mock = get_object_mock.return_value
mocker.patch("briar.gtk.toolbar.Toolbar._setup_toolbar")
with pytest.raises(Exception,
match="Callback needed when showing back button"):
Toolbar().show_back_button(True)
get_object_mock.assert_called_once_with("back_button")
back_button_mock.hide.assert_not_called()
back_button_mock.show.assert_not_called()
back_button_mock.connect.assert_not_called()
def test_hide_back_button(mocker):
get_object_mock = mocker.patch("gi.repository.Gtk.Builder.get_object")
back_button_mock = get_object_mock.return_value
mocker.patch("briar.gtk.toolbar.Toolbar._setup_toolbar")
Toolbar().show_back_button(False)
get_object_mock.assert_called_once_with("back_button")
back_button_mock.hide.assert_called_once()
back_button_mock.show.assert_not_called()
back_button_mock.connect.assert_not_called()