test_uploading_media.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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 png_file():
  9. return os.path.join(TESTS_DIR, "images", "test.png")
  10. @pytest.fixture
  11. def svg_file():
  12. return os.path.join(TESTS_DIR, "images", "test.svg")
  13. @pytest.fixture
  14. def hashable_file():
  15. return os.path.join(TESTS_DIR, "css", "test.css")
  16. @pytest.fixture
  17. def hashed_file():
  18. return os.path.join(TESTS_DIR, "css", "test.4846cb3b.css")
  19. @pytest.fixture
  20. def upload(admin_client):
  21. def post_upload(theme, asset_files=None):
  22. url = reverse("misago:admin:themes:upload-media", kwargs={"pk": theme.pk})
  23. if asset_files is not None:
  24. data = asset_files if isinstance(asset_files, list) else [asset_files]
  25. else:
  26. data = ""
  27. return admin_client.post(url, {"assets": data})
  28. return post_upload
  29. def test_font_file_can_be_uploaded(upload, theme):
  30. font_file = os.path.join(TESTS_DIR, "font", "Lato.ttf")
  31. with open(font_file, "rb") as fp:
  32. upload(theme, fp)
  33. assert theme.media.exists()
  34. def test_text_file_can_be_uploaded(upload, theme):
  35. text_file = os.path.join(TESTS_DIR, "font", "OFL.txt")
  36. with open(text_file) as fp:
  37. upload(theme, fp)
  38. assert theme.media.exists()
  39. def test_svg_file_can_be_uploaded(upload, theme):
  40. svg_file = os.path.join(TESTS_DIR, "images", "test.svg")
  41. with open(svg_file) as fp:
  42. upload(theme, fp)
  43. assert theme.media.exists()
  44. def test_png_file_can_be_uploaded(upload, theme, png_file):
  45. with open(png_file, "rb") as fp:
  46. upload(theme, fp)
  47. assert theme.media.exists()
  48. def test_media_file_name_is_set_as_asset_name(upload, theme, svg_file):
  49. with open(svg_file) as fp:
  50. upload(theme, fp)
  51. media = theme.media.last()
  52. expected_filename = str(svg_file).split("/")[-1]
  53. assert media.name == expected_filename
  54. def test_media_file_is_uploaded_to_theme_directory(upload, theme, svg_file):
  55. with open(svg_file) as fp:
  56. upload(theme, fp)
  57. media = theme.media.last()
  58. assert theme.dirname in str(media.file)
  59. def test_hash_is_added_to_uploaded_media_file_name(
  60. upload, theme, hashable_file, hashed_file
  61. ):
  62. with open(hashable_file) as fp:
  63. upload(theme, fp)
  64. media = theme.media.last()
  65. filename = str(media.file.path).split("/")[-1]
  66. expected_filename = str(hashed_file).split("/")[-1]
  67. assert filename == expected_filename
  68. def test_hash_is_set_on_media_asset(upload, theme, hashed_file):
  69. with open(hashed_file) as fp:
  70. upload(theme, fp)
  71. media = theme.media.last()
  72. assert media.hash
  73. def test_media_file_name_is_preserved_if_it_already_contains_correct_hash(
  74. upload, theme, hashed_file
  75. ):
  76. with open(hashed_file) as fp:
  77. upload(theme, fp)
  78. media = theme.media.last()
  79. filename = str(media.file.path).split("/")[-1]
  80. expected_filename = str(hashed_file).split("/")[-1]
  81. assert filename == expected_filename
  82. def test_new_hash_is_added_to_media_file_name_if_it_contains_incorrect_hash(
  83. upload, theme
  84. ):
  85. incorrectly_hashed_file = os.path.join(TESTS_DIR, "css", "test.0046cb3b.css")
  86. with open(incorrectly_hashed_file) as fp:
  87. upload(theme, fp)
  88. media = theme.media.last()
  89. filename = str(media.file.path).split("/")[-1]
  90. assert media.hash in filename
  91. def test_newly_uploaded_media_file_replaces_old_one_if_file_names_are_same(
  92. upload, theme, hashable_file
  93. ):
  94. with open(hashable_file) as fp:
  95. upload(theme, fp)
  96. original_media = theme.media.get()
  97. with open(os.path.join(TESTS_DIR, "css", "test-changed.css")) as fp:
  98. size = len(fp.read())
  99. fp.seek(0)
  100. upload(
  101. theme, UploadedFile(fp, name="test.css", content_type="text/css", size=size)
  102. )
  103. updated_media = theme.media.last()
  104. assert updated_media.name == original_media.name
  105. assert updated_media.hash != original_media.hash
  106. assert theme.media.count() == 1
  107. def test_image_dimensions_are_set_for_uploaded_image_file(upload, theme, png_file):
  108. with open(png_file, "rb") as fp:
  109. upload(theme, fp)
  110. media = theme.media.last()
  111. assert media.width
  112. assert media.height
  113. def test_thumbnail_is_generated_in_theme_directory_for_uploaded_image_file(
  114. upload, theme, png_file
  115. ):
  116. with open(png_file, "rb") as fp:
  117. upload(theme, fp)
  118. media = theme.media.last()
  119. assert theme.dirname in str(media.thumbnail)
  120. def test_uploading_media_triggers_css_build(
  121. upload, theme, png_file, mock_build_theme_css
  122. ):
  123. with open(png_file, "rb") as fp:
  124. upload(theme, fp)
  125. mock_build_theme_css.assert_called_once_with(theme.pk)
  126. def test_error_message_is_set_if_no_media_was_uploaded(upload, theme):
  127. response = upload(theme)
  128. assert_has_error_message(response)
  129. def test_error_message_is_set_if_user_attempts_to_upload_file_to_default_theme(
  130. upload, default_theme
  131. ):
  132. response = upload(default_theme)
  133. assert_has_error_message(response)
  134. def test_error_message_is_set_if_user_attempts_to_upload_file_to_nonexisting_theme(
  135. upload, nonexisting_theme
  136. ):
  137. response = upload(nonexisting_theme)
  138. assert_has_error_message(response)