|
# retoor <retoor@molodetz.nl>
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from devplacepy.models import GameLegacyForm
|
|
|
|
|
|
def test_game_legacy_form_accepts_valid_key():
|
|
assert GameLegacyForm(key="multiplier").key == "multiplier"
|
|
|
|
|
|
def test_game_legacy_form_rejects_empty_key():
|
|
with pytest.raises(ValidationError):
|
|
GameLegacyForm(key="")
|
|
|
|
|
|
def test_game_legacy_form_rejects_overlong_key():
|
|
with pytest.raises(ValidationError):
|
|
GameLegacyForm(key="x" * 41)
|
|
|
|
|
|
def test_isslop_run_form_accepts_git_and_http_sources():
|
|
from devplacepy.models import IsslopRunForm
|
|
|
|
assert IsslopRunForm(url="https://github.com/owner/repo").url == "https://github.com/owner/repo"
|
|
assert IsslopRunForm(url="git@github.com:owner/repo.git").url == "git@github.com:owner/repo.git"
|
|
assert IsslopRunForm(url=" https://example.com ").url == "https://example.com"
|
|
|
|
|
|
def test_isslop_run_form_rejects_other_schemes():
|
|
from devplacepy.models import IsslopRunForm
|
|
|
|
for bad in ("ftp://example.com/file", "javascript:alert(1)//aaa", "file:///etc/passwd"):
|
|
with pytest.raises(ValidationError):
|
|
IsslopRunForm(url=bad)
|
|
|
|
|
|
def test_isslop_run_form_normalizes_typos_and_bare_domains():
|
|
from devplacepy.models import IsslopRunForm
|
|
|
|
assert (
|
|
IsslopRunForm(url="https:/retoor.molodetz.nl/retoor/devplacepy").url
|
|
== "https://retoor.molodetz.nl/retoor/devplacepy"
|
|
)
|
|
assert IsslopRunForm(url="example.com/owner/repo").url == "https://example.com/owner/repo"
|
|
assert IsslopRunForm(url="http:/x.dev/a").url == "http://x.dev/a"
|
|
|
|
|
|
def test_reaction_form_accepts_any_single_emoji():
|
|
from devplacepy.models import ReactionForm
|
|
|
|
for value in (
|
|
"\U0001F44D",
|
|
"\U0001F984",
|
|
"\u2764\uFE0F",
|
|
"\U0001F44D\U0001F3FD",
|
|
"\U0001F9D1\u200d\U0001F4BB",
|
|
"\U0001F3F3\uFE0F\u200d\U0001F308",
|
|
"\U0001F1F3\U0001F1F1",
|
|
"1\uFE0F\u20E3",
|
|
):
|
|
assert ReactionForm(emoji=value).emoji == value
|
|
|
|
|
|
def test_reaction_form_accepts_every_emoji_the_picker_offers():
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from devplacepy.models import ReactionForm
|
|
|
|
data_path = (
|
|
Path(__file__).resolve().parents[2]
|
|
/ "devplacepy"
|
|
/ "static"
|
|
/ "vendor"
|
|
/ "emoji-picker-element"
|
|
/ "data.json"
|
|
)
|
|
entries = json.loads(data_path.read_text(encoding="utf-8"))
|
|
offered = [entry["emoji"] for entry in entries]
|
|
offered += [
|
|
skin["emoji"] for entry in entries for skin in (entry.get("skins") or [])
|
|
]
|
|
|
|
assert len(offered) > 3000
|
|
for value in offered:
|
|
assert ReactionForm(emoji=value).emoji == value
|
|
|
|
|
|
def test_reaction_form_strips_surrounding_whitespace():
|
|
from devplacepy.models import ReactionForm
|
|
|
|
assert ReactionForm(emoji=" \U0001F680 ").emoji == "\U0001F680"
|
|
|
|
|
|
def test_reaction_form_rejects_non_emoji_values():
|
|
from devplacepy.models import ReactionForm
|
|
|
|
for value in (
|
|
"notanemoji",
|
|
"a",
|
|
" ",
|
|
"",
|
|
"<script>",
|
|
"\u200b",
|
|
"\U0001F44D x",
|
|
"\U0001F44D\U0001F44D",
|
|
):
|
|
with pytest.raises(ValidationError):
|
|
ReactionForm(emoji=value)
|