From cff3a47fd862f66c14bf2c901e733530d1779f7e Mon Sep 17 00:00:00 2001 From: Chad Whitacre Date: Wed, 31 May 2017 08:59:30 -0400 Subject: [PATCH] First pass at get_packages_for_claiming --- gratipay/models/participant/packages.py | 37 +++++++++++++++++++++++++ tests/py/test_packages.py | 35 +++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/gratipay/models/participant/packages.py b/gratipay/models/participant/packages.py index 26c8825937..67c99a0769 100644 --- a/gratipay/models/participant/packages.py +++ b/gratipay/models/participant/packages.py @@ -6,6 +6,43 @@ class Packages(object): + def get_packages_for_claiming(self, manager): + + """Return a list of packages on the named ``manager`` for which the + participant has verified an email address on Gratipay, along with the + current package owner on Gratipay (if any). + + :param string manager: the name of the package manager on which to look + for potential packages + + :return: a list of (:py:class:`~gratipay.models.package.Package`, + :py:class:`Participant`) tuples, where the participant is the one who + has already claimed the package (or ``None``) + + """ + return self.db.all(''' + + WITH verified_emails AS ( + SELECT address + FROM emails + WHERE participant_id=%s + AND verified is true + ) + SELECT pkg.*::packages package + , p.*::participants claimed_by + FROM packages pkg + LEFT JOIN teams_to_packages tp + ON pkg.id = tp.package_id + LEFT JOIN teams t + ON t.id = tp.team_id + LEFT JOIN participants p + ON t.owner = p.username + WHERE package_manager=%s + AND emails && array(SELECT * FROM verified_emails) + + ''', (self.id, manager)) + + def start_package_claims(self, c, nonce, *packages): """Takes a cursor, nonce and list of packages, inserts into ``claims`` and returns ``None`` (or raise :py:exc:`NoPackages`). diff --git a/tests/py/test_packages.py b/tests/py/test_packages.py index 4f7ebca8d9..f0c9bde6cd 100644 --- a/tests/py/test_packages.py +++ b/tests/py/test_packages.py @@ -190,3 +190,38 @@ def test_ordering(self): , ('email', UNLINKED) , ('bmail', OTHER) ] + + +class GetPackagesForClaiming(Harness): + + def test_gets_packages_for_claiming(self): + foo = self.make_package() + alice = self.make_participant('alice', email_address='alice@example.com') + assert alice.get_packages_for_claiming(NPM) == [(foo, None)] + + def test_excludes_packages_for_half_verified_emails(self): + foo = self.make_package() + alice = self.make_participant('alice', email_address='alice@example.com') + self.make_package(name='bar', emails=['bob@example.com']) + alice.start_email_verification('bob@example.com') + assert alice.get_packages_for_claiming(NPM) == [(foo, None)] + + def test_includes_packages_for_verified_but_non_primary_emails(self): + foo = self.make_package() + alice = self.make_participant('alice', email_address='alice@example.com') + bar = self.make_package(name='bar', emails=['bob@example.com']) + self.add_and_verify_email(alice, 'bob@example.com') + assert alice.get_packages_for_claiming(NPM) == [(foo, None), (bar, None)] + + def test_includes_packages_already_claimed_by_self(self): + foo = self.make_package() + alice = self.make_participant('alice', email_address='alice@example.com') + foo.get_or_create_linked_team(self.db, alice) + assert alice.get_packages_for_claiming(NPM) == [(foo, alice)] + + def test_includes_packages_already_claimed_by_other(self): + foo = self.make_package(emails=['alice@example.com', 'bob@example.com']) + alice = self.make_participant('alice', email_address='alice@example.com') + foo.get_or_create_linked_team(self.db, alice) + bob = self.make_participant('bob', email_address='bob@example.com') + assert bob.get_packages_for_claiming(NPM) == [(foo, alice)]