Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix commit unless managed #162

Merged
merged 2 commits into from Mar 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 12 additions & 12 deletions tcms/testcases/models.py
Expand Up @@ -529,29 +529,29 @@ def mail(self, template, subject, context={}, to=[], request=None):
mailto(template, subject, to, context, request)

def remove_bug(self, bug_id, run_id=None):
cursor = connection.writer_cursor
sql = SQL.REMOVE_BUG
args = [bug_id, self.pk]
if run_id:
sql = SQL.REMOVE_BUG_WITH_RUN_ID
args.append(run_id)
cursor.execute(sql, args)
transaction.commit_unless_managed()
with transaction.atomic():
cursor = connection.writer_cursor
cursor.execute(sql, args)

def remove_component(self, component):
cursor = connection.writer_cursor
cursor.execute(SQL.REMOVE_COMPONENT, (self.case_id, component.id))
transaction.commit_unless_managed()
with transaction.atomic():
cursor = connection.writer_cursor
cursor.execute(SQL.REMOVE_COMPONENT, (self.case_id, component.id))

def remove_plan(self, plan):
cursor = connection.writer_cursor
cursor.execute(SQL.REMOVE_PLAN, (plan.plan_id, self.case_id))
transaction.commit_unless_managed()
with transaction.atomic():
cursor = connection.writer_cursor
cursor.execute(SQL.REMOVE_PLAN, (plan.plan_id, self.case_id))

def remove_tag(self, tag):
cursor = connection.writer_cursor
cursor.execute(SQL.REMOVE_TAG, (self.pk, tag.pk))
transaction.commit_unless_managed()
with transaction.atomic():
cursor = connection.writer_cursor
cursor.execute(SQL.REMOVE_TAG, (self.pk, tag.pk))

def get_url_path(self, request=None):
return reverse('tcms.testcases.views.get', args=[self.pk, ])
Expand Down
174 changes: 174 additions & 0 deletions tcms/testcases/tests.py
Expand Up @@ -5,6 +5,17 @@
from django.forms import ValidationError

from fields import MultipleEmailField
from tcms.testcases.models import TestCaseBugSystem
from tcms.testcases.models import TestCasePlan
from tcms.tests import BasePlanCase
from tcms.tests.factories import ComponentFactory
from tcms.tests.factories import TestBuildFactory
from tcms.tests.factories import TestCaseComponentFactory
from tcms.tests.factories import TestCaseFactory
from tcms.tests.factories import TestCaseRunFactory
from tcms.tests.factories import TestCaseTagFactory
from tcms.tests.factories import TestRunFactory
from tcms.tests.factories import TestTagFactory


class TestMultipleEmailField(unittest.TestCase):
Expand Down Expand Up @@ -52,3 +63,166 @@ def test_clean(self):
self.field.required = False
data = self.field.clean(value)
self.assertEqual(data, [])


class TestCaseRemoveBug(BasePlanCase):
"""Test TestCase.remove_bug"""

@classmethod
def setUpClass(cls):
super(TestCaseRemoveBug, cls).setUpClass()
cls.build = TestBuildFactory(product=cls.product)
cls.test_run = TestRunFactory(product_version=cls.version, plan=cls.plan,
manager=cls.tester, default_tester=cls.tester)
cls.case_run = TestCaseRunFactory(assignee=cls.tester, tested_by=cls.tester,
case=cls.case, run=cls.test_run, build=cls.build)
cls.bug_system = TestCaseBugSystem.objects.get(name='Bugzilla')

@classmethod
def tearDownClass(cls):
cls.case_run.delete()
cls.test_run.delete()
cls.build.delete()
super(TestCaseRemoveBug, cls).tearDownClass()

def setUp(self):
self.bug_id_1 = '12345678'
self.case.add_bug(self.bug_id_1, self.bug_system.pk,
summary='error when add a bug to a case')
self.bug_id_2 = '10000'
self.case.add_bug(self.bug_id_2, self.bug_system.pk, case_run=self.case_run)

def tearDown(self):
self.case.case_bug.all().delete()

def test_remove_case_bug(self):
self.case.remove_bug(self.bug_id_1)

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_1).exists()
self.assertFalse(bug_found)

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_2).exists()
self.assertTrue(bug_found,
'Bug {0} does not exist. It should not be deleted.'.format(self.bug_id_2))

def test_case_bug_not_removed_by_passing_case_run(self):
self.case.remove_bug(self.bug_id_1, run_id=self.case_run.pk)

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_1).exists()
self.assertTrue(bug_found,
'Bug {0} does not exist. It should not be deleted.'.format(self.bug_id_1))

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_2).exists()
self.assertTrue(bug_found,
'Bug {0} does not exist. It should not be deleted.'.format(self.bug_id_2))

def test_remove_case_run_bug(self):
self.case.remove_bug(self.bug_id_2, run_id=self.case_run.pk)

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_2).exists()
self.assertFalse(bug_found)

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_1).exists()
self.assertTrue(bug_found,
'Bug {0} does not exist. It should not be deleted.'.format(self.bug_id_1))

def test_case_run_bug_not_removed_by_missing_case_run(self):
self.case.remove_bug(self.bug_id_2)

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_1).exists()
self.assertTrue(bug_found,
'Bug {0} does not exist. It should not be deleted.'.format(self.bug_id_1))

bug_found = self.case.case_bug.filter(bug_id=self.bug_id_2).exists()
self.assertTrue(bug_found,
'Bug {0} does not exist. It should not be deleted.'.format(self.bug_id_2))


class TestCaseRemoveComponent(BasePlanCase):
"""Test TestCase.remove_component"""

@classmethod
def setUpClass(cls):
super(TestCaseRemoveComponent, cls).setUpClass()

cls.component_1 = ComponentFactory(name='Application',
product=cls.product,
initial_owner=cls.tester,
initial_qa_contact=cls.tester)
cls.component_2 = ComponentFactory(name='Database',
product=cls.product,
initial_owner=cls.tester,
initial_qa_contact=cls.tester)

cls.cc_rel_1 = TestCaseComponentFactory(case=cls.case, component=cls.component_1)
cls.cc_rel_2 = TestCaseComponentFactory(case=cls.case, component=cls.component_2)

@classmethod
def tearDownClass(cls):
cls.cc_rel_1.delete()
cls.cc_rel_2.delete()
cls.component_1.delete()
cls.component_2.delete()
super(TestCaseRemoveComponent, cls).tearDownClass()

def test_remove_a_component(self):
self.case.remove_component(self.component_1)

found = self.case.component.filter(pk=self.component_1.pk).exists()
self.assertFalse(
found, 'Component {0} exists. But, it should be removed.'.format(self.component_1.pk))
found = self.case.component.filter(pk=self.component_2.pk).exists()
self.assertTrue(
found,
'Component {0} does not exist. It should not be removed.'.format(self.component_2.pk))


class TestCaseRemovePlan(BasePlanCase):
"""Test TestCase.remove_plan"""

@classmethod
def setUpClass(cls):
super(TestCaseRemovePlan, cls).setUpClass()

cls.new_case = TestCaseFactory(author=cls.tester, default_tester=None, reviewer=cls.tester,
plan=[cls.plan])

@classmethod
def tearDownClass(cls):
TestCasePlan.objects.filter(plan=cls.plan, case=cls.new_case).delete()
cls.new_case.delete()
super(TestCaseRemovePlan, cls).tearDownClass()

def test_remove_plan(self):
self.new_case.remove_plan(self.plan)

found = self.plan.case.filter(pk=self.new_case.pk).exists()
self.assertFalse(
found, 'Case {0} should has no relationship to plan {0} now.'.format(self.new_case.pk,
self.plan.pk))


