コード例 #1
0
ファイル: test_email.py プロジェクト: rpanczer/gratipay.com
    def check(self, *package_names):
        package_names, post = package_names[:-1], package_names[-1]
        post.return_value = 'some-github-url'

        nonce = self.start(self.address, *package_names)
        result = self.alice.finish_email_verification(self.address, nonce)

        # email?
        packages = [Package.from_names(NPM, name) for name in package_names]
        assert result == (_email.VERIFICATION_SUCCEEDED, packages,
                          True if packages else None)
        assert self.alice.email_address == P(
            'alice').email_address == self.address

        # database?
        for name in package_names:
            package = Package.from_names(NPM, name)
            assert package.team.package == package
            assert package.team.review_url == 'some-github-url'

        # GitHub issue?
        npackages = len(package_names)
        if npackages == 0:
            assert not post.called
        else:
            assert post.call_count == 1
            posted = json.loads(post.mock_calls[0][1][0])
            if npackages == 1:
                assert posted['title'] == 'foo'
                assert 'for at least a week' in posted['body']
            else:
                assert posted['title'] == 'bar and foo'
                assert 'for at least a week' in posted['body']
            assert self.db.all('select review_url from teams'
                               ) == ['some-github-url'] * npackages
コード例 #2
0
    def check(self, *package_names):
        package_names, post = package_names[:-1], package_names[-1]
        post.return_value = 'some-github-url'

        nonce = self.start(self.address, *package_names)
        result = self.alice.finish_email_verification(self.address, nonce)

        # email?
        packages = [Package.from_names(NPM, name) for name in package_names]
        assert result == (_email.VERIFICATION_SUCCEEDED, packages, True if packages else None)
        assert self.alice.email_address == P('alice').email_address == self.address

        # database?
        for name in package_names:
            package = Package.from_names(NPM, name)
            assert package.team.package == package
            assert package.team.review_url == 'some-github-url'

        # GitHub issue?
        npackages = len(package_names)
        if npackages == 0:
            assert not post.called
        else:
            assert post.call_count == 1
            posted = json.loads(post.mock_calls[0][1][0])
            if npackages == 1:
                assert posted['title'] == 'foo'
                assert 'for at least a week' in posted['body']
            else:
                assert posted['title'] == 'bar and foo'
                assert 'for at least a week' in posted['body']
            assert self.db.all('select review_url from teams') == ['some-github-url'] * npackages
コード例 #3
0
ファイル: test_email.py プロジェクト: rpanczer/gratipay.com
 def test_deleting_package_removes_open_claims(self):
     self.add_and_verify_email(self.alice, self.address)
     self.alice.set_paypal_address(self.address)
     self.start(self.address, 'foo')
     load = lambda: self.db.one('select * from claims')
     assert load() is not None
     Package.from_names('npm', 'foo').delete()
     assert load() is None
コード例 #4
0
 def test_deleting_package_removes_open_claims(self):
     self.add_and_verify_email(self.alice, self.address)
     self.alice.set_paypal_address(self.address)
     self.start(self.address, 'foo')
     _load = lambda: self.db.one('select * from claims')
     assert _load() is not None
     Package.from_names('npm', 'foo').delete()
     assert _load() is None
コード例 #5
0
    def test_while_we_are_at_it_that_packages_have_unique_teams_that_survive_comparison(self):
        self.test_verified_address_and_multiple_packages_succeeds()

        foo = Package.from_names('npm', 'foo')
        bar = Package.from_names('npm', 'bar')

        assert foo.team == foo.team
        assert bar.team == bar.team
        assert foo.team != bar.team
コード例 #6
0
ファイル: test_email.py プロジェクト: rpanczer/gratipay.com
    def test_while_we_are_at_it_that_packages_have_unique_teams_that_survive_comparison(
            self):
        self.test_verified_address_and_multiple_packages_succeeds()

        foo = Package.from_names('npm', 'foo')
        bar = Package.from_names('npm', 'bar')

        assert foo.team == foo.team
        assert bar.team == bar.team
        assert foo.team != bar.team
コード例 #7
0
 def test_finishing_email_verification_with_preexisting_paypal_doesnt_update_paypal(self):
     self.add_and_verify_email(self.alice, self.address)
     self.alice.set_paypal_address(self.address)
     nonce = self.start(self.address, 'foo')
     result = self.alice.finish_email_verification(self.address, nonce)
     foo = Package.from_names('npm', 'foo')
     assert result == (_email.VERIFICATION_SUCCEEDED, [foo], False)
コード例 #8
0
def consume_change_stream(stream, db):
    """Given an iterable of CouchDB change notifications and a
    :py:class:`~GratipayDB`, read from the stream and write to the db.

    The npm registry is a CouchDB app, which means we get a change stream from
    it that allows us to follow registry updates in near-realtime. Our strategy
    here is to maintain open connections to both the registry and our own
    database, and write as we read.

    """
    with db.get_connection() as connection:
        for change in stream:

            # Decide what to do.
            if change.get('deleted'):
                package = Package.from_names(NPM, change['id'])
                if not package:
                    # As a result of CouchDB's compaction algorithm, we might
                    # receive 'deleted' events for docs even if we haven't seen
                    # the corresponding events for when the doc was created
                    continue
                op, kw = package.delete, {}
            else:
                op = Package.upsert
                kw = process_doc(change['doc'])
                if not kw:
                    continue
                kw['package_manager'] = NPM

            # Do it.
            cursor = connection.cursor()
            kw['cursor'] = cursor
            op(**kw)
            cursor.run('UPDATE worker_coordination SET npm_last_seq=%(seq)s', change)
            connection.commit()
コード例 #9
0
ファイル: harness.py プロジェクト: cyberjacob/www.gittip.com
 def claim_package(self, participant, package):
     """Given a participant and a package, claim the package for the participant.
     """
     if participant.__class__ is not Participant:
         participant = P(participant)
     if package.__class__ is not Package:
         package = Package.from_names(NPM, package)
     package.get_or_create_linked_team(self.db, participant)
コード例 #10
0
ファイル: test_email.py プロジェクト: rpanczer/gratipay.com
 def test_finishing_email_verification_with_preexisting_paypal_doesnt_update_paypal(
         self):
     self.add_and_verify_email(self.alice, self.address)
     self.alice.set_paypal_address(self.address)
     nonce = self.start(self.address, 'foo')
     result = self.alice.finish_email_verification(self.address, nonce)
     foo = Package.from_names('npm', 'foo')
     assert result == (_email.VERIFICATION_SUCCEEDED, [foo], False)
コード例 #11
0
ファイル: harness.py プロジェクト: shridharmanvi/gratipay.com
 def claim_package(self, participant, package):
     """Given a participant and a package, claim the package for the participant.
     """
     if participant.__class__ is not Participant:
         participant = P(participant)
     if package.__class__ is not Package:
         package = Package.from_names(NPM, package)
     package.get_or_create_linked_team(self.db, participant)
コード例 #12
0
 def claim_package(self):
     foo = Package.from_names('npm', 'foo')
     alice = self.make_participant('alice', claimed_time='now')
     alice.start_email_verification('*****@*****.**', foo)
     nonce = alice.get_email('*****@*****.**').nonce
     alice.finish_email_verification('*****@*****.**', nonce)
     team = alice.get_teams()[0]
     assert team.package == foo
     return team.slug
コード例 #13
0
 def test_but_once_claimed_then_team_persists(self):
     self.make_package()
     self.check()
     foo = Package.from_names(NPM, 'foo')
     assert self.finish_claiming() == (email.VERIFICATION_SUCCEEDED, [foo], True)
     foo.delete()
     self.visit('/foo/')
     foo = self.css('#content .statement p')
     assert foo.text == 'Foo fooingly.'
コード例 #14
0
 def claim_package(self):
     foo = Package.from_names('npm', 'foo')
     alice = self.make_participant('alice', claimed_time='now')
     alice.start_email_verification('*****@*****.**', foo)
     nonce = alice.get_email('*****@*****.**').nonce
     alice.finish_email_verification('*****@*****.**', nonce)
     team = alice.get_teams()[0]
     assert team.package == foo
     return team.slug
コード例 #15
0
 def test_but_once_claimed_then_team_persists(self):
     self.make_package()
     self.check()
     foo = Package.from_names(NPM, 'foo')
     assert self.finish_claiming() == (email.VERIFICATION_SUCCEEDED, [foo], True)
     foo.delete()
     self.visit('/foo/')
     foo = self.css('#content .statement p')
     assert foo.text == 'Foo fooingly.'
コード例 #16
0
 def make_package(self, package_manager=NPM, name='foo', description='Foo fooingly.',
                                                 emails=['*****@*****.**'], claimed_by=None):
     """Factory for packages.
     """
     self.db.run( 'INSERT INTO packages (package_manager, name, description, emails) '
                  'VALUES (%s, %s, %s, %s) RETURNING *'
                , (package_manager, name, description, emails)
                 )
     package = Package.from_names(NPM, name)
     if claimed_by:  # either a username (existing or not) or a Participant object
         if type(claimed_by) is unicode:
             maybe = P(claimed_by)
             claimed_by = maybe if maybe is not None else self.make_owner(claimed_by)
         admin = self.make_admin()
         team = package.get_or_create_linked_team(self.db, claimed_by)
         team.update_review_status('approved', admin)
     return package
コード例 #17
0
ファイル: harness.py プロジェクト: cyberjacob/www.gittip.com
 def make_package(self, package_manager=NPM, name='foo', description='Foo fooingly.',
                                                 emails=['*****@*****.**'], claimed_by=None):
     """Factory for packages.
     """
     self.db.run( 'INSERT INTO packages (package_manager, name, description, emails) '
                  'VALUES (%s, %s, %s, %s) RETURNING *'
                , (package_manager, name, description, emails)
                 )
     package = Package.from_names(NPM, name)
     if claimed_by:  # either a username (existing or not) or a Participant object
         if type(claimed_by) is unicode:
             maybe = P(claimed_by)
             claimed_by = maybe if maybe is not None else self.make_owner(claimed_by)
         admin = self.make_admin()
         team = package.get_or_create_linked_team(self.db, claimed_by)
         team.update_review_status('approved', admin)
     return package
コード例 #18
0
ファイル: sync_npm.py プロジェクト: cyberjacob/www.gittip.com
def consume_change_stream(stream, db):
    """Given an iterable of CouchDB change notifications and a
    :py:class:`~GratipayDB`, read from the stream and write to the db.

    The npm registry is a CouchDB app, which means we get a change stream from
    it that allows us to follow registry updates in near-realtime. Our strategy
    here is to maintain open connections to both the registry and our own
    database, and write as we read.

    """
    with db.get_connection() as connection:
        for change in stream:

            # Decide what to do.
            if change.get('deleted'):
                package = Package.from_names(NPM, change['id'])
                if not package:
                    # As a result of CouchDB's compaction algorithm, we might
                    # receive 'deleted' events for docs even if we haven't seen
                    # the corresponding events for when the doc was created
                    continue
                op, kw = package.delete, {}
            else:
                op = Package.upsert
                doc = change.get('doc')
                if not doc:
                    continue    # We've seen this in the wild.
                kw = process_doc(doc)
                if not kw:
                    continue
                kw['package_manager'] = NPM

            # Do it.
            cursor = connection.cursor()
            kw['cursor'] = cursor
            op(**kw)
            cursor.run('UPDATE worker_coordination SET npm_last_seq=%(seq)s', change)
            connection.commit()
コード例 #19
0
 def test_claiming_deleted_packages_is_a_noop(self):
     self.make_package()
     self.check()
     Package.from_names(NPM, 'foo').delete()
     assert self.finish_claiming() == (email.VERIFICATION_SUCCEEDED, [], None)
コード例 #20
0
 def test_deleted_packages_are_404(self):
     self.make_package()
     Package.from_names(NPM, 'foo').delete()
     self.visit('/on/npm/foo')
     assert self.css('#content h1').text == '404'
コード例 #21
0
 def test_deleted_packages_are_404(self):
     self.make_package()
     Package.from_names(NPM, 'foo').delete()
     self.visit('/on/npm/foo')
     assert self.css('#content h1').text == '404'
コード例 #22
0
 def test_from_names_can_use_a_cursor(self):
     self.make_package()
     with self.db.get_cursor() as cursor:
         assert Package.from_names(NPM, 'foo', cursor).name == 'foo'
コード例 #23
0
 def test_can_be_instantiated_from_names(self):
     self.make_package()
     assert Package.from_names(NPM, 'foo').name == 'foo'
コード例 #24
0
 def test_closing_team_unlinks_package(self):
     _, _, team = self.link()
     team.close()
     assert Package.from_names('npm', 'foo').team is None
コード例 #25
0
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

import mock
from gratipay.models.package import Package, NPM
from gratipay.models.package.emails import PRIMARY, VERIFIED, UNVERIFIED, UNLINKED, OTHER
from gratipay.testing import Harness
from psycopg2 import IntegrityError
from pytest import raises


Foo = lambda cursor=None: Package.from_names(NPM, 'foo', cursor)


class Basics(Harness):

    def test_can_be_instantiated_from_id(self):
        package = self.make_package()
        assert Package.from_id(package.id).id == package.id

    def test_from_id_can_use_a_cursor(self):
        package = self.make_package()
        with self.db.get_cursor() as cursor:
            assert Package.from_id(package.id, cursor).id == package.id

    def test_can_be_instantiated_from_names(self):
        self.make_package()
        assert Package.from_names(NPM, 'foo').name == 'foo'

    def test_from_names_can_use_a_cursor(self):
        self.make_package()
コード例 #26
0
 def test_claiming_deleted_packages_is_a_noop(self):
     self.make_package()
     self.check()
     Package.from_names(NPM, 'foo').delete()
     assert self.finish_claiming() == (email.VERIFICATION_SUCCEEDED, [], None)