mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 08:23:20 +00:00
添加contest权限验证、contest密码验证api
添加problem、contest单元测试。
This commit is contained in:
parent
53d0cae8ea
commit
ee49d0a815
@ -27,7 +27,7 @@ class EditConetestSeriaizer(serializers.Serializer):
|
|||||||
real_time_rank = serializers.BooleanField()
|
real_time_rank = serializers.BooleanField()
|
||||||
|
|
||||||
|
|
||||||
class ContestSerializer(serializers.ModelSerializer):
|
class ContestAdminSerializer(serializers.ModelSerializer):
|
||||||
start_time = DateTimeTZField()
|
start_time = DateTimeTZField()
|
||||||
end_time = DateTimeTZField()
|
end_time = DateTimeTZField()
|
||||||
create_time = DateTimeTZField()
|
create_time = DateTimeTZField()
|
||||||
@ -36,6 +36,11 @@ class ContestSerializer(serializers.ModelSerializer):
|
|||||||
status = serializers.CharField()
|
status = serializers.CharField()
|
||||||
contest_type = serializers.CharField()
|
contest_type = serializers.CharField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Contest
|
||||||
|
|
||||||
|
|
||||||
|
class ContestSerializer(ContestAdminSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Contest
|
model = Contest
|
||||||
exclude = ('password', 'visible')
|
exclude = ('password', 'visible')
|
||||||
|
@ -74,6 +74,16 @@ class ContestAPITest(APITestCase):
|
|||||||
response = self.client.get("{}?id={}".format(self.url, contest_id))
|
response = self.client.get("{}?id={}".format(self.url, contest_id))
|
||||||
self.assertSuccess(response)
|
self.assertSuccess(response)
|
||||||
|
|
||||||
|
def test_contest_password(self):
|
||||||
|
contest_id = self.create_contest().data["data"]["id"]
|
||||||
|
self.create_user("test", "test123")
|
||||||
|
url = self.reverse("contest_password_api")
|
||||||
|
resp = self.client.post(url, {"contest_id": contest_id, "password": "error_password"})
|
||||||
|
self.assertFailed(resp)
|
||||||
|
|
||||||
|
resp = self.client.post(url, {"contest_id": contest_id, "password": DEFAULT_CONTEST_DATA["password"]})
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
|
||||||
|
|
||||||
class ContestAnnouncementAPITest(APITestCase):
|
class ContestAnnouncementAPITest(APITestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from ..views.oj import ContestAnnouncementListAPI, ContestAPI
|
from ..views.oj import ContestAnnouncementListAPI, ContestAPI
|
||||||
|
from ..views.oj import ContestPasswordVerifyAPI
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r"^contest/?$", ContestAPI.as_view(), name="contest_api"),
|
url(r"^contest/?$", ContestAPI.as_view(), name="contest_api"),
|
||||||
|
url(r"^contest/password/?$", ContestPasswordVerifyAPI.as_view(), name="contest_password_api"),
|
||||||
url(r"^contest/announcement/?$", ContestAnnouncementListAPI.as_view(), name="contest_announcement_api"),
|
url(r"^contest/announcement/?$", ContestAnnouncementListAPI.as_view(), name="contest_announcement_api"),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -3,7 +3,7 @@ import dateutil.parser
|
|||||||
from utils.api import APIView, validate_serializer
|
from utils.api import APIView, validate_serializer
|
||||||
|
|
||||||
from ..models import Contest, ContestAnnouncement
|
from ..models import Contest, ContestAnnouncement
|
||||||
from ..serializers import (ContestAnnouncementSerializer, ContestSerializer,
|
from ..serializers import (ContestAnnouncementSerializer, ContestAdminSerializer,
|
||||||
CreateConetestSeriaizer,
|
CreateConetestSeriaizer,
|
||||||
CreateContestAnnouncementSerializer,
|
CreateContestAnnouncementSerializer,
|
||||||
EditConetestSeriaizer)
|
EditConetestSeriaizer)
|
||||||
@ -21,7 +21,7 @@ class ContestAPI(APIView):
|
|||||||
if not data["password"]:
|
if not data["password"]:
|
||||||
data["password"] = None
|
data["password"] = None
|
||||||
contest = Contest.objects.create(**data)
|
contest = Contest.objects.create(**data)
|
||||||
return self.success(ContestSerializer(contest).data)
|
return self.success(ContestAdminSerializer(contest).data)
|
||||||
|
|
||||||
@validate_serializer(EditConetestSeriaizer)
|
@validate_serializer(EditConetestSeriaizer)
|
||||||
def put(self, request):
|
def put(self, request):
|
||||||
@ -41,7 +41,7 @@ class ContestAPI(APIView):
|
|||||||
for k, v in data.items():
|
for k, v in data.items():
|
||||||
setattr(contest, k, v)
|
setattr(contest, k, v)
|
||||||
contest.save()
|
contest.save()
|
||||||
return self.success(ContestSerializer(contest).data)
|
return self.success(ContestAdminSerializer(contest).data)
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
contest_id = request.GET.get("id")
|
contest_id = request.GET.get("id")
|
||||||
@ -50,7 +50,7 @@ class ContestAPI(APIView):
|
|||||||
contest = Contest.objects.get(id=contest_id)
|
contest = Contest.objects.get(id=contest_id)
|
||||||
if request.user.is_admin() and contest.created_by != request.user:
|
if request.user.is_admin() and contest.created_by != request.user:
|
||||||
return self.error("Contest does not exist")
|
return self.error("Contest does not exist")
|
||||||
return self.success(ContestSerializer(contest).data)
|
return self.success(ContestAdminSerializer(contest).data)
|
||||||
except Contest.DoesNotExist:
|
except Contest.DoesNotExist:
|
||||||
return self.error("Contest does not exist")
|
return self.error("Contest does not exist")
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class ContestAPI(APIView):
|
|||||||
|
|
||||||
if request.user.is_admin():
|
if request.user.is_admin():
|
||||||
contests = contests.filter(created_by=request.user)
|
contests = contests.filter(created_by=request.user)
|
||||||
return self.success(self.paginate_data(request, contests, ContestSerializer))
|
return self.success(self.paginate_data(request, contests, ContestAdminSerializer))
|
||||||
|
|
||||||
|
|
||||||
class ContestAnnouncementAPI(APIView):
|
class ContestAnnouncementAPI(APIView):
|
||||||
|
@ -38,7 +38,7 @@ class ContestAPI(APIView):
|
|||||||
class ContestPasswordVerifyAPI(APIView):
|
class ContestPasswordVerifyAPI(APIView):
|
||||||
@validate_serializer(ContestPasswordVerifySerializer)
|
@validate_serializer(ContestPasswordVerifySerializer)
|
||||||
@login_required
|
@login_required
|
||||||
def get(self, request):
|
def post(self, request):
|
||||||
data = request.data
|
data = request.data
|
||||||
try:
|
try:
|
||||||
contest = Contest.objects.get(id=data["contest_id"], visible=True, password__isnull=False)
|
contest = Contest.objects.get(id=data["contest_id"], visible=True, password__isnull=False)
|
||||||
|
110
problem/tests.py
110
problem/tests.py
@ -9,6 +9,17 @@ from utils.api.tests import APITestCase
|
|||||||
|
|
||||||
from .models import ProblemTag
|
from .models import ProblemTag
|
||||||
from .views.admin import TestCaseUploadAPI
|
from .views.admin import TestCaseUploadAPI
|
||||||
|
from contest.tests import DEFAULT_CONTEST_DATA
|
||||||
|
|
||||||
|
DEFAULT_PROBLEM_DATA = {"_id": "A-110", "title": "test", "description": "<p>test</p>", "input_description": "test",
|
||||||
|
"output_description": "test", "time_limit": 1000, "memory_limit": 256, "difficulty": "Low",
|
||||||
|
"visible": True, "tags": ["test"], "languages": ["C", "C++", "Java", "Python2"], "template": {},
|
||||||
|
"samples": [{"input": "test", "output": "test"}], "spj": False, "spj_language": "C",
|
||||||
|
"spj_code": "", "test_case_id": "499b26290cc7994e0b497212e842ea85",
|
||||||
|
"test_case_score": [{"output_name": "1.out", "input_name": "1.in", "output_size": 0,
|
||||||
|
"stripped_output_md5": "d41d8cd98f00b204e9800998ecf8427e",
|
||||||
|
"input_size": 0, "score": 0}],
|
||||||
|
"rule_type": "ACM", "hint": "<p>test</p>", "source": "test"}
|
||||||
|
|
||||||
|
|
||||||
class ProblemTagListAPITest(APITestCase):
|
class ProblemTagListAPITest(APITestCase):
|
||||||
@ -83,15 +94,7 @@ class ProblemAdminAPITest(APITestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.url = self.reverse("problem_admin_api")
|
self.url = self.reverse("problem_admin_api")
|
||||||
self.create_super_admin()
|
self.create_super_admin()
|
||||||
self.data = {"_id": "A-110", "title": "test", "description": "<p>test</p>", "input_description": "test",
|
self.data = DEFAULT_PROBLEM_DATA
|
||||||
"output_description": "test", "time_limit": 1000, "memory_limit": 256, "difficulty": "Low",
|
|
||||||
"visible": True, "tags": ["test"], "languages": ["C", "C++", "Java", "Python2"], "template": {},
|
|
||||||
"samples": [{"input": "test", "output": "test"}], "spj": False, "spj_language": "C",
|
|
||||||
"spj_code": "", "test_case_id": "499b26290cc7994e0b497212e842ea85",
|
|
||||||
"test_case_score": [{"output_name": "1.out", "input_name": "1.in", "output_size": 0,
|
|
||||||
"stripped_output_md5": "d41d8cd98f00b204e9800998ecf8427e",
|
|
||||||
"input_size": 0, "score": 0}],
|
|
||||||
"rule_type": "ACM", "hint": "<p>test</p>", "source": "test"}
|
|
||||||
|
|
||||||
def test_create_problem(self):
|
def test_create_problem(self):
|
||||||
resp = self.client.post(self.url, data=self.data)
|
resp = self.client.post(self.url, data=self.data)
|
||||||
@ -131,3 +134,92 @@ class ProblemAdminAPITest(APITestCase):
|
|||||||
data["id"] = problem_id
|
data["id"] = problem_id
|
||||||
resp = self.client.put(self.url, data=data)
|
resp = self.client.put(self.url, data=data)
|
||||||
self.assertSuccess(resp)
|
self.assertSuccess(resp)
|
||||||
|
|
||||||
|
|
||||||
|
class ProblemAPITest(APITestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.url = self.reverse("problem_api")
|
||||||
|
self.create_admin()
|
||||||
|
|
||||||
|
def create_problem(self):
|
||||||
|
url = self.reverse("problem_admin_api")
|
||||||
|
return self.client.post(url, data=DEFAULT_PROBLEM_DATA)
|
||||||
|
|
||||||
|
def test_get_problem_list(self):
|
||||||
|
self.create_problem()
|
||||||
|
resp = self.client.get(self.url)
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
|
||||||
|
def get_one_problem(self):
|
||||||
|
problem_id = self.create_problem().data["data"]["_id"]
|
||||||
|
resp = self.client.get(self.url + "?id=" + str(problem_id))
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
|
||||||
|
|
||||||
|
class ContestProblemAdminTest(APITestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.url = self.reverse("contest_problem_admin_api")
|
||||||
|
self.create_admin()
|
||||||
|
|
||||||
|
def create_contest(self):
|
||||||
|
url = self.reverse("contest_admin_api")
|
||||||
|
return self.client.post(url, data=DEFAULT_CONTEST_DATA)
|
||||||
|
|
||||||
|
def test_create_contest_problem(self):
|
||||||
|
contest = self.create_contest()
|
||||||
|
data = DEFAULT_PROBLEM_DATA
|
||||||
|
data["contest_id"] = contest.data["data"]["id"]
|
||||||
|
resp = self.client.post(self.url, data=data)
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
return resp
|
||||||
|
|
||||||
|
def test_get_contest_problem(self):
|
||||||
|
contest = self.test_create_contest_problem()
|
||||||
|
contest_id = contest.data["data"]["id"]
|
||||||
|
resp = self.client.get(self.url + "?contest_id=" + str(contest_id))
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
self.assertEqual(len(resp.data["data"]), 1)
|
||||||
|
|
||||||
|
def test_get_one_contest_problem(self):
|
||||||
|
contest = self.test_create_contest_problem()
|
||||||
|
contest_id = contest.data["data"]["id"]
|
||||||
|
resp = self.client.get(self.url + "?id=" + str(contest_id))
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
|
||||||
|
|
||||||
|
class ContestProblemTest(APITestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.url = self.reverse("contest_problem_api")
|
||||||
|
self.create_admin()
|
||||||
|
|
||||||
|
url = self.reverse("contest_admin_api")
|
||||||
|
self.contest = self.client.post(url, data=DEFAULT_CONTEST_DATA)
|
||||||
|
self.data = DEFAULT_PROBLEM_DATA
|
||||||
|
self.data["contest"] = self.contest.data["data"]["id"]
|
||||||
|
url = self.reverse("contest_problem_admin_api")
|
||||||
|
self.problem = self.client.post(url, self.data)
|
||||||
|
|
||||||
|
def test_get_contest_problem_list(self):
|
||||||
|
contest_id = self.contest.data["data"]["id"]
|
||||||
|
resp = self.client.get(self.url + "?contest_id=" + str(contest_id))
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
self.assertEqual(len(resp.data["data"]), 1)
|
||||||
|
|
||||||
|
def test_get_one_contest_problem(self):
|
||||||
|
contest_id = self.contest.data["data"]["id"]
|
||||||
|
problem_id = self.problem.data["data"]["_id"]
|
||||||
|
resp = self.client.get("{}?contest_id={}&problem_id={}".format(self.url,contest_id, problem_id))
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
|
||||||
|
def test_regular_user_get_contest_problem(self):
|
||||||
|
self.create_user("test", "test123")
|
||||||
|
contest_id = self.contest.data["data"]["id"]
|
||||||
|
problem_id = self.problem.data["data"]["_id"]
|
||||||
|
resp = self.client.get("{}?contest_id={}&problem_id={}".format(self.url,contest_id, problem_id))
|
||||||
|
self.assertFailed(resp)
|
||||||
|
|
||||||
|
url = self.reverse("contest_password_api")
|
||||||
|
self.client.post(url, {"contest_id": contest_id, "password": DEFAULT_CONTEST_DATA["password"]})
|
||||||
|
resp = self.client.get("{}?contest_id={}&problem_id={}".format(self.url,contest_id, problem_id))
|
||||||
|
self.assertSuccess(resp)
|
||||||
|
|
||||||
|
@ -5,5 +5,5 @@ from ..views.admin import ContestProblemAPI, ProblemAPI, TestCaseUploadAPI
|
|||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r"^test_case/upload/?$", TestCaseUploadAPI.as_view(), name="test_case_upload_api"),
|
url(r"^test_case/upload/?$", TestCaseUploadAPI.as_view(), name="test_case_upload_api"),
|
||||||
url(r"^problem/?$", ProblemAPI.as_view(), name="problem_admin_api"),
|
url(r"^problem/?$", ProblemAPI.as_view(), name="problem_admin_api"),
|
||||||
url(r"^contest/problem/?$", ContestProblemAPI.as_view(), name="contest_problem_api")
|
url(r"^contest/problem/?$", ContestProblemAPI.as_view(), name="contest_problem_admin_api"),
|
||||||
]
|
]
|
||||||
|
@ -4,6 +4,6 @@ from ..views.oj import ProblemTagAPI, ProblemAPI, ContestProblemAPI
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r"^problem/tags/?$", ProblemTagAPI.as_view(), name="problem_tag_list_api"),
|
url(r"^problem/tags/?$", ProblemTagAPI.as_view(), name="problem_tag_list_api"),
|
||||||
url(r"^problems/?$", ProblemAPI.as_view(), name="problem_list_api"),
|
url(r"^problem/?$", ProblemAPI.as_view(), name="problem_api"),
|
||||||
url(r"^contest_problems/?$", ContestProblemAPI.as_view(), name="contest_problem_api"),
|
url(r"^contest/problem/?$", ContestProblemAPI.as_view(), name="contest_problem_api"),
|
||||||
]
|
]
|
||||||
|
@ -48,5 +48,13 @@ class ProblemAPI(APIView):
|
|||||||
class ContestProblemAPI(APIView):
|
class ContestProblemAPI(APIView):
|
||||||
@check_contest_permission
|
@check_contest_permission
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
problem_id = request.GET.get("problem_id")
|
||||||
|
if problem_id:
|
||||||
|
try:
|
||||||
|
problem = ContestProblem.objects.get(_id=problem_id, contest=self.contest, visible=True)
|
||||||
|
except ContestProblem.DoesNotExist:
|
||||||
|
return self.error("Problem does not exist.")
|
||||||
|
return self.success(ContestProblemSerializer(problem).data)
|
||||||
|
|
||||||
contest_problems = ContestProblem.objects.filter(contest=self.contest, visible=True)
|
contest_problems = ContestProblem.objects.filter(contest=self.contest, visible=True)
|
||||||
return self.success(ContestProblemSerializer(contest_problems, many=True).data)
|
return self.success(ContestProblemSerializer(contest_problems, many=True).data)
|
||||||
|
Loading…
Reference in New Issue
Block a user