From d529a2329d43ee2b7a7d3b69c1cbb55290ed879a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 28 Nov 2025 10:34:44 +0000 Subject: [PATCH] Refactor request argument parsing and test database helper Co-authored-by: durneviv --- src/engine.py | 2 +- src/handlers/v2/auth.py | 2 +- src/handlers/v2/base.py | 2 +- src/helpers.py | 23 ++++++++++++++++++++++- tests/base.py | 26 +++++++++++++++++++++++++- tests/helpers_t.py | 14 ++++++++++++++ 6 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/engine.py b/src/engine.py index 7813197..ad8320b 100644 --- a/src/engine.py +++ b/src/engine.py @@ -258,7 +258,7 @@ def update(self): self.updateMoves() def reset(self): - _moves = None + self._moves = None @property def moved(self): diff --git a/src/handlers/v2/auth.py b/src/handlers/v2/auth.py index 4b865c8..ad87b37 100644 --- a/src/handlers/v2/auth.py +++ b/src/handlers/v2/auth.py @@ -38,7 +38,7 @@ def get(self): try: token = request.user.get_verification() except Exception as e: - raise APIException(e.message) + raise APIException(str(e)) data = { 'username': request.user.username, 'url': urljoin(config.SITE_URL, config.VERIFY_URL), diff --git a/src/handlers/v2/base.py b/src/handlers/v2/base.py index 0f8f93e..a46a61a 100644 --- a/src/handlers/v2/base.py +++ b/src/handlers/v2/base.py @@ -125,6 +125,6 @@ def urls(self, urls): self.rest(*url) def addChild(self, name, import_name, url_prefix): - name = '{}.{}'.format(self.name, name) + name = '{}_{}'.format(self.name, name) url_prefix = '{}{}'.format(self.url_prefix, url_prefix) return BlueprintBase(name, import_name, url_prefix=url_prefix) diff --git a/src/helpers.py b/src/helpers.py index 3296801..07dcb44 100644 --- a/src/helpers.py +++ b/src/helpers.py @@ -60,5 +60,26 @@ def get_prefix(game_type, game_limit=None): return '{}-{}'.format(game_type, game_limit if game_limit is not None else '*') +def _get_request_json(request): + """ + Try to read JSON data without raising BadRequest if payload is invalid. + Flask's `request.json` property raises in that scenario, so prefer the + `get_json(silent=True)` helper when available, but fall back to the legacy + attribute for test doubles. + """ + get_json = getattr(request, 'get_json', None) + if callable(get_json): + try: + return get_json(silent=True) + except TypeError: + # Older Flask versions might not accept the silent kwarg. + try: + return get_json() + except TypeError: + return None + return getattr(request, 'json', None) + + def get_request_arg(request, name): - return request.form.get(name) or (request.json or {}).get(name) + json_payload = _get_request_json(request) or {} + return request.form.get(name) or json_payload.get(name) diff --git a/tests/base.py b/tests/base.py index d7719e6..45dbb54 100644 --- a/tests/base.py +++ b/tests/base.py @@ -8,7 +8,31 @@ from fakeredis import FakeStrictRedis from flask import Flask from peewee import SqliteDatabase, Model -from playhouse.test_utils import test_database +try: + from playhouse.test_utils import test_database +except (ImportError, AttributeError): + from contextlib import contextmanager + + @contextmanager + def test_database(database, models, create_tables=True, fail_silently=False): + """ + Lightweight replacement for the Peewee helper that was removed in newer + releases. It temporarily binds the provided models to the supplied + database, creates their tables, and tears everything down afterwards. + """ + originals = {model: model._meta.database for model in models} + database.bind(models, bind_refs=False, bind_backrefs=False) + if create_tables: + database.connect(reuse_if_open=True) + database.create_tables(models) + try: + yield + finally: + if create_tables: + database.drop_tables(models) + database.close() + for model, original in originals.items(): + model._meta.database = original from app import app import cache diff --git a/tests/helpers_t.py b/tests/helpers_t.py index f73c804..c3a8260 100644 --- a/tests/helpers_t.py +++ b/tests/helpers_t.py @@ -84,3 +84,17 @@ class _Request(): # from form request.form['arg1'] = 'fsuccess' self.assertEqual(get_request_arg(request, 'arg1'), 'fsuccess') + # via get_json helper (ensures silent parsing) + class _JsonMethodRequest(): + form = {} + + def __init__(self): + self._payload = {'arg1': 'msuccess'} + + def get_json(self, silent=False): + if not silent: + raise ValueError('get_json must be called in silent mode') + return self._payload + + request_method = _JsonMethodRequest() + self.assertEqual(get_request_arg(request_method, 'arg1'), 'msuccess')