Repository: carpentries/amy

Issue:
Allow pre-population of Group in training request form
It would be nice to be able to allow a pass through of the group_name in order to pre-populate the form with the appropriate group name. I have a group that would like to open up applications in their organization and then be able to go through a process in conjunction with us to help select the instructors who will be trained.

This feature would allow us to sent out a URL which is something like:
`https://amy.software-carpentry.org/workshops/request_training/?id_group_name=Thisisatest`

From my read of [this stackoverflow](http://stackoverflow.com/questions/25173991/how-to-pre-populate-django-form-with-part-of-url) topic I think it would be a slight tweak to the View to make it happen.

Allow pre-population of Group in training request form
It would be nice to be able to allow a pass through of the group_name in order to pre-populate the form with the appropriate group name. I have a group that would like to open up applications in their organization and then be able to go through a process in conjunction with us to help select the instructors who will be trained.

This feature would allow us to sent out a URL which is something like:
`https://amy.software-carpentry.org/workshops/request_training/?id_group_name=Thisisatest`

From my read of [this stackoverflow](http://stackoverflow.com/questions/25173991/how-to-pre-populate-django-form-with-part-of-url) topic I think it would be a slight tweak to the View to make it happen.



Discussion:
See also #877.

See also #877.


Resolving patch:
diff --git a/extforms/views.py b/extforms/views.py
--- a/extforms/views.py
+++ b/extforms/views.py
@@ -259,11 +259,13 @@ def trainingrequest_create(request):
     """A form to let all users (no login required) to request Instructor
     Training."""
 
-    form = TrainingRequestForm()
+    group_name = request.GET.get('group', None) or None  # replace empty string with None
+    form = TrainingRequestForm(initial_group_name=group_name)
+
     page_title = 'Apply for Instructor Training'
 
     if request.method == 'POST':
-        form = TrainingRequestForm(request.POST)
+        form = TrainingRequestForm(request.POST, initial_group_name=group_name)
 
         if form.is_valid():
             form.save()
diff --git a/workshops/forms.py b/workshops/forms.py
--- a/workshops/forms.py
+++ b/workshops/forms.py
@@ -1107,6 +1107,15 @@ class Meta:
             'max_travelling_frequency': forms.RadioSelect(),
         }
 
+    def __init__(self, *args, initial_group_name=None, **kwargs):
+        initial = kwargs.pop('initial', {})
+        if initial_group_name is not None:
+            initial['group_name'] = initial_group_name
+        super().__init__(*args, initial=initial, **kwargs)
+        if initial_group_name is not None:
+            field = self.fields['group_name']
+            field.widget = field.hidden_widget()
+
 
 class TrainingRequestUpdateForm(forms.ModelForm):
     person = selectable.AutoCompleteSelectField(


Test patch:
diff --git a/extforms/test/__init__.py b/extforms/test/__init__.py
new file mode 100644
diff --git a/extforms/test/test_training_request_form.py b/extforms/test/test_training_request_form.py
new file mode 100644
--- /dev/null
+++ b/extforms/test/test_training_request_form.py
@@ -0,0 +1,127 @@
+from django.core.urlresolvers import reverse
+
+from workshops.models import Person, Role, TrainingRequest
+from workshops.test import TestBase
+
+
+class TestTrainingRequestForm(TestBase):
+    def setUp(self):
+        self._setUpRoles()
+
+    def test_request_added(self):
+        data = {
+            'group': 'coolprogrammers',
+            'personal': 'John',
+            'family': 'Smith',
+            'email': 'john@smith.com',
+            'github': '',
+            'occupation': '',
+            'occupation_other': 'unemployed',
+            'affiliation': 'AGH University of Science and Technology',
+            'location': 'Cracow',
+            'country': 'PL',
+            'domains': [1, 2],
+            'domains_other': '',
+            'gender': Person.MALE,
+            'gender_other': '',
+            'previous_involvement': [Role.objects.get(name='host').id],
+            'previous_training': 'none',
+            'previous_training_other': '',
+            'previous_training_explanation': '',
+            'previous_experience': 'none',
+            'previous_experience_other': '',
+            'previous_experience_explanation': '',
+            'programming_language_usage_frequency': 'daily',
+            'reason': 'Just for fun.',
+            'teaching_frequency_expectation': 'often',
+            'teaching_frequency_expectation_other': '',
+            'max_travelling_frequency': 'yearly',
+            'max_travelling_frequency_other': '',
+            'addition_skills': '',
+            'comment': '',
+            'agreed_to_code_of_conduct': 'on',
+            'agreed_to_complete_training': 'on',
+            'agreed_to_teach_workshops': 'on',
+            'privacy_consent': True,
+            'recaptcha_response_field': 'PASSED',
+        }
+        rv = self.client.post(reverse('training_request'), data,
+                              follow=True)
+        self.assertEqual(rv.status_code, 200)
+        content = rv.content.decode('utf-8')
+        self._save_html(content)
+        self.assertNotIn('Fix errors below', content)
+        self.assertEqual(TrainingRequest.objects.all().count(), 1)
+
+
+class GroupNameFieldTestsBase(TestBase):
+    """Tests for [#1005] feature -- Allow pre-population of Group in training
+    request form.
+
+    [#1005]: https://github.com/swcarpentry/amy/issues/1005"""
+
+    url_suffix = ''
+
+    def setUp(self):
+        url = reverse('training_request') + self.url_suffix
+        self.form = self.app.get(url).form
+
+    def fillin_and_submit(self):
+        # fillin the form
+        self.form['personal'] = 'John'
+        self.form['family'] = 'Smith'
+        self.form['email'] = 'john@smith.com'
+        self.form['affiliation'] = 'AGH University of Science and Technology'
+        self.form['location'] = 'Cracow'
+        self.form['country'] = 'PL'
+        self.form['reason'] = 'Just for fun.'
+        self.form['agreed_to_code_of_conduct'] = True
+        self.form['agreed_to_complete_training'] = True
+        self.form['agreed_to_teach_workshops'] = True
+        self.form['privacy_consent'] = True
+        self.form['recaptcha_response_field'] = 'PASSED'
+
+        # submit the form
+        self.rs = self.form.submit()
+
+    def assertSubmissionIsRecorded(self, with_group_name):
+        # the form should be successfully submitted
+        self.assertEqual(self.rs.status_code, 200)
+
+        # submission should be recorded
+        self.assertEqual(TrainingRequest.objects.count(), 1)
+
+        # with right group name
+        request = TrainingRequest.objects.first()
+        self.assertEqual(request.group_name, with_group_name)
+
+
+class WhenGroupNameIsPrefilledIn(GroupNameFieldTestsBase):
+    url_suffix = '?group=asdf qwer'
+
+    def test_then_the_group_name_field_should_be_not_displayed(self):
+        self.assertEqual(self.form['group_name'].attrs.get('type'), 'hidden')
+
+    def test_then_the_prefilled_in_value_should_be_used(self):
+        self.fillin_and_submit()
+        self.assertSubmissionIsRecorded(with_group_name='asdf qwer')
+
+
+class WhenNoGroupNameIsPrefilledIn(GroupNameFieldTestsBase):
+    url_suffix = ''
+
+    def test_group_field_should_be_displayed(self):
+        self.assertNotEqual(self.form['group_name'].attrs.get('type'), 'hidden')
+
+    def test_group_name_field_should_be_optional(self):
+        self.fillin_and_submit()
+        self.assertSubmissionIsRecorded(with_group_name='')
+
+    def test_group_name_provided_by_user_should_be_used(self):
+        self.form['group_name'] = 'asdf'
+        self.fillin_and_submit()
+        self.assertSubmissionIsRecorded(with_group_name='asdf')
+
+
+class WhenEmptyGroupNameIsPrefilledIn(WhenNoGroupNameIsPrefilledIn):
+    url_suffix = '?group='
diff --git a/workshops/test/test_training_request.py b/workshops/test/test_training_request.py
--- a/workshops/test/test_training_request.py
+++ b/workshops/test/test_training_request.py
@@ -15,57 +15,6 @@
 )
 
 
-class TestTrainingRequestForm(TestBase):
-    def setUp(self):
-        self._setUpUsersAndLogin()
-        self._setUpRoles()
-
-    def test_request_added(self):
-        data = {
-            'group': 'coolprogrammers',
-            'personal': 'John',
-            'family': 'Smith',
-            'email': 'john@smith.com',
-            'github': '',
-            'occupation': '',
-            'occupation_other': 'unemployed',
-            'affiliation': 'AGH University of Science and Technology',
-            'location': 'Cracow',
-            'country': 'PL',
-            'domains': [1, 2],
-            'domains_other': '',
-            'gender': Person.MALE,
-            'gender_other': '',
-            'previous_involvement': [Role.objects.get(name='host').id],
-            'previous_training': 'none',
-            'previous_training_other': '',
-            'previous_training_explanation': '',
-            'previous_experience': 'none',
-            'previous_experience_other': '',
-            'previous_experience_explanation': '',
-            'programming_language_usage_frequency': 'daily',
-            'reason': 'Just for fun.',
-            'teaching_frequency_expectation': 'often',
-            'teaching_frequency_expectation_other': '',
-            'max_travelling_frequency': 'yearly',
-            'max_travelling_frequency_other': '',
-            'addition_skills': '',
-            'comment': '',
-            'agreed_to_code_of_conduct': 'on',
-            'agreed_to_complete_training': 'on',
-            'agreed_to_teach_workshops': 'on',
-            'privacy_consent': True,
-            'recaptcha_response_field': 'PASSED',
-        }
-        rv = self.client.post(reverse('training_request'), data,
-                              follow=True)
-        self.assertEqual(rv.status_code, 200)
-        content = rv.content.decode('utf-8')
-        self._save_html(content)
-        self.assertNotIn('Fix errors below', content)
-        self.assertEqual(TrainingRequest.objects.all().count(), 1)
-
-
 def create_training_request(state, person):
     return TrainingRequest.objects.create(
         personal='John',