diff --git a/gratipay/utils/fake_data.py b/gratipay/utils/fake_data.py index c21cb94d9a..fa6d294dc6 100644 --- a/gratipay/utils/fake_data.py +++ b/gratipay/utils/fake_data.py @@ -58,8 +58,13 @@ def fake_sentence(start=1, stop=100): return faker.sentence(random.randrange(start,stop)) -def fake_participant(db, is_admin=False): +def fake_participant(db, is_admin=False, random_identities=True): """Create a fake User. + + :param Postgres db: a ``Postgres`` or ``Cursor`` object + :param bool is_admin: whether to make the participant an admin + :param bool random_identities: whether to give the participant random identities + """ username = faker.first_name() + fake_text_id(3) try: @@ -74,12 +79,40 @@ def fake_participant(db, is_admin=False): , balanced_customer_href=faker.uri() , is_suspicious=False , claimed_time=faker.date_time_this_year() + , email_address='{}@example.com'.format(username) ) + participant = Participant.from_username(username) + + if random_identities: + if random.randrange(100) < 66: + fake_participant_identity(participant) + if random.randrange(100) < 33: + fake_participant_identity(participant) + if random.randrange(100) < 50: + fake_participant_identity(participant) + except IntegrityError: return fake_participant(db, is_admin) - #Call participant constructor to perform other DB initialization - return Participant.from_username(username) + return participant + + +def fake_participant_identity(participant, verification=None): + """Pick a country and make an identity for the participant there. + + :param Participant participant: a participant object + :param bool verification: the value to set verification to; None will result in a 50% chance + either way + :returns: a country id + + """ + country_id = random_country_id(participant.db) + participant.store_identity_info(country_id, 'nothing-enforced', {}) + if verification: + participant.set_identity_verification(country_id, verification) + elif (random.randrange(2) == 0): # 50% + participant.set_identity_verification(country_id, True) + return country_id def fake_team(db, teamowner): @@ -200,6 +233,10 @@ def fake_exchange(db, participant, amount, fee, timestamp): ) +def random_country_id(db): + return db.one("SELECT id FROM countries ORDER BY random() LIMIT 1") + + def prep_db(db): db.run(""" CREATE OR REPLACE FUNCTION process_transfer() RETURNS trigger AS $$ @@ -251,10 +288,25 @@ def populate_db(db, num_participants=100, ntips=200, num_teams=5, num_transfers= """Populate DB with fake data. """ print("Making Participants") + make_flag_tester = num_participants > 1 + participants = [] - for i in xrange(num_participants): + for i in xrange(num_participants - 1 if make_flag_tester else num_participants): participants.append(fake_participant(db)) + if make_flag_tester: + # make a participant for testing weird flags + flag_tester = fake_participant(db, random_identities=False) + participants.append(flag_tester) + + nepal = db.one("SELECT id FROM countries WHERE code2='NP'") + flag_tester.store_identity_info(nepal, 'nothing-enforced', {}) + flag_tester.set_identity_verification(nepal, True) + + vatican = db.one("SELECT id FROM countries WHERE code2='VA'") + flag_tester.store_identity_info(vatican, 'nothing-enforced', {}) + flag_tester.set_identity_verification(vatican, True) + print("Making Teams") teams = [] teamowners = random.sample(participants, num_teams) @@ -357,8 +409,15 @@ def populate_db(db, num_participants=100, ntips=200, num_teams=5, num_transfers= print("") +def _wireup(): + env = wireup.env() + db = wireup.db(env) + wireup.crypto(env) + return db + + def main(db=None, *a, **kw): - db = db or wireup.db(wireup.env()) + db = db or _wireup() clean_db(db) prep_db(db) populate_db(db, *a, **kw) diff --git a/tests/py/test_fake_data.py b/tests/py/test_fake_data.py index c6caa36aca..df49351381 100644 --- a/tests/py/test_fake_data.py +++ b/tests/py/test_fake_data.py @@ -28,3 +28,9 @@ def test_fake_data(self): assert len(payment_instructions) == num_tips else: assert len(payment_instructions) == (num_participants - num_teams) + + + def test_fake_participant_identity(self): + crusher = self.make_participant('crusher', email_address='crusher@example.com') + country_id = fake_data.fake_participant_identity(crusher) + assert [x.country.id for x in crusher.list_identity_metadata()] == [country_id] diff --git a/www/dashboard/countries.spt b/www/dashboard/countries.spt new file mode 100644 index 0000000000..26f790a903 --- /dev/null +++ b/www/dashboard/countries.spt @@ -0,0 +1,62 @@ +from aspen import Response + +[---] +if not user.ADMIN: + raise Response(403) + +countries = website.db.all(""" + + SELECT name + , array_agg(username) as usernames + , array_agg(is_verified) as verifications + FROM participant_identities pi + JOIN participants p + ON p.id = participant_id + JOIN countries c + ON c.id = country_id + GROUP BY c.name + +""") + +multiple = website.db.all(""" + + WITH counts AS ( + SELECT participant_id, count(*) count + FROM participant_identities + GROUP BY participant_id + ) + SELECT p.*::participants + FROM participants p + JOIN counts c + ON p.id = c.participant_id + WHERE c.count > 1 + +""") + +zip = zip +[---] text/html +

Multiple

+{% for participant in multiple %} +{{ participant.username }} +{% for identity in participant.list_identity_metadata() %} +| {% if identity.is_verified %} +{{ identity.country.name }} +{% else %} +{{ identity.country.name }} +{% endif %} +{% endfor %} +
+{% endfor %} + +

By Country

+{% for country in countries %} +{{ country.name }} +{% for username, is_verified in zip(country.usernames, country.verifications) %} +| {% if is_verified %} +{{ username }} +{% else %} +{{ username }} +{% endif %} +{% endfor %} +
+{% endfor %}