Skip to content

Commit c42ef19

Browse files
authored
fix: Fix behavior for duplicate uploads to match legacy client expectations (#43)
- Fix pytest logging
1 parent 63191ec commit c42ef19

3 files changed

Lines changed: 88 additions & 1 deletion

File tree

kirovy/settings/testing.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,31 @@
1515
}
1616
}
1717

18+
LOGGING = {
19+
"version": 1,
20+
"disable_existing_loggers": False,
21+
"formatters": {
22+
"tests_logging": {
23+
"()": structlog.stdlib.ProcessorFormatter,
24+
"processor": structlog.dev.ConsoleRenderer(),
25+
},
26+
},
27+
"handlers": {
28+
"pytest_console": {
29+
"class": "logging.StreamHandler",
30+
"formatter": "tests_logging",
31+
},
32+
},
33+
"loggers": {
34+
"kirovy": {
35+
"handlers": ["pytest_console"],
36+
"level": "DEBUG",
37+
},
38+
"django_structlog": {
39+
"handlers": ["pytest_console"],
40+
"level": "DEBUG",
41+
},
42+
},
43+
}
44+
1845
# MEDIA_ROOT gets modified in common_fixtures.py in the tmp_media_root fixture.

kirovy/views/map_upload_views.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,31 @@ def post(self, request: KirovyRequest, format=None) -> KirovyResponse:
390390
legacy_map_service = legacy_upload.get_legacy_service_for_slug(game.slug.lower())(uploaded_file)
391391

392392
map_hashes = self._get_file_hashes(ContentFile(legacy_map_service.file_contents_merged.read()))
393-
self.verify_file_does_not_exist(map_hashes)
393+
try:
394+
self.verify_file_does_not_exist(map_hashes)
395+
except KirovyValidationError:
396+
# The old database just accepts duplicate uploads as if the map didn't exist.
397+
# The client expects a successful upload in this scenario, so we need to mirror that.
398+
_LOGGER.debug(
399+
"Map already exists. Backwards compatible endpoint, returning success",
400+
map_hash=map_hashes.sha1,
401+
client_info=self.user_log_attrs,
402+
)
403+
existing_file = cnc_map.CncMapFile.objects.prefetch_related("cnc_map").get(hash_sha1=map_hashes.sha1)
404+
405+
return KirovyResponse(
406+
ResultResponseData(
407+
message="Upload succeeded!",
408+
result={
409+
"cnc_map": existing_file.cnc_map.map_name,
410+
"cnc_map_file": existing_file.file.url,
411+
"cnc_map_id": existing_file.cnc_map_id,
412+
"extracted_preview_file": None,
413+
"download_url": f"/{game.slug}/{existing_file.hash_sha1}.zip",
414+
},
415+
),
416+
status=status.HTTP_200_OK,
417+
)
394418

395419
# Make the map that we will attach the map file to.
396420
new_map = cnc_map.CncMap(

tests/test_views/test_backwards_compatibility.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from kirovy import typing as t
1111
from kirovy.models import CncGame, CncMapFile, CncMap
12+
from kirovy.objects.ui_objects import ResultResponseData
1213
from kirovy.response import KirovyResponse
1314

1415
if t.TYPE_CHECKING:
@@ -128,3 +129,38 @@ def _download_and_check_hash(
128129
assert cnc_map_file.cnc_map.map_name == expected_map_name
129130
if ip_address:
130131
assert cnc_map_file.ip_address == ip_address
132+
133+
134+
def test_map_upload_duplicate_file_backwards_compatible(
135+
client_anonymous,
136+
zip_map_for_legacy_upload,
137+
file_map_desert,
138+
game_yuri,
139+
):
140+
"""
141+
Test duplicate uploads for backwards compatible uploads.
142+
Duplicates should just return successful like the old database.
143+
"""
144+
url = "/upload"
145+
original_extension = pathlib.Path(file_map_desert.name).suffix
146+
upload_file, file_sha1 = zip_map_for_legacy_upload(file_map_desert)
147+
upload_response: KirovyResponse[ResultResponseData] = client_anonymous.post(
148+
url, {"file": upload_file, "game": game_yuri.slug}, format="multipart", content_type=None, REMOTE_ADDR="2.2.2.2"
149+
)
150+
151+
assert upload_response.status_code == status.HTTP_200_OK
152+
assert upload_response.data["result"]["download_url"] == f"/{game_yuri.slug}/{file_sha1}.zip"
153+
original_map_id = upload_response.data["result"]["cnc_map_id"]
154+
155+
_download_and_check_hash(
156+
client_anonymous, file_sha1, game_yuri, "desert", [original_extension], ip_address="2.2.2.2"
157+
)
158+
159+
upload_file.seek(0)
160+
duplicate_upload_response: KirovyResponse[ResultResponseData] = client_anonymous.post(
161+
url, {"file": upload_file, "game": game_yuri.slug}, format="multipart", content_type=None, REMOTE_ADDR="1.2.2.2"
162+
)
163+
164+
assert duplicate_upload_response.status_code == status.HTTP_200_OK
165+
assert duplicate_upload_response.data["message"] == "Upload succeeded!"
166+
assert duplicate_upload_response.data["result"]["cnc_map_id"] == original_map_id

0 commit comments

Comments
 (0)