diff --git a/amy/trainings/forms.py b/amy/trainings/forms.py index bfb2838b2..4fe487b7f 100644 --- a/amy/trainings/forms.py +++ b/amy/trainings/forms.py @@ -95,6 +95,13 @@ class BulkAddTrainingProgressForm(forms.ModelForm): required=True, ) + involvement_type = forms.ModelChoiceField( + label="Type of involvement", + required=False, + queryset=Involvement.objects.default_order().filter(archived_at__isnull=True), + widget=RadioSelect(), + ) + helper = BootstrapHelper( additional_form_class="training-progress", submit_label="Add", @@ -106,8 +113,10 @@ class BulkAddTrainingProgressForm(forms.ModelForm): # the template where this form is used "requirement", "state", + "involvement_type", "event", "url", + "date", "notes", ) @@ -117,11 +126,16 @@ class Meta: # no 'trainees' "requirement", "state", + "involvement_type", "event", "url", + "date", "notes", ] widgets = { "state": RadioSelect, "notes": TextInput, } + + class Media: + js = ("trainingprogress_form.js",) diff --git a/amy/trainings/tests/test_trainees.py b/amy/trainings/tests/test_trainees.py index eccd70d5f..2c1cacde3 100644 --- a/amy/trainings/tests/test_trainees.py +++ b/amy/trainings/tests/test_trainees.py @@ -28,10 +28,14 @@ def setUp(self): self._setUpRoles() self.training = TrainingRequirement.objects.get(name="Training") - self.lesson_contribution, _ = TrainingRequirement.objects.get_or_create( - name="Lesson Contribution", defaults={"url_required": True} + self.get_involved, _ = TrainingRequirement.objects.get_or_create( + name="Get Involved", defaults={"involvement_required": True} ) self.welcome = TrainingRequirement.objects.get(name="Welcome Session") + self.demo = TrainingRequirement.objects.get(name="Demo") + self.involvement, _ = Involvement.objects.get_or_create( + name="GitHub Contribution", defaults={"url_required": True} + ) self.ttt_event = Event.objects.create( start=datetime(2018, 7, 14), @@ -40,11 +44,23 @@ def setUp(self): ) self.ttt_event.tags.add(Tag.objects.get(name="TTT")) + # add some training tasks + self.ironman.task_set.create( + event=self.ttt_event, + role=Role.objects.get(name="learner"), + ) + self.spiderman.task_set.create( + event=self.ttt_event, + role=Role.objects.get(name="learner"), + ) + def test_view_loads(self): rv = self.client.get(reverse("all_trainees")) self.assertEqual(rv.status_code, 200) - def test_bulk_add_progress(self): + def test_bulk_add_progress__welcome(self): + # Arrange + # create a pre-existing progress to ensure bulk adding doesn't interfere TrainingProgress.objects.create( trainee=self.spiderman, requirement=self.welcome, state="n" ) @@ -55,22 +71,15 @@ def test_bulk_add_progress(self): "submit": "", } - # all trainees need to have a training task to assign a training - # progress to them - self.ironman.task_set.create( - event=self.ttt_event, - role=Role.objects.get(name="learner"), - ) - self.spiderman.task_set.create( - event=self.ttt_event, - role=Role.objects.get(name="learner"), - ) - + # Act rv = self.client.post(reverse("all_trainees"), data, follow=True) + # Assert + self.assertEqual(rv.status_code, 200) self.assertEqual(rv.resolver_match.view_name, "all_trainees") msg = "Successfully changed progress of all selected trainees." self.assertContains(rv, msg) + got = set( TrainingProgress.objects.values_list("trainee", "requirement", "state") ) @@ -81,6 +90,111 @@ def test_bulk_add_progress(self): } self.assertEqual(got, expected) + def test_bulk_add_progress__training(self): + # Arrange + # create a pre-existing progress to ensure bulk adding doesn't interfere + TrainingProgress.objects.create( + trainee=self.spiderman, requirement=self.training, state="n" + ) + data = { + "trainees": [self.spiderman.pk, self.ironman.pk], + "requirement": self.training.pk, + "state": "a", + "event": self.ttt_event.pk, + "submit": "", + } + + # Act + rv = self.client.post(reverse("all_trainees"), data, follow=True) + + # Assert + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv.resolver_match.view_name, "all_trainees") + msg = "Successfully changed progress of all selected trainees." + self.assertContains(rv, msg) + + got = set( + TrainingProgress.objects.values_list("trainee", "requirement", "state") + ) + expected = { + (self.spiderman.pk, self.training.pk, "n"), + (self.spiderman.pk, self.training.pk, "a"), + (self.ironman.pk, self.training.pk, "a"), + } + self.assertEqual(got, expected) + + def test_bulk_add_progress__demo(self): + # Arrange + # create a pre-existing progress to ensure bulk adding doesn't interfere + TrainingProgress.objects.create( + trainee=self.spiderman, requirement=self.demo, state="n" + ) + data = { + "trainees": [self.spiderman.pk, self.ironman.pk], + "requirement": self.demo.pk, + "state": "a", + "submit": "", + } + + # Act + rv = self.client.post(reverse("all_trainees"), data, follow=True) + + # Assert + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv.resolver_match.view_name, "all_trainees") + msg = "Successfully changed progress of all selected trainees." + self.assertContains(rv, msg) + + got = set( + TrainingProgress.objects.values_list("trainee", "requirement", "state") + ) + expected = { + (self.spiderman.pk, self.demo.pk, "n"), + (self.spiderman.pk, self.demo.pk, "a"), + (self.ironman.pk, self.demo.pk, "a"), + } + self.assertEqual(got, expected) + + def test_bulk_add_progress__get_involved(self): + # Arrange + # create a pre-existing progress to ensure bulk adding doesn't interfere + TrainingProgress.objects.create( + trainee=self.spiderman, + requirement=self.get_involved, + state="n", + involvement_type=self.involvement, + url="https://example.org", + date=date(2022, 5, 3), + ) + data = { + "trainees": [self.spiderman.pk, self.ironman.pk], + "requirement": self.get_involved.pk, + "state": "a", + "involvement_type": self.involvement.pk, + "url": "https://example.org", + "date": "2023-6-21", + "submit": "", + } + + # Act + rv = self.client.post(reverse("all_trainees"), data, follow=True) + + # Assert + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv.resolver_match.view_name, "all_trainees") + msg = "Successfully changed progress of all selected trainees." + self.assertContains(rv, msg) + + got = set( + TrainingProgress.objects.values_list("trainee", "requirement", "state") + ) + expected = { + (self.spiderman.pk, self.get_involved.pk, "n"), + (self.spiderman.pk, self.get_involved.pk, "a"), + (self.ironman.pk, self.get_involved.pk, "a"), + } + self.assertEqual(got, expected) + class TestFilterTraineesByInstructorStatus(TestBase): def _setUpPermissions(self):