Skip to content

Commit

Permalink
Drop aresponses
Browse files Browse the repository at this point in the history
  • Loading branch information
layday committed Oct 15, 2024
1 parent d303c19 commit 70a892f
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 191 deletions.
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ dependencies = [
]
optional-dependencies."test" = [
"anyio >= 4.3.0",
"aresponses >= 3",
"coverage[toml] >= 7.4.3",
"pytest >= 8",
"pytest-xdist >= 3.5.0",
Expand Down
34 changes: 13 additions & 21 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
from pathlib import Path
from typing import Any

import aiohttp
import aiohttp.web
import pytest
from aresponses import ResponsesMockServer
from aresponses.errors import NoRouteFoundError
from _pytest.fixtures import SubRequest
from yarl import URL

import instawow._logging
Expand All @@ -17,7 +14,7 @@
from instawow.shared_ctx import ConfigBoundCtx
from instawow.wow_installations import _DELECTABLE_DIR_NAMES, Flavour

from .fixtures.http import ROUTES
from .fixtures.http import ROUTES, ResponsesMockServer


def pytest_addoption(parser: pytest.Parser):
Expand All @@ -42,17 +39,13 @@ def caplog(caplog: pytest.LogCaptureFixture):
instawow._logging.logger.remove(handler_id)


class _StrictResponsesMockServer(ResponsesMockServer):
async def _find_response(self, request: aiohttp.web.Request):
response = await super()._find_response(request)
if response == (None, None):
raise NoRouteFoundError(f'No match found for <{request.method} {request.url}>')
return response


@pytest.fixture
async def iw_aresponses():
async with _StrictResponsesMockServer() as server:
async def iw_aresponses(
monkeypatch: pytest.MonkeyPatch,
):
async with ResponsesMockServer() as server:
monkeypatch.setattr('aiohttp.TCPConnector', server.tcp_connector_class)
monkeypatch.setattr('aiohttp.ClientRequest.is_ssl', lambda _: False)
yield server


Expand Down Expand Up @@ -115,7 +108,9 @@ def _iw_global_config_defaults(


@pytest.fixture
async def iw_web_client(iw_global_config: instawow.config.GlobalConfig):
async def iw_web_client(
iw_global_config: instawow.config.GlobalConfig,
):
async with instawow.http.init_web_client(iw_global_config.http_cache_dir) as web_client:
yield web_client

Expand All @@ -132,9 +127,7 @@ def iw_config_ctx(iw_profile_config: instawow.config.ProfileConfig):


@pytest.fixture(autouse=True, params=['all'])
async def _iw_mock_aiohttp_requests(
request: pytest.FixtureRequest, iw_aresponses: _StrictResponsesMockServer
):
async def _iw_mock_aiohttp_requests(request: SubRequest, iw_aresponses: ResponsesMockServer):
if request.config.getoption('--iw-no-mock-http') or any(
m.name == 'iw_no_mock_http' for m in request.node.iter_markers()
):
Expand All @@ -150,5 +143,4 @@ async def _iw_mock_aiohttp_requests(

routes = (ROUTES[k] for k in ROUTES.keys() & urls)

for route in routes:
iw_aresponses.add(**route.to_aresponses_add_args())
iw_aresponses.add(*routes)
129 changes: 35 additions & 94 deletions tests/fixtures/http/__init__.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
# pyright: strict

from __future__ import annotations

import importlib.resources
import json
import re
from collections.abc import Awaitable, Callable
from functools import cache
from io import BytesIO
from typing import Any
from zipfile import ZipFile

import attrs
from aiohttp.web import Request, Response
from yarl import URL

from instawow._version import get_version

_match_any = re.compile(r'.*')
from ._mock_server import Response, Route
from ._mock_server import ResponsesMockServer as ResponsesMockServer


def _load_fixture(filename: str):
Expand All @@ -38,199 +33,145 @@ def _make_addon_zip(*folders: str):
return buffer.getvalue()


@attrs.frozen
class Route:
url: URL = attrs.field(converter=URL)
response: (
Response
| Callable[[Request], Response]
| Callable[[Request], Awaitable[Response]]
| dict[str, Any]
| str
)
path_pattern: re.Pattern[str] | None = None
method: str = 'GET'
body_pattern: re.Pattern[str] | None = None
match_querystring: bool = False
repeat: float = float('inf')
case_insensitive: bool = False

def _make_path_pattern(self):
if self.path_pattern is not None:
return self.path_pattern

if self.case_insensitive:
return re.compile(rf'^{re.escape(self.url.path_qs)}$', re.IGNORECASE)

return self.url.path_qs

def to_aresponses_add_args(self) -> dict[str, Any]:
return {
'host_pattern': self.url.host,
'path_pattern': self._make_path_pattern(),
'method_pattern': self.method,
'body_pattern': _match_any if self.body_pattern is None else self.body_pattern,
'match_querystring': self.match_querystring,
'repeat': self.repeat,
'response': self.response,
}


ROUTES = {
r.url: r
for r in (
Route(
'//pypi.org/pypi/instawow/json',
r'//pypi\.org/pypi/instawow/json',
{'info': {'version': get_version()}},
),
Route(
'//raw.githubusercontent.com/layday/instawow-data/data/base-catalogue-v7.compact.json',
r'//raw\.githubusercontent\.com/layday/instawow-data/data/base-catalogue-v7\.compact\.json',
_load_json_fixture('base-catalogue-v7.compact.json'),
),
Route(
'//api.curseforge.com/v1/mods',
r'//api\.curseforge\.com/v1/mods',
_load_json_fixture('curse-addon--all.json'),
method='POST',
),
Route(
'//api.curseforge.com/v1/mods/search?gameId=1&slug=molinari',
r'//api\.curseforge\.com/v1/mods/search\?gameId=1&slug=molinari',
_load_json_fixture('curse-addon-slug-search.json'),
match_querystring=True,
),
Route(
'//api.curseforge.com/v1/mods/20338/files',
r'//api\.curseforge\.com/v1/mods/20338/files',
_load_json_fixture('curse-addon-files.json'),
),
Route(
'//api.curseforge.com/v1/mods/20338/files/4419396',
r'//api\.curseforge\.com/v1/mods/20338/files/4419396',
_load_json_fixture('curse-addon-file-4419396.json'),
),
Route(
'//api.curseforge.com/v1/mods/20338/files/5090686',
r'//api\.curseforge\.com/v1/mods/20338/files/5090686',
_load_json_fixture('curse-addon-file-5090686.json'),
),
Route(
'//api.curseforge.com/v1/mods/20338/files/{id}/changelog',
r'//api\.curseforge\.com/v1/mods/20338/files/(\d+)/changelog',
_load_json_fixture('curse-addon-changelog.json'),
path_pattern=re.compile(r'^/v1/mods/20338/files/(\d+)/changelog$'),
),
Route(
'//edge.forgecdn.net',
r'//edge\.forgecdn\.net/.*',
lambda _: Response(body=_make_addon_zip('Molinari')),
path_pattern=_match_any,
),
Route(
'//api.mmoui.com/v3/game/WOW/filelist.json',
r'//api\.mmoui\.com/v3/game/WOW/filelist\.json',
_load_json_fixture('wowi-filelist.json'),
),
Route(
'//api.mmoui.com/v3/game/WOW/filedetails/{id}.json',
r'//api\.mmoui\.com/v3/game/WOW/filedetails/(\d*)\.json',
_load_json_fixture('wowi-filedetails.json'),
path_pattern=re.compile(r'^/v3/game/WOW/filedetails/(\d*)\.json$'),
),
Route(
'//cdn.wowinterface.com',
r'//cdn\.wowinterface\.com/.*',
lambda _: Response(body=_make_addon_zip('Molinari')),
path_pattern=_match_any,
),
Route(
'//api.tukui.org/v1/addon/tukui',
r'//api\.tukui\.org/v1/addon/tukui',
_load_json_fixture('tukui-ui--tukui.json'),
),
Route(
'//api.tukui.org/v1/addon/elvui',
r'//api\.tukui\.org/v1/addon/elvui',
_load_json_fixture('tukui-ui--elvui.json'),
),
Route(
'//api.tukui.org/v1/download/',
r'//api\.tukui\.org/v1/download/.*',
lambda _: Response(body=_make_addon_zip('Tukui')),
path_pattern=re.compile(r'^/v1/download/'),
),
Route(
'//api.github.com/repos/nebularg/PackagerTest',
r'//api\.github\.com/repos/nebularg/PackagerTest',
_load_json_fixture('github-repo-release-json.json'),
),
Route(
'//api.github.com/repos/nebularg/PackagerTest/releases?per_page=10',
r'//api\.github\.com/repos/nebularg/PackagerTest/releases\?per_page=10',
_load_json_fixture('github-release-release-json.json'),
match_querystring=True,
),
Route(
'//api.github.com/repos/nebularg/PackagerTest/releases/assets/37156458',
r'//api\.github\.com/repos/nebularg/PackagerTest/releases/assets/37156458',
_load_json_fixture('github-release-release-json-release-json.json'),
),
Route(
'//api.github.com/repositories/388670',
r'//api\.github\.com/repositories/388670',
_load_json_fixture('github-repo-molinari.json'),
),
Route(
'//api.github.com/repos/p3lim-wow/Molinari',
r'//api\.github\.com/repos/p3lim-wow/Molinari',
_load_json_fixture('github-repo-molinari.json'),
case_insensitive=True,
),
Route(
'//api.github.com/repositories/388670/releases?per_page=10',
r'//api\.github\.com/repositories/388670/releases\?per_page=10',
_load_json_fixture('github-release-molinari.json'),
case_insensitive=True,
match_querystring=True,
),
Route(
'//api.github.com/repos/p3lim-wow/Molinari/releases?per_page=10',
r'//api\.github\.com/repos/p3lim-wow/Molinari/releases\?per_page=10',
_load_json_fixture('github-release-molinari.json'),
case_insensitive=True,
match_querystring=True,
),
Route(
URL(
re.escape(
next(
a['url']
for a in _load_json_fixture('github-release-molinari.json')[0]['assets']
if a['name'] == 'release.json'
)
).with_scheme(''),
),
_load_json_fixture('github-release-molinari-release-json.json'),
case_insensitive=True,
),
Route(
'//api.github.com/repos/AdiAddons/AdiBags',
r'//api\.github\.com/repos/AdiAddons/AdiBags',
_load_json_fixture('github-repo-no-releases.json'),
),
Route(
'//api.github.com/repos/AdiAddons/AdiBags/releases?per_page=10',
r'//api\.github\.com/repos/AdiAddons/AdiBags/releases\?per_page=10',
lambda _: Response(body=b'', status=404),
match_querystring=True,
),
Route(
'//api.github.com/repos/AdiAddons/AdiButtonAuras/releases/tags/2.0.19',
r'//api\.github\.com/repos/AdiAddons/AdiButtonAuras/releases/tags/2\.0\.19',
_load_json_fixture('github-release-no-assets.json'),
),
Route(
'//api.github.com/repos/layday/foobar',
r'//api\.github\.com/repos/layday/foobar',
lambda _: Response(body=b'', status=404),
),
Route(
'//api.github.com/repos/{x}/{y}/releases/asssets/{z}',
r'//api\.github\.com/repos(/[^/]*){2}/releases/assets/.*',
lambda _: Response(body=_make_addon_zip('Molinari')),
path_pattern=re.compile(r'^/repos(/[^/]*){2}/releases/assets/'),
),
Route(
'//github.com/login/device/code',
r'//github\.com/login/device/code',
_load_json_fixture('github-oauth-login-device-code.json'),
method='POST',
),
Route(
'//github.com/login/oauth/access_token',
r'//github\.com/login/oauth/access_token',
_load_json_fixture('github-oauth-login-access-token.json'),
method='POST',
),
Route(
'//api.github.com/repos/28/NoteworthyII',
r'//api\.github\.com/repos/28/NoteworthyII',
_load_json_fixture('github-repo-no-release-json.json'),
),
Route(
'//api.github.com/repos/28/NoteworthyII/releases?per_page=10',
r'//api\.github\.com/repos/28/NoteworthyII/releases\?per_page=10',
_load_json_fixture('github-release-no-release-json.json'),
match_querystring=True,
),
)
}
Loading

0 comments on commit 70a892f

Please sign in to comment.