You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
5.1 KiB

  1. # Copyright (c) 2018 Tildes contributors <code@tildes.net>
  2. # SPDX-License-Identifier: AGPL-3.0-or-later
  3. from datetime import timedelta
  4. from freezegun import freeze_time
  5. from marshmallow.fields import URL
  6. from pytest import raises
  7. from tildes.lib.datetime import utc_now
  8. from tildes.models.topic import EDIT_GRACE_PERIOD, Topic
  9. from tildes.schemas.fields import Markdown, SimpleString
  10. from tildes.schemas.topic import TopicSchema
  11. def test_text_creation_validations(mocker, session_user, session_group):
  12. """Ensure that text topic creation goes through expected validation."""
  13. mocker.spy(TopicSchema, "load")
  14. mocker.spy(Markdown, "_validate")
  15. mocker.spy(SimpleString, "_validate")
  16. Topic.create_text_topic(session_group, session_user, "a title", "the text")
  17. assert TopicSchema.load.called
  18. assert SimpleString._validate.call_args[0][1] == "a title"
  19. assert Markdown._validate.call_args[0][1] == "the text"
  20. def test_link_creation_validations(mocker, session_user, session_group):
  21. """Ensure that link topic creation goes through expected validation."""
  22. mocker.spy(TopicSchema, "load")
  23. mocker.spy(SimpleString, "_validate")
  24. mocker.spy(URL, "_validate")
  25. Topic.create_link_topic(
  26. session_group, session_user, "the title", "http://example.com"
  27. )
  28. assert TopicSchema.load.called
  29. assert SimpleString._validate.call_args[0][1] == "the title"
  30. assert URL._validate.call_args[0][1] == "http://example.com"
  31. def test_text_topic_edit_uses_markdown_field(mocker, text_topic):
  32. """Ensure editing a text topic is validated by the Markdown field class."""
  33. mocker.spy(Markdown, "_validate")
  34. text_topic.markdown = "Some new text after edit"
  35. assert Markdown._validate.called
  36. def test_text_topic_type(text_topic):
  37. """Ensure a text topic has the correct type set."""
  38. assert text_topic.is_text_type
  39. assert not text_topic.is_link_type
  40. def test_link_topic_type(link_topic):
  41. """Ensure a link topic has the correct type set."""
  42. assert link_topic.is_link_type
  43. assert not link_topic.is_text_type
  44. def test_delete_sets_deleted_time(db, text_topic):
  45. """Ensure a deleted topic gets its deleted_time set."""
  46. assert not text_topic.is_deleted
  47. assert not text_topic.deleted_time
  48. text_topic.is_deleted = True
  49. db.commit()
  50. db.refresh(text_topic)
  51. assert text_topic.deleted_time
  52. def test_link_domain_errors_on_text_topic(text_topic):
  53. """Ensure trying to get the domain of a text topic is an error."""
  54. with raises(ValueError):
  55. assert text_topic.link_domain == "this shouldn't work"
  56. def test_link_domain_on_link_topic(link_topic):
  57. """Ensure getting the domain of a link topic works."""
  58. assert link_topic.link_domain == "example.com"
  59. def test_edit_markdown_errors_on_link_topic(link_topic):
  60. """Ensure trying to edit the markdown of a link topic is an error."""
  61. with raises(AttributeError):
  62. link_topic.markdown = "Some new markdown"
  63. def test_edit_markdown_on_text_topic(text_topic):
  64. """Ensure editing the markdown of a text topic works and updates html."""
  65. original_html = text_topic.rendered_html
  66. text_topic.markdown = "Some new markdown"
  67. assert text_topic.rendered_html != original_html
  68. def test_edit_grace_period(text_topic):
  69. """Ensure last_edited_time isn't set if the edit is inside grace period."""
  70. one_sec = timedelta(seconds=1)
  71. edit_time = text_topic.created_time + EDIT_GRACE_PERIOD - one_sec
  72. with freeze_time(edit_time):
  73. text_topic.markdown = "some new markdown"
  74. assert not text_topic.last_edited_time
  75. def test_edit_after_grace_period(text_topic):
  76. """Ensure last_edited_time is set after the grace period."""
  77. one_sec = timedelta(seconds=1)
  78. edit_time = text_topic.created_time + EDIT_GRACE_PERIOD + one_sec
  79. with freeze_time(edit_time):
  80. text_topic.markdown = "some new markdown"
  81. assert text_topic.last_edited_time == utc_now()
  82. def test_multiple_edits_update_time(text_topic):
  83. """Ensure multiple edits all update last_edited_time."""
  84. one_sec = timedelta(seconds=1)
  85. initial_time = text_topic.created_time + EDIT_GRACE_PERIOD + one_sec
  86. for minutes in range(0, 4):
  87. edit_time = initial_time + timedelta(minutes=minutes)
  88. with freeze_time(edit_time):
  89. text_topic.markdown = f"edit #{minutes}"
  90. assert text_topic.last_edited_time == utc_now()
  91. def test_topic_initial_last_activity_time(text_topic):
  92. """Ensure last_activity_time is initially the same as created_time."""
  93. assert text_topic.last_activity_time == text_topic.created_time
  94. def test_convert_all_caps(session_user, session_group):
  95. """Ensure that all-caps titles are converted to title case."""
  96. topic = Topic.create_link_topic(
  97. session_group, session_user, "THE TITLE", "http://example.com"
  98. )
  99. assert topic.title == "The Title"
  100. def test_no_convert_partial_caps_title(session_user, session_group):
  101. """Ensure that partially-caps titles are not converted to title case."""
  102. topic = Topic.create_link_topic(
  103. session_group, session_user, "This is a TITLE", "http://example.com"
  104. )
  105. assert topic.title == "This is a TITLE"