Skip to content

Commit

Permalink
Add unittests for Contest and Problem models
Browse files Browse the repository at this point in the history
  • Loading branch information
Ninjaclasher committed Jun 2, 2020
1 parent 64325ad commit 32a36de
Show file tree
Hide file tree
Showing 4 changed files with 497 additions and 0 deletions.
Empty file added judge/models/tests/__init__.py
Empty file.
90 changes: 90 additions & 0 deletions judge/models/tests/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from django.contrib.auth.models import Permission, User

from judge.models import Organization, Profile


class UserFixturesMixin:
# TODO: fixture?
users_data = {
'superuser': {
'is_superuser': True,
'is_staff': True,
},
'staff_contest_1': {
'is_staff': True,
'_meta': {
'permissions': (
'edit_own_contest',
'see_private_contest',
),
},
},
'staff_contest_2': {
'is_staff': True,
'_meta': {
'permissions': (
'edit_own_contest',
'edit_all_contest',
),
},
},
'staff_problem_1': {
'is_staff': True,
'_meta': {
'permissions': (
'edit_own_problem',
'see_private_problem',
),
},
},
'staff_problem_2': {
'is_staff': True,
'_meta': {
'permissions': (
'edit_own_problem',
'edit_all_problem',
),
},
},
'staff_problem_3': {
'is_staff': True,
'_meta': {
'permissions': (
'edit_own_problem',
'edit_public_problem',
),
},
},
'staff_problem_4': {
'_meta': {
'permissions': (
'see_organization_problem',
),
},
},
'normal': {},
}

@classmethod
def setUpTestData(self):
self.users = {}
for username, all_data in self.users_data.items():
data = all_data.copy()
metadata = data.pop('_meta', {})
user = User.objects.create(
username=username,
**data,
)
user.user_permissions.set(Permission.objects.filter(codename__in=metadata.get('permissions', ())))
self.users[username] = user

self.profiles = {key: Profile.objects.create(user=user) for key, user in self.users.items()}

self.organizations = {
'open': Organization.objects.create(
name='open',
slug='open',
short_name='open',
registrant=self.profiles['superuser'],
),
}
206 changes: 206 additions & 0 deletions judge/models/tests/test_contest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
from django.test import TestCase
from django.utils import timezone

from judge.models import Contest, ContestParticipation
from judge.models.tests.base import UserFixturesMixin


class ContestTestCase(UserFixturesMixin, TestCase):
@classmethod
def setUpTestData(self):
super().setUpTestData()
_now = timezone.now()
self.basic_contest = Contest.objects.create(
name='Basic Contest',
key='basic',
start_time=_now - timezone.timedelta(days=1),
end_time=_now + timezone.timedelta(days=100),
)
self.basic_contest.organizers.add(self.profiles['superuser'])
self.basic_contest.organizers.add(self.profiles['staff_contest_1'])

self.hidden_scoreboard_contest = Contest.objects.create(
name='Hidden Scoreboard Contest',
key='hidden_scoreboard',
start_time=_now - timezone.timedelta(days=1),
end_time=_now + timezone.timedelta(days=100),
is_visible=True,
hide_scoreboard=True,
problem_label_script='''
function(n)
return tostring(math.floor(n))
end
''',
)

self.profiles['normal'].current_contest = ContestParticipation.objects.create(
contest=self.hidden_scoreboard_contest,
user=self.profiles['normal'],
)
self.profiles['normal'].save()

self.private_contest = Contest.objects.create(
name='Private Contest',
key='private',
start_time=_now - timezone.timedelta(days=5),
end_time=_now - timezone.timedelta(days=3),
is_visible=True,
is_private=True,
is_organization_private=True,
)
self.private_contest.private_contestants.add(self.profiles['staff_contest_1'])

def test_basic_contest(self):
self.assertTrue(self.basic_contest.show_scoreboard)
self.assertIsInstance(self.basic_contest.contest_window_length, timezone.timedelta)
self.assertIsInstance(self.basic_contest._now, timezone.datetime)
self.assertTrue(self.basic_contest.can_join)
self.assertIsNone(self.basic_contest.time_before_start)
self.assertIsInstance(self.basic_contest.time_before_end, timezone.timedelta)
self.assertFalse(self.basic_contest.ended)
self.assertEqual(str(self.basic_contest), self.basic_contest.name)
self.assertEqual(self.basic_contest.get_label_for_problem(0), '1')

