Add personal notes, DeepSearch history, backup offload, and gateway auth throttling
DevPlace CI / test (push) Failing after 28m20s
DevPlace CI / test (push) Failing after 28m20s
Also streamline the top navigation: drop the Tools dropdown, make Quizzes and Battles icon-only entries, and remove the Workspace, Containers and Editor entry points from the project detail page.
This commit is contained in:
+69
-1
@@ -2,7 +2,12 @@
|
||||
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from devplacepy.rendering import render_content, render_title
|
||||
from devplacepy.rendering import (
|
||||
markdown_structure_signature,
|
||||
render_content,
|
||||
render_title,
|
||||
safe_truncate,
|
||||
)
|
||||
|
||||
|
||||
def test_emoji_shortcodes():
|
||||
@@ -12,6 +17,37 @@ def test_emoji_shortcodes():
|
||||
assert ":rocket:" not in out
|
||||
|
||||
|
||||
def test_markdown_structure_signature_counts_elements():
|
||||
text = (
|
||||
"# Title\n\n"
|
||||
"- one\n- two\n\n"
|
||||
"1. first\n2. second\n\n"
|
||||
"```python\nprint(1)\n```\n\n"
|
||||
"[link](https://example.com)\n"
|
||||
)
|
||||
assert markdown_structure_signature(text) == {
|
||||
"code_fences": 1,
|
||||
"list_items": 4,
|
||||
"headers": 1,
|
||||
"links": 1,
|
||||
}
|
||||
|
||||
|
||||
def test_markdown_structure_signature_blank_text():
|
||||
assert markdown_structure_signature("") == {
|
||||
"code_fences": 0,
|
||||
"list_items": 0,
|
||||
"headers": 0,
|
||||
"links": 0,
|
||||
}
|
||||
|
||||
|
||||
def test_markdown_structure_signature_ignores_word_changes():
|
||||
original = markdown_structure_signature("- alpha\n- beta\n- gamma\n")
|
||||
reworded = markdown_structure_signature("- Alpha\n- beta\n- gamma\n")
|
||||
assert original == reworded
|
||||
|
||||
|
||||
def test_markdown_bold_and_italic():
|
||||
out = str(render_content("this is **bold** and _em_"))
|
||||
assert "<strong>bold</strong>" in out
|
||||
@@ -47,6 +83,38 @@ def test_plain_url_autolinked():
|
||||
assert '<a href="https://example.com/page" target="_blank" rel="noopener noreferrer">' in out
|
||||
|
||||
|
||||
def test_safe_truncate_short_text_unchanged():
|
||||
text = "short content"
|
||||
assert safe_truncate(text, 300) == text
|
||||
|
||||
|
||||
def test_safe_truncate_backs_off_to_word_boundary():
|
||||
text = "a" * 45 + " " + "b" * 45
|
||||
truncated = safe_truncate(text, 50)
|
||||
assert truncated == "a" * 45
|
||||
|
||||
|
||||
def test_safe_truncate_does_not_split_a_url_straddling_the_cutoff():
|
||||
prefix = "word " * 58
|
||||
url = "https://example.com/gallery/a-very-long-descriptive-photo-name.jpg"
|
||||
text = prefix + url + " more words after the link that get cut off entirely"
|
||||
truncated = safe_truncate(text, 300)
|
||||
assert url not in truncated
|
||||
assert "example.com" not in truncated
|
||||
out = str(render_content(truncated + "..."))
|
||||
assert "<img" not in out
|
||||
assert "<a href=" not in out
|
||||
|
||||
|
||||
def test_safe_truncate_keeps_a_url_that_fits_before_the_cutoff():
|
||||
url = "https://example.com/image.png"
|
||||
text = url + " " + ("word " * 60)
|
||||
truncated = safe_truncate(text, 300)
|
||||
assert url in truncated
|
||||
out = str(render_content(truncated))
|
||||
assert f'<img src="{url}"' in out
|
||||
|
||||
|
||||
def test_mention_links_to_profile():
|
||||
out = str(render_content("hello @alice_test there"))
|
||||
assert '<a href="/profile/alice_test" class="mention-link">@alice_test</a>' in out
|
||||
|
||||
Reference in New Issue
Block a user