def post(self, request, *args, **kwargs):
        """ Return a mapping of participant IDs to membership statuses. """
        postdata = json.loads(self.request.body)
        par_pks = postdata.get('participant_ids')
        if not isinstance(par_pks, list):
            return JsonResponse({'message': 'Bad request'}, status=400)

        # Span databases to map from participants -> users -> email addresses
        participants = models.Participant.objects.filter(pk__in=par_pks)
        user_to_par = dict(participants.values_list('user_id', 'pk'))
        email_addresses = EmailAddress.objects.filter(
            user_id__in=user_to_par, verified=True
        )
        email_to_user = dict(email_addresses.values_list('email', 'user_id'))

        # Gives email -> membership info for all matches
        matches = geardb_utils.matching_memberships(email_to_user)

        # Default to blank memberships in case not found
        participant_memberships = {
            pk: geardb_utils.repr_blank_membership() for pk in par_pks
        }

        # Update participants where matching membership information was found
        for email, membership in matches.items():
            par_pk = user_to_par[email_to_user[email]]
            # We might overwrite a previous membership record, but that will
            # only happen if the user has memberships under 2+ emails
            # (Older memberships come first, so this will safely yield the newest)
            participant_memberships[par_pk] = membership

        return JsonResponse({'memberships': participant_memberships})
Exemple #2
0
    def test_just_one_record(self):
        """ When requesting records under many emails, just one is returned.

        (Provided that the primary email is included in the lookup list)
        """
        person_id = self.create_tim()
        alternate_emails = [f'tim@{i}.example.com' for i in range(3)]
        for email in alternate_emails:
            self.record_alternate_email(person_id, email)

        # When we request just the alternate emails, it returns one for each
        self.assertEqual(len(geardb.matching_memberships(alternate_emails)), 3)

        # However, so long as the primary is included, we'll just have one
        all_emails = ['*****@*****.**'] + alternate_emails
        self.expect_under_email('*****@*****.**', lookup=all_emails)
Exemple #3
0
    def test_just_one_record(self):
        """ When requesting records under many emails, just one is returned.

        (Provided that the primary email is included in the lookup list)
        """
        person_id = self.create_tim()
        alternate_emails = [f'tim@{i}.example.com' for i in range(3)]
        for email in alternate_emails:
            self.record_alternate_email(person_id, email)

        # When we request just the alternate emails, it returns one for each
        self.assertEqual(len(geardb.matching_memberships(alternate_emails)), 3)

        # However, so long as the primary is included, we'll just have one
        all_emails = ['*****@*****.**'] + alternate_emails
        self.expect_under_email('*****@*****.**', lookup=all_emails)
Exemple #4
0
    def test_alternate_email(self):
        """ We can look up participants by other emails. """
        person_id = self.create_tim()

        # First, there is no known membership for the other email
        self.assertEqual(geardb.matching_memberships(['*****@*****.**']), OrderedDict())

        # Then, after tying the alternate email to the main account, results!
        self.record_alternate_email(person_id, '*****@*****.**')
        self.expect_under_email('*****@*****.**')

        # Importantly, we can still look up by the main email address!
        self.expect_under_email('*****@*****.**')

        # If looking up by both emails, the primary email is reported
        # (Importantly, only one membership is returned)
        self.expect_under_email('*****@*****.**', lookup=['*****@*****.**', '*****@*****.**'])
Exemple #5
0
    def test_alternate_email(self):
        """ We can look up participants by other emails. """
        person_id = self.create_tim()

        # First, there is no known membership for the other email
        self.assertEqual(geardb.matching_memberships(['*****@*****.**']),
                         OrderedDict())

        # Then, after tying the alternate email to the main account, results!
        self.record_alternate_email(person_id, '*****@*****.**')
        self.expect_under_email('*****@*****.**')

        # Importantly, we can still look up by the main email address!
        self.expect_under_email('*****@*****.**')

        # If looking up by both emails, the primary email is reported
        # (Importantly, only one membership is returned)
        self.expect_under_email('*****@*****.**',
                                lookup=['*****@*****.**', '*****@*****.**'])
    def test_empty_emails(self):
        """ Passing an empty list of emails will return zero matches.

        There's no need to hit the database.
        """
        self.assertEqual(OrderedDict(), geardb_utils.matching_memberships([]))
Exemple #7
0
 def expect_under_email(self, email, lookup=None):
     expected = self.just_tim
     expected['membership']['email'] = email
     lookup_emails = lookup or [email]
     results = geardb.matching_memberships(lookup_emails)  # (OrderedDict)
     self.assertEqual({email: expected}, dict(results))
Exemple #8
0
 def test_no_people_record(self):
     """ Without a match, nothing is returned. """
     matches = geardb.matching_memberships(['*****@*****.**'])
     self.assertEqual(matches, OrderedDict())
Exemple #9
0
 def one_match(self, email):
     matches = geardb.matching_memberships([email])
     self.assertEqual(len(matches), 1)
     return matches[email]
Exemple #10
0
 def expect_under_email(self, email, lookup=None):
     expected = self.just_tim
     expected['membership']['email'] = email
     lookup_emails = lookup or [email]
     results = geardb.matching_memberships(lookup_emails)  # (OrderedDict)
     self.assertEqual({email: expected}, dict(results))
Exemple #11
0
 def test_no_people_record(self):
     """ Without a match, nothing is returned. """
     matches = geardb.matching_memberships(['*****@*****.**'])
     self.assertEqual(matches, OrderedDict())
Exemple #12
0
 def one_match(self, email):
     matches = geardb.matching_memberships([email])
     self.assertEqual(len(matches), 1)
     return matches[email]