-
Notifications
You must be signed in to change notification settings - Fork 1
fix(ci): add missing Dependency & Standards Validation gate job #154
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
Open
williaby
wants to merge
3
commits into
main
Choose a base branch
from
claude/fix-required-check-contexts-0
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| """Unit tests for the LedgerBase application factory.""" | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
||
| import ledgerbase | ||
|
|
||
| HTTP_OK = 200 | ||
|
|
||
|
|
||
| def test_create_app_returns_configured_app(monkeypatch: pytest.MonkeyPatch) -> None: | ||
| """create_app returns a Flask app wired to the configured database URI.""" | ||
| monkeypatch.setenv("DATABASE_URL", "sqlite:///unit-test.db") | ||
| app = ledgerbase.create_app() | ||
| assert app.config["SQLALCHEMY_DATABASE_URI"] == "sqlite:///unit-test.db" | ||
| assert app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] is False | ||
|
|
||
|
|
||
| def test_create_app_defaults_the_database_uri( | ||
| monkeypatch: pytest.MonkeyPatch, | ||
| ) -> None: | ||
| """create_app falls back to a local SQLite database when DATABASE_URL is unset.""" | ||
| monkeypatch.delenv("DATABASE_URL", raising=False) | ||
| app = ledgerbase.create_app() | ||
| assert app.config["SQLALCHEMY_DATABASE_URI"] == "sqlite:///default.db" | ||
|
|
||
|
|
||
| def test_create_app_rejects_empty_database_url( | ||
| monkeypatch: pytest.MonkeyPatch, | ||
| ) -> None: | ||
| """An empty DATABASE_URL is rejected rather than silently accepted.""" | ||
| monkeypatch.setenv("DATABASE_URL", "") | ||
| with pytest.raises(ValueError, match="DATABASE_URL"): | ||
| ledgerbase.create_app() | ||
|
|
||
|
|
||
| def test_create_app_uses_template_dir_when_present( | ||
| monkeypatch: pytest.MonkeyPatch, | ||
| ) -> None: | ||
| """The sibling templates directory is used as the Jinja search path.""" | ||
| monkeypatch.setattr(Path, "is_dir", lambda _self: True) | ||
| app = ledgerbase.create_app() | ||
| assert app.template_folder is not None | ||
| assert app.template_folder.endswith("templates") | ||
|
|
||
|
|
||
| def test_create_app_registers_core_routes() -> None: | ||
| """create_app wires the index, login, and debug-sentry routes.""" | ||
| app = ledgerbase.create_app() | ||
| rules = {rule.rule for rule in app.url_map.iter_rules()} | ||
| assert {"/", "/login", "/debug-sentry"} <= rules | ||
|
|
||
|
|
||
| def test_index_route_responds() -> None: | ||
| """The index route reports that the API is running.""" | ||
| app = ledgerbase.create_app() | ||
| app.config.update(TESTING=True) | ||
| response = app.test_client().get("/") | ||
| assert response.status_code == HTTP_OK | ||
| assert b"LedgerBase API is running." in response.data | ||
|
|
||
|
|
||
| def test_debug_sentry_route_raises() -> None: | ||
| """The debug-sentry route deliberately raises a division error.""" | ||
| app = ledgerbase.create_app() | ||
| app.config.update(TESTING=True) | ||
| with pytest.raises(ZeroDivisionError): | ||
| app.test_client().get("/debug-sentry") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,67 @@ | ||
| """Unit tests for the configuration module.""" | ||
|
|
||
| import pytest | ||
|
|
||
| from ledgerbase import config | ||
|
|
||
|
|
||
| def test_config_default() -> None: | ||
| """Test that the `config` module has the expected `__name__` attribute. | ||
| def test_config_module_loads() -> None: | ||
| """The config module exposes the expected public surface.""" | ||
| assert hasattr(config, "Config") | ||
| assert hasattr(config, "DevelopmentConfig") | ||
| assert hasattr(config, "ProductionConfig") | ||
|
|
||
|
|
||
| def test_base_config_defaults() -> None: | ||
| """The base Config disables SQLAlchemy modification tracking.""" | ||
| assert config.Config.SQLALCHEMY_TRACK_MODIFICATIONS is False | ||
| assert config.Config.SECRET_KEY | ||
|
|
||
|
|
||
| def test_development_config_enables_debug() -> None: | ||
| """DevelopmentConfig turns debug on.""" | ||
| assert config.DevelopmentConfig.DEBUG is True | ||
|
|
||
|
|
||
| def test_production_config_hardened() -> None: | ||
| """ProductionConfig turns debug off and forces secure cookies over HTTPS.""" | ||
| assert config.ProductionConfig.DEBUG is False | ||
| assert config.ProductionConfig.SESSION_COOKIE_SECURE is True | ||
| assert config.ProductionConfig.PREFERRED_URL_SCHEME == "https" | ||
|
|
||
|
|
||
| def test_get_security_settings() -> None: | ||
| """get_security_settings mirrors the hardened production values.""" | ||
| settings = config.get_security_settings() | ||
| assert settings == { | ||
| "SESSION_COOKIE_SECURE": True, | ||
| "PREFERRED_URL_SCHEME": "https", | ||
| } | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| ("env", "expected"), | ||
| [ | ||
| ("development", config.DevelopmentConfig), | ||
| ("production", config.ProductionConfig), | ||
| ("PRODUCTION", config.ProductionConfig), | ||
| ("nonsense", config.DevelopmentConfig), | ||
| ], | ||
| ) | ||
| def test_get_config_explicit_env(env: str, expected: type) -> None: | ||
| """get_config maps an explicit environment name case-insensitively.""" | ||
| assert config.get_config(env) is expected | ||
|
|
||
|
|
||
| def test_get_config_reads_flask_env(monkeypatch: pytest.MonkeyPatch) -> None: | ||
| """get_config falls back to FLASK_ENV when no argument is given.""" | ||
| monkeypatch.setenv("FLASK_ENV", "production") | ||
| assert config.get_config() is config.ProductionConfig | ||
|
|
||
|
|
||
| This ensures that the `config` module is properly loaded and accessible. | ||
| """ | ||
| if not hasattr(config, "__name__"): | ||
| pytest.fail("The `config` module should have a `__name__` attribute.") | ||
| def test_get_config_defaults_to_development( | ||
| monkeypatch: pytest.MonkeyPatch, | ||
| ) -> None: | ||
| """get_config defaults to development when FLASK_ENV is unset.""" | ||
| monkeypatch.delenv("FLASK_ENV", raising=False) | ||
| assert config.get_config() is config.DevelopmentConfig |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| """Shared pytest fixtures for the LedgerBase test suite.""" | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
||
| from flask import Flask | ||
| from ledgerbase.error_handlers import register_error_handlers | ||
|
|
||
| REPO_ROOT = Path(__file__).resolve().parent.parent | ||
| TEMPLATE_DIR = REPO_ROOT / "templates" | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def app() -> Flask: | ||
| """Return a minimal Flask app wired to the repository template directory.""" | ||
| flask_app = Flask(__name__, template_folder=str(TEMPLATE_DIR)) | ||
| flask_app.config.update(TESTING=True) | ||
| register_error_handlers(flask_app) | ||
|
|
||
| @flask_app.route("/boom") | ||
| def boom() -> str: | ||
| raise RuntimeError | ||
|
|
||
| return flask_app | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def client(app: Flask): # noqa: ANN201 | ||
| """Return a test client for the minimal Flask app.""" | ||
| return app.test_client() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Resolve the repository root before choosing
template_dir.Path(__file__).resolve().parent.parentresolves to<repo>/src.tests/conftest.pylines 10-11 establish the template directory as<repo>/templates. Whensrc/templatesis absent, the fallback Flask app cannot render the HTML error templates and raisesTemplateNotFound.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents