Skip to content

Commit

Permalink
Merge pull request #11 from tle-ko/hepheir/issue7
Browse files Browse the repository at this point in the history
Problem Statistics API 동작하도록 수정했습니다
  • Loading branch information
hepheir authored Sep 4, 2024
2 parents 26c2b45 + 3038736 commit aa3ded2
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 14 deletions.
22 changes: 22 additions & 0 deletions app/apps/crews/activities/fixtures/single_activity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"model": "activities.crewactivity",
"pk": 1,
"fields": {
"crew": 1,
"name": "1회차",
"start_at": "2024-08-01T17:04:27",
"end_at": "2024-08-31T17:04:31"
}
},
{
"model": "activities.crewactivityproblem",
"pk": 1,
"fields": {
"crew": 1,
"activity": 1,
"problem": 1,
"order": 1
}
}
]
26 changes: 26 additions & 0 deletions app/apps/crews/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,29 @@ def test_201_크루_생성(self):
"is_active": True
})
self.assertEqual(res.status_code, status.HTTP_201_CREATED, res.json())


class CrewStatisticsAPIViewTest(TestCase):
fixtures = ['sample.json', 'single_activity']
maxDiff = None

def setUp(self) -> None:
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)

def test_200_ok(self) -> None:
res = self.client.get("/api/v1/crew/1/statistics")
self.assertEqual(res.status_code, status.HTTP_200_OK)

def test_200_응답_데이터_형식_검사(self) -> None:
res = self.client.get("/api/v1/crew/1/statistics")
self.assertDictEqual(res.json(), {
"difficulties": [
{
"difficulty": 0,
"problem_count": 1,
"ratio": 1,
},
],
"tags": [],
})
2 changes: 1 addition & 1 deletion app/apps/problems/analyses/dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ class ProblemTagDTO:
name_en: str

def __hash__(self) -> int:
return self.key
return hash(self.key)
21 changes: 16 additions & 5 deletions app/apps/problems/models.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
from __future__ import annotations

from typing import Optional

from django.db import models

from apps.problems.dto import ProblemDTO
from apps.problems.enums import Unit
from users.models import User


class ProblemrManager(models.Manager):
def filter(self,
created_by: Optional[User] = None,
**kwargs) -> models.QuerySet[Problem]:
extra_kwargs = {}
if created_by is not None:
extra_kwargs[Problem.field_name.CREATED_BY] = created_by
return self.filter(**(extra_kwargs | kwargs))


class Problem(models.Model):
title = models.CharField(
max_length=100,
help_text='문제 이름을 입력해주세요.',
blank=False,
)
link = models.URLField(
help_text='문제 링크를 입력해주세요. (선택)',
blank=True,
)
description = models.TextField(
help_text='문제 설명을 입력해주세요.',
blank=False,
)
input_description = models.TextField(
help_text='문제 입력 설명을 입력해주세요.',
blank=True,
)
output_description = models.TextField(
help_text='문제 출력 설명을 입력해주세요.',
blank=True,
)
memory_limit = models.FloatField(
help_text='문제 메모리 제한을 입력해주세요. (MB 단위)',
Expand All @@ -36,7 +46,6 @@ class Problem(models.Model):
)
time_limit = models.FloatField(
help_text='문제 시간 제한을 입력해주세요. (초 단위)',
default=1.0,
)
time_limit_unit = models.TextField(
choices=Unit.choices,
Expand All @@ -51,6 +60,8 @@ class Problem(models.Model):
)
updated_at = models.DateTimeField(auto_now=True)

objects: ProblemrManager = ProblemrManager()

class field_name:
TITLE = 'title'
LINK = 'link'
Expand Down
2 changes: 1 addition & 1 deletion app/apps/problems/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class Meta:


class ProblemStatisticSerializer(serializers.Serializer):
difficulty = ProblemStatisticsDifficultyField()
difficulties = ProblemStatisticsDifficultyField()
tags = ProblemStatisticsTagsField()

def __init__(self, instance: ProblemStatisticDTO = None, **kwargs):
Expand Down
73 changes: 73 additions & 0 deletions app/apps/problems/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from django.test import TestCase
from rest_framework import status

from apps.problems.models import Problem
from users.models import User


class ProblemCreateAPIViewTest(TestCase):
fixtures = ['sample.json']
maxDiff = None

def setUp(self) -> None:
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)
self.sample_data = {
"title": "Test Problem",
"link": "https://boj.kr/1000",
"description": "테스트용 문제입니다.",
"input_description": "입력이 없습니다.",
"output_description": "출력이 없습니다.",
"memory_limit": 0,
"time_limit": 0,
}
self.required_fields = [
"title",
"description",
"input_description",
"output_description",
"memory_limit",
"time_limit",
]

def test_201_문제_생성(self):
res = self.client.post("/api/v1/problem", self.sample_data)
self.assertEqual(res.status_code, status.HTTP_201_CREATED)

def test_401_비로그인_사용_불가(self):
self.client.logout()
res = self.client.post("/api/v1/problem", self.sample_data)
self.assertEqual(res.status_code, status.HTTP_401_UNAUTHORIZED)

def test_201_링크가_누락_되어도_문제_생성_가능(self):
data = self.sample_data.copy()
del data['link']
res = self.client.post("/api/v1/problem", data)
self.assertEqual(res.status_code, status.HTTP_201_CREATED)

def test_400_일부_필드_누락(self):
for drop_field in self.required_fields:
with self.subTest(drop_field=drop_field):
res = self.client.post("/api/v1/problem", {
field: self.sample_data[field]
for field in self.required_fields if field != drop_field
})
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)


class ProblemDetailRetrieveAPIViewTest(TestCase):
fixtures = ['sample.json']
maxDiff = None

def setUp(self) -> None:
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)

def test_200_문제_정보_가져오기(self):
problem = Problem.objects.get(pk=1)
res = self.client.get(f"/api/v1/problem/{problem.pk}/detail")
self.assertEqual(res.status_code, status.HTTP_200_OK)

def test_404(self):
res = self.client.get(f"/api/v1/problem/999/detail")
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
2 changes: 1 addition & 1 deletion app/apps/problems/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
urlpatterns = [
path("problems", views.ProblemSearchListAPIView.as_view()),
path("problem", views.ProblemCreateAPIView.as_view()),
path("problem/<int:id>/detail", views.ProblemDetailRetrieveUpdateDestroyAPIView.as_view()),
path("problem/<int:problem_id>/detail", views.ProblemDetailRetrieveUpdateDestroyAPIView.as_view()),
]
17 changes: 11 additions & 6 deletions app/apps/problems/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@


class ProblemCreateAPIView(generics.CreateAPIView):
"""문제 생성 API"""
"""문제 생성 API.
."""

queryset = models.Problem.objects.all()
permission_classes = [permissions.IsAuthenticated]
Expand All @@ -31,21 +33,24 @@ def create(self, request, *args, **kwargs):


class ProblemDetailRetrieveUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
"""문제 상세 조회, 수정, 삭제 API"""
"""문제 상세 조회, 수정, 삭제 API.
."""

queryset = models.Problem.objects.all()
permission_classes = [permissions.IsAuthenticated]
serializer_class = serializers.ProblemDetailSerializer
lookup_field = 'id'
lookup_url_kwarg = 'problem_id'


class ProblemSearchListAPIView(generics.ListAPIView):
"""문제 검색 API"""
"""문제 검색 API.
."""

permission_classes = [permissions.IsAuthenticated]
serializer_class = serializers.ProblemMinimalSerializer

def get_queryset(self):
return models.Problem.objects.filter(**{
models.Problem.field_name.CREATED_BY: self.request.user,
})
return models.Problem.objects.filter(created_by=self.request.user)

0 comments on commit aa3ded2

Please sign in to comment.