Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase test coverage of the Nginx extension #1467

Merged
merged 1 commit into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading