diff --git a/tcms/testplans/tests/test_views.py b/tcms/testplans/tests/test_views.py
index 9f1b10764b..f17ffef692 100644
--- a/tcms/testplans/tests/test_views.py
+++ b/tcms/testplans/tests/test_views.py
@@ -7,8 +7,9 @@
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
-from tcms.tests import BasePlanCase, remove_perm_from_user
-from tcms.tests.factories import TagFactory, UserFactory
+from tcms.tests import BasePlanCase, LoggedInTestCase, remove_perm_from_user, user_should_have_perm
+from tcms.tests.factories import (TagFactory, UserFactory, TestPlanFactory,
+ ProductFactory, VersionFactory, PlanTypeFactory)
from tcms.utils.permissions import initiate_user_with_default_setups
@@ -54,3 +55,125 @@ def test_view_tags_without_permissions(self):
# assert tag actions are shown
self.assertNotContains(response, 'Add Tag')
self.assertContains(response, '%s' % _('Remove'))
+
+
+class EditPlanViewTest(LoggedInTestCase):
+ test_plan_name = 'plan name'
+
+ @classmethod
+ def setUpTestData(cls):
+ super().setUpTestData()
+
+ user_should_have_perm(cls.tester, perm='testplans.change_testplan')
+ cls.product = ProductFactory()
+ cls.product_version = VersionFactory(product=cls.product)
+ cls.test_plan_type = PlanTypeFactory()
+ cls.test_plan_1 = TestPlanFactory()
+ cls.testplan_edit_url = reverse('plan-edit', args=[cls.test_plan_1.pk])
+
+ cls.testplan_edit_data = {
+ 'author': cls.tester.pk,
+ 'product': cls.product.pk,
+ 'product_version': cls.product_version.pk,
+ 'type': cls.test_plan_type.pk,
+ 'name': cls.test_plan_1.name,
+
+ 'email_settings-0-auto_to_plan_author': 'off',
+ 'email_settings-0-auto_to_case_owner': 'off',
+ 'email_settings-0-auto_to_case_default_tester': 'off',
+ 'email_settings-0-notify_on_case_update': 'off',
+ 'email_settings-0-notify_on_plan_update': 'off',
+
+ 'email_settings-0-id': cls.test_plan_1.emailing.pk,
+ 'email_settings-TOTAL_FORMS': '1',
+ 'email_settings-INITIAL_FORMS': '1',
+ 'email_settings-MIN_NUM_FORMS': '0',
+ 'email_settings-MAX_NUM_FORMS': '1',
+ 'is_active': True,
+ }
+
+ def test_show_testplan_edit_page(self):
+ response = self.client.get(self.testplan_edit_url)
+ self.assertContains(response, _('Edit TestPlan'))
+ self.assert_notify_form(response)
+ self.assertContains(
+ response,
+ '',
+ html=True)
+
+ def test_edit_testplan_text_field(self):
+ edit_data = self.testplan_edit_data.copy()
+ new_text = 'Edited: {0}'.format(self.test_plan_1.text)
+ edit_data['text'] = new_text
+
+ response = self.client.post(self.testplan_edit_url, data=edit_data, follow=True)
+
+ self.assertContains(response, new_text, html=True)
+ self.test_plan_1.refresh_from_db()
+ self.assertEqual(new_text, self.test_plan_1.text)
+
+ # Issue: When there is an invalid value on notify_formset,
+ # returned response is always the default (ON).
+ def test_with_invalid_notify_form_value(self):
+ test_plan = TestPlanFactory(
+ author=self.tester)
+
+ testplan_edit_url = reverse('plan-edit', args=[test_plan.pk])
+ edit_data = self.testplan_edit_data.copy()
+ edit_data['email_settings-0-auto_to_plan_author'] = 'invalid_value'
+
+ response = self.client.post(testplan_edit_url, data=edit_data, follow=True)
+
+ self.assert_notify_form(response)
+
+ def test_with_invalid_product_shows_error(self):
+ edit_data = self.testplan_edit_data.copy()
+ edit_data['product'] = -1
+
+ response = self.client.post(self.testplan_edit_url, data=edit_data, follow=True)
+
+ self.assertContains(
+ response,
+ _('Select a valid choice. That choice is not one of the available choices.'))
+
+ def test_with_invalid_type_shows_error(self):
+ edit_data = self.testplan_edit_data.copy()
+ edit_data['type'] = -1
+
+ response = self.client.post(self.testplan_edit_url, data=edit_data, follow=True)
+
+ self.assertContains(
+ response,
+ _('Select a valid choice. That choice is not one of the available choices.'))
+
+ def test_with_invalid_version_shows_error(self):
+ edit_data = self.testplan_edit_data.copy()
+ edit_data['product_version'] = -1
+
+ response = self.client.post(self.testplan_edit_url, data=edit_data, follow=True)
+
+ self.assertContains(
+ response,
+ _('Select a valid choice. That choice is not one of the available choices.'))
+
+ def assert_notify_form(self, response):
+ self.assertContains(
+ response,
+ '', html=True)
+ self.assertContains(
+ response,
+ '', html=True)
+ self.assertContains(
+ response,
+ '', html=True)
+ self.assertContains(
+ response,
+ '', html=True)
+ self.assertContains(
+ response,
+ '', html=True)
diff --git a/tcms/testplans/views.py b/tcms/testplans/views.py
index 221e4b4050..eb652fd127 100644
--- a/tcms/testplans/views.py
+++ b/tcms/testplans/views.py
@@ -85,7 +85,13 @@ def form_valid(self, form):
return super().form_valid(form)
# taken from FormMixin.form_invalid()
- return self.render_to_response(self.get_context_data(notify_formset=notify_formset))
+ context_data = self.get_context_data(form=form, notify_formset=notify_formset)
+ return self.render_to_response(context_data)
+
+ def form_invalid(self, form):
+ notify_formset = PlanNotifyFormSet(self.request.POST, instance=self.object)
+ context_data = self.get_context_data(form=form, notify_formset=notify_formset)
+ return self.render_to_response(context_data)
class SearchTestPlanView(TemplateView): # pylint: disable=missing-permission-required