Skip to content

Commit

Permalink
Increase test coverage of the Nginx extension (#1467)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartfeenstra authored May 7, 2024
1 parent 543f694 commit 906ab78
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 181 deletions.
178 changes: 3 additions & 175 deletions betty/extension/nginx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,110 +2,20 @@

from collections.abc import Sequence
from pathlib import Path
from typing import Any, Self

from PyQt6.QtWidgets import (
QFormLayout,
QButtonGroup,
QRadioButton,
QWidget,
QHBoxLayout,
QLineEdit,
QFileDialog,
QPushButton,
)

from betty.app import App
from betty.app.extension import ConfigurableExtension
from betty.config import Configuration
from betty.extension.nginx.artifact import (
generate_configuration_file,
generate_dockerfile_file,
)
from betty.extension.nginx.config import NginxConfiguration
from betty.extension.nginx.gui import _NginxGuiWidget
from betty.generate import Generator, GenerationContext
from betty.gui import GuiBuilder
from betty.gui.error import ExceptionCatcher
from betty.locale import Str
from betty.serde.dump import Dump, VoidableDump, minimize, Void, VoidableDictDump
from betty.serde.load import Asserter, Fields, OptionalField, Assertions
from betty.serve import ServerProvider, Server


class NginxConfiguration(Configuration):
def __init__(
self,
*,
www_directory_path: str | None = None,
https: bool | None = None,
):
super().__init__()
self._https = https
self.www_directory_path = www_directory_path

@property
def https(self) -> bool | None:
return self._https

@https.setter
def https(self, https: bool | None) -> None:
self._https = https
self._dispatch_change()

@property
def www_directory_path(self) -> str | None:
return self._www_directory_path

@www_directory_path.setter
def www_directory_path(self, www_directory_path: str | None) -> None:
self._www_directory_path = www_directory_path
self._dispatch_change()

def update(self, other: Self) -> None:
self._https = other._https
self._www_directory_path = other._www_directory_path
self._dispatch_change()

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
asserter = Asserter()
asserter.assert_record(
Fields(
OptionalField(
"https",
Assertions(
asserter.assert_or(
asserter.assert_bool(), asserter.assert_none()
)
)
| asserter.assert_setattr(configuration, "https"),
),
OptionalField(
"www_directory_path",
Assertions(asserter.assert_str())
| asserter.assert_setattr(configuration, "www_directory_path"),
),
)
)(dump)
return configuration

def dump(self) -> VoidableDump:
dump: VoidableDictDump[VoidableDump] = {
"https": self.https,
"www_directory_path": (
Void
if self.www_directory_path is None
else str(self.www_directory_path)
),
}
return minimize(dump, True)


class Nginx(
ConfigurableExtension[NginxConfiguration], Generator, ServerProvider, GuiBuilder
):
Expand Down Expand Up @@ -151,87 +61,5 @@ def www_directory_path(self) -> str:
self._app.project.configuration.www_directory_path
)

def gui_build(self) -> QWidget:
def gui_build(self) -> _NginxGuiWidget:
return _NginxGuiWidget(self._app, self._configuration)


class _NginxGuiWidget(QWidget):
def __init__(
self, app: App, configuration: NginxConfiguration, *args: Any, **kwargs: Any
):
super().__init__(*args, **kwargs)
self._app = app
self._configuration = configuration
layout = QFormLayout()

self.setLayout(layout)

https_button_group = QButtonGroup()

def _update_configuration_https_base_url(checked: bool) -> None:
if checked:
self._configuration.https = None

self._nginx_https_base_url = QRadioButton(
"Use HTTPS and HTTP/2 if the site's URL starts with https://"
)
self._nginx_https_base_url.setChecked(self._configuration.https is None)
self._nginx_https_base_url.toggled.connect(_update_configuration_https_base_url)
layout.addRow(self._nginx_https_base_url)
https_button_group.addButton(self._nginx_https_base_url)

def _update_configuration_https_https(checked: bool) -> None:
if checked:
self._configuration.https = True

self._nginx_https_https = QRadioButton("Use HTTPS and HTTP/2")
self._nginx_https_https.setChecked(self._configuration.https is True)
self._nginx_https_https.toggled.connect(_update_configuration_https_https)
layout.addRow(self._nginx_https_https)
https_button_group.addButton(self._nginx_https_https)

def _update_configuration_https_http(checked: bool) -> None:
if checked:
self._configuration.https = False

self._nginx_https_http = QRadioButton("Use HTTP")
self._nginx_https_http.setChecked(self._configuration.https is False)
self._nginx_https_http.toggled.connect(_update_configuration_https_http)
layout.addRow(self._nginx_https_http)
https_button_group.addButton(self._nginx_https_http)

def _update_configuration_www_directory_path(www_directory_path: str) -> None:
self._configuration.www_directory_path = (
None
if www_directory_path == ""
or www_directory_path
== str(self._app.project.configuration.www_directory_path)
else www_directory_path
)

self._nginx_www_directory_path = QLineEdit()
self._nginx_www_directory_path.setText(
str(self._configuration.www_directory_path)
if self._configuration.www_directory_path is not None
else str(self._app.project.configuration.www_directory_path)
)
self._nginx_www_directory_path.textChanged.connect(
_update_configuration_www_directory_path
)
www_directory_path_layout = QHBoxLayout()
www_directory_path_layout.addWidget(self._nginx_www_directory_path)

def find_www_directory_path() -> None:
with ExceptionCatcher(self):
found_www_directory_path = QFileDialog.getExistingDirectory(
self,
"Serve your site from...",
directory=self._nginx_www_directory_path.text(),
)
if "" != found_www_directory_path:
self._nginx_www_directory_path.setText(found_www_directory_path)