class TestCaseRemoveTag(BasePlanCase):
"""Test TestCase.remove_tag"""

@classmethod
def setUpClass(cls):
super(TestCaseRemoveTag, cls).setUpClass()

cls.tag_rhel = TestTagFactory(name='rhel')
cls.tag_fedora = TestTagFactory(name='fedora')
TestCaseTagFactory(case=cls.case, tag=cls.tag_rhel, user=cls.tester.pk)
TestCaseTagFactory(case=cls.case, tag=cls.tag_fedora, user=cls.tester.pk)

@classmethod
def tearDownClass(cls):
cls.case.tag.clear()
cls.tag_rhel.delete()
cls.tag_fedora.delete()
super(TestCaseRemoveTag, cls).tearDownClass()

def test_remove_tag(self):
self.case.remove_tag(self.tag_rhel)

tag_pks = list(self.case.tag.all().values_list('pk', flat=True))
self.assertEqual([self.tag_fedora.pk], tag_pks)
74 changes: 74 additions & 0 deletions tcms/testruns/tests.py
@@ -1 +1,75 @@
# -*- coding: utf-8 -*-

import httplib

from django import test
from django.core.urlresolvers import reverse

from tcms.testruns.models import TestRun
from tcms.testruns.models import TestCaseRun
from tcms.tests import BasePlanCase
from tcms.tests.factories import TestRunFactory
from tcms.tests.factories import TestBuildFactory
from tcms.tests.factories import TestCaseRunFactory


# ### Test case for View methods ###


class TestOrderCases(BasePlanCase):
"""Test view method order_case"""

@classmethod
def setUpClass(cls):
super(TestOrderCases, cls).setUpClass()
cls.build = TestBuildFactory(product=cls.product)
cls.test_run = TestRunFactory(product_version=cls.version, plan=cls.plan,
manager=cls.tester, default_tester=cls.tester)
cls.case_run_1 = TestCaseRunFactory(assignee=cls.tester, tested_by=cls.tester,
run=cls.test_run, case=cls.case_1, build=cls.build,
sortkey=101)
cls.case_run_2 = TestCaseRunFactory(assignee=cls.tester, tested_by=cls.tester,
run=cls.test_run, case=cls.case_2, build=cls.build,
sortkey=200)
cls.case_run_3 = TestCaseRunFactory(assignee=cls.tester, tested_by=cls.tester,
run=cls.test_run, case=cls.case_3, build=cls.build,
sortkey=300)

@classmethod
def tearDownClass(cls):
cls.case_run_1.delete()
cls.case_run_2.delete()
cls.case_run_3.delete()
cls.test_run.delete()
cls.build.delete()
super(TestOrderCases, cls).tearDownClass()

def setUp(self):
self.client = test.Client()

def test_404_if_run_does_not_exist(self):
nonexisting_run_pk = TestRun.objects.count() + 1
url = reverse('tcms.testruns.views.order_case', args=[nonexisting_run_pk])
response = self.client.get(url)
self.assertEqual(httplib.NOT_FOUND, response.status_code)

def test_prompt_if_no_case_run_is_passed(self):
url = reverse('tcms.testruns.views.order_case', args=[self.test_run.pk])
response = self.client.get(url)
self.assertIn('At least one case is required by re-oder in run', response.content)

def test_order_case_runs(self):
url = reverse('tcms.testruns.views.order_case', args=[self.test_run.pk])
response = self.client.get(url, {'case_run': [self.case_run_1.pk,
self.case_run_2.pk,
self.case_run_3.pk]})

redirect_to = reverse('tcms.testruns.views.get', args=[self.test_run.pk])
self.assertRedirects(response, redirect_to)

