import sys from os import getcwd from pathlib import Path from types import SimpleNamespace from unittest.mock import Mock, patch import pytest from sanic.app import Sanic from sanic.worker.loader import AppLoader, CertLoader STATIC = Path.cwd() / "tests" / "static" @pytest.mark.parametrize( "module_input", ("tests.fake.server:app", "tests.fake.server.app") ) def test_load_app_instance(module_input): loader = AppLoader(module_input) app = loader.load() assert isinstance(app, Sanic) @pytest.mark.parametrize( "module_input", ("tests.fake.server:create_app", "tests.fake.server:create_app()"), ) def test_load_app_factory(module_input): loader = AppLoader(module_input, as_factory=True) app = loader.load() assert isinstance(app, Sanic) def test_load_app_simple(): loader = AppLoader(str(STATIC), as_simple=True) app = loader.load() assert isinstance(app, Sanic) def test_create_with_factory(): loader = AppLoader(factory=lambda: Sanic("Test")) app = loader.load() assert isinstance(app, Sanic) def test_cwd_in_path(): AppLoader("tests.fake.server:app").load() assert getcwd() in sys.path def test_input_is_dir(): loader = AppLoader(str(STATIC)) message = ( "App not found.\n Please use --simple if you are passing a " f"directory to sanic.\n eg. sanic {str(STATIC)} --simple" ) with pytest.raises(ValueError, match=message): loader.load() def test_input_is_factory(): ns = SimpleNamespace(module="foo") loader = AppLoader("tests.fake.server:create_app", args=ns) message = ( "Module is not a Sanic app, it is a function\n If this callable " "returns a Sanic instance try: \nsanic foo --factory" ) with pytest.raises(ValueError, match=message): loader.load() def test_input_is_module(): ns = SimpleNamespace(module="foo") loader = AppLoader("tests.fake.server", args=ns) message = ( "Module is not a Sanic app, it is a module\n " "Perhaps you meant foo:app?" ) with pytest.raises(ValueError, match=message): loader.load() @pytest.mark.parametrize("creator", ("mkcert", "trustme")) @patch("sanic.worker.loader.TrustmeCreator") @patch("sanic.worker.loader.MkcertCreator") def test_cert_loader(MkcertCreator: Mock, TrustmeCreator: Mock, creator: str): CertLoader._creators = { "mkcert": MkcertCreator, "trustme": TrustmeCreator, } MkcertCreator.return_value = MkcertCreator TrustmeCreator.return_value = TrustmeCreator data = { "creator": creator, "key": Path.cwd() / "tests" / "certs" / "localhost" / "privkey.pem", "cert": Path.cwd() / "tests" / "certs" / "localhost" / "fullchain.pem", "localhost": "localhost", } app = Sanic("Test") loader = CertLoader(data) # type: ignore loader.load(app) creator_class = MkcertCreator if creator == "mkcert" else TrustmeCreator creator_class.assert_called_once_with(app, data["key"], data["cert"]) creator_class.generate_cert.assert_called_once_with("localhost")