← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~finnrg/launchpad:feat/LP-2653-getMergeProposals-date-filtering into launchpad:master

 

Finn Gärtner has proposed merging ~finnrg/launchpad:feat/LP-2653-getMergeProposals-date-filtering into launchpad:master.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~finnrg/launchpad/+git/launchpad/+merge/491799
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~finnrg/launchpad:feat/LP-2653-getMergeProposals-date-filtering into launchpad:master.
diff --git a/lib/lp/code/interfaces/webservice.py b/lib/lp/code/interfaces/webservice.py
index 568f4a9..90dff64 100644
--- a/lib/lp/code/interfaces/webservice.py
+++ b/lib/lp/code/interfaces/webservice.py
@@ -79,7 +79,7 @@ from lp.code.interfaces.sourcepackagerecipe import ISourcePackageRecipe
 from lp.code.interfaces.sourcepackagerecipebuild import (
     ISourcePackageRecipeBuild,
 )
-from lp.registry.interfaces.person import IPerson
+from lp.registry.interfaces.person import IPerson, IPersonViewRestricted
 from lp.registry.interfaces.product import IProduct
 from lp.registry.interfaces.sourcepackage import ISourcePackage
 from lp.services.fields import InlineObject
@@ -260,3 +260,8 @@ patch_collection_property(
 patch_collection_property(
     ISourcePackageRecipe, "completed_builds", ISourcePackageRecipeBuild
 )
+
+# IPersonViewRestricted
+patch_collection_return_type(
+    IPersonViewRestricted, "getMergeProposals", IBranchMergeProposal
+)
diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py
index 848383d..0e1704f 100644
--- a/lib/lp/code/model/branchcollection.py
+++ b/lib/lp/code/model/branchcollection.py
@@ -376,6 +376,8 @@ class GenericBranchCollection:
         prerequisite_branch=None,
         merged_revnos=None,
         merged_revision=None,
+        created_before=None,
+        created_since=None,
         eager_load=False,
     ):
         """See `IBranchCollection`."""
@@ -392,6 +394,8 @@ class GenericBranchCollection:
             or prerequisite_branch is not None
             or merged_revnos is not None
             or merged_revision is not None
+            or created_before is not None
+            or created_since is not None
         ):
             return self._naiveGetMergeProposals(
                 statuses,
@@ -400,6 +404,8 @@ class GenericBranchCollection:
                 prerequisite_branch,
                 merged_revnos,
                 merged_revision,
+                created_before=created_before,
+                created_since=created_since,
                 eager_load=eager_load,
             )
         else:
@@ -418,6 +424,8 @@ class GenericBranchCollection:
         prerequisite_branch=None,
         merged_revnos=None,
         merged_revision=None,
+        created_before=None,
+        created_since=None,
         eager_load=False,
     ):
         Target = ClassAlias(Branch, "target")
@@ -478,6 +486,14 @@ class GenericBranchCollection:
             expressions.append(
                 BranchMergeProposal.queue_status.is_in(statuses)
             )
+        if created_before is not None:
+            expressions.append(
+                BranchMergeProposal.date_created < created_before
+            )
+        if created_since is not None:
+            expressions.append(
+                BranchMergeProposal.date_created > created_since
+            )
         resultset = self.store.using(*tables).find(
             BranchMergeProposal, *expressions
         )
diff --git a/lib/lp/code/model/gitcollection.py b/lib/lp/code/model/gitcollection.py
index fe7055c..e511039 100644
--- a/lib/lp/code/model/gitcollection.py
+++ b/lib/lp/code/model/gitcollection.py
@@ -311,6 +311,8 @@ class GenericGitCollection:
         prerequisite_path=None,
         merged_revision_ids=None,
         merge_proposal_ids=None,
+        created_before=None,
+        created_since=None,
         eager_load=False,
     ):
         """See `IGitCollection`."""
@@ -325,6 +327,8 @@ class GenericGitCollection:
             or prerequisite_path is not None
             or merged_revision_ids is not None
             or merge_proposal_ids is not None
+            or created_before is not None
+            or created_since is not None
         ):
             return self._naiveGetMergeProposals(
                 statuses,
@@ -334,6 +338,8 @@ class GenericGitCollection:
                 prerequisite_path,
                 merged_revision_ids,
                 merge_proposal_ids,
+                created_before=created_before,
+                created_since=created_since,
                 eager_load=eager_load,
             )
         else:
@@ -353,6 +359,8 @@ class GenericGitCollection:
         prerequisite_path=None,
         merged_revision_ids=None,
         merge_proposal_ids=None,
+        created_before=None,
+        created_since=None,
         eager_load=False,
     ):
         Target = ClassAlias(GitRepository, "target")
@@ -413,6 +421,14 @@ class GenericGitCollection:
             expressions.append(
                 BranchMergeProposal.queue_status.is_in(statuses)
             )
+        if created_before is not None:
+            expressions.append(
+                BranchMergeProposal.date_created < created_before
+            )
+        if created_since is not None:
+            expressions.append(
+                BranchMergeProposal.date_created > created_since
+            )
         resultset = self.store.using(*tables).find(
             BranchMergeProposal, *expressions
         )