def test_hidden_scoreboard_contest(self):
self.assertFalse(self.hidden_scoreboard_contest.show_scoreboard)
for i in range(3):
with self.subTest(contest_problem_index=i):
self.assertEqual(self.hidden_scoreboard_contest.get_label_for_problem(i), str(i))

def test_private_contest(self):
self.assertTrue(self.private_contest.can_join)
self.assertIsNone(self.private_contest.time_before_start)
self.assertIsNone(self.private_contest.time_before_end)

def _test_contest_user(self, contest, user, methods):
for method, func in methods.items():
func(
getattr(contest, method)(user),
msg='Method %s failed for user "%s", contest "%s".' % (method, user.username, contest.name),
)

def test_basic_contest_superuser_user(self):
methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertTrue,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.basic_contest, self.users['superuser'], methods)

def test_basic_contest_staff_contest_1_user(self):
methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertTrue,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.basic_contest, self.users['staff_contest_1'], methods)

def test_basic_contest_staff_contest_2_user(self):
methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertTrue,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.basic_contest, self.users['staff_contest_2'], methods)

def test_basic_contest_normal_user(self):
with self.assertRaises(Contest.Inaccessible):
self.basic_contest.access_check(self.users['normal'])

methods = {
# scoreboard checks don't do accessibility checks
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertFalse,
'is_editable_by': self.assertFalse,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.basic_contest, self.users['normal'], methods)

def test_hidden_scoreboard_contest_staff_contest_1_user(self):
methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertFalse,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.hidden_scoreboard_contest, self.users['staff_contest_1'], methods)

def test_hidden_scoreboard_contest_staff_contest_2_user(self):
methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertTrue,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.hidden_scoreboard_contest, self.users['staff_contest_2'], methods)

def test_hidden_scoreboard_contest_normal_user(self):
methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertFalse,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertFalse,
'is_in_contest': self.assertTrue,
}
self._test_contest_user(self.hidden_scoreboard_contest, self.users['normal'], methods)

def test_private_contest_staff_contest_1_user(self):
methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertFalse,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.private_contest, self.users['staff_contest_1'], methods)

def test_private_contest_normal_user(self):
with self.assertRaises(Contest.PrivateContest):
self.private_contest.access_check(self.users['normal'])
self.private_contest.private_contestants.add(self.profiles['normal'])
with self.assertRaises(Contest.PrivateContest):
self.private_contest.access_check(self.users['normal'])
self.private_contest.organizations.add(self.organizations['open'])
self.profiles['normal'].organizations.add(self.organizations['open'])

methods = {
'can_see_own_scoreboard': self.assertTrue,
'can_see_full_scoreboard': self.assertTrue,
'is_accessible_by': self.assertTrue,
'is_editable_by': self.assertFalse,
'is_in_contest': self.assertFalse,
}
self._test_contest_user(self.private_contest, self.users['normal'], methods)

def _test_contest_list_user(self, user):
# We only care about consistency between Contest.is_accessible_by and Contest.get_visible_contests
contest_keys = []
for contest in Contest.objects.all():
if contest.is_accessible_by(user):
contest_keys.append(contest.key)

self.assertListEqual(
list(Contest.get_visible_contests(user).values_list('key', flat=True)),
contest_keys,
)

def test_contests_list_superuser_user(self):
self._test_contest_list_user(self.users['superuser'])

def test_contests_list_staff_contest_1_user(self):
self._test_contest_list_user(self.users['staff_contest_1'])

def test_contests_list_staff_contest_2_user(self):
self._test_contest_list_user(self.users['staff_contest_2'])

def test_contests_list_normal_user(self):
self._test_contest_list_user(self.users['normal'])
Loading

0 comments on commit 32a36de

Please sign in to comment.