diff --git a/src/apps/api/serializers/competitions.py b/src/apps/api/serializers/competitions.py index c18eff0a7..0314d831d 100644 --- a/src/apps/api/serializers/competitions.py +++ b/src/apps/api/serializers/competitions.py @@ -171,6 +171,10 @@ class CompetitionUpdateSerializer(CompetitionSerializer): queue = None +class CompetitionCreateSerializer(CompetitionSerializer): + queue = None + + class CompetitionDetailSerializer(serializers.ModelSerializer): created_by = serializers.CharField(source='created_by.username', read_only=True) pages = PageSerializer(many=True) diff --git a/src/apps/api/tests/test_competitions.py b/src/apps/api/tests/test_competitions.py index 7617dfbd2..989f668f4 100644 --- a/src/apps/api/tests/test_competitions.py +++ b/src/apps/api/tests/test_competitions.py @@ -8,7 +8,7 @@ from rest_framework.test import APITestCase from api.serializers.competitions import CompetitionSerializer -from competitions.models import CompetitionParticipant, Submission +from competitions.models import CompetitionParticipant, Submission, Competition from factories import UserFactory, CompetitionFactory, CompetitionParticipantFactory, PhaseFactory, LeaderboardFactory, \ ColumnFactory, SubmissionFactory, SubmissionScoreFactory, TaskFactory @@ -75,6 +75,13 @@ def test_adding_organizer_accepts_them_if_they_were_existing_participant(self): status=CompetitionParticipant.APPROVED ).count() == 1 + def test_delete_own_competition(self): + self.client.login(username='creator', password='creator') + url = reverse('competition-detail', kwargs={"pk": self.comp.pk}) + resp = self.client.delete(url) + assert resp.status_code == 204 + assert not Competition.objects.filter(pk=self.comp.pk).exists() + class PhaseMigrationTests(APITestCase): def setUp(self): diff --git a/src/apps/api/views/competitions.py b/src/apps/api/views/competitions.py index 12a40cf6e..d27a3fe5e 100644 --- a/src/apps/api/views/competitions.py +++ b/src/apps/api/views/competitions.py @@ -23,9 +23,9 @@ from api.pagination import LargePagination from api.renderers import ZipRenderer from rest_framework.viewsets import ModelViewSet -from api.serializers.competitions import CompetitionSerializer, CompetitionSerializerSimple, PhaseSerializer, \ +from api.serializers.competitions import CompetitionSerializerSimple, PhaseSerializer, \ CompetitionCreationTaskStatusSerializer, CompetitionDetailSerializer, CompetitionParticipantSerializer, \ - FrontPageCompetitionsSerializer, PhaseResultsSerializer, CompetitionUpdateSerializer + FrontPageCompetitionsSerializer, PhaseResultsSerializer, CompetitionUpdateSerializer, CompetitionCreateSerializer from api.serializers.leaderboards import LeaderboardPhaseSerializer, LeaderboardSerializer from competitions.emails import send_participation_requested_emails, send_participation_accepted_emails, \ send_participation_denied_emails, send_direct_participant_email @@ -146,7 +146,8 @@ def get_serializer_class(self): elif self.request.method == 'PATCH': return CompetitionUpdateSerializer else: - return CompetitionSerializer + # Really just CompetitionSerializer with queue = None + return CompetitionCreateSerializer def create(self, request, *args, **kwargs): """Mostly a copy of the underlying base create, however we return some additional data @@ -158,7 +159,6 @@ def create(self, request, *args, **kwargs): # TODO - This is Temporary. Need to change Leaderboard to Phase connect to M2M and handle this correctly. # save leaderboard individually, then pass pk to each phase - print(f"{request.data['leaderboards']}") data = request.data if 'leaderboards' in data: leaderboard_data = data['leaderboards'][0] diff --git a/src/apps/competitions/unpackers/v1.py b/src/apps/competitions/unpackers/v1.py index ed7c6dc85..449569667 100644 --- a/src/apps/competitions/unpackers/v1.py +++ b/src/apps/competitions/unpackers/v1.py @@ -143,7 +143,8 @@ def _unpack_leaderboards(self): except KeyError: raise CompetitionUnpackingException('Could not find leaderboards declared on the competition leaderboard') try: - columns = sorted([{'title': k, **v} for k, v in leaderboard['columns'].items()], key=lambda c: c['rank']) + # use rank = 1 if rank is not defined in .yaml file + columns = sorted([{'title': k, **v} for k, v in leaderboard['columns'].items()], key=lambda c: c.get('rank', 1)) except KeyError: raise CompetitionUnpackingException('Could not find columns declared on the competition leaderboard') diff --git a/src/apps/datasets/migrations/0007_auto_20230609_1738.py b/src/apps/datasets/migrations/0007_auto_20230609_1738.py new file mode 100644 index 000000000..f54d966c8 --- /dev/null +++ b/src/apps/datasets/migrations/0007_auto_20230609_1738.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.17 on 2023-06-09 17:38 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('datasets', '0006_auto_20230528_0829'), + ] + + operations = [ + migrations.AlterField( + model_name='data', + name='competition', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='submission', to='competitions.Competition'), + ), + ] diff --git a/src/apps/datasets/models.py b/src/apps/datasets/models.py index 3d97e8b45..48d50f3f3 100644 --- a/src/apps/datasets/models.py +++ b/src/apps/datasets/models.py @@ -58,7 +58,7 @@ class Data(ChaHubSaveMixin, models.Model): # are NOT marked True, since they are not created by unpacking! was_created_by_competition = models.BooleanField(default=False) - competition = models.ForeignKey(Competition, on_delete=models.PROTECT, null=True, related_name='submission') + competition = models.ForeignKey(Competition, on_delete=models.CASCADE, null=True, related_name='submission') file_name = models.CharField(max_length=64, default="") def get_download_url(self): diff --git a/src/static/riot/competitions/editor/_competition_details.tag b/src/static/riot/competitions/editor/_competition_details.tag index a91445998..419fddec7 100644 --- a/src/static/riot/competitions/editor/_competition_details.tag +++ b/src/static/riot/competitions/editor/_competition_details.tag @@ -88,7 +88,7 @@
- +
diff --git a/src/static/riot/competitions/editor/_phases.tag b/src/static/riot/competitions/editor/_phases.tag index 532f49500..e2dc437c1 100644 --- a/src/static/riot/competitions/editor/_phases.tag +++ b/src/static/riot/competitions/editor/_phases.tag @@ -267,8 +267,10 @@ self.has_initialized_calendars = true } - $(self.refs.calendar_start).calendar('set date', self.phases[self.selected_phase_index].start) - $(self.refs.calendar_end).calendar('set date', self.phases[self.selected_phase_index].end) + if(!(self.selected_phase_index === undefined)){ + $(self.refs.calendar_start).calendar('set date', self.phases[self.selected_phase_index].start) + $(self.refs.calendar_end).calendar('set date', self.phases[self.selected_phase_index].end) + } } self.close_modal = function () { diff --git a/src/static/riot/competitions/public-list.tag b/src/static/riot/competitions/public-list.tag index 66c087599..20d77b2eb 100644 --- a/src/static/riot/competitions/public-list.tag +++ b/src/static/riot/competitions/public-list.tag @@ -1,6 +1,6 @@

Public Competitions

-
+
{ current_page } of {Math.ceil(competitions.count/competitions.page_size)} @@ -32,7 +32,7 @@
-
+
{ current_page } of {Math.ceil(competitions.count/competitions.page_size)} diff --git a/src/static/riot/datasets/management.tag b/src/static/riot/datasets/management.tag index 3f802592e..281eff368 100644 --- a/src/static/riot/datasets/management.tag +++ b/src/static/riot/datasets/management.tag @@ -116,7 +116,7 @@ {selected_row.key} - {selected_row.created_by} + {selected_row.created_by} {pretty_date(selected_row.created_when)} {_.startCase(selected_row.type)} {_.startCase(selected_row.is_public)} diff --git a/src/static/riot/submissions/resource_submissions.tag b/src/static/riot/submissions/resource_submissions.tag index 719676109..fa14093a0 100644 --- a/src/static/riot/submissions/resource_submissions.tag +++ b/src/static/riot/submissions/resource_submissions.tag @@ -112,7 +112,7 @@ { selected_row.competition.title } - {selected_row.created_by} + {selected_row.created_by} {pretty_date(selected_row.created_when)} {_.startCase(selected_row.type)} {_.startCase(selected_row.is_public)} diff --git a/src/static/riot/tasks/management.tag b/src/static/riot/tasks/management.tag index b262d5fd7..abe2e365e 100644 --- a/src/static/riot/tasks/management.tag +++ b/src/static/riot/tasks/management.tag @@ -96,7 +96,7 @@

{selected_task.description}

-
Created By: {selected_task.created_by}
+
Key: {selected_task.key}
Has Been Validated diff --git a/src/templates/pages/home.html b/src/templates/pages/home.html index 12c322157..1d7cef45f 100644 --- a/src/templates/pages/home.html +++ b/src/templates/pages/home.html @@ -9,7 +9,7 @@
-

BETA

+
{% endblock %} @@ -23,10 +23,8 @@

BETA

+

Welcome to Codabench!

-
-

Welcome to Codabench Beta !

-