diff --git a/lib/lp/code/model/hasbranches.py b/lib/lp/code/model/hasbranches.py
index 17c08ca..47836f7 100644
--- a/lib/lp/code/model/hasbranches.py
+++ b/lib/lp/code/model/hasbranches.py
@@ -55,7 +55,12 @@ class HasMergeProposalsMixin:
     """A mixin implementation class for `IHasMergeProposals`."""
 
     def getMergeProposals(
-        self, status=None, visible_by_user=None, eager_load=False
+        self,
+        status=None,
+        visible_by_user=None,
+        created_before=None,
+        created_since=None,
+        eager_load=False,
     ):
         """See `IHasMergeProposals`."""
         # Circular import.
@@ -71,7 +76,12 @@ class HasMergeProposalsMixin:
         def _getProposals(interface):
             collection = removeSecurityProxy(interface(self))
             collection = collection.visibleByUser(visible_by_user)
-            return collection.getMergeProposals(status, eager_load=False)
+            return collection.getMergeProposals(
+                status,
+                created_before=created_before,
+                created_since=created_since,
+                eager_load=False,
+            )
 
         # SourcePackage Bazaar branches are an aberration which was not
         # replicated for Git, so SourcePackage does not support Git.
diff --git a/lib/lp/code/model/tests/test_hasbranches.py b/lib/lp/code/model/tests/test_hasbranches.py
index 64bfdbd..557e168 100644
--- a/lib/lp/code/model/tests/test_hasbranches.py
+++ b/lib/lp/code/model/tests/test_hasbranches.py
@@ -56,7 +56,9 @@ class TestHasMergeProposalsWebservice(TestCaseWithFactory):
         owner = self.factory.makePerson()
         owner_url = api_url(owner)
         webservice = webservice_for_person(
-            owner, permission=OAuthPermission.READ_PRIVATE
+            owner,
+            permission=OAuthPermission.READ_PRIVATE,
+            default_api_version="devel",
         )
 
         def create_merge_proposals():
diff --git a/lib/lp/registry/interfaces/person.py b/lib/lp/registry/interfaces/person.py
index a3cb45b..81c0164 100644
--- a/lib/lp/registry/interfaces/person.py
+++ b/lib/lp/registry/interfaces/person.py
@@ -91,6 +91,7 @@ from lp.app.validators.email import email_validator
 from lp.app.validators.name import name_validator
 from lp.blueprints.interfaces.specificationtarget import IHasSpecifications
 from lp.bugs.interfaces.bugtarget import IHasBugs
+from lp.code.enums import BranchMergeProposalStatus
 from lp.code.interfaces.hasbranches import (
     IHasBranches,
     IHasMergeProposals,
@@ -1930,6 +1931,40 @@ class IPersonViewRestricted(
         If no orderby is provided, Person.sortingColumns is used.
         """
 
+    @operation_parameters(
+        status=List(
+            title=_("A list of merge proposal statuses to filter by."),
+            value_type=Choice(vocabulary=BranchMergeProposalStatus),
+        ),
+        created_before=Datetime(
+            title=_(
+                "Search for merge proposals that were created"
+                "before the given date."
+            ),
+            required=False,
+        ),
+        created_since=Datetime(
+            title=_(
+                "Search for merge proposals that were created"
+                "since the given date."
+            ),
+            required=False,
+        ),
+    )
+    @call_with(visible_by_user=REQUEST_USER, eager_load=True)
+    # Really IBranchMergeProposal
+    @operation_returns_collection_of(Interface)
+    @export_read_operation()
+    @operation_for_version("devel")
+    def getMergeProposals(
+        status=None,
+        visible_by_user=None,
+        created_before=None,
+        created_since=None,
+        eager_load=False,
+    ):
+        """Return matching BranchMergeProposals."""
+
 
 class IPersonEditRestricted(Interface):
     """IPerson attributes that require launchpad.Edit permission."""
diff --git a/lib/lp/registry/tests/test_person.py b/lib/lp/registry/tests/test_person.py
index 2d60691..b4f8457 100644
--- a/lib/lp/registry/tests/test_person.py
+++ b/lib/lp/registry/tests/test_person.py
@@ -908,6 +908,48 @@ class TestPerson(TestCaseWithFactory):
         )
 
 
+class TestPersonMergeProposals(TestCaseWithFactory):
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super().setUp()
+
+    def _makeOwnedBranchMergeProposal(self):
+        self.user = self.factory.makePerson()
+        branch = self.factory.makeBranch(owner=self.user)
+        self.today = datetime.now(timezone.utc)
+        ten_days_ago = self.factory.makeBranchMergeProposal(
+            registrant=self.user,
+            source_branch=branch,
+            date_created=self.today - timedelta(days=10),
+        )
+        nine_days_ago = self.factory.makeBranchMergeProposal(
+            registrant=self.user,
+            source_branch=branch,
+            date_created=self.today - timedelta(days=9),
+        )
+        self.allMergeProposals = [nine_days_ago, ten_days_ago]
+
+    def test_all_merge_proposals(self):
+        self._makeOwnedBranchMergeProposal()
+        mp = self.user.getMergeProposals()
+        self.assertEqual(self.allMergeProposals, list(mp))
+
+    def test_created_before(self):
+        self._makeOwnedBranchMergeProposal()
+        mp = self.user.getMergeProposals(
+            created_before=self.today - timedelta(days=9)
+        )
+        self.assertEqual(self.allMergeProposals[1:], list(mp))
+
+    def test_created_since(self):
+        self._makeOwnedBranchMergeProposal()
+        mp = self.user.getMergeProposals(
+            created_since=self.today - timedelta(days=10)
+        )
+        self.assertEqual(self.allMergeProposals[:1], list(mp))
+
+
 class TestPersonStates(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 

Follow ups