self._nginx_www_directory_path_find = QPushButton("...")
self._nginx_www_directory_path_find.released.connect(find_www_directory_path)
www_directory_path_layout.addWidget(self._nginx_www_directory_path_find)
layout.addRow("WWW directory", www_directory_path_layout)
82 changes: 82 additions & 0 deletions betty/extension/nginx/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""Integrate Betty with `nginx <https://nginx.org/>`_."""

from typing import Self

from betty.config import Configuration
from betty.serde.dump import Dump, VoidableDump, minimize, Void, VoidableDictDump
from betty.serde.load import Asserter, Fields, OptionalField, Assertions


class NginxConfiguration(Configuration):
def __init__(
self,
*,
www_directory_path: str | None = None,
https: bool | None = None,
):
super().__init__()
self._https = https
self.www_directory_path = www_directory_path

@property
def https(self) -> bool | None:
return self._https

@https.setter
def https(self, https: bool | None) -> None:
self._https = https
self._dispatch_change()

@property
def www_directory_path(self) -> str | None:
return self._www_directory_path

@www_directory_path.setter
def www_directory_path(self, www_directory_path: str | None) -> None:
self._www_directory_path = www_directory_path
self._dispatch_change()

def update(self, other: Self) -> None:
self._https = other._https
self._www_directory_path = other._www_directory_path
self._dispatch_change()

@classmethod
def load(
cls,
dump: Dump,
configuration: Self | None = None,
) -> Self:
if configuration is None:
configuration = cls()
asserter = Asserter()
asserter.assert_record(
Fields(
OptionalField(
"https",
Assertions(
asserter.assert_or(
asserter.assert_bool(), asserter.assert_none()
)
)
| asserter.assert_setattr(configuration, "https"),
),
OptionalField(
"www_directory_path",
Assertions(asserter.assert_str())
| asserter.assert_setattr(configuration, "www_directory_path"),
),
)
)(dump)
return configuration

def dump(self) -> VoidableDump:
dump: VoidableDictDump[VoidableDump] = {
"https": self.https,
"www_directory_path": (
Void
if self.www_directory_path is None
else str(self.www_directory_path)
),
}
return minimize(dump, True)
100 changes: 100 additions & 0 deletions betty/extension/nginx/gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""Integrate Betty with `nginx <https://nginx.org/>`_."""

from typing import Any

from PyQt6.QtWidgets import (
QFormLayout,
QButtonGroup,
QRadioButton,
QWidget,
QHBoxLayout,
QLineEdit,
QFileDialog,
QPushButton,
)

from betty.app import App
from betty.extension.nginx.config import NginxConfiguration
from betty.gui.error import ExceptionCatcher


class _NginxGuiWidget(QWidget):
def __init__(
self, app: App, configuration: NginxConfiguration, *args: Any, **kwargs: Any
):
super().__init__(*args, **kwargs)
self._app = app
self._configuration = configuration
layout = QFormLayout()

self.setLayout(layout)

https_button_group = QButtonGroup()

def _update_configuration_https_base_url(checked: bool) -> None:
if checked:
self._configuration.https = None

self._nginx_https_base_url = QRadioButton(
"Use HTTPS and HTTP/2 if the site's URL starts with https://"
)
self._nginx_https_base_url.setChecked(self._configuration.https is None)
self._nginx_https_base_url.toggled.connect(_update_configuration_https_base_url)
layout.addRow(self._nginx_https_base_url)
https_button_group.addButton(self._nginx_https_base_url)

def _update_configuration_https_https(checked: bool) -> None:
if checked:
self._configuration.https = True

self._nginx_https_https = QRadioButton("Use HTTPS and HTTP/2")
self._nginx_https_https.setChecked(self._configuration.https is True)
self._nginx_https_https.toggled.connect(_update_configuration_https_https)
layout.addRow(self._nginx_https_https)
https_button_group.addButton(self._nginx_https_https)

def _update_configuration_https_http(checked: bool) -> None:
if checked:
self._configuration.https = False

self._nginx_https_http = QRadioButton("Use HTTP")
self._nginx_https_http.setChecked(self._configuration.https is False)
self._nginx_https_http.toggled.connect(_update_configuration_https_http)
layout.addRow(self._nginx_https_http)
https_button_group.addButton(self._nginx_https_http)

def _update_configuration_www_directory_path(www_directory_path: str) -> None:
self._configuration.www_directory_path = (
None
if www_directory_path == ""
or www_directory_path
== str(self._app.project.configuration.www_directory_path)
else www_directory_path
)

self._nginx_www_directory_path = QLineEdit()
self._nginx_www_directory_path.setText(
str(self._configuration.www_directory_path)
if self._configuration.www_directory_path is not None
else str(self._app.project.configuration.www_directory_path)
)
self._nginx_www_directory_path.textChanged.connect(
_update_configuration_www_directory_path
)
www_directory_path_layout = QHBoxLayout()
www_directory_path_layout.addWidget(self._nginx_www_directory_path)

def find_www_directory_path() -> None:
with ExceptionCatcher(self):
found_www_directory_path = QFileDialog.getExistingDirectory(
self,
"Serve your site from...",
directory=self._nginx_www_directory_path.text(),
)
if "" != found_www_directory_path:
self._nginx_www_directory_path.setText(found_www_directory_path)

self._nginx_www_directory_path_find = QPushButton("...")
self._nginx_www_directory_path_find.released.connect(find_www_directory_path)
www_directory_path_layout.addWidget(self._nginx_www_directory_path_find)
layout.addRow("WWW directory", www_directory_path_layout)
Loading

0 comments on commit 906ab78

Please sign in to comment.