Red-DiscordBot/tests/cogs/test_trivia.py
Vexed b493103dcb
Improve validation in trivia (#5947)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-01-02 05:24:27 +01:00

79 lines
2.5 KiB
Python

import textwrap
from typing import Any
import pytest
import yaml
from schema import And, Optional, SchemaError
from redbot.cogs.trivia.schema import (
ALWAYS_MATCH,
MATCH_ALL_BUT_STR,
NO_QUESTIONS_ERROR_MSG,
TRIVIA_LIST_SCHEMA,
format_schema_error,
)
def test_trivia_lists():
from redbot.cogs.trivia import InvalidListError, get_core_lists, get_list
list_names = get_core_lists()
assert list_names
problem_lists = []
for l in list_names:
try:
get_list(l)
except InvalidListError as exc:
e = exc.__cause__
if isinstance(e, SchemaError):
problem_lists.append((l.stem, f"SCHEMA error:\n{e!s}"))
else:
problem_lists.append((l.stem, f"YAML error:\n{e!s}"))
if problem_lists:
msg = "\n".join(
f"- {name}:\n{textwrap.indent(error, ' ')}" for name, error in problem_lists
)
raise TypeError("The following lists contain errors:\n" + msg)
def _get_error_message(*keys: Any, key: str = "UNKNOWN", parent_key: str = "UNKNOWN") -> str:
if not keys:
return TRIVIA_LIST_SCHEMA._error
current = TRIVIA_LIST_SCHEMA.schema
for key_name in keys:
if isinstance(current, And):
current = current.args[0]
current = current[key_name]
return str(current._error).format(key=repr(key), parent_key=repr(parent_key))
@pytest.mark.parametrize(
"data,error_msg",
(
("text", _get_error_message()),
({"AUTHOR": 123}, _get_error_message(Optional("AUTHOR"), key="AUTHOR")),
({"CONFIG": 123}, _get_error_message(Optional("CONFIG"), key="CONFIG")),
(
{"CONFIG": {"key": "value"}},
_get_error_message(Optional("CONFIG"), ALWAYS_MATCH, key="key", parent_key="CONFIG"),
),
(
{"CONFIG": {"bot_plays": "wrong type"}},
_get_error_message(
Optional("CONFIG"), Optional("bot_plays"), key="bot_plays", parent_key="CONFIG"
),
),
({"AUTHOR": "Correct type but no questions."}, NO_QUESTIONS_ERROR_MSG),
({"Question": "wrong type"}, _get_error_message(str, key="Question")),
({"Question": [{"wrong": "type"}]}, _get_error_message(str, key="Question")),
({123: "wrong key type"}, _get_error_message(MATCH_ALL_BUT_STR, key="123")),
),
)
def test_trivia_schema_error_messages(data: Any, error_msg: str):
with pytest.raises(SchemaError) as exc:
TRIVIA_LIST_SCHEMA.validate(data)
assert format_schema_error(exc.value) == error_msg