修改并完善比赛及其他部分的内容及测试

This commit is contained in:
hohoTT 2015-08-21 18:16:34 +08:00
parent 33fec6531a
commit 53d2b674c9
12 changed files with 365 additions and 16 deletions

View File

@ -90,6 +90,8 @@ class AnnouncementAdminAPITest(APITestCase):
"visible": True, "is_global": False, "groups": [self.group.id]}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertEqual(response.data["data"]["title"], "11")
self.assertEqual(response.data["data"]["content"], "22")
def test_edit_group_at_least_one(self):
self.client.login(username="test1", password="testaa")

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('group', '0004_merge'),
]
operations = [
migrations.CreateModel(
name='Contest',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(unique=True, max_length=40)),
('description', models.TextField()),
('mode', models.IntegerField()),
('show_rank', models.BooleanField()),
('show_user_submission', models.BooleanField()),
('password', models.CharField(max_length=30, null=True, blank=True)),
('contest_type', models.IntegerField()),
('start_time', models.DateTimeField()),
('end_time', models.DateTimeField()),
('create_time', models.DateTimeField(auto_now_add=True)),
('last_updated_time', models.DateTimeField(auto_now=True)),
('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
('groups', models.ManyToManyField(to='group.Group')),
],
options={
'db_table': 'contest',
},
),
migrations.CreateModel(
name='ContestProblem',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(max_length=50)),
('description', models.TextField()),
('input_description', models.CharField(max_length=10000)),
('output_description', models.CharField(max_length=10000)),
('samples', models.TextField(blank=True)),
('test_case_id', models.CharField(max_length=40)),
('hint', models.TextField(null=True, blank=True)),
('create_time', models.DateTimeField(auto_now_add=True)),
('time_limit', models.IntegerField()),
('memory_limit', models.IntegerField()),
('visible', models.BooleanField(default=True)),
('total_submit_number', models.IntegerField(default=0)),
('total_accepted_number', models.IntegerField(default=0)),
('sort_index', models.CharField(max_length=30)),
('contest', models.ForeignKey(to='contest.Contest')),
('created_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
],
options={
'db_table': 'contest_problem',
},
),
migrations.CreateModel(
name='ContestProblemTestCase',
fields=[
('id', models.CharField(max_length=40, serialize=False, primary_key=True, db_index=True)),
('score', models.IntegerField()),
('problem', models.ForeignKey(to='contest.ContestProblem')),
],
options={
'db_table': 'contest_problem_test_case',
},
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('contest', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='contest',
name='visible',
field=models.BooleanField(default=True),
),
]

View File

@ -33,6 +33,8 @@ class Contest(models.Model):
# 这个比赛是谁创建的
created_by = models.ForeignKey(User)
groups = models.ManyToManyField(Group)
# 是否可见 false的话相当于删除
visible = models.BooleanField(default=True)
class Meta:
db_table = "contest"

View File

@ -13,10 +13,11 @@ class CreateContestSerializer(serializers.Serializer):
contest_type = serializers.IntegerField()
show_rank = serializers.BooleanField()
show_user_submission = serializers.BooleanField()
password = serializers.CharField(max_length=30, required=False)
password = serializers.CharField(max_length=30, required=False, default=None)
start_time = serializers.DateTimeField()
end_time = serializers.DateTimeField()
groups = serializers.ListField(child=serializers.IntegerField())
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
visible = serializers.BooleanField()
class ContestSerializer(serializers.ModelSerializer):
@ -32,16 +33,18 @@ class ContestSerializer(serializers.ModelSerializer):
class EditContestSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField(max_length=40)
description = serializers.CharField(max_length=10000)
mode = serializers.IntegerField()
contest_type = serializers.IntegerField()
show_rank = serializers.BooleanField()
show_user_submission = serializers.BooleanField()
password = serializers.CharField(max_length=30, required=False)
password = serializers.CharField(max_length=30, required=False, default=None)
start_time = serializers.DateTimeField()
end_time = serializers.DateTimeField()
groups = serializers.ListField(child=serializers.IntegerField())
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
visible = serializers.BooleanField()
class ContestProblemSampleSerializer(serializers.ListField):

