Repository: uclouvain/osis-portal

Issue:
NoReverseMatch: Reverse for 'select_internship_speciality' with arguments '()' and keyword arguments '{'specialit...
https://sentry.osis.uclouvain.be/uclouvain/osis-portal/issues/33936/

```
NoReverseMatch: Reverse for 'select_internship_speciality' with arguments '()' and keyword arguments '{'speciality_id': None, 'cohort_id': '2', 'internship_id': '17'}' not found. 1 pattern(s) tried: ['internship/cohort/(?P<cohort_id>[0-9]+)/selection/(?P<internship_id>[0-9]+)/(?P<speciality_id>[0-9]+)/$']
(6 additional frame(s) were not displayed)
...
  File "internship/decorators/global_view_decorators.py", line 39, in wrapper
    response = function(request, *args, **kwargs)
  File "internship/decorators/cohort_view_decorators.py", line 46, in wrapper
    response = function(request, cohort_id, *args, **kwargs)
  File "internship/views/main.py", line 166, in assign_speciality_for_internship
    return redirect("select_internship_speciality", cohort_id=cohort_id, internship_id=internship_id, speciality_id=speciality_id)

NoReverseMatch: Reverse for 'select_internship_speciality' with arguments '()' and keyword arguments '{'speciality_id': None, 'cohort_id': '2', 'internship_id': '17'}' not found. 1 pattern(s) tried: ['internship/cohort/(?P<cohort_id>[0-9]+)/selection/(?P<internship_id>[0-9]+)/(?P<speciality_id>[0-9]+)/$']
```


Discussion:

Resolving patch:
diff --git a/internship/views/main.py b/internship/views/main.py
--- a/internship/views/main.py
+++ b/internship/views/main.py
@@ -24,23 +24,25 @@
 #    see http://www.gnu.org/licenses/.
 #
 ############################################################################
-from django.contrib.auth.decorators import login_required, permission_required
+import datetime
+
 from django.contrib import messages
-from django.core.exceptions import MultipleObjectsReturned
-from django.shortcuts import redirect
+from django.contrib.auth.decorators import login_required, permission_required
 from django.forms import formset_factory
+from django.shortcuts import redirect
 from django.utils.translation import ugettext_lazy as _
-import datetime
+from django.views.decorators.http import require_POST
 
-from base.views import layout
 import base.models as mdl_base
 import internship.models as mdl_internship
-from internship.forms.form_select_speciality import SpecialityForm
-from internship.forms.form_offer_preference import OfferPreferenceFormSet, OfferPreferenceForm
+from base.views import layout
 from dashboard.views import main as dash_main_view
 from internship.decorators.cohort_view_decorators import redirect_if_not_in_cohort
 from internship.decorators.cohort_view_decorators import redirect_if_subscription_not_allowed
 from internship.decorators.global_view_decorators import redirect_if_multiple_registrations
+from internship.forms.form_offer_preference import OfferPreferenceFormSet, OfferPreferenceForm
+from internship.forms.form_select_speciality import SpecialityForm
+
 
 @login_required
 @permission_required('internship.can_access_internship', raise_exception=True)
