pypiserver/tests/test_init.py
Matthew Planchard c668b1814a
Use argparse config throughout app (#349)
This PR is a pretty substantial refactor of the entrypoints of pypiserver (`__main__` and `__init__`) to use the argparse-based config added in #339.

- Updated `RunConfig` and `UpdateConfig` classes to have exclusive init kwargs, instead of taking an namespace. This turned out to be much easier when working with the library-style app initialization in `__init__`, both for direct instantiation and via paste config
- Added an `iter_packages()` method to the `RunConfig` to iterate over packages specified by the configuration (note @elfjes, I think that replacing this with e.g. a `backend` reference will be a nice way to tie in #348)
- Added a general-purpose method to map legacy keyword arguments to the `app()` and `paste_app_factory()` functions to updated forms
- Refactored the `paste_app_factory()` to not mutate the incoming dictionary
- Removed all argument-parsing and config-related code from `__main__` and `core`
- Moved `_logwrite` from `__init__` to `__main__`, since that was the only place it was being used after the updates to `core`
- Updated `digest_file` to use `hashlib.new(algo)` instead of `getattr(hashlib, algo)`, because the former supports more algorithms
- Updated `setup.py` to, instead of calling `eval()` on the entirety of `__init__`, to instead just evaluate the line that defines the version
- Assigned the config to a `._pypiserver_config` attribute on the `Bottle` instance to reduce hacky test workarounds
- Fixed the tox config, which I broke in #339 

* Config: add auth & absolute path resolution

* Config: check pkg dirs on config creation

* Instantiate config with kwargs, not namespace

* WIP: still pulling the threads

* Init seems to be working

* tests passing locally, still need to update cache

* Fix tox command

* unused import

* Fix typing

* Be more selective in exec() in setup.py

* Require accurate casing for hash algos

* Remove old comment

* Comments, minor updates and simplifications

* move _logwrite to a more reasonable place

* Update config to work with cache

* Type cachemanager listdir in core

* Update config module docstring, rename method

* Add more comments re: paste config

* Add comments to main, remove unneded check

* Remove commented code

* Use {posargs} instead of [] for clarity in tox

* Add dupe check for kwarg updater

* Remove unused references on app instance

* Fix typo

* Remove redundancy in log level parsing
2020-10-25 18:48:28 -05:00

106 lines
2.7 KiB
Python

"""
Test module for app initialization
"""
# Standard library imports
import logging
import pathlib
import typing as t
# Third party imports
import pytest
# Local imports
import pypiserver
logger = logging.getLogger(__name__)
TEST_DIR = pathlib.Path(__file__).parent
HTPASS_FILE = TEST_DIR / "htpasswd.a.a"
WELCOME_FILE = TEST_DIR / "sample_msg.html"
# TODO: make these tests meaningful
@pytest.mark.parametrize(
"conf_options",
[
{},
{"root": "~/stable_packages"},
{
"root": "~/unstable_packages",
"authenticated": "upload",
"passwords": str(HTPASS_FILE),
},
# Verify that the strip parser works properly.
{"authenticated": str("upload")},
],
)
def test_paste_app_factory(conf_options: dict) -> None:
"""Test the paste_app_factory method"""
pypiserver.paste_app_factory({}, **conf_options) # type: ignore
def test_app_factory() -> None:
assert pypiserver.app() is not pypiserver.app()
@pytest.mark.parametrize(
"incoming, updated",
(
(
{"authenticated": []},
{"authenticate": []},
),
(
{"passwords": "./foo"},
{"password_file": "./foo"},
),
(
{"root": str(TEST_DIR)},
{"roots": [TEST_DIR.expanduser().resolve()]},
),
(
{"root": [str(TEST_DIR), str(TEST_DIR)]},
{
"roots": [
TEST_DIR.expanduser().resolve(),
TEST_DIR.expanduser().resolve(),
]
},
),
(
{"redirect_to_fallback": False},
{"disable_fallback": True},
),
(
{"server": "auto"},
{"server_method": "auto"},
),
(
{"welcome_file": str(WELCOME_FILE.resolve())},
{"welcome_msg": WELCOME_FILE.read_text()},
),
),
)
def test_backwards_compat_kwargs_conversion(
incoming: t.Dict[str, t.Any], updated: t.Dict[str, t.Any]
) -> None:
"""Test converting legacy kwargs to modern ones."""
assert pypiserver.backwards_compat_kwargs(incoming) == updated
@pytest.mark.parametrize(
"kwargs",
(
{"redirect_to_fallback": False, "disable_fallback": False},
{"disable_fallback": False, "redirect_to_fallback": False},
),
)
def test_backwards_compat_kwargs_duplicate_check(
kwargs: t.Dict[str, t.Any]
) -> None:
"""Duplicate legacy and modern kwargs cause an error."""
with pytest.raises(ValueError) as err:
pypiserver.backwards_compat_kwargs(kwargs)
assert "('redirect_to_fallback', 'disable_fallback')" in str(err.value)