test_sortkeys = [
TestCaseRun.objects.get(pk=self.case_run_1.pk).sortkey,
TestCaseRun.objects.get(pk=self.case_run_2.pk).sortkey,
TestCaseRun.objects.get(pk=self.case_run_3.pk).sortkey,
]
self.assertEqual([10, 20, 30], test_sortkeys)
17 changes: 7 additions & 10 deletions tcms/testruns/views.py
Expand Up @@ -1240,9 +1240,7 @@ def order_case(request, run_id):
))

case_run_ids = request.REQUEST.getlist('case_run')
sql = 'UPDATE `test_case_runs` SET `sortkey` = %s WHERE `test_case_runs`' \
'.`case_run_id` = %s'
cursor = connection.writer_cursor
sql = 'UPDATE test_case_runs SET sortkey = %s WHERE test_case_runs.case_run_id = %s'
# sort key begin with 10, end with length*10, step 10.
# e.g.
# case_run_ids = [10334, 10294, 10315, 10443]
Expand All @@ -1256,14 +1254,13 @@ def order_case(request, run_id):
# (30, 10315)
# (40, 10443)
new_sort_keys = xrange(10, (len(case_run_ids) + 1) * 10, 10)
key_id_pairs = itertools.izip(new_sort_keys, case_run_ids)
for key_id_pair in key_id_pairs:
cursor.execute(sql, key_id_pair)
transaction.commit_unless_managed()
key_id_pairs = itertools.izip(new_sort_keys, (int(pk) for pk in case_run_ids))
with transaction.atomic():
for key_id_pair in key_id_pairs:
cursor = connection.writer_cursor
cursor.execute(sql, key_id_pair)

return HttpResponseRedirect(
reverse('tcms.testruns.views.get', args=[run_id, ])
)
return HttpResponseRedirect(reverse('tcms.testruns.views.get', args=[run_id]))


@user_passes_test(lambda u: u.has_perm('testruns.change_testrun'))
Expand Down
46 changes: 46 additions & 0 deletions tcms/tests/__init__.py
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-

from django import test

from tcms.tests.factories import ProductFactory
from tcms.tests.factories import TestCaseFactory
from tcms.tests.factories import TestPlanFactory
from tcms.tests.factories import UserFactory
from tcms.tests.factories import VersionFactory


class BasePlanCase(test.TestCase):
"""Base test case by providing essential Plan and Case objects used in tests"""

@classmethod
def setUpClass(cls):
super(BasePlanCase, cls).setUpClass()

cls.product = ProductFactory(name='Nitrate')
cls.version = VersionFactory(value='0.1', product=cls.product)
cls.tester = UserFactory()
cls.plan = TestPlanFactory(author=cls.tester, owner=cls.tester,
product=cls.product, product_version=cls.version)
cls.case = TestCaseFactory(author=cls.tester, default_tester=None, reviewer=cls.tester,
plan=[cls.plan])
cls.case_1 = TestCaseFactory(author=cls.tester, default_tester=None, reviewer=cls.tester,
plan=[cls.plan])
cls.case_2 = TestCaseFactory(author=cls.tester, default_tester=None, reviewer=cls.tester,
plan=[cls.plan])
cls.case_3 = TestCaseFactory(author=cls.tester, default_tester=None, reviewer=cls.tester,
plan=[cls.plan])

@classmethod
def tearDownClass(cls):
cls.case.plan.clear()
cls.case.delete()
cls.case_1.delete()
cls.case_2.delete()
cls.case_3.delete()
cls.plan.delete()
cls.plan.type.delete()
cls.tester.delete()
cls.version.delete()
cls.product.delete()
cls.product.classification.delete()
super(BasePlanCase, cls).tearDownClass()
2 changes: 1 addition & 1 deletion tcms/tests/factories.py
Expand Up @@ -443,7 +443,7 @@ class Meta:

case = factory.SubFactory(TestCaseFactory)
tag = factory.SubFactory(TestTagFactory)
user = factory.SubFactory(UserFactory)
user = 0


class TestCaseTextFactory(DjangoModelFactory):
Expand Down