View File

@ -1,3 +1,219 @@
# coding=utf-8
import json
from django.core.urlresolvers import reverse
from django.test import TestCase
# Create your tests here.
from rest_framework.test import APITestCase, APIClient
from account.models import User
from group.models import Group
from contest.models import Contest, ContestProblem
from announcement.models import Announcement
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
class ContestAdminAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse('contest_admin_api')
user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
user1.set_password("testaa")
user1.save()
user2 = User.objects.create(username="test2", admin_type=ADMIN)
user2.set_password("testbb")
user2.save()
user3 = User.objects.create(username="test3", admin_type=REGULAR_USER)
user3.set_password("testcc")
user3.save()
self.group = Group.objects.create(name="group1", description="des0",
join_group_setting=0, visible=True,
admin=user2)
self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
self.group_contest = Contest.objects.create(title="titley", description="descriptiony", mode=1,
contest_type=2, show_rank=True, show_user_submission=True,
start_time="2015-08-15T10:00:00.000Z",
end_time="2015-08-15T12:00:00.000Z",
password="aacc", created_by=User.objects.get(username="test1"))
# 以下是比赛发布的测试
def test_invalid_format(self):
self.client.login(username="test1", password="testaa")
data = {"title": "test1"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_global_contest_does_not_has_privileges(self):
self.client.login(username="test2", password="testbb")
data = {"title": "title0", "description": "description0", "mode": 1, "contest_type": 2,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "password": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"只有超级管理员才可创建公开赛"})
def test_global_contest_password_exists(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "description": "description0", "mode": 1, "contest_type": 2,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"此比赛为有密码的公开赛,密码不可为空"})
def test_group_contest_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "description": "description0", "mode": 1, "contest_type": 0,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"请至少选择一个小组"})
def test_global_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title1", "description": "description1", "mode": 1, "contest_type": 2,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "password": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_group_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title3", "description": "description3", "mode": 1, "contest_type": 0,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "groups": [self.group.id], "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_time_error(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title2", "description": "description2", "mode": 1, "contest_type": 2,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T12:00:00.000Z",
"end_time": "2015-08-15T10:00:00.000Z", "password": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛的开始时间不能晚于或等于比赛结束的时间"})
def test_contest_has_exists(self):
self.client.login(username="test1", password="testaa")
data = {"title": "titlex", "description": "descriptionx", "mode": 1, "contest_type": 2,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "password": "aabb", "visible": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛名已经存在"})
# 以下是编辑比赛的测试
def test_put_invalid_data(self):
self.client.login(username="test1", password="testaa")
data = {"title": "test0", "description": "description0"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_contest_does_not_exist(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id + 10, "title": "title2", "description": "description2", "mode": 1,
"contest_type": 2, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T12:00:00.000Z", "password": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该比赛不存在!"})
def test_edit_global_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "titlez", "description": "descriptionz", "mode": 1,
"contest_type": 2, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T13:00:00.000Z", "password": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertEqual(response.data["data"]["title"], "titlez")
self.assertEqual(response.data["data"]["end_time"], "2015-08-15T13:00:00Z")
def test_edit_group_contest_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.group_contest.id, "title": "titleyyy", "description": "descriptionyyyy", "mode": 1,
"contest_type": 0, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T13:00:00.000Z",
"groups": [self.group.id], "visible": False}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertEqual(response.data["data"]["title"], "titleyyy")
self.assertEqual(response.data["data"]["end_time"], "2015-08-15T13:00:00Z")
self.assertEqual(response.data["data"]["visible"], False)
def test_edit_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.group_contest.id, "title": "titleyyy", "description": "descriptionyyyy", "mode": 1,
"contest_type": 0, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T13:00:00.000Z", "visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"请至少选择一个小组"})
def test_edit_contest_has_exists(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "titley", "description": "descriptiony", "mode": 1,
"contest_type": 2, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T12:00:00.000Z", "password": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"该比赛名称已经存在"})
def test_edit_global_contest_does_not_has_privileges(self):
self.client.login(username="test2", password="testbb")
data = {"id": self.global_contest.id, "title": "titlexxxxxxxxx", "description": "descriptionxxxxxx", "mode": 1,
"contest_type": 2, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T10:00:00.000Z", "end_time": "2015-08-15T12:00:00.000Z", "password": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"只有超级管理员才可创建公开赛"})
def test_edit_global_contest_password_exists(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "title0", "description": "description0", "mode": 1, "contest_type": 2,
"show_rank": True, "show_user_submission": True, "start_time": "2015-08-15T10:00:00.000Z",
"end_time": "2015-08-15T12:00:00.000Z", "visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"此比赛为有密码的公开赛,密码不可为空"})
def test_edit_time_error(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.global_contest.id, "title": "titleaaaa", "description": "descriptionaaaaa", "mode": 1,
"contest_type": 2, "show_rank": True, "show_user_submission": True,
"start_time": "2015-08-15T12:00:00.000Z", "end_time": "2015-08-15T10:00:00.000Z", "password": "aabb",
"visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"比赛的开始时间不能晚于或等于比赛结束的时间"})
# 以下是比赛分页的测试
def test_get_data_successfully(self):
self.client.login(username="test1", password="testaa")
self.assertEqual(self.client.get(self.url).data["code"], 0)
def test_keyword_contest(self):
self.client.login(username="test1", password="testaa")
response = self.client.get(self.url + "?visible=true")
self.assertEqual(response.data["code"], 0)
for item in response.data["data"]:
self.assertEqual(item["visible"], True)
class ContestProblemAdminAPItEST(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse('contest_problem_admin_api')
self.user = User.objects.create(username="test", admin_type=SUPER_ADMIN)
self.user.set_password("testaa")
self.user.save()
self.client.login(username="test", password="testaa")
self. contest_problem = ContestProblem.objects.create(title="title1",
description="description1",
input_description="input1_description",
output_description="output1_description",
test_case_id="1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
difficulty=1,
hint="hint1",
created_by=User.objects.get(username="test"),
sort_index="a")

View File

@ -2,6 +2,7 @@
import json
from django.shortcuts import render
from django.db import IntegrityError
from django.utils import dateparse
from django.db.models import Q
from rest_framework.views import APIView
from utils.shortcuts import (serializer_invalid_response, error_response,
@ -15,7 +16,6 @@ from .serializers import (CreateContestSerializer, ContestSerializer, EditContes
CreateContestProblemSerializer, ContestProblemSerializer, EditContestProblemSerializer)
def contest_page(request, contest_id):
pass
@ -49,12 +49,16 @@ class ContestAdminAPIView(APIView):
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
if not groups.count():
return error_response(u"请至少选择一个小组")
if data["start_time"] >= data["end_time"]:
return error_response(u"比赛的开始时间不能晚于或等于比赛结束的时间")
try:
contest = Contest.objects.create(title=data["title"], description=data["description"],
mode=data["mode"], show_rank=data["show_rank"],
mode=data["mode"], contest_type=data["contest_type"],
show_rank=data["show_rank"], password=data["password"],
show_user_submission=data["show_user_submission"],
start_time=["start_time"], end_time=data["end_time"],
password=data["password"])
start_time=dateparse.parse_datetime(data["start_time"]),
end_time=dateparse.parse_datetime(data["end_time"]),
created_by=request.user, visible=data["visible"])
except IntegrityError:
return error_response(u"比赛名已经存在")
contest.groups.add(*groups)
@ -96,13 +100,17 @@ class ContestAdminAPIView(APIView):
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
if not groups.count():
return error_response(u"请至少选择一个小组")
if data["start_time"] >= data["end_time"]:
return error_response(u"比赛的开始时间不能晚于或等于比赛结束的时间")
contest.title = data["title"]
contest.description = data["description"]
contest.mode = data["mode"]
contest.contest_type = data["contest_type"]
contest.show_rank = data["show_rank"]
contest.show_user_submission = data["show_user_submission"]
contest.start_time = ["start_time"]
contest.end_time = data["end_time"]
contest.start_time = dateparse.parse_datetime(data["start_time"])
contest.end_time = dateparse.parse_datetime(data["end_time"])
contest.visible = data["visible"]
contest.password = data["password"]
contest.save()

View File

@ -226,7 +226,8 @@ class JoinGroupRequestAdminAPIView(APIView, GroupAPIViewBase):
if serializer.is_valid():
data = serializer.data
try:
join_request = JoinGroupRequest.objects.get(id=data["request_id"], group__admin=request.user, status=False)
join_request = JoinGroupRequest.objects.get(id=data["request_id"], group__admin=request.user,
status=False)
except JoinGroupRequest.DoesNotExist:
return error_response(u"请求不存在")

View File

@ -52,6 +52,7 @@ INSTALLED_APPS = (
'problem',
'admin',
'submission',
'contest',
'rest_framework',
'rest_framework_swagger',

View File

@ -8,6 +8,8 @@ from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterA
UserAdminAPIView, UserInfoAPIView)
from announcement.views import AnnouncementAdminAPIView
from contest.views import ContestAdminAPIView, ContestAdminAPIView
from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView,
JoinGroupAPIView, JoinGroupRequestAdminAPIView)
@ -34,6 +36,7 @@ urlpatterns = [
url(r'^api/username_check/$', UsernameCheckAPIView.as_view(), name="username_check_api"),
url(r'^api/email_check/$', EmailCheckAPIView.as_view(), name="email_check_api"),
url(r'^api/admin/announcement/$', AnnouncementAdminAPIView.as_view(), name="announcement_admin_api"),
url(r'^api/admin/contest/$', ContestAdminAPIView.as_view(), name="contest_admin_api"),
url(r'^api/admin/user/$', UserAdminAPIView.as_view(), name="user_admin_api"),
url(r'^problem/(?P<problem_id>\d+)/$', "problem.views.problem_page", name="problem_page"),
url(r'^announcement/(?P<announcement_id>\d+)/$', "announcement.views.announcement_page",
@ -48,6 +51,7 @@ urlpatterns = [
url(r'^api/admin/group_member/$', GroupMemberAdminAPIView.as_view(), name="group_member_admin_api"),
url(r'^api/admin/group_join/$', JoinGroupAPIView.as_view(), name="group_join_admin_api"),
url(r'^api/admin/problem/$', ProblemAdminAPIView.as_view(), name="problem_admin_api"),
url(r'^api/admin/contest_problem/$', ContestAdminAPIView.as_view(), name="contest_problem_admin_api"),
url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"),
url(r'^api/admin/tag/$', ProblemTagAdminAPIView.as_view(), name="problem_tag_admin_api"),
url(r'^problem/(?P<problem_id>\d+)/my_submissions/$', "submission.views.problem_my_submissions_list_page",

View File

@ -1,7 +1,7 @@
# coding=utf-8
import json
from django.test import TestCase
from django.test import TestCase, Client
from django.core.urlresolvers import reverse
from rest_framework.test import APITestCase, APIClient
@ -39,7 +39,6 @@ class ProblemPageTest(TestCase):
self.assertTemplateUsed(response, "utils/error.html")
class ProblemAdminTest(APITestCase):
def _create_data(self, problem_id, visible, tags):
data = {"id": problem_id,
@ -167,5 +166,26 @@ class ProblemTagAdminAPITest(APITestCase):
class ProblemListPageTest(TestCase):
def setUp(self):
pass
self.client = Client()
self.url = reverse('problem_list_page', kwargs={"page": 1})
self.user = User.objects.create(username="test", admin_type=SUPER_ADMIN)
self.user.set_password("testaa")
self.user.save()
self.client.login(username="test", password="testaa")
ProblemTag.objects.create(name="tag1")
ProblemTag.objects.create(name="tag2")
self.problem = Problem.objects.create(title="title1",
description="description1",
input_description="input1_description",
output_description="output1_description",
test_case_id="1",
source="source1",
samples=json.dumps([{"input": "1 1", "output": "2"}]),
time_limit=100,
memory_limit=1000,
difficulty=1,
hint="hint1",
created_by=User.objects.get(username="test"))

View File

@ -56,7 +56,6 @@ class ProblemAdminAPIView(APIView):
difficulty=data["difficulty"],
created_by=request.user,
hint=data["hint"])
for tag in data["tags"]:
try:
tag = ProblemTag.objects.get(name=tag)