test_uploading_css.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import os
  2. import pytest
  3. from django.core.files.uploadedfile import UploadedFile
  4. from django.urls import reverse
  5. from ....test import assert_has_error_message
  6. TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
  7. @pytest.fixture
  8. def css_file():
  9. return os.path.join(TESTS_DIR, "css", "test.css")
  10. @pytest.fixture
  11. def other_file():
  12. return os.path.join(TESTS_DIR, "images", "test.png")
  13. @pytest.fixture
  14. def hashed_css_file():
  15. return os.path.join(TESTS_DIR, "css", "test.4846cb3b.css")
  16. @pytest.fixture
  17. def upload(admin_client):
  18. def post_upload(theme, asset_files=None):
  19. url = reverse(
  20. "misago:admin:appearance:themes:upload-css", kwargs={"pk": theme.pk}
  21. )
  22. if asset_files is not None:
  23. data = asset_files if isinstance(asset_files, list) else [asset_files]
  24. else:
  25. data = None
  26. return admin_client.post(url, {"assets": data})
  27. return post_upload
  28. def test_css_file_can_be_uploaded(upload, theme, css_file):
  29. with open(css_file) as fp:
  30. upload(theme, fp)
  31. assert theme.css.exists()
  32. def test_multiple_css_files_can_be_uploaded_at_once(
  33. upload, theme, css_file, hashed_css_file
  34. ):
  35. with open(css_file) as fp1:
  36. with open(hashed_css_file) as fp2:
  37. upload(theme, [fp1, fp2])
  38. assert theme.css.exists()
  39. assert theme.css.count() == 2
  40. def test_css_files_uploaded_one_after_another_are_ordered(
  41. upload, theme, css_file, hashed_css_file
  42. ):
  43. with open(css_file) as fp:
  44. upload(theme, fp)
  45. first_css = theme.css.last()
  46. assert first_css.name == str(css_file).split("/")[-1]
  47. assert first_css.order == 0
  48. with open(hashed_css_file) as fp:
  49. upload(theme, fp)
  50. last_css = theme.css.last()
  51. assert last_css.name == str(hashed_css_file).split("/")[-1]
  52. assert last_css.order == 1
  53. def test_multiple_css_files_uploaded_at_once_are_ordered(
  54. upload, theme, css_file, hashed_css_file
  55. ):
  56. with open(css_file) as fp1:
  57. with open(hashed_css_file) as fp2:
  58. upload(theme, [fp1, fp2])
  59. assert list(theme.css.values_list("name", flat=True)) == [
  60. str(css_file).split("/")[-1],
  61. str(hashed_css_file).split("/")[-1],
  62. ]
  63. assert list(theme.css.values_list("order", flat=True)) == [0, 1]
  64. def test_uploaded_file_is_rejected_if_its_not_css_file(upload, theme, other_file):
  65. with open(other_file, "rb") as fp:
  66. upload(theme, fp)
  67. assert not theme.css.exists()
  68. def test_error_message_is_set_if_uploaded_file_is_not_css(upload, theme, other_file):
  69. with open(other_file, "rb") as fp:
  70. response = upload(theme, fp)
  71. assert_has_error_message(response)
  72. def test_if_some_of_uploaded_files_are_incorrect_only_css_files_are_added_to_theme(
  73. upload, theme, css_file, other_file
  74. ):
  75. with open(css_file) as fp1:
  76. with open(other_file, "rb") as fp2:
  77. upload(theme, [fp1, fp2])
  78. assert theme.css.exists()
  79. assert theme.css.count() == 1
  80. css = theme.css.last()
  81. expected_filename = str(css_file).split("/")[-1]
  82. assert css.name == expected_filename
  83. def test_css_file_is_uploaded_to_theme_directory(upload, theme, css_file):
  84. with open(css_file) as fp:
  85. upload(theme, fp)
  86. css = theme.css.last()
  87. assert theme.dirname in str(css.source_file)
  88. def test_css_file_name_is_set_as_asset_name(upload, theme, css_file):
  89. with open(css_file) as fp:
  90. upload(theme, fp)
  91. css = theme.css.last()
  92. expected_filename = str(css_file).split("/")[-1]
  93. assert css.name == expected_filename
  94. def test_hash_is_added_to_uploaded_css_file_name(
  95. upload, theme, css_file, hashed_css_file
  96. ):
  97. with open(css_file) as fp:
  98. upload(theme, fp)
  99. css = theme.css.last()
  100. filename = str(css.source_file.path).split("/")[-1]
  101. expected_filename = str(hashed_css_file).split("/")[-1]
  102. assert filename == expected_filename
  103. def test_hash_is_set_on_css_source_asset(upload, theme, css_file):
  104. with open(css_file) as fp:
  105. upload(theme, fp)
  106. css = theme.css.last()
  107. assert css.source_hash
  108. def test_css_file_name_is_preserved_if_it_already_contains_correct_hash(
  109. upload, theme, hashed_css_file
  110. ):
  111. with open(hashed_css_file) as fp:
  112. upload(theme, fp)
  113. css = theme.css.last()
  114. filename = str(css.source_file.path).split("/")[-1]
  115. expected_filename = str(hashed_css_file).split("/")[-1]
  116. assert filename == expected_filename
  117. def test_new_hash_is_added_to_css_file_name_if_it_contains_incorrect_hash(
  118. upload, theme
  119. ):
  120. incorrectly_hashed_css_file = os.path.join(TESTS_DIR, "css", "test.0046cb3b.css")
  121. with open(incorrectly_hashed_css_file) as fp:
  122. upload(theme, fp)
  123. css = theme.css.last()
  124. filename = str(css.source_file.path).split("/")[-1]
  125. assert css.source_hash in filename
  126. def test_newly_uploaded_css_file_replaces_old_one_if_file_names_are_same(
  127. upload, theme, css_file
  128. ):
  129. with open(css_file) as fp:
  130. upload(theme, fp)
  131. original_css = theme.css.get()
  132. with open(os.path.join(TESTS_DIR, "css", "test-changed.css")) as fp:
  133. size = len(fp.read())
  134. fp.seek(0)
  135. upload(
  136. theme, UploadedFile(fp, name="test.css", content_type="text/css", size=size)
  137. )
  138. updated_css = theme.css.last()
  139. assert updated_css.name == original_css.name
  140. assert updated_css.source_hash != original_css.source_hash
  141. assert theme.css.count() == 1
  142. def test_newly_uploaded_css_file_reuses_replaced_file_order_if_names_are_same(
  143. upload, theme, css_file, hashed_css_file
  144. ):
  145. with open(css_file) as fp:
  146. upload(theme, fp)
  147. original_css = theme.css.last()
  148. with open(hashed_css_file) as fp:
  149. upload(theme, fp)
  150. with open(os.path.join(TESTS_DIR, "css", "test-changed.css")) as fp:
  151. size = len(fp.read())
  152. fp.seek(0)
  153. upload(
  154. theme, UploadedFile(fp, name="test.css", content_type="text/css", size=size)
  155. )
  156. updated_css = theme.css.get(order=original_css.order)
  157. assert updated_css.name == original_css.name
  158. def test_error_message_is_set_if_no_css_file_was_uploaded(upload, theme):
  159. response = upload(theme)
  160. assert_has_error_message(response)
  161. def test_error_message_is_set_if_user_attempts_to_upload_css_file_to_default_theme(
  162. upload, default_theme
  163. ):
  164. response = upload(default_theme)
  165. assert_has_error_message(response)
  166. def test_error_message_is_set_if_user_attempts_to_upload_css_file_to_nonexisting_theme(
  167. upload, nonexisting_theme
  168. ):
  169. response = upload(nonexisting_theme)
  170. assert_has_error_message(response)