import re
from django.conf import settings
from django.contrib.auth.models import User
from django.test.utils import override_settings
from django.urls import reverse
from oioioi.base.tests import TestCase
from oioioi.contests.models import (
Contest,
ContestPermission,
ProblemInstance,
Round,
Submission,
)
from oioioi.contests.tests.utils import make_user_contest_admin
from oioioi.programs.models import Test
from oioioi.questions.models import Message
[docs]def change_contest_type(contest):
contest.controller_name = 'oioioi.contests.tests.PrivateContestController'
contest.save()
[docs]class TestContestDashboard(TestCase):
[docs] fixtures = [
'test_users',
'test_contest',
'test_full_package',
'test_problem_instance',
'test_messages',
'test_templates',
'test_submission',
]
[docs] compile_flags = re.M | re.S
[docs] def test_contest_dashboard(self):
user = User.objects.get(username='test_user')
contest = Contest.objects.get(id='c')
make_user_contest_admin(user, contest)
self.assertTrue(self.client.login(username='test_user'))
self.client.get('/c/c/')
url = reverse('simpleui_contest_dashboard')
response = self.client.get(url)
content = response.content.decode('utf-8')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Recent activity')
self.assertContains(response, contest.name + '</h1>')
submission = Submission.objects.get(id=1)
problem_name = r'Sum.*yce \(zad1\)'
problem_score = submission.score.to_int()
regex = '.*<tr>.*' + problem_name + '.*OK.*' + str(problem_score) + '.*</tr>.*'
regex = re.compile(regex, self.compile_flags)
self.assertTrue(regex.match(content))
# This test expects that there is no reply to the message with id=1
message = Message.objects.get(id=1)
regex = '.*<tr>.*General.*' + message.topic + '.*QUESTION.*</tr>.*'
regex = re.compile(regex, self.compile_flags)
self.assertTrue(regex.match(content))
regex = '.*problem__solved--low.*0 / 1.*'
regex = re.compile(regex, self.compile_flags)
self.assertTrue(regex.match(content))
[docs] def test_open_contest_dashboard(self):
user = User.objects.get(username='test_user')
contest = Contest.objects.get(id='c')
make_user_contest_admin(user, contest)
self.assertTrue(self.client.login(username='test_user'))
self.client.get('/c/c/')
url = reverse('simpleui_contest_dashboard')
response = self.client.get(url)
self.assertNotContains(response, 'pointsChart')
[docs] def test_not_open_contest_dashboard(self):
user = User.objects.get(username='test_user')
contest = Contest.objects.get(id='c')
make_user_contest_admin(user, contest)
change_contest_type(contest)
self.assertTrue(self.client.login(username='test_user'))
self.client.get('/c/c/')
url = reverse('simpleui_contest_dashboard')
response = self.client.get(url)
self.assertContains(response, 'pointsChart', count=1)
[docs] def test_contest_dashboard_lacking_permissions(self):
self.assertTrue(self.client.login(username='test_user'))
self.client.get('/c/c/')
url = reverse('simpleui_contest_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
[docs] def test_contest_dashboard_no_rounds(self):
user = User.objects.get(username='test_user')
contest = Contest.objects.get(id='c')
make_user_contest_admin(user, contest)
rounds = Round.objects.filter(contest=contest)
for rnd in rounds:
rnd.delete()
self.assertTrue(self.client.login(username='test_user'))
self.client.get('/c/c/')
url = reverse('simpleui_contest_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<p>There are no rounds in this contest.</p>')
[docs]class TestUserDashboard(TestCase):
[docs] fixtures = [
'test_users',
'test_contest',
'test_full_package',
'test_problem_instance',
'test_messages',
'test_templates',
'test_submission',
]
[docs] compile_flags = re.M | re.S
[docs] def test_permissions(self):
self.assertTrue(self.client.login(username='test_user'))
url = reverse('simpleui_user_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
user = User.objects.get(username='test_user')
c = Contest.objects.get(id='c')
make_user_contest_admin(user, c)
url = reverse('simpleui_user_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertTrue(self.client.login(username='test_admin'))
url = reverse('simpleui_user_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
@override_settings(ARCHIVE_USERCONTESTS=True)
[docs] def test_permissions_invisible(self):
self.assertTrue(self.client.login(username='test_user'))
url = reverse('simpleui_user_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
[docs] def test_user_dashboard(self):
user = User.objects.get(username='test_user')
c = Contest.objects.get(id='c')
make_user_contest_admin(user, c)
self.assertTrue(self.client.login(username='test_user'))
url = reverse('simpleui_user_dashboard')
response = self.client.get(url)
content = response.content.decode('utf-8')
self.assertEqual(response.status_code, 200)
regex = '.*">' + c.name + '</a>.*'
regex = re.compile(regex, self.compile_flags)
self.assertTrue(regex.match(content))
self.assertContains(response, '0 submissions')
self.assertContains(response, '1 submission')
self.assertContains(response, '0 questions')
self.assertContains(response, '1 round')
self.assertContains(response, '1 problem')
self.assertNotContains(response, '0 users')
self.assertNotContains(response, 'contest_graph')
self.assertContains(response, 'User dashboard</h1>')
change_contest_type(c)
response = self.client.get(url)
self.assertContains(response, '0 submissions')
self.assertContains(response, '1 submission')
self.assertContains(response, '0 questions')
self.assertContains(response, '1 round')
self.assertContains(response, '1 problem')
self.assertContains(response, '0 users')
self.assertContains(response, 'contest_graph')
self.assertContains(response, 'User dashboard</h1>')
[docs] def test_user_dashboard_empty(self):
Contest.objects.all().delete()
self.assertTrue(self.client.login(username='test_admin'))
url = reverse('simpleui_user_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Create contest', count=1)
self.assertContains(response, 'create one')
self.assertContains(response, 'There are no contests to display.')
[docs] def test_user_dashboard_full(self):
user = User.objects.get(username='test_user')
for i in range(10):
c = Contest()
c.name = 'tmp' + str(i)
c.controller_name = 'oioioi.contests.controllers.ContestController'
c.id = 'tmp' + str(i)
c.save()
make_user_contest_admin(user, c)
self.assertTrue(self.client.login(username='test_user'))
url = reverse('simpleui_user_dashboard')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Show all contests')
[docs]class TestProblemInstance(TestCase):
"""Abstract base class with login utility for problem instance tests classes."""
[docs] def login(self, get_problems):
c = Contest.objects.get(id='c')
c.controller_name = 'oioioi.teachers.controllers.TeacherContestController'
c.save()
user = User.objects.get(username='test_user')
ContestPermission.objects.get_or_create(
user=user, permission='contests.contest_admin', contest=c
)
self.assertTrue(self.client.login(username='test_user'))
self.client.get('/c/c/')
if get_problems:
pi = ProblemInstance.objects.filter(contest=c)[0]
p = pi.problem
return pi, p
return c
[docs]class TestProblemInstanceSettings(TestProblemInstance):
[docs] fixtures = [
'test_users',
'teachers',
'test_contest',
'test_full_package',
'test_problem_instance',
'test_messages',
'test_templates',
'test_submission',
]
[docs] def test_test_settings_ok(self):
c = self.login(get_problems=False)
pi = ProblemInstance.objects.filter(contest=c)[0]
form_data = self.form_data.copy()
form_data['form-0-max_score'] = '44'
form_data['form-1-memory_limit'] = '1337'
form_data['form-3-time_limit'] = '666'
self.client.post(
reverse(
'simpleui_problem_settings', kwargs={'problem_instance_id': str(pi.id)}
),
form_data,
follow=True,
)
self.assertEqual(Test.objects.get(id=1).max_score, 44)
self.assertEqual(Test.objects.get(id=2).memory_limit, 1337)
self.assertEqual(Test.objects.get(id=4).time_limit, 666)
@override_settings(MAX_TEST_TIME_LIMIT_PER_PROBLEM=6000)
[docs] def test_time_limit(self):
c = self.login(get_problems=False)
pi = ProblemInstance.objects.filter(contest=c)[0]
response = self.client.post(
reverse(
'simpleui_problem_settings', kwargs={'problem_instance_id': str(pi.id)}
),
self.form_data,
follow=True,
)
self.assertContains(
response,
"Sum of time limits for all tests is too big. It's "
"51s, but it shouldn't exceed 6s.",
html=True,
)
@override_settings(MAX_MEMORY_LIMIT_FOR_TEST=100)
[docs] def test_memory_limit(self):
c = self.login(get_problems=False)
pi = ProblemInstance.objects.filter(contest=c)[0]
response = self.client.post(
reverse(
'simpleui_problem_settings', kwargs={'problem_instance_id': str(pi.id)}
),
self.form_data,
follow=True,
)
self.assertContains(
response,
"Memory limit mustn't be greater than %dKiB."
% settings.MAX_MEMORY_LIMIT_FOR_TEST,
html=True,
)
[docs]class TestProblemInstanceValidation(TestProblemInstance):
[docs] fixtures = [
'test_users',
'teachers',
'test_contest',
'test_full_package',
'test_problem_instance',
]
[docs] def test_max_scores(self):
c = self.login(get_problems=False)
pi = ProblemInstance.objects.filter(contest=c)[0]
response = self.client.post(
reverse(
'simpleui_problem_settings', kwargs={'problem_instance_id': str(pi.id)}
),
self.form_data,
follow=True,
)
self.assertContains(
response, "Scores for tests in the same group must be equal"
)