Skip to content

Commit

Permalink
Clone TP: always 'Copy All Test Cases' & keep default tester
Browse files Browse the repository at this point in the history
the original label of this checkbox is misleading. It was meant to
mean that all test cases from the source TP will be included in the
destination TP.

In addition this field was named link_testcases which together with
copy_testcases were controlling if TCs will be just added to the
new TP (aka link via m2m relationship) or cloned with new TC PKs.
The two options are opposite so it doesn't makes sense to keep
only 1 of the two boolean fields to control this behavior.

Always keep the Default tester for test cases
  • Loading branch information
atodorov committed Jul 24, 2019
1 parent 8452b57 commit a9c7ccf
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 105 deletions.
18 changes: 0 additions & 18 deletions tcms/static/js/testplan_actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -638,24 +638,6 @@ Nitrate.TestPlans.Clone.on_load = function() {
configure_product_on_load();
update_version_select_from_product($('#id_product'), '#id_product_version')

jQ('#id_link_testcases').bind('change', function(e) {
if (this.checked) {
this.parentNode.parentNode.className = 'choose';
jQ('#id_clone_case_zone')[0].style.display = 'block';
} else {
this.parentNode.parentNode.className = 'unchoose';
jQ('#id_clone_case_zone')[0].style.display = 'none';
}
});

jQ('#id_copy_testcases').bind('change', function(e) {
if (this.checked) {
jQ('#id_keep_case_default_tester')[0].disabled = false;
} else {
jQ('#id_keep_case_default_tester')[0].disabled = true;
}
});

jQ('.js-cancel-button').bind('click', function() {
window.history.back();
});
Expand Down
2 changes: 0 additions & 2 deletions tcms/templates/plan/clone.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ <h2>{% trans "Clone TestPlan" %} {{ test_plan.name }}</h2>
<li>{{ clone_form.set_parent }}{{ clone_form.set_parent.label }} ({{ clone_form.set_parent.help_text }})</li>
<li>
<fieldset class="choose">
<legend>{{ clone_form.link_testcases }}{% trans "Copy" %} {{ clone_form.link_testcases.label }}</legend>
<ul id="id_clone_case_zone" style="display:block ;list-style-type:none;">
<li>{{ clone_form.copy_testcases }}{{ clone_form.copy_testcases.label }} ({{ clone_form.copy_testcases.help_text }})</li>
<li>{{ clone_form.keep_case_default_tester }}{{ clone_form.keep_case_default_tester.label }} ({{ clone_form.keep_case_default_tester.help_text }})</li>
</ul>
</fieldset>
</li>
Expand Down
9 changes: 0 additions & 9 deletions tcms/testplans/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,11 @@ class ClonePlanForm(BasePlanForm):
queryset=PlanType.objects.all(),
required=False,
)
link_testcases = forms.BooleanField(
label='All Test Cases',
required=False
)
copy_testcases = forms.BooleanField(
label='Create a copy',
help_text='Unchecking will create a link to selected plans',
required=False
)
keep_case_default_tester = forms.BooleanField(
label='Keep Default Tester',
help_text='Unchecking will make me the default tester of copied cases',
required=False
)
set_parent = forms.BooleanField(
label='Set source plan as parent',
help_text='Check it to set the source plan as parent of new cloned '
Expand Down
85 changes: 38 additions & 47 deletions tcms/testplans/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,7 @@ def make_cloned_name(self):

def clone(self, new_name=None, product=None, version=None,
new_author=None, set_parent=True,
link_cases=True, copy_cases=None,
new_case_default_tester=None,
copy_cases=None,
default_component_initial_owner=None):
"""Clone this plan
Expand All @@ -164,10 +163,8 @@ def clone(self, new_name=None, product=None, version=None,
author is used.
:param bool set_parent: Whether to set original plan as parent of cloned plan.
Set by default.
:param bool link_cases: Whether to link cases to cloned plan. Default is True.
:param bool copy_cases: Whether to copy cases to cloned plan instead of just linking them.
Default is False.
:param new_case_default_tester: The default tester of copied cases. Used only if copy cases.
:param default_component_initial_owner: Used only if copy cases. If copied case does not
have original case' component, create it and use this value as the initial_owner.
:rtype: cloned plan
Expand All @@ -192,54 +189,48 @@ def clone(self, new_name=None, product=None, version=None,
for tp_tag_src in self.tag.all():
tp_dest.add_tag(tag=tp_tag_src)

# Link the cases of the plan
if link_cases:
tpcases_src = self.case.all()
# include TCs inside cloned TP
for tpcase_src in self.case.all():
tcp = get_object_or_404(TestCasePlan, plan=self, case=tpcase_src)

if copy_cases:
# todo: use the function which clones the test cases instead of
# duplicating the clone operation here
for tpcase_src in tpcases_src:
tcp = get_object_or_404(TestCasePlan, plan=self, case=tpcase_src)
default_tester = new_case_default_tester or tpcase_src.default_tester

tc_category, _ = Category.objects.get_or_create(
name=tpcase_src.category.name, product=product)

tpcase_dest = TestCase.objects.create(
create_date=tpcase_src.create_date,
is_automated=tpcase_src.is_automated,
script=tpcase_src.script,
arguments=tpcase_src.arguments,
summary=tpcase_src.summary,
requirement=tpcase_src.requirement,
case_status=TestCaseStatus.get_proposed(),
category=tc_category,
priority=tpcase_src.priority,
author=new_author,
default_tester=default_tester,
text=tpcase_src.text)

# Add case to plan.
tp_dest.add_case(tpcase_dest, tcp.sortkey)

for tc_tag_src in tpcase_src.tag.all():
tpcase_dest.add_tag(tag=tc_tag_src)

for component in tpcase_src.component.filter(product__id=self.product_id):
try:
new_c = tp_dest.product.component.get(name=component.name)
except ObjectDoesNotExist:
new_c = tp_dest.product.component.create(
name=component.name,
initial_owner=default_component_initial_owner,
description=component.description)

tpcase_dest.add_component(new_c)
tc_category, _ = Category.objects.get_or_create(
name=tpcase_src.category.name, product=product)

tpcase_dest = TestCase.objects.create(
create_date=tpcase_src.create_date,
is_automated=tpcase_src.is_automated,
script=tpcase_src.script,
arguments=tpcase_src.arguments,
summary=tpcase_src.summary,
requirement=tpcase_src.requirement,
case_status=TestCaseStatus.get_proposed(),
category=tc_category,
priority=tpcase_src.priority,
author=new_author,
default_tester=tpcase_src.default_tester,
text=tpcase_src.text)

# Add case to plan.
tp_dest.add_case(tpcase_dest, tcp.sortkey)

for tc_tag_src in tpcase_src.tag.all():
tpcase_dest.add_tag(tag=tc_tag_src)

for component in tpcase_src.component.filter(product__id=self.product_id):
try:
new_c = tp_dest.product.component.get(name=component.name)
except ObjectDoesNotExist:
new_c = tp_dest.product.component.create(
name=component.name,
initial_owner=default_component_initial_owner,
description=component.description)

tpcase_dest.add_component(new_c)
else:
for tpcase_src in tpcases_src:
tcp = get_object_or_404(TestCasePlan, plan=self, case=tpcase_src)
tp_dest.add_case(tpcase_src, tcp.sortkey)
tp_dest.add_case(tpcase_src, tcp.sortkey)

return tp_dest

Expand Down
29 changes: 8 additions & 21 deletions tcms/testplans/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,17 +443,15 @@ def test_open_clone_page_to_clone_one_plan(self):
self.plan.name),
html=True)

def verify_cloned_plan(self, original_plan, cloned_plan,
link_cases=True, copy_cases=None,
keep_case_default_tester=None):
def verify_cloned_plan(self, original_plan, cloned_plan, copy_cases=None):
self.assertEqual('Copy of {}'.format(original_plan.name), cloned_plan.name)
self.assertEqual(cloned_plan.text, original_plan.text)
self.assertEqual(Product.objects.get(pk=self.product.pk), cloned_plan.product)
self.assertEqual(Version.objects.get(pk=self.version.pk), cloned_plan.product_version)

self._verify_options(original_plan, cloned_plan, copy_cases, link_cases)
self._verify_options(original_plan, cloned_plan, copy_cases)

if link_cases and copy_cases:
if copy_cases:
# Ensure cases of original plan are not linked to cloned plan
for case in original_plan.case.all():
original_case_not_linked_to_cloned_plan = TestCasePlan.objects.filter(
Expand All @@ -470,18 +468,14 @@ def verify_cloned_plan(self, original_plan, cloned_plan,
else:
self.assertEqual(self.plan_tester, copied_case.author)

if keep_case_default_tester:
self.assertEqual(original_case.default_tester, copied_case.default_tester)
else:
me = self.plan_tester
self.assertEqual(me, copied_case.default_tester)
self.assertEqual(original_case.default_tester, copied_case.default_tester)

def _verify_options(self, original_plan, cloned_plan, copy_cases, link_cases):
def _verify_options(self, original_plan, cloned_plan, copy_cases):
# Verify option set_parent
self.assertEqual(TestPlan.objects.get(pk=original_plan.pk), cloned_plan.parent)

# Verify options link_testcases and copy_testcases
if link_cases and not copy_cases:
# Verify option copy_testcases
if not copy_cases:
for case in original_plan.case.all():
is_case_linked = TestCasePlan.objects.filter(plan=cloned_plan, case=case).exists()
self.assertTrue(is_case_linked)
Expand All @@ -493,8 +487,6 @@ def test_clone_a_plan_with_default_options(self):
'product': self.product.pk,
'product_version': self.version.pk,
'set_parent': 'on',
'link_testcases': 'on',
'keep_case_default_tester': 'on',
'submit': 'Clone',
}
self.client.login( # nosec:B106:hardcoded_password_funcarg
Expand All @@ -518,8 +510,6 @@ def test_clone_a_plan_by_copying_cases(self):
'product': self.product.pk,
'product_version': self.version.pk,
'set_parent': 'on',
'link_testcases': 'on',
'keep_case_default_tester': 'on',
'submit': 'Clone',

'copy_testcases': 'on',
Expand All @@ -529,9 +519,7 @@ def test_clone_a_plan_by_copying_cases(self):
password='password')
self.client.post(self.plan_clone_url, post_data)
cloned_plan = TestPlan.objects.get(name=self.totally_new_plan.make_cloned_name())
self.verify_cloned_plan(self.totally_new_plan, cloned_plan,
copy_cases=True,
keep_case_default_tester=True)
self.verify_cloned_plan(self.totally_new_plan, cloned_plan, copy_cases=True)

def test_clone_a_plan_by_setting_me_to_copied_cases_author_default_tester(self):
post_data = {
Expand All @@ -540,7 +528,6 @@ def test_clone_a_plan_by_setting_me_to_copied_cases_author_default_tester(self):
'product': self.product.pk,
'product_version': self.version.pk,
'set_parent': 'on',
'link_testcases': 'on',
'submit': 'Clone',

'copy_testcases': 'on',
Expand Down
8 changes: 0 additions & 8 deletions tcms/testplans/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,20 +372,12 @@ def clone(request):
set_parent=clone_options['set_parent'],

# Link or copy cases
link_cases=clone_options['link_testcases'],
copy_cases=clone_options['copy_testcases'],
default_component_initial_owner=request.user,
)

clone_params['new_author'] = request.user

# pylint: disable=invalid-name
assign_me_as_copied_case_default_tester = \
clone_options['copy_testcases'] and \
not clone_options['keep_case_default_tester']
if assign_me_as_copied_case_default_tester:
clone_params['new_case_default_tester'] = request.user

cloned_plan = test_plan.clone(**clone_params)

return HttpResponseRedirect(
Expand Down

0 comments on commit a9c7ccf

Please sign in to comment.