@@ -151,6 +153,7 @@ def zip_offers_formset_and_first_choices(formset, internships_offers, number_cho
             zipped_data.append((offer, form, number_choices_by_organization.get(offer.organization.id, 0)))
     return zipped_data
 
+@require_POST
 @login_required
 @permission_required('internship.can_access_internship', raise_exception=True)
 @redirect_if_multiple_registrations


Test patch:
diff --git a/internship/tests/views/test_main.py b/internship/tests/views/test_main.py
--- a/internship/tests/views/test_main.py
+++ b/internship/tests/views/test_main.py
@@ -38,7 +38,6 @@
 
 class TestMain(TestCase):
     def setUp(self):
-        self.c = Client()
         self.student = base.tests.models.test_student.create_student("45451298")
         self.user = User.objects.create_user('user', 'user@test.com', 'userpass')
         self.student.person.user = self.user
@@ -50,40 +49,40 @@ def setUp(self):
 
     def test_can_access_internship_home(self):
         home_url = reverse("internship_home", kwargs={'cohort_id': self.cohort.id})
-        response = self.c.get(home_url)
+        response = self.client.get(home_url)
         self.assertEqual(response.status_code, 302)
 
-        self.c.force_login(self.user)
-        response = self.c.get(home_url)
+        self.client.force_login(self.user)
+        response = self.client.get(home_url)
         self.assertEqual(response.status_code, 200)
 
     def test_can_access_internship_selection(self):
         selection_url = reverse("select_internship", kwargs={'cohort_id': self.cohort.id})
-        response = self.c.get(selection_url)
+        response = self.client.get(selection_url)
         self.assertEqual(response.status_code, 302)
 
-        self.c.force_login(self.user)
-        response = self.c.get(selection_url)
+        self.client.force_login(self.user)
+        response = self.client.get(selection_url)
         self.assertEqual(response.status_code, 302) # Now redirected to first internship
 
     def test_can_access_specific_internship_selection(self):
         selection_url = reverse("select_specific_internship", kwargs={'internship_id': self.internship.id, 'cohort_id': self.cohort.id})
-        response = self.c.get(selection_url)
+        response = self.client.get(selection_url)
         self.assertEqual(response.status_code, 302)
 
-        self.c.force_login(self.user)
-        response = self.c.get(selection_url)
+        self.client.force_login(self.user)
+        response = self.client.get(selection_url)
         self.assertEqual(response.status_code, 200)
 
     def test_can_access_internship_selection_with_speciality(self):
         selection_url = reverse("select_internship_speciality", kwargs={'internship_id': self.internship.id,
                                                                         'speciality_id': 1,
                                                                         'cohort_id': self.cohort.id})
-        response = self.c.get(selection_url)
+        response = self.client.get(selection_url)
         self.assertEqual(response.status_code, 302)
 
-        self.c.force_login(self.user)
-        response = self.c.get(selection_url)
+        self.client.force_login(self.user)
+        response = self.client.get(selection_url)
         self.assertEqual(response.status_code, 200)
 
 
@@ -94,8 +93,9 @@ def setUp(self):
         self.student.person.user = user
         self.student.person.save()
         add_permission(self.student.person.user, "can_access_internship")
-        self.c = Client()
-        self.c.force_login(user)
+
+        self.client.force_login(user)
+
         self.cohort = CohortFactory()
         self.internship_1 = InternshipFactory(cohort=self.cohort)
         self.internship_2 = InternshipFactory(cohort=self.cohort)
@@ -130,13 +130,13 @@ def test_with_zero_choices(self):
         selection_url = reverse("select_internship_speciality", kwargs={'internship_id': self.internship_1.id,
                                                                         'speciality_id': self.speciality_1.id,
                                                                         'cohort_id': self.cohort.id})
-        self.assertRaises(ValidationError, self.c.post, selection_url, {})
+        self.assertRaises(ValidationError, self.client.post, selection_url, {})
 
     def test_with_one_choice(self):
         selection_url = reverse("select_internship_speciality", kwargs={'internship_id': self.internship_2.id,
                                                                         'speciality_id': self.speciality_2.id,
                                                                         'cohort_id': self.cohort.id})
-        response = self.c.post(selection_url, data={'form-TOTAL_FORMS': '2',
+        response = self.client.post(selection_url, data={'form-TOTAL_FORMS': '2',
                                          'form-INITIAL_FORMS': '0',
                                          'form-MIN_NUM_FORMS': '2',
                                          'form-MAX_NUM_FORMS': '2',
@@ -156,7 +156,7 @@ def test_with_multiple_choice(self):
         selection_url = reverse("select_internship_speciality", kwargs={'internship_id': self.internship_1.id,
                                                                         'speciality_id': self.speciality_1.id,
                                                                         'cohort_id': self.cohort.id})
-        self.c.post(selection_url, data={'form-TOTAL_FORMS': '4',
+        self.client.post(selection_url, data={'form-TOTAL_FORMS': '4',
                                          'form-INITIAL_FORMS': '0',
                                          'form-MIN_NUM_FORMS': '4',
                                          'form-MAX_NUM_FORMS': '4',
@@ -172,7 +172,7 @@ def test_with_multiple_choice(self):
         choices = list(mdl_internship_choice.search(student=self.student))
         self.assertEqual(len(choices), 4)
 
-        self.c.post(selection_url, data={'form-TOTAL_FORMS': '4',
+        self.client.post(selection_url, data={'form-TOTAL_FORMS': '4',
                                          'form-INITIAL_FORMS': '0',
                                          'form-MIN_NUM_FORMS': '4',
                                          'form-MAX_NUM_FORMS': '4',
@@ -192,7 +192,7 @@ def test_with_incorrect_speciality(self):
         selection_url = reverse("select_internship_speciality", kwargs={'internship_id': self.internship_1.id,
                                                                         'speciality_id': self.speciality_1.id,
                                                                         'cohort_id': self.cohort.id})
-        self.c.post(selection_url, data={'form-TOTAL_FORMS': '4',
+        self.client.post(selection_url, data={'form-TOTAL_FORMS': '4',
                                          'form-INITIAL_FORMS': '0',
                                          'form-MIN_NUM_FORMS': '4',
                                          'form-MAX_NUM_FORMS': '4',
@@ -214,7 +214,7 @@ def test_replace_previous_choices(self):
         selection_url = reverse("select_internship_speciality", kwargs={'internship_id': self.internship_2.id,
                                                                         'speciality_id': self.speciality_2.id,
                                                                         'cohort_id': self.cohort.id})
-        self.c.post(selection_url, data={'form-TOTAL_FORMS': '2',
+        self.client.post(selection_url, data={'form-TOTAL_FORMS': '2',
                                          'form-INITIAL_FORMS': '0',
                                          'form-MIN_NUM_FORMS': '2',
                                          'form-MAX_NUM_FORMS': '2',
@@ -238,7 +238,7 @@ def test_two_personal_internships_at_most(self):
         selection_url = reverse("select_internship_speciality", kwargs={'internship_id': InternshipFactory(cohort=self.cohort).id,
                                                                         'speciality_id': speciality.id,
                                                                         'cohort_id': self.cohort.id})
-        self.c.post(selection_url, data={'form-TOTAL_FORMS': '1',
+        self.client.post(selection_url, data={'form-TOTAL_FORMS': '1',
                                          'form-INITIAL_FORMS': '0',
                                          'form-MIN_NUM_FORMS': '1',
                                          'form-MAX_NUM_FORMS': '1',
@@ -257,3 +257,13 @@ def add_permission(user, codename):
 
 def get_permission(codename):
     return Permission.objects.get(codename=codename)
+
+
+class TestMainAccess(TestCase):
+    def test_assign_speciality_for_internship_get_error(self):
+        url = reverse('assign_speciality', kwargs={
+            'cohort_id': 0,
+            'internship_id': 1,
+        })
+        response = self.client.get(url)
+        self.assertEqual(response.status_code, 405)
\ No newline at end of file