Merge lp:~abentley/launchpad/user-blueprints-tests into lp:launchpad

Proposed by Aaron Bentley
Status: Merged
Merged at revision: 16157
Proposed branch: lp:~abentley/launchpad/user-blueprints-tests
Merge into: lp:launchpad
Diff against target: 241 lines (+215/-1)
2 files modified
lib/lp/registry/tests/test_person.py (+213/-0)
lib/lp/testing/factory.py (+2/-1)
To merge this branch: bzr merge lp:~abentley/launchpad/user-blueprints-tests
Reviewer Review Type Date Requested Status
Richard Harding (community) Approve
Review via email: mp+129944@code.launchpad.net

Commit message

Add tests for Person.specifications.

Description of the change

= Summary =
Add tests for Person.specifications.

== Pre-implementation notes ==
None

== LOC Rationale ==
Part of private projects

== Implementation details ==
This branch adds tests for Person.specifications, so that a follow-on branch can re-write it to use Storm expressions. Many of these tests were copied from the tests for Sprint.specifications.

== Tests ==
bin/test -t TestSpecifications test_person

== Demo and Q/A ==
None

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/testing/factory.py
  lib/lp/registry/tests/test_person.py

To post a comment you must log in.
Revision history for this message
Richard Harding (rharding) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/registry/tests/test_person.py'
--- lib/lp/registry/tests/test_person.py 2012-09-28 06:15:58 +0000
+++ lib/lp/registry/tests/test_person.py 2012-10-16 16:52:26 +0000
@@ -24,6 +24,14 @@
24from lp.answers.model.answercontact import AnswerContact24from lp.answers.model.answercontact import AnswerContact
25from lp.app.enums import InformationType25from lp.app.enums import InformationType
26from lp.app.interfaces.launchpad import ILaunchpadCelebrities26from lp.app.interfaces.launchpad import ILaunchpadCelebrities
27from lp.blueprints.enums import (
28 NewSpecificationDefinitionStatus,
29 SpecificationDefinitionStatus,
30 SpecificationImplementationStatus,
31 SpecificationPriority,
32 SpecificationFilter,
33 SpecificationSort,
34 )
27from lp.blueprints.model.specification import Specification35from lp.blueprints.model.specification import Specification
28from lp.bugs.interfaces.bugtasksearch import (36from lp.bugs.interfaces.bugtasksearch import (
29 get_person_bugtasks_search_params,37 get_person_bugtasks_search_params,
@@ -1550,3 +1558,208 @@
1550 # 10. One to get all distroseries of a bug's distro. (See comment on1558 # 10. One to get all distroseries of a bug's distro. (See comment on
1551 # getAssignedBugTasksDueBefore() to understand why it's needed)1559 # getAssignedBugTasksDueBefore() to understand why it's needed)
1552 self.assertThat(recorder, HasQueryCount(Equals(12)))1560 self.assertThat(recorder, HasQueryCount(Equals(12)))
1561
1562
1563def list_result(sprint, filter=None, user=None):
1564 result = sprint.specifications(user, SpecificationSort.DATE, filter=filter)
1565 return list(result)
1566
1567
1568class TestSpecifications(TestCaseWithFactory):
1569
1570 layer = DatabaseFunctionalLayer
1571
1572 def setUp(self):
1573 super(TestSpecifications, self).setUp()
1574 self.date_created = datetime.now(pytz.utc)
1575
1576 def makeSpec(self, owner=None, date_created=0, title=None,
1577 status=NewSpecificationDefinitionStatus.NEW,
1578 name=None, priority=None, information_type=None):
1579 blueprint = self.factory.makeSpecification(
1580 title=title, status=status, name=name, priority=priority,
1581 information_type=information_type, owner=owner,
1582 )
1583 removeSecurityProxy(blueprint).datecreated = (
1584 self.date_created + timedelta(date_created))
1585 return blueprint
1586
1587 def test_specifications_quantity(self):
1588 # Ensure the quantity controls the maximum number of entries.
1589 owner = self.factory.makePerson()
1590 for count in range(10):
1591 self.factory.makeSpecification(owner=owner)
1592 self.assertEqual(10, owner.specifications(None).count())
1593 result = owner.specifications(None, quantity=None).count()
1594 self.assertEqual(10, result)
1595 self.assertEqual(8, owner.specifications(None, quantity=8).count())
1596 self.assertEqual(10, owner.specifications(None, quantity=11).count())
1597
1598 def test_date_sort(self):
1599 # Sort on date_created.
1600 owner = self.factory.makePerson()
1601 blueprint1 = self.makeSpec(owner, date_created=0)
1602 blueprint2 = self.makeSpec(owner, date_created=-1)
1603 blueprint3 = self.makeSpec(owner, date_created=1)
1604 result = list_result(owner)
1605 self.assertEqual([blueprint3, blueprint1, blueprint2], result)
1606
1607 def test_date_sort_id(self):
1608 # date-sorting when no date varies uses object id.
1609 owner = self.factory.makePerson()
1610 blueprint1 = self.makeSpec(owner)
1611 blueprint2 = self.makeSpec(owner)
1612 blueprint3 = self.makeSpec(owner)
1613 result = list_result(owner)
1614 self.assertEqual([blueprint1, blueprint2, blueprint3], result)
1615
1616 def test_priority_sort(self):
1617 # Sorting by priority works and is the default.
1618 # When priority is supplied, status is ignored.
1619 blueprint1 = self.makeSpec(priority=SpecificationPriority.UNDEFINED,
1620 status=SpecificationDefinitionStatus.NEW)
1621 owner = blueprint1.owner
1622 blueprint2 = self.makeSpec(
1623 owner, priority=SpecificationPriority.NOTFORUS,
1624 status=SpecificationDefinitionStatus.APPROVED)
1625 blueprint3 = self.makeSpec(
1626 owner, priority=SpecificationPriority.LOW,
1627 status=SpecificationDefinitionStatus.NEW)
1628 result = owner.specifications(None)
1629 self.assertEqual([blueprint3, blueprint1, blueprint2], list(result))
1630 result = owner.specifications(None, sort=SpecificationSort.PRIORITY)
1631 self.assertEqual([blueprint3, blueprint1, blueprint2], list(result))
1632
1633 def test_priority_sort_fallback_status(self):
1634 # Sorting by priority falls back to defintion_status.
1635 # When status is supplied, name is ignored.
1636 blueprint1 = self.makeSpec(
1637 status=SpecificationDefinitionStatus.NEW, name='a')
1638 owner = blueprint1.owner
1639 blueprint2 = self.makeSpec(
1640 owner, status=SpecificationDefinitionStatus.APPROVED, name='c')
1641 blueprint3 = self.makeSpec(
1642 owner, status=SpecificationDefinitionStatus.DISCUSSION, name='b')
1643 result = owner.specifications(None)
1644 self.assertEqual([blueprint2, blueprint3, blueprint1], list(result))
1645 result = owner.specifications(None, sort=SpecificationSort.PRIORITY)
1646 self.assertEqual([blueprint2, blueprint3, blueprint1], list(result))
1647
1648 def test_priority_sort_fallback_name(self):
1649 # Sorting by priority falls back to name
1650 blueprint1 = self.makeSpec(name='b')
1651 owner = blueprint1.owner
1652 blueprint2 = self.makeSpec(owner, name='c')
1653 blueprint3 = self.makeSpec(owner, name='a')
1654 result = owner.specifications(None)
1655 self.assertEqual([blueprint3, blueprint1, blueprint2], list(result))
1656 result = owner.specifications(None, sort=SpecificationSort.PRIORITY)
1657 self.assertEqual([blueprint3, blueprint1, blueprint2], list(result))
1658
1659 def test_ignore_inactive(self):
1660 # Specs for inactive products are skipped.
1661 product = self.factory.makeProduct()
1662 with celebrity_logged_in('admin'):
1663 product.active = False
1664 spec = self.factory.makeSpecification(product=product)
1665 self.assertNotIn(spec, spec.owner.specifications(None))
1666
1667 def test_include_distro(self):
1668 # Specs for distributions are included.
1669 distribution = self.factory.makeDistribution()
1670 spec = self.factory.makeSpecification(distribution=distribution)
1671 self.assertIn(spec, spec.owner.specifications(None))
1672
1673 def test_informational(self):
1674 # INFORMATIONAL causes only informational specs to be shown.
1675 enum = SpecificationImplementationStatus
1676 informational = self.factory.makeSpecification(
1677 implementation_status=enum.INFORMATIONAL)
1678 owner = informational.owner
1679 plain = self.factory.makeSpecification(owner=owner)
1680 result = owner.specifications(None)
1681 self.assertIn(informational, result)
1682 self.assertIn(plain, result)
1683 result = owner.specifications(
1684 None, filter=[SpecificationFilter.INFORMATIONAL])
1685 self.assertIn(informational, result)
1686 self.assertNotIn(plain, result)
1687
1688 def test_completeness(self):
1689 # If COMPLETE is specified, completed specs are listed. If INCOMPLETE
1690 # is specified or neither is specified, only incomplete specs are
1691 # listed.
1692 enum = SpecificationImplementationStatus
1693 implemented = self.factory.makeSpecification(
1694 implementation_status=enum.IMPLEMENTED)
1695 owner = implemented.owner
1696 non_implemented = self.factory.makeSpecification(owner=owner)
1697 result = owner.specifications(
1698 None, filter=[SpecificationFilter.COMPLETE])
1699 self.assertIn(implemented, result)
1700 self.assertNotIn(non_implemented, result)
1701
1702 result = owner.specifications(
1703 None, filter=[SpecificationFilter.INCOMPLETE])
1704 self.assertNotIn(implemented, result)
1705 self.assertIn(non_implemented, result)
1706 result = owner.specifications(
1707 None)
1708 self.assertNotIn(implemented, result)
1709 self.assertIn(non_implemented, result)
1710
1711 def test_all(self):
1712 # ALL causes both complete and incomplete to be listed.
1713 enum = SpecificationImplementationStatus
1714 implemented = self.factory.makeSpecification(
1715 implementation_status=enum.IMPLEMENTED)
1716 owner = implemented.owner
1717 non_implemented = self.factory.makeSpecification(owner=owner)
1718 result = owner.specifications(None, filter=[SpecificationFilter.ALL])
1719 self.assertContentEqual([implemented, non_implemented], result)
1720
1721 def test_valid(self):
1722 # VALID adjusts COMPLETE to exclude OBSOLETE and SUPERSEDED specs.
1723 # (INCOMPLETE already excludes OBSOLETE and SUPERSEDED.)
1724 i_enum = SpecificationImplementationStatus
1725 d_enum = SpecificationDefinitionStatus
1726 implemented = self.factory.makeSpecification(
1727 implementation_status=i_enum.IMPLEMENTED)
1728 owner = implemented.owner
1729 self.factory.makeSpecification(owner=owner, status=d_enum.SUPERSEDED)
1730 self.factory.makeSpecification(owner=owner, status=d_enum.OBSOLETE)
1731 filter = [SpecificationFilter.VALID, SpecificationFilter.COMPLETE]
1732 results = owner.specifications(None, filter=filter)
1733 self.assertContentEqual([implemented], results)
1734
1735 def test_roles(self):
1736 # If roles are specified, they control which specifications are shown.
1737 # If no roles are specified, all roles are used.
1738 created = self.factory.makeSpecification()
1739 person = created.owner
1740
1741 def rlist(filter=None):
1742 return list(person.specifications(None, filter=filter))
1743 assigned = self.factory.makeSpecification(assignee=person)
1744 drafting = self.factory.makeSpecification(drafter=person)
1745 approving = self.factory.makeSpecification(approver=person)
1746 subscribed = self.factory.makeSpecification()
1747 subscribed.subscribe(person)
1748 self.assertEqual([created, assigned, drafting, approving, subscribed],
1749 rlist([]))
1750 self.assertEqual([created], rlist([SpecificationFilter.CREATOR]))
1751 self.assertEqual([assigned], rlist([SpecificationFilter.ASSIGNEE]))
1752 self.assertEqual([drafting], rlist([SpecificationFilter.DRAFTER]))
1753 self.assertEqual([approving], rlist([SpecificationFilter.APPROVER]))
1754 self.assertEqual([subscribed],
1755 rlist([SpecificationFilter.SUBSCRIBER]))
1756
1757 def test_text_search(self):
1758 # Text searches work.
1759 blueprint1 = self.makeSpec(title='abc')
1760 owner = blueprint1.owner
1761 blueprint2 = self.makeSpec(owner, title='def')
1762 result = list_result(owner, ['abc'])
1763 self.assertEqual([blueprint1], result)
1764 result = list_result(owner, ['def'])
1765 self.assertEqual([blueprint2], result)
15531766
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2012-10-15 23:20:25 +0000
+++ lib/lp/testing/factory.py 2012-10-16 16:52:26 +0000
@@ -2129,7 +2129,8 @@
2129 if status.name not in status_names:2129 if status.name not in status_names:
2130 # Set the closed status after the status has a sane initial state.2130 # Set the closed status after the status has a sane initial state.
2131 naked_spec.definition_status = status2131 naked_spec.definition_status = status
2132 if status == SpecificationDefinitionStatus.OBSOLETE:2132 if status in (SpecificationDefinitionStatus.OBSOLETE,
2133 SpecificationDefinitionStatus.SUPERSEDED):
2133 # This is to satisfy a DB constraint of obsolete specs.2134 # This is to satisfy a DB constraint of obsolete specs.
2134 naked_spec.completer = owner2135 naked_spec.completer = owner
2135 naked_spec.date_completed = datetime.now(pytz.UTC)2136 naked_spec.date_completed = datetime.now(pytz.UTC)