diff --git a/photo/queries.py b/photo/queries.py index 952b969..94fc159 100644 --- a/photo/queries.py +++ b/photo/queries.py @@ -30,9 +30,13 @@ CollectionType, ContestSubmissionType, ContestType, + ContestWithWinnersType, + ContestWinnerType, PictureCommentType, PictureType, UserType, + WinnerSubmissionType, + WinnerSubmissionPictureType, ) from utils.enums import ContestInternalStates @@ -130,3 +134,42 @@ def set_order(element): else: query_results.sort(key=set_order) return query_results + + @strawberry.field + def contest_winners(self) -> List[ContestWithWinnersType]: + contests = Contest.objects.filter(winners__isnull=False).distinct().order_by('voting_draw_end') + result = [] + + for contest in contests: + winners = [] + for winner in contest.winners.all(): + submission = ContestSubmission.objects.filter( + contest=contest, + picture__user=winner + ).first() + + if submission: + winner_data = ContestWinnerType( + name_first=winner.name_first, + name_last=winner.name_last, + submission=WinnerSubmissionType( + picture=WinnerSubmissionPictureType( + name=submission.picture.name, + file=str(submission.picture.file) + ), + number_votes=submission.votes.count() + ) + ) + winners.append(winner_data) + + if winners: + contest_data = ContestWithWinnersType( + title=contest.title, + description=contest.description, + prize=contest.prize or "", + voting_draw_end=str(contest.voting_draw_end), + winners=winners + ) + result.append(contest_data) + + return result diff --git a/photo/tests/test_queries/graphql_queries.py b/photo/tests/test_queries/graphql_queries.py index 3a1875f..59e7f93 100644 --- a/photo/tests/test_queries/graphql_queries.py +++ b/photo/tests/test_queries/graphql_queries.py @@ -228,3 +228,25 @@ } } """ + +CONTEST_WINNERS_QUERY = """ + query { + contestWinners { + title + description + prize + voting_draw_end + winners { + name_first + name_last + submission { + picture { + name + file + } + number_votes + } + } + } + } +""" diff --git a/photo/tests/test_queries/test_contest_winners.py b/photo/tests/test_queries/test_contest_winners.py new file mode 100644 index 0000000..0759905 --- /dev/null +++ b/photo/tests/test_queries/test_contest_winners.py @@ -0,0 +1,102 @@ +import pytest +from django.utils import timezone + +from photo.models import Contest, ContestSubmission, Picture, User +from photo.tests.test_queries.graphql_queries import CONTEST_WINNERS_QUERY +from utils.enums import ContestInternalStates + +pytestmark = pytest.mark.django_db + + +def test_contest_winners_query(client): + # Create test users + user1 = User.objects.create( + email="user1@test.com", + name_first="User", + name_last="One" + ) + user2 = User.objects.create( + email="user2@test.com", + name_first="User", + name_last="Two" + ) + + # Create test pictures + picture1 = Picture.objects.create( + user=user1, + name="Picture 1", + file="test1.jpg" + ) + picture2 = Picture.objects.create( + user=user2, + name="Picture 2", + file="test2.jpg" + ) + + # Create test contests + contest1 = Contest.objects.create( + title="Contest 1", + description="Test Contest 1", + prize="Prize 1", + voting_draw_end=timezone.now(), + internal_status=ContestInternalStates.CLOSED + ) + contest2 = Contest.objects.create( + title="Contest 2", + description="Test Contest 2", + prize="Prize 2", + voting_draw_end=timezone.now() + timezone.timedelta(days=1), + internal_status=ContestInternalStates.CLOSED + ) + + # Create submissions + submission1 = ContestSubmission.objects.create( + contest=contest1, + picture=picture1 + ) + submission2 = ContestSubmission.objects.create( + contest=contest2, + picture=picture2 + ) + + # Add votes to submissions + submission1.votes.add(user2) + submission2.votes.add(user1) + + # Add winners to contests + contest1.winners.add(user1) + contest2.winners.add(user2) + + # Execute query + response = client.post( + "/graphql/", + {"query": CONTEST_WINNERS_QUERY}, + content_type="application/json", + ) + + # Check response + assert response.status_code == 200 + data = response.json()["data"]["contestWinners"] + assert len(data) == 2 + + # Check first contest + assert data[0]["title"] == "Contest 1" + assert data[0]["description"] == "Test Contest 1" + assert data[0]["prize"] == "Prize 1" + assert len(data[0]["winners"]) == 1 + assert data[0]["winners"][0]["name_first"] == "User" + assert data[0]["winners"][0]["name_last"] == "One" + assert data[0]["winners"][0]["submission"]["picture"]["name"] == "Picture 1" + assert data[0]["winners"][0]["submission"]["picture"]["file"] == "test1.jpg" + assert data[0]["winners"][0]["submission"]["number_votes"] == 1 + + # Check second contest + assert data[1]["title"] == "Contest 2" + assert data[1]["description"] == "Test Contest 2" + assert data[1]["prize"] == "Prize 2" + assert len(data[1]["winners"]) == 1 + assert data[1]["winners"][0]["name_first"] == "User" + assert data[1]["winners"][0]["name_last"] == "Two" + assert data[1]["winners"][0]["submission"]["picture"]["name"] == "Picture 2" + assert data[1]["winners"][0]["submission"]["picture"]["file"] == "test2.jpg" + assert data[1]["winners"][0]["submission"]["number_votes"] == 1 diff --git a/photo/types.py b/photo/types.py index e63affc..2c8c453 100644 --- a/photo/types.py +++ b/photo/types.py @@ -134,3 +134,31 @@ class CloseContestMutationResponse: success: bool results: ContestType errors: str + + +@strawberry.type +class WinnerSubmissionPictureType: + name: str + file: str + + +@strawberry.type +class WinnerSubmissionType: + picture: WinnerSubmissionPictureType + number_votes: int + + +@strawberry.type +class ContestWinnerType: + name_first: str + name_last: str + submission: WinnerSubmissionType + + +@strawberry.type +class ContestWithWinnersType: + title: str + description: str + prize: str + voting_draw_end: str + winners: List[ContestWinnerType]