151 lines
6.1 KiB
Python
151 lines
6.1 KiB
Python
from unittest.mock import patch
|
|
|
|
from discgolf.models import DiscGolfCourse
|
|
from discgolf.utils import _parse_udisc_datetime, import_udisc_csv
|
|
from people.models import Person
|
|
from scrobbles.models import Scrobble
|
|
|
|
|
|
class TestParserHelpers:
|
|
def test_parse_udisc_datetime(self):
|
|
dt = _parse_udisc_datetime("Jun 15, 2026 10:00 AM")
|
|
assert dt is not None
|
|
assert dt.year == 2026
|
|
assert dt.month == 6
|
|
assert dt.day == 15
|
|
assert dt.hour == 10
|
|
assert dt.minute == 0
|
|
|
|
def test_parse_udisc_datetime_date_only(self):
|
|
dt = _parse_udisc_datetime("Jun 15, 2026")
|
|
assert dt is not None
|
|
assert dt.year == 2026
|
|
|
|
|
|
class TestImportUdiscCSV:
|
|
def test_import_singles_creates_course(self, user, udisc_singles_csv_file):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
course = DiscGolfCourse.objects.filter(title="Maple Hill").first()
|
|
assert course is not None
|
|
assert course.layout_name == "Mountains"
|
|
assert course.number_of_holes == 3
|
|
assert course.par_total == 9
|
|
assert course.par_per_hole == {"hole_1": 3, "hole_2": 3, "hole_3": 3}
|
|
|
|
def test_import_singles_creates_scrobble(self, user, udisc_singles_csv_file):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
assert Scrobble.objects.filter(source="uDisc").count() == 1
|
|
|
|
def test_import_singles_logdata(self, user, udisc_singles_csv_file):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
scrobble = Scrobble.objects.filter(source="uDisc").first()
|
|
log = scrobble.log
|
|
assert log["course_name"] == "Maple Hill"
|
|
assert log["par"] == 9
|
|
assert log["round_type"] == "Singles"
|
|
assert "Alice" in log["scores"]
|
|
assert "Bob" in log["scores"]
|
|
assert log["scores"]["Alice"]["total"] == 9
|
|
assert log["scores"]["Bob"]["total"] == 12
|
|
|
|
def test_import_singles_creates_people(self, user, udisc_singles_csv_file):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
assert Person.objects.filter(name="Alice").exists()
|
|
assert Person.objects.filter(name="Bob").exists()
|
|
|
|
def test_import_teams_creates_scrobble(self, user, udisc_teams_csv_file):
|
|
import_udisc_csv(udisc_teams_csv_file, user.id)
|
|
assert Scrobble.objects.filter(source="uDisc").count() == 1
|
|
|
|
def test_import_teams_logdata(self, user, udisc_teams_csv_file):
|
|
import_udisc_csv(udisc_teams_csv_file, user.id)
|
|
scrobble = Scrobble.objects.filter(source="uDisc").first()
|
|
assert scrobble.log["round_type"] == "Teams"
|
|
alice_bob = scrobble.log["scores"]["Alice+Bob"]
|
|
assert "person_ids" in alice_bob
|
|
assert len(alice_bob["person_ids"]) == 2
|
|
|
|
def test_import_creates_team_people(self, user, udisc_teams_csv_file):
|
|
import_udisc_csv(udisc_teams_csv_file, user.id)
|
|
assert Person.objects.filter(name="Alice").exists()
|
|
assert Person.objects.filter(name="Bob").exists()
|
|
assert Person.objects.filter(name="Charlie").exists()
|
|
assert Person.objects.filter(name="Diana").exists()
|
|
|
|
def test_import_teams_par_per_hole(self, user, udisc_teams_csv_file):
|
|
import_udisc_csv(udisc_teams_csv_file, user.id)
|
|
course = DiscGolfCourse.objects.get(title="Maple Hill")
|
|
assert course.par_per_hole == {"hole_1": 3, "hole_2": 3, "hole_3": 3}
|
|
|
|
def test_import_no_par_returns_empty(self, user, udisc_csv_no_par_file):
|
|
result = import_udisc_csv(udisc_csv_no_par_file, user.id)
|
|
assert result == []
|
|
|
|
def test_import_empty_csv(self, user, db):
|
|
import tempfile
|
|
|
|
with tempfile.NamedTemporaryFile(
|
|
mode="w", suffix=".csv", delete=False, encoding="utf-8-sig"
|
|
) as f:
|
|
f.write("PlayerName,CourseName,LayoutName,StartDate,Hole1,Total\n")
|
|
path = f.name
|
|
|
|
result = import_udisc_csv(path, user.id)
|
|
assert result == []
|
|
|
|
def test_import_idempotent(self, user, udisc_singles_csv_file):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
assert DiscGolfCourse.objects.filter(title="Maple Hill").count() == 1
|
|
assert Scrobble.objects.filter(source="uDisc").count() == 2
|
|
|
|
def test_import_course_defaults_only_on_create(
|
|
self, user, udisc_singles_csv_file
|
|
):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
course = DiscGolfCourse.objects.get(title="Maple Hill")
|
|
assert course.layout_name == "Mountains"
|
|
|
|
course.layout_name = "Updated"
|
|
course.save()
|
|
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
course.refresh_from_db()
|
|
assert course.layout_name == "Updated"
|
|
|
|
@patch("discgolf.utils.ScrobbleNtfyNotification")
|
|
def test_import_sends_notification(self, mock_notification_class, user, udisc_singles_csv_file):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
mock_notification_class.assert_called_once()
|
|
mock_notification_class.return_value.send.assert_called_once()
|
|
|
|
def test_import_hole_scores_per_player(self, user, udisc_singles_csv_file):
|
|
import_udisc_csv(udisc_singles_csv_file, user.id)
|
|
scrobble = Scrobble.objects.filter(source="uDisc").first()
|
|
alice = scrobble.log["scores"]["Alice"]
|
|
assert alice["hole_1"] == 4
|
|
assert alice["hole_2"] == 2
|
|
assert alice["hole_3"] == 3
|
|
bob = scrobble.log["scores"]["Bob"]
|
|
assert bob["hole_1"] == 3
|
|
assert bob["hole_2"] == 4
|
|
assert bob["hole_3"] == 5
|
|
|
|
def test_import_record_error_on_bad_data(self, user, db):
|
|
import tempfile
|
|
|
|
content = """PlayerName,CourseName,LayoutName,StartDate,Hole1,Hole2,Hole3,Total
|
|
Par,,Mountains,"Jun 15, 2026 10:00 AM",3,3,3,9
|
|
"""
|
|
with tempfile.NamedTemporaryFile(
|
|
mode="w", suffix=".csv", delete=False, encoding="utf-8-sig"
|
|
) as f:
|
|
f.write(content)
|
|
path = f.name
|
|
|
|
errors = []
|
|
result = import_udisc_csv(path, user.id, record_error=errors.append)
|
|
assert len(result) == 1
|
|
course = DiscGolfCourse.objects.first()
|
|
assert course.title == ""
|