diff --git a/account/tests.py b/account/tests.py index e868f62..d0adf8a 100644 --- a/account/tests.py +++ b/account/tests.py @@ -370,7 +370,7 @@ class UserLogoutTest(TestCase): user.set_password("1") user.save() - def logout_success(self): + def test_logout_success(self): self.client = Client() self.client.login(username="test", password="1") response = self.client.get("/logout/") diff --git a/contest/test_urls.py b/contest/test_urls.py new file mode 100644 index 0000000..234c600 --- /dev/null +++ b/contest/test_urls.py @@ -0,0 +1,9 @@ +# coding=utf-8 +from django.conf.urls import include, url +from django.views.generic import TemplateView + + +urlpatterns = [ + + url(r'^login/$', TemplateView.as_view(template_name="oj/account/login.html"), name="user_login_page"), +] diff --git a/contest/tests.py b/contest/tests.py index adbf00b..626a3ab 100644 --- a/contest/tests.py +++ b/contest/tests.py @@ -1,15 +1,18 @@ # coding=utf-8 import json from django.core.urlresolvers import reverse -from django.test import TestCase +from django.test import TestCase, Client +from django.http import HttpResponse from rest_framework.test import APITestCase, APIClient from account.models import User from group.models import Group from contest.models import Contest, ContestProblem +from .models import ContestSubmission from announcement.models import Announcement from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN +from decorators import check_user_contest_permission class ContestAdminAPITest(APITestCase): @@ -398,3 +401,181 @@ class ContestProblemAdminAPItEST(APITestCase): response = self.client.put(self.url, data=data) self.assertEqual(response.data["code"], 1) + +class ContestPasswordVerifyAPITest(APITestCase): + def setUp(self): + self.client = APIClient() + self.url = reverse('contest_password_verify_api') + self.user = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user.set_password("testaa") + self.user.save() + self.user2 = User.objects.create(username="test2", admin_type=ADMIN) + self.user2.set_password("testbb") + self.user2.save() + self.client.login(username="test1", password="testaa") + 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")) + + def test_invalid_format(self): + self.client.login(username="test2", password="testbb") + data = {"contest_id": self.global_contest.id} + response = self.client.post(self.url, data=data) + self.assertEqual(response.data["code"], 1) + + def test_contest_does_not_exist(self): + self.client.login(username="test2", password="testbb") + data = {"contest_id": self.global_contest.id + 1, "password": "aacc"} + response = self.client.post(self.url, data=data) + self.assertEqual(response.data, {"code": 1, "data": u"比赛不存在"}) + + def test_contest_password_verify_unsuccessfully(self): + self.client.login(username="test2", password="testbb") + data = {"contest_id": self.global_contest.id, "password": "aabb"} + response = self.client.post(self.url, data=data) + self.assertEqual(response.data, {"code": 1, "data": u"密码错误"}) + + def test_contest_password_verify_successfully(self): + self.client.login(username="test2", password="testbb") + data = {"contest_id": self.global_contest.id, "password": "aacc"} + response = self.client.post(self.url, data=data) + self.assertEqual(response.data["code"], 0) + + +class ContestPageTest(TestCase): + # 单个比赛详情页的测试 + def setUp(self): + self.client = Client() + self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user1.set_password("testaa") + self.user1.save() + self.client.login(username="test1", password="testaa") + 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")) + + def test_visit_contest_page_successfully(self): + response = self.client.get('/contest/1/') + self.assertEqual(response.status_code, 200) + + def test_visit_contest_page_unsuccessfully(self): + response = self.client.get('/contest/10/') + self.assertTemplateUsed(response, "utils/error.html") + + +class ContestProblemPageTest(TestCase): + # 单个比赛题目详情页的测试 + def setUp(self): + self.client = Client() + self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user1.set_password("testaa") + self.user1.save() + self.client.login(username="test1", password="testaa") + 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.contest_problem = ContestProblem.objects.create(title="titlex", + description="descriptionx", + 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, + hint="hint1", + created_by=User.objects.get(username="test1"), + contest=Contest.objects.get(title="titlex"), + sort_index="a") + + def test_visit_contest_problem_page_successfully(self): + response = self.client.get('/contest/1/problem/1/') + self.assertEqual(response.status_code, 200) + + def test_visit_contest_page_unsuccessfully(self): + response = self.client.get('/contest/10/') + self.assertTemplateUsed(response, "utils/error.html") + + def test_visit_contest_submissions_page_successfully(self): + ContestSubmission.objects.create(user=self.user1, + contest=self.global_contest, + problem=self.contest_problem, + ac=True) + response = self.client.get('/contest/1/problem/1/submissions/') + self.assertEqual(response.status_code, 200) + + +class ContestProblemListPageTest(TestCase): + # 比赛题目列表的测试 + def setUp(self): + self.client = Client() + self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user1.set_password("testaa") + self.user1.save() + self.client.login(username="test1", password="testaa") + 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.contest_problem = ContestProblem.objects.create(title="titlex", + description="descriptionx", + 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, + hint="hint1", + created_by=User.objects.get(username="test1"), + contest=Contest.objects.get(title="titlex"), + sort_index="a") + + def test_visit_contest_problem_list_page_successfully(self): + response = self.client.get('/contest/1/problems/') + self.assertEqual(response.status_code, 200) + + def test_visit_contest_problem_page_unsuccessfully(self): + response = self.client.get('/contest/1/problem/100/') + self.assertTemplateUsed(response, "utils/error.html") + + +class ContestListPageTest(TestCase): + # 以下是所有比赛列表页的测试 + def setUp(self): + self.client = Client() + self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user1.set_password("testaa") + self.user1.save() + self.url = reverse('contest_list_page') + self.client.login(username="test1", password="testaa") + 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")) + + def test_visit_contest_list_page_successfully(self): + response = self.client.get('/contests/') + self.assertEqual(response.status_code, 200) + + def test_visit_contest_list_page_unsuccessfully(self): + response = self.client.get('/contests/2/') + self.assertTemplateUsed(response, "utils/error.html") + + def test_query_by_keyword(self): + response = self.client.get(self.url + "?keyword=title1") + self.assertEqual(response.status_code, 200) + + def test_query_by_join_successfully(self): + response = self.client.get(self.url + "?join=True") + self.assertEqual(response.status_code, 200) + + + + diff --git a/contest/views.py b/contest/views.py index eaef55b..af8d469 100644 --- a/contest/views.py +++ b/contest/views.py @@ -320,7 +320,6 @@ def contest_problems_list_page(request, contest_id): contest = Contest.objects.get(id=contest_id) except Contest.DoesNotExist: return error_page(request, u"比赛不存在") - contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") submissions = ContestSubmission.objects.filter(user=request.user, contest=contest) state = {} @@ -334,10 +333,8 @@ def contest_problems_list_page(request, contest_id): item.state = 2 else: item.state = 0 - # 右侧的公告列表 announcements = Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time") - return render(request, "oj/contest/contest_problems_list.html", {"contest_problems": contest_problems, "announcements": announcements, "contest": {"id": contest_id}}) diff --git a/contest_submission/tests.py b/contest_submission/tests.py index b1eace1..975d11c 100644 --- a/contest_submission/tests.py +++ b/contest_submission/tests.py @@ -1,14 +1,97 @@ +# coding=utf-8 import json - +from django.test import TestCase, Client from django.core.urlresolvers import reverse -from account.models import User, ADMIN, SUPER_ADMIN - +from account.models import User, REGULAR_USER, ADMIN, SUPER_ADMIN +from problem.models import Problem from contest.models import Contest, ContestProblem from submission.models import Submission from rest_framework.test import APITestCase, APIClient -# Create your tests here. +class ContestSubmissionAPITest(APITestCase): + def setUp(self): + self.client = APIClient() + self.url = reverse('contest_submission_api') + self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user1.set_password("testaa") + self.user1.save() + self.user2 = User.objects.create(username="test2", admin_type=REGULAR_USER) + self.user2.set_password("testbb") + self.user2.save() + self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1, + contest_type=1, show_rank=True, show_user_submission=True, + start_time="2015-08-15T10:00:00.000Z", + end_time="2015-08-30T12:00:00.000Z", + created_by=User.objects.get(username="test1")) + self.contest_problem = ContestProblem.objects.create(title="titlex", + description="descriptionx", + 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, + hint="hint1", + created_by=User.objects.get(username="test1"), + contest=Contest.objects.get(title="titlex"), + sort_index="a") + + # 以下是创建比赛的提交 + def test_invalid_format(self): + self.client.login(username="test1", password="testaa") + data = {"contest_id": self.global_contest.id, "language": 1} + response = self.client.post(self.url, data=data) + self.assertEqual(response.data["code"], 1) + + def test_contest_submission_successfully(self): + self.client.login(username="test1", password="testaa") + data = {"contest_id": self.global_contest.id, "problem_id": self.contest_problem.id, + "language": 1, "code": '#include "stdio.h"\nint main(){\n\treturn 0;\n}'} + response = self.client.post(self.url, data=data) + self.assertEqual(response.data["code"], 0) + + def test_contest_problem_does_not_exist(self): + self.client.login(username="test1", password="testaa") + data = {"contest_id": self.global_contest.id, "problem_id": self.contest_problem.id + 10, + "language": 1, "code": '#include "stdio.h"\nint main(){\n\treturn 0;\n}'} + response = self.client.post(self.url, data=data) + self.assertEqual(response.data, {"code": 1, "data": u"题目不存在"}) + + +class ContestProblemMySubmissionListTest(TestCase): + # 以下是我比赛单个题目的提交列表的测试 + def setUp(self): + self.client = Client() + self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user1.set_password("testaa") + self.user1.save() + self.user2 = User.objects.create(username="test2", admin_type=REGULAR_USER) + self.user2.set_password("testbb") + self.user2.save() + self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1, + contest_type=1, show_rank=True, show_user_submission=True, + start_time="2015-08-15T10:00:00.000Z", + end_time="2015-08-30T12:00:00.000Z", + created_by=User.objects.get(username="test1")) + self.contest_problem = ContestProblem.objects.create(title="titlex", + description="descriptionx", + 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, + hint="hint1", + created_by=self.user1, + contest=self.global_contest, + sort_index="a") + + def test_contestsList_page_not_exist(self): + self.client.login(username="test1", password="testaa") + response = self.client.get('/contest/1/submissions/999/') + self.assertTemplateUsed(response, "utils/error.html") + class SubmissionAPITest(APITestCase): def setUp(self): diff --git a/contest_submission/views.py b/contest_submission/views.py index 003ad8a..f136245 100644 --- a/contest_submission/views.py +++ b/contest_submission/views.py @@ -1,6 +1,5 @@ # coding=utf-8 import json - import redis from django.shortcuts import render from django.core.paginator import Paginator @@ -9,16 +8,15 @@ from rest_framework.views import APIView from judge.judger_controller.tasks import judge from judge.judger_controller.settings import redis_config + from account.decorators import login_required from account.models import SUPER_ADMIN from contest.decorators import check_user_contest_permission - from problem.models import Problem from contest.models import Contest, ContestProblem from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page, paginate - from submission.models import Submission from .serializers import CreateContestSubmissionSerializer from submission.serializers import SubmissionSerializer @@ -35,31 +33,24 @@ class ContestSubmissionAPIView(APIView): serializer = CreateContestSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data - try: - contest = Contest.objects.get(id=data["contest_id"]) - except Contest.DoesNotExist: - return error_response(u"比赛不存在") + contest = Contest.objects.get(id=data["contest_id"]) try: problem = ContestProblem.objects.get(contest=contest, id=data["problem_id"]) # 更新题目提交计数器 problem.total_submit_number += 1 problem.save() - except Problem.DoesNotExist: + except ContestProblem.DoesNotExist: return error_response(u"题目不存在") - submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]), contest_id=contest.id, code=data["code"], problem_id=problem.id) try: judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception: return error_response(u"提交判题任务失败") - # 增加redis 中判题队列长度的计数器 r = redis.Redis(host=redis_config["host"], port=redis_config["port"], db=redis_config["db"]) r.incr("judge_queue_length") - return success_response({"submission_id": submission.id}) - else: return serializer_invalid_response(serializer) @@ -75,7 +66,7 @@ def contest_problem_my_submissions_list_page(request, contest_id, contest_proble return error_page(request, u"比赛不存在") try: contest_problem = ContestProblem.objects.get(id=contest_problem_id, visible=True) - except Problem.DoesNotExist: + except ContestProblem.DoesNotExist: return error_page(request, u"比赛问题不存在") submissions = Submission.objects.filter(user_id=request.user.id, problem_id=contest_problem.id).order_by( "-create_time"). \ @@ -95,8 +86,26 @@ def contest_problem_submissions_list_page(request, contest_id, page=1): return error_page(request, u"比赛不存在") # 以下是本场比赛中所有的提交 submissions = Submission.objects.filter(contest_id=contest_id). \ - values("id", "result", "create_time", "accepted_answer_time", "language", "user_id").order_by("-create_time") + values("id", "contest_id", "problem_id", "result", "create_time", "accepted_answer_time", "language", "user_id").order_by("-create_time") + language = request.GET.get("language", None) + filter = None + if language: + submissions = submissions.filter(language=int(language)) + filter = {"name": "language", "content": language} + result = request.GET.get("result", None) + if result: + submissions = submissions.filter(result=int(result)) + filter = {"name": "result", "content": result} paginator = Paginator(submissions, 20) + + # 为查询题目标题创建新字典 + title = {} + contest_problems = ContestProblem.objects.filter(contest=contest) + for item in contest_problems: + title[item.id] = item.title + for item in submissions: + item['title'] = title[item['problem_id']] + try: current_page = paginator.page(int(page)) except Exception: @@ -110,11 +119,10 @@ def contest_problem_submissions_list_page(request, contest_id, page=1): next_page = current_page.next_page_number() except Exception: pass - return render(request, "oj/contest/submissions_list.html", {"submissions": current_page, "page": int(page), "previous_page": previous_page, "next_page": next_page, "start_id": int(page) * 20 - 20, - "contest": contest}) + "contest": contest, "filter":filter}) class ContestSubmissionAdminAPIView(APIView): @@ -147,5 +155,4 @@ class ContestSubmissionAdminAPIView(APIView): return error_response(u"参数错误!") if problem_id: submissions = submissions.filter(problem_id=problem_id) - - return paginate(request, submissions, SubmissionSerializer) + return paginate(request, submissions, SubmissionSerializer) \ No newline at end of file diff --git a/problem/tests.py b/problem/tests.py index 2a7aecc..9819486 100644 --- a/problem/tests.py +++ b/problem/tests.py @@ -187,5 +187,19 @@ class ProblemListPageTest(TestCase): hint="hint1", created_by=User.objects.get(username="test")) + def test_problemListPage_not_exist(self): + response = self.client.get('/problems/999/') + self.assertTemplateUsed(response, "utils/error.html") + def test_query_by_keyword(self): + response = self.client.get(self.url + "?keyword=title1") + self.assertEqual(response.status_code, 200) + + def test_query_by_tag_successfully(self): + response = self.client.get(self.url + "?tag=") + self.assertEqual(response.status_code, 200) + + def test_tag_does_not_exists(self): + response = self.client.get(self.url + "?tag=xxxxxx") + self.assertTemplateUsed(response, "utils/error.html") diff --git a/submission/tests.py b/submission/tests.py index 0d374ee..ad3b85a 100644 --- a/submission/tests.py +++ b/submission/tests.py @@ -1,6 +1,6 @@ # coding=utf-8 import json -from django.test import TestCase +from django.test import TestCase, Client from django.core.urlresolvers import reverse from account.models import User, REGULAR_USER, ADMIN, SUPER_ADMIN from problem.models import Problem @@ -11,7 +11,7 @@ from rest_framework.test import APITestCase, APIClient class SubmissionsListPageTest(TestCase): def setUp(self): - self.client = APIClient() + self.client = Client() self.user = User.objects.create(username="gogoing", admin_type=REGULAR_USER) self.user2 = User.objects.create(username="cool", admin_type=REGULAR_USER) self.user2.set_password("666666") @@ -124,25 +124,78 @@ class SubmissionAPITest(APITestCase): response = self.client.get(self.url, data=data) self.assertEqual(response.data["code"], 0) + def test_parameter_error(self): + self.client.login(username="test1", password="testaa") + response = self.client.get(self.url) + self.assertEqual(response.data, {"code": 1, "data": u"参数错误"}) -class ContestSubmissionAPITest(APITestCase): + +class SubmissionAdminAPITest(APITestCase): def setUp(self): self.client = APIClient() - self.url = reverse('contest_submission_api') - self.user1 = User.objects.create(username="test1", admin_type=REGULAR_USER) - self.user1.set_password("testaa") - self.user1.save() - self.user2 = User.objects.create(username="test2", admin_type=SUPER_ADMIN) - self.user2.set_password("testbb") - self.user2.save() + self.url = reverse('submission_admin_api_view') + self.user = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user.set_password("testaa") + self.user.save() + self.client.login(username="test1", password="testaa") + 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=self.user) 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="test2")) + password="aacc", created_by=self.user) + + self.submission = Submission.objects.create(user_id=self.user.id, + language=1, + code='#include "stdio.h"\nint main(){\n\treturn 0;\n}', + problem_id=self.problem.id) def test_invalid_format(self): + response = self.client.get(self.url) + self.assertEqual(response.data, {"code": 1, "data": u"参数错误"}) + + +class SubmissionPageTest(TestCase): + # 单个题目的提交详情页 + def setUp(self): + self.client = Client() + self.user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN) + self.user1.set_password("testaa") + self.user1.save() + self.user2 = User.objects.create(username="test2", admin_type=ADMIN) + self.user2.set_password("testbb") + self.user2.save() self.client.login(username="test1", password="testaa") - data = {"language": 1} - response = self.client.post(self.url, data=data) - pass + 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="test1")) + 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.submission = Submission.objects.create(user_id=self.user1.id, + language=1, + code='#include "stdio.h"\nint main(){\n\treturn 0;\n}', + problem_id=self.problem.id) diff --git a/submission/views.py b/submission/views.py index 0925e13..6180f8e 100644 --- a/submission/views.py +++ b/submission/views.py @@ -139,7 +139,7 @@ def my_submission_list_page(request, page=1): 我的所有提交的列表页 """ submissions = Submission.objects.filter(user_id=request.user.id, contest_id__isnull=True). \ - values("id", "result", "create_time", "accepted_answer_time", "language").order_by("-create_time") + values("id", "problem_id", "result", "create_time", "accepted_answer_time", "language").order_by("-create_time") language = request.GET.get("language", None) filter = None if language: diff --git a/template/src/oj/contest/my_submissions_list.html b/template/src/oj/contest/my_submissions_list.html index fb24bef..8c8aa5a 100644 --- a/template/src/oj/contest/my_submissions_list.html +++ b/template/src/oj/contest/my_submissions_list.html @@ -18,17 +18,19 @@
{{ item.output }}
@@ -45,23 +50,19 @@
{% if problem.hint %}
{% endif %}
-
-