Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions oioioi/problems/tests/test_problem.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

from django.conf import settings
from django.contrib.auth.models import AnonymousUser, Permission, User
from django.contrib.contenttypes.models import ContentType
Expand Down Expand Up @@ -542,6 +544,58 @@ def test_form_accessibility(self):
self.assertNotContains(response, 'id="open-form"')


@override_settings(CONTEST_MODE=ContestMode.neutral)
class TestProblemSiteExampleTests(TestCase, TestStreamingMixin):
fixtures = [
"test_users",
"test_full_package",
"test_problem_instance_with_no_contest",
"test_problem_site",
]

def _list_url(self):
return reverse("problem_site_example_tests", kwargs={"site_key": "123"})

def _file_url(self, filename):
return reverse("problem_site_example_test_file", kwargs={"site_key": "123", "filename": filename})

def test_list_returns_example_tests(self):
# No auth required — same access model as the statement view
response = self.client.get(self._list_url())
self.assertEqual(response.status_code, 200)
data = json.loads(response.content)
self.assertEqual({e["name"] for e in data}, {"0", "1ocen"})
entry = next(e for e in data if e["name"] == "0")
self.assertEqual(entry["in_url"], self._file_url("sum0.in"))
self.assertEqual(entry["out_url"], self._file_url("sum0.out"))

def test_list_wrong_site_key_returns_404(self):
url = reverse("problem_site_example_tests", kwargs={"site_key": "nonexistent"})
self.assertEqual(self.client.get(url).status_code, 404)

def test_file_input(self):
# No auth required
response = self.client.get(self._file_url("sum0.in"))
self.assertStreamingEqual(response, b"1 2\n")

def test_file_output(self):
response = self.client.get(self._file_url("sum0.out"))
self.assertStreamingEqual(response, b"3\n")

def test_file_wrong_extension_returns_404(self):
self.assertEqual(self.client.get(self._file_url("sum0.txt")).status_code, 404)

def test_file_wrong_test_name_returns_404(self):
self.assertEqual(self.client.get(self._file_url("sum99.in")).status_code, 404)

def test_file_wrong_short_name_returns_404(self):
self.assertEqual(self.client.get(self._file_url("wrong0.in")).status_code, 404)

def test_unsafe_methods_not_allowed(self):
self.assertEqual(self.client.post(self._list_url()).status_code, 405)
self.assertEqual(self.client.post(self._file_url("sum0.in")).status_code, 405)


@override_settings(LANGUAGE_CODE="en")
class TestProblemChangeForm(TestCase):
fixtures = [
Expand Down
10 changes: 10 additions & 0 deletions oioioi/problems/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@
views.problem_site_external_attachment_view,
name="problem_site_external_attachment",
),
path(
Comment thread
Arapak marked this conversation as resolved.
"example_tests/",
views.problem_site_example_tests_view,
name="problem_site_example_tests",
),
path(
"example_tests/<str:filename>",
views.problem_site_example_test_file_view,
name="problem_site_example_test_file",
),
]

urlpatterns = [
Expand Down
68 changes: 65 additions & 3 deletions oioioi/problems/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
When,
)
from django.db.models.functions import Coalesce
from django.http import Http404, HttpResponse, HttpResponseBadRequest
from django.http import Http404, HttpResponse, HttpResponseBadRequest, JsonResponse
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.encoding import force_str
from django.utils.safestring import mark_safe
from django.utils.translation import get_language
from django.utils.translation import gettext_lazy as _
from django.views.decorators.http import require_http_methods
from django.views.decorators.http import require_http_methods, require_safe
from unidecode import unidecode

from oioioi.base.permissions import enforce_condition, not_anonymous
Expand Down Expand Up @@ -92,7 +92,7 @@
query_statement,
show_proposal_form,
)
from oioioi.programs.models import ModelSolution
from oioioi.programs.models import ModelSolution, Test


def show_statement_view(request, statement_id):
Expand Down Expand Up @@ -569,6 +569,68 @@ def problem_site_external_attachment_view(request, site_key, attachment_id):
return stream_file(attachment.content, attachment.download_name)


@require_safe
def problem_site_example_tests_view(request, site_key):
problem = get_object_or_404(Problem, problemsite__url_key=site_key)
tests = Test.objects.filter(
problem_instance=problem.main_problem_instance,
kind="EXAMPLE",
).order_by("order", "name")

result = []
for test in tests:
basename = f"{problem.short_name}{test.name}"
result.append(
{
"name": test.name,
"in_url": reverse(
"problem_site_example_test_file",
kwargs={"site_key": site_key, "filename": f"{basename}.in"},
)
if test.input_file
else None,
"out_url": reverse(
"problem_site_example_test_file",
kwargs={"site_key": site_key, "filename": f"{basename}.out"},
)
if test.output_file
else None,
}
)

return JsonResponse(result, safe=False)


@require_safe
def problem_site_example_test_file_view(request, site_key, filename):
problem = get_object_or_404(Problem, problemsite__url_key=site_key)

base, ext = os.path.splitext(filename)
if ext not in (".in", ".out"):
raise Http404

short_name = problem.short_name
if not base.startswith(short_name):
raise Http404
test_name = base[len(short_name) :]

test = get_object_or_404(
Test,
problem_instance=problem.main_problem_instance,
kind="EXAMPLE",
name=test_name,
)

if ext == ".in":
if not test.input_file:
raise Http404
return stream_file(test.input_file, filename)
else:
if not test.output_file:
raise Http404
return stream_file(test.output_file, filename)


def problemset_add_to_contest_view(request, site_key):
problem_name = request.GET.get("problem_name")
if not problem_name:
Expand Down
Loading