def test_strikethrough(): """Ensure strikethrough works and doesn't turn into a group link.""" markdown = "This ~~should not~~ should work" processed = convert_markdown_to_safe_html(markdown) assert "<del>" in processed assert "<a" not in processed
def test_add_anchor_to_headings(): """Ensure that a basic heading ends up with the expected id.""" markdown = "# Some heading" html = convert_markdown_to_safe_html(markdown) html = add_anchors_to_headings(html) assert 'id="some_heading"' in html
def test_subreddit_linkified_without_punctuation(): """Ensure subreddit is linkified without punctuation.""" markdown = "Check out: /r/antarctica!" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="https://www.reddit.com/r/antarctica/")
def __init__(self, conversation: MessageConversation, sender: User, markdown: str): """Add a new reply to a message conversation.""" self.conversation = conversation self.sender = sender self.markdown = markdown self.rendered_html = convert_markdown_to_safe_html(markdown)
def test_subreddit_with_leading_forward_slash_linkified(): """Ensure subreddit with leading forward slash is linkified.""" markdown = "Check out: /r/antarctica" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="https://www.reddit.com/r/antarctica/")
def edit(self, new_markdown: str, user: User, edit_message: str) -> None: """Set the page's markdown, render its HTML, and commit the repo.""" if new_markdown == self.markdown: return self.markdown = new_markdown self.rendered_html = convert_markdown_to_safe_html(new_markdown) self.rendered_html = add_anchors_to_headings(self.rendered_html) self.last_edited_time = utc_now() repo = Repository(self.BASE_PATH) author = Signature(user.username, user.username) repo.index.read() repo.index.add(str(self.file_path.relative_to(self.BASE_PATH))) repo.index.write() # Prepend the group name and page path to the edit message - if you change the # format of this, make sure to also change the page-editing template to match edit_message = f"~{self.group.path}/{self.path}: {edit_message}" repo.create_commit( repo.head.name, author, author, edit_message, repo.index.write_tree(), [repo.head.target], )
def test_group_ref_inside_link_not_replaced(): """Ensure a group ref inside a longer link doesn't get re-linked.""" markdown = "Found [this band from a ~music.punk post](http://whitelung.ca)" processed = convert_markdown_to_safe_html(markdown) assert processed.count("<a") == 1 assert 'href="/~music.punk"' not in processed
def test_group_ref_inside_other_tags_linkified(): """Ensure a group ref inside non-ignored tags gets linked.""" markdown = "> Here is **a ~group.reference inside** other stuff" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="/~group.reference")
def test_uppercase_group_ref_links_correctly(): """Ensure using uppercase in a group ref works but links correctly.""" markdown = "That was in ~Music.Metal.Progressive" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="/~music.metal.progressive")
def test_existing_link_group_ref_not_replaced(): """Ensure a group ref with an existing link doesn't get overwritten.""" markdown = "Doesn't go [~where.you.expect](http://example.com)" processed = convert_markdown_to_safe_html(markdown) assert '<a href="http://example.com"' in processed assert 'href="/~where.you.expect"' not in processed
def test_invalid_group_reference_not_linkified(): """Ensure an invalid group reference doesn't linkify.""" markdown = ("You can't name a group ~games.pokémon.\n" "You also can't have a name like ~_underscores.") processed = convert_markdown_to_safe_html(markdown) assert "<a" not in processed
def test_group_reference_linkified(): """Ensure a simple group reference gets linkified.""" markdown = "Yeah, I saw that in ~books.fantasy yesterday." processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="/~books.fantasy")
def test_html_lookalike_not_closed(): """Ensure text that looks like an HTML tag isn't "fixed" by adding a closing tag.""" markdown = "I can't believe it's not <blank>!" processed = convert_markdown_to_safe_html(markdown) assert "<blank>" in processed assert "</blank>" not in processed
def test_html_disallowed_attributes(): """Ensure disallowed HTML attributes are removed.""" markdown = ('<a href="example.com" title="example" target="_blank" ' 'referrerpolicy="unsafe-url">test link</a>') processed = convert_markdown_to_safe_html(markdown) assert processed == '<p><a href="example.com" title="example">test link</a></p>\n'
def test_username_and_group_refs_linked(): """Ensure username and group references together get linkified.""" markdown = '@SomeUser makes the best posts in ~some.group for sure' processed = convert_markdown_to_safe_html(markdown) assert '<a href="/user/SomeUser">@SomeUser</a>' in processed assert '<a href="/~some.group">~some.group</a>' in processed
def test_html_attr_whitelist_violation(): """Ensure using non-whitelisted HTML attributes removes the tag.""" markdown = ('<a href="example.com" title="example" target="_blank" ' 'referrerpolicy="unsafe-url">test link</a>') processed = convert_markdown_to_safe_html(markdown) assert processed == '<p>test link</p>\n'
def test_strikethrough_with_group(): """Ensure strikethrough works with a group name in the middle.""" markdown = "They ~~spammed ~music heavily~~ posted lots of songs." processed = convert_markdown_to_safe_html(markdown) assert processed.count("<del>") == 1 assert "<a" in processed
def test_anchor_on_complex_heading(): """Ensure that a more complex heading still gets the expected id.""" markdown = "# This *heading* has **more formatting**" html = convert_markdown_to_safe_html(markdown) html = add_anchors_to_headings(html) assert 'id="this_heading_has_more_formatting"' in html
def test_image_syntax_ignored(): """Ensure inline image syntax is treated as a link.""" markdown = "An exclamation mark preceding a ![link](url)." processed = convert_markdown_to_safe_html(markdown) assert "!<a" in processed assert "img" not in processed
def test_a_rel_kept_user_bio_context(): """Ensure a rel= attr is kept on an <a> tag in the user bio context.""" markdown = '<a href="http://example.com" rel="something">Link</a>' processed = convert_markdown_to_safe_html(markdown, HTMLSanitizationContext.USER_BIO) assert "rel=" in processed
def test_u_alt_style_username_ref_linked(): """Ensure a u/username reference gets linkified.""" markdown = "Hey u/SomeUser, what do you think of this?" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="/user/SomeUser")
def test_subreddit_followed_by_apostrophe_not_linkified(): """Ensure we don't linkify apostrophes after subreddit references.""" markdown = "/r/funny's moderators" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="https://www.reddit.com/r/funny/")
def test_subreddit_lookalike_conjunction_not_linkified(): """Ensure where forward slash used for conjunction, text doesn't linkify.""" markdown = "water/ocean" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert len(soup.find_all("a")) == 0
def __init__(self, conversation: MessageConversation, sender: User, markdown: str): """Add a new reply to a message conversation.""" self.conversation_id = conversation.conversation_id self.sender_id = sender.user_id self.markdown = markdown self.rendered_html = convert_markdown_to_safe_html(markdown) incr_counter("messages", type="reply")
def test_username_and_group_refs_linked(): """Ensure username and group references together get linkified.""" markdown = "@SomeUser makes the best posts in ~some.group for sure" processed = convert_markdown_to_safe_html(markdown) soup = BeautifulSoup(processed, features="html5lib") assert soup.find("a", href="/user/SomeUser") assert soup.find("a", href="/~some.group")
def test_accidental_ordered_list(): """Ensure a common "accidental" ordered list gets escaped.""" markdown = ('What year did this happen?\n\n' '1975. It was a long time ago.\n\n' 'But I remember it like it was yesterday.') html = convert_markdown_to_safe_html(markdown) assert '<ol' not in html
def test_username_ref_inside_pre_ignored(): """Ensure a username ref inside a <pre> tag doesn't get linked.""" markdown = ('```\n' '# Code blatantly stolen from @HelpfulGuy on StackOverflow\n' '```\n') processed = convert_markdown_to_safe_html(markdown) assert '<a' not in processed
def test_heading_links_to_itself(): """Ensure that a heading ends up containing a link to itself.""" markdown = "## Important information" html = convert_markdown_to_safe_html(markdown) html = add_anchors_to_headings(html) soup = BeautifulSoup(html, features="html5lib") assert soup.h2.a["href"] == "#" + soup.h2["id"]
def test_subreddit_inside_pre_ignored(): """Ensure a subreddit link inside a <pre> tag doesn't get linked.""" markdown = ("```\n" "# This is a code block\n" "# I found this code on r/python, hopefully it works\n" "```\n") processed = convert_markdown_to_safe_html(markdown) assert "<a" not in processed
def __init__(self, sender: User, recipient: User, subject: str, markdown: str): """Create a new message conversation between two users.""" self.sender = sender self.recipient = recipient self.unread_user_ids = [self.recipient.user_id] self.subject = subject self.markdown = markdown self.rendered_html = convert_markdown_to_safe_html(markdown)