import copy import os import shutil from datetime import timedelta from zipfile import ZipFile from django.conf import settings from utils.api.tests import APITestCase from .models import ProblemTag from .views.admin import TestCaseUploadAPI from contest.models import Contest from contest.tests import DEFAULT_CONTEST_DATA DEFAULT_PROBLEM_DATA = {"_id": "A-110", "title": "test", "description": "

test

", "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": "

test

", "source": "test"} class ProblemTagListAPITest(APITestCase): def test_get_tag_list(self): ProblemTag.objects.create(name="name1") ProblemTag.objects.create(name="name2") resp = self.client.get(self.reverse("problem_tag_list_api")) self.assertSuccess(resp) resp_data = resp.data["data"] self.assertEqual(resp_data[0]["name"], "name1") self.assertEqual(resp_data[1]["name"], "name2") class TestCaseUploadAPITest(APITestCase): def setUp(self): self.api = TestCaseUploadAPI() self.url = self.reverse("test_case_upload_api") self.create_super_admin() def test_filter_file_name(self): self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in", ".DS_Store"], spj=False), ["1.in", "1.out"]) self.assertEqual(self.api.filter_name_list(["2.in", "2.out"], spj=False), []) self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in"], spj=True), ["1.in", "2.in"]) self.assertEqual(self.api.filter_name_list(["2.in", "3.in"], spj=True), []) def make_test_case_zip(self): base_dir = os.path.join("/tmp", "test_case") shutil.rmtree(base_dir, ignore_errors=True) os.mkdir(base_dir) file_names = ["1.in", "1.out", "2.in", ".DS_Store"] for item in file_names: with open(os.path.join(base_dir, item), "w", encoding="utf-8") as f: f.write(item + "\n" + item + "\r\n" + "end") zip_file = os.path.join(base_dir, "test_case.zip") with ZipFile(os.path.join(base_dir, "test_case.zip"), "w") as f: for item in file_names: f.write(os.path.join(base_dir, item), item) return zip_file def test_upload_spj_test_case_zip(self): with open(self.make_test_case_zip(), "rb") as f: resp = self.client.post(self.url, data={"spj": "true", "file": f}, format="multipart") self.assertSuccess(resp) data = resp.data["data"] self.assertEqual(data["spj"], True) test_case_dir = os.path.join(settings.TEST_CASE_DIR, data["id"]) self.assertTrue(os.path.exists(test_case_dir)) for item in data["info"]: name = item["input_name"] with open(os.path.join(test_case_dir, name), "r", encoding="utf-8") as f: self.assertEqual(f.read(), name + "\n" + name + "\n" + "end") def test_upload_test_case_zip(self): with open(self.make_test_case_zip(), "rb") as f: resp = self.client.post(self.url, data={"spj": "false", "file": f}, format="multipart") self.assertSuccess(resp) data = resp.data["data"] self.assertEqual(data["spj"], False) test_case_dir = os.path.join(settings.TEST_CASE_DIR, data["id"]) self.assertTrue(os.path.exists(test_case_dir)) for item in data["info"]: name = item["input_name"] with open(os.path.join(test_case_dir, name), "r", encoding="utf-8") as f: self.assertEqual(f.read(), name + "\n" + name + "\n" + "end") class ProblemAdminAPITest(APITestCase): def setUp(self): self.url = self.reverse("problem_admin_api") self.create_super_admin() self.data = DEFAULT_PROBLEM_DATA def test_create_problem(self): resp = self.client.post(self.url, data=self.data) self.assertSuccess(resp) return resp def test_duplicate_display_id(self): self.test_create_problem() resp = self.client.post(self.url, data=self.data) self.assertFailed(resp, "Display ID already exists") def test_spj(self): data = copy.deepcopy(self.data) data["spj"] = True resp = self.client.post(self.url, data) self.assertFailed(resp, "Invalid spj") data["spj_code"] = "test" resp = self.client.post(self.url, data=data) self.assertSuccess(resp) def test_get_problem(self): self.test_create_problem() resp = self.client.get(self.url) self.assertSuccess(resp) def test_get_one_problem(self): problem_id = self.test_create_problem().data["data"]["id"] resp = self.client.get(self.url + "?id=" + str(problem_id)) self.assertSuccess(resp) def test_edit_problem(self): problem_id = self.test_create_problem().data["data"]["id"] data = copy.deepcopy(self.data) data["id"] = problem_id resp = self.client.put(self.url, data=data) 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(f"{self.url}?limit=10") 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") contest_data = copy.deepcopy(DEFAULT_CONTEST_DATA) contest_data["password"] = "" contest_data["start_time"] = contest_data["start_time"] + timedelta(hours=1) self.contest = self.client.post(url, data=contest_data).data["data"] problem_data = copy.deepcopy(DEFAULT_PROBLEM_DATA) problem_data["contest"] = self.contest["id"] url = self.reverse("contest_problem_admin_api") self.problem = self.client.post(url, problem_data).data["data"] def test_get_contest_problem_list(self): contest_id = self.contest["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["id"] problem_id = self.problem["_id"] resp = self.client.get("{}?contest_id={}&problem_id={}".format(self.url, contest_id, problem_id)) self.assertSuccess(resp) def test_regular_user_get_not_started_contest_problem(self): self.create_user("test", "test123") resp = self.client.get(self.url + "?contest_id=" + str(self.contest["id"])) self.assertDictEqual(resp.data, {"error": "error", "data": "Contest has not started yet."}) def test_reguar_user_get_started_contest_problem(self): self.create_user("test", "test123") contest = Contest.objects.first() contest.start_time = contest.start_time - timedelta(hours=1) contest.save() resp = self.client.get(self.url + "?contest_id=" + str(self.contest["id"])) self.assertSuccess(resp)