Exemple #1
0
    def test_matched_similar_persons(self):
        """Ensure function finds matching persons."""
        data = [
            {
                'personal': 'Harry',
                'family': 'Potter',
                'username': '******',
                'email': '*****@*****.**',
                'event': '',
                'role': '',
            },
            {
                'personal': 'Romuald',
                'family': 'Weazel',
                'username': '',
                'email': '*****@*****.**',
                'event': '',
                'role': '',
            }
        ]
        verify_upload_person_task(data)

        self.assertEqual(len(data[0]['similar_persons']), 1)
        self.assertEqual(len(data[1]['similar_persons']), 1)

        self.assertEqual(data[0]['similar_persons'][0][0],
                         self.harry.pk)
        self.assertEqual(data[1]['similar_persons'][0][0],
                         self.ron.pk)
Exemple #2
0
    def test_matched_similar_persons(self):
        """Ensure function finds matching persons."""
        data = [
            {
                "personal": "Harry",
                "family": "Potter",
                "username": "******",
                "email": "*****@*****.**",
                "event": "",
                "role": "",
            },
            {
                "personal": "Romuald",
                "family": "Weazel",
                "username": "",
                "email": "*****@*****.**",
                "event": "",
                "role": "",
            },
        ]
        verify_upload_person_task(data)

        self.assertEqual(len(data[0]["similar_persons"]), 1)
        self.assertEqual(len(data[1]["similar_persons"]), 1)

        self.assertEqual(data[0]["similar_persons"][0][0], self.harry.pk)
        self.assertEqual(data[1]["similar_persons"][0][0], self.ron.pk)
Exemple #3
0
 def test_duplicate_errors(self):
     """Ensure errors about duplicate person in the database are present."""
     data = self.make_data()
     data[0]["personal"] = "Harry"
     data[0]["family"] = "Potter"
     data[0]["email"] = "*****@*****.**"
     verify_upload_person_task(data)
     self.assertEqual(len(data[0]["errors"]), 2)
     self.assertIn(
         "Person with this email address already exists.", data[0]["errors"]
     )
     self.assertIn("Person with this username already exists.", data[0]["errors"])
Exemple #4
0
 def test_duplicate_errors(self):
     """Ensure errors about duplicate person in the database are present."""
     data = self.make_data()
     data[0]['personal'] = 'Harry'
     data[0]['family'] = 'Potter'
     data[0]['email'] = '*****@*****.**'
     verify_upload_person_task(data)
     self.assertEqual(len(data[0]['errors']), 2)
     self.assertIn('Person with this email address already exists.',
                   data[0]['errors'])
     self.assertIn('Person with this username already exists.',
                   data[0]['errors'])
Exemple #5
0
 def test_duplicate_errors(self):
     """Ensure errors about duplicate person in the database are present."""
     data = self.make_data()
     data[0]['personal'] = 'Harry'
     data[0]['family'] = 'Potter'
     data[0]['email'] = '*****@*****.**'
     verify_upload_person_task(data)
     self.assertEqual(len(data[0]['errors']), 2)
     self.assertIn('Person with this email address already exists.',
                   data[0]['errors'])
     self.assertIn('Person with this username already exists.',
                   data[0]['errors'])
Exemple #6
0
 def test_username_from_nonexisting_person(self):
     """Make sure the username is not being changed."""
     data = [{
         'personal': 'Harry',
         'family': 'Frotter',
         'username': '******',
         'email': '*****@*****.**',
         'event': '',
         'role': '',
         'existing_person_id': None,
     }]
     verify_upload_person_task(data)
     self.assertEqual('supplied_username', data[0]['username'])
Exemple #7
0
 def test_username_from_nonexisting_person(self):
     """Make sure the username is not being changed."""
     data = [
         {
             'personal': 'Harry',
             'family': 'Frotter',
             'username': '******',
             'email': '*****@*****.**',
             'event': '',
             'role': '',
             'existing_person_id': None,
         }
     ]
     verify_upload_person_task(data)
     self.assertEqual('supplied_username', data[0]['username'])
Exemple #8
0
 def test_username_from_nonexisting_person(self):
     """Make sure the username is not being changed."""
     data = [
         {
             "personal": "Harry",
             "family": "Frotter",
             "username": "******",
             "email": "*****@*****.**",
             "event": "",
             "role": "",
             "existing_person_id": None,
         }
     ]
     verify_upload_person_task(data)
     self.assertEqual("supplied_username", data[0]["username"])
Exemple #9
0
 def test_username_from_existing_person(self):
     """Make sure the username is being changed for correct one."""
     data = [
         {
             "personal": "Harry",
             "family": "Potter",
             "username": "******",
             "email": "*****@*****.**",
             "event": "",
             "role": "",
             "existing_person_id": Person.objects.get(email="*****@*****.**").pk,
         }
     ]
     verify_upload_person_task(data)
     self.assertEqual("potter_harry", data[0]["username"])
Exemple #10
0
 def test_verify_with_good_data(self):
     good_data = self.make_data()
     has_errors = verify_upload_person_task(good_data, match=True)
     self.assertFalse(has_errors)
     # make sure 'errors' wasn't set
     # 'errors' may be an empty list, which evaluates to False
     self.assertFalse(good_data[0]['errors'])
Exemple #11
0
 def test_verify_with_good_data(self):
     good_data = self.make_data()
     has_errors = verify_upload_person_task(good_data, match=True)
     self.assertFalse(has_errors)
     # make sure 'errors' wasn't set
     # 'errors' may be an empty list, which evaluates to False
     self.assertFalse(good_data[0]['errors'])
Exemple #12
0
 def test_username_from_existing_person(self):
     """Make sure the username is being changed for correct one."""
     data = [
         {
             'personal': 'Harry',
             'family': 'Potter',
             'username': '******',
             'email': '*****@*****.**',
             'event': '',
             'role': '',
             'existing_person_id': Person.objects
                                         .get(email='*****@*****.**')
                                         .pk,
         }
     ]
     verify_upload_person_task(data)
     self.assertEqual('potter_harry', data[0]['username'])
Exemple #13
0
    def test_verify_event_doesnt_exist(self):
        bad_data = self.make_data()
        bad_data[0]['event'] = 'no-such-event'
        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertTrue(has_errors)

        errors = bad_data[0]['errors']
        self.assertEqual(len(errors), 1)
        self.assertTrue('Event with slug' in errors[0])
Exemple #14
0
    def test_verify_event_doesnt_exist(self):
        bad_data = self.make_data()
        bad_data[0]['event'] = 'no-such-event'
        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertTrue(has_errors)

        errors = bad_data[0]['errors']
        self.assertEqual(len(errors), 1)
        self.assertTrue('Event with slug' in errors[0])
Exemple #15
0
    def test_verify_event_doesnt_exist(self):
        bad_data = self.make_data()
        bad_data[0]["event"] = "no-such-event"
        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertTrue(has_errors)

        errors = bad_data[0]["errors"]
        self.assertEqual(len(errors), 1)
        self.assertTrue("Event with slug" in errors[0])
Exemple #16
0
    def test_verify_role_doesnt_exist(self):
        bad_data = self.make_data()
        bad_data[0]['role'] = 'foobar'

        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertTrue(has_errors)

        errors = bad_data[0]['errors']
        self.assertTrue(len(errors) == 1)
        self.assertTrue('Role with name' in errors[0])
Exemple #17
0
    def test_verify_email_caseinsensitive_matches(self):
        bad_data = self.make_data()
        # test both matching and case-insensitive matching
        for email in ("*****@*****.**", "*****@*****.**"):
            bad_data[0]["email"] = email
            bad_data[0]["personal"] = "Harry"
            bad_data[0]["family"] = "Potter"

            has_errors = verify_upload_person_task(bad_data, match=True)
            self.assertFalse(has_errors, "Bad email: {}".format(email))
Exemple #18
0
    def test_verify_role_doesnt_exist(self):
        bad_data = self.make_data()
        bad_data[0]['role'] = 'foobar'

        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertTrue(has_errors)

        errors = bad_data[0]['errors']
        self.assertTrue(len(errors) == 1)
        self.assertTrue('Role with name' in errors[0])
Exemple #19
0
    def test_verify_email_caseinsensitive_matches(self):
        bad_data = self.make_data()
        # test both matching and case-insensitive matching
        for email in ('*****@*****.**', '*****@*****.**'):
            bad_data[0]['email'] = email
            bad_data[0]['personal'] = 'Harry'
            bad_data[0]['family'] = 'Potter'

            has_errors = verify_upload_person_task(bad_data, match=True)
            self.assertFalse(has_errors, 'Bad email: {}'.format(email))
Exemple #20
0
    def test_verify_email_caseinsensitive_matches(self):
        bad_data = self.make_data()
        # test both matching and case-insensitive matching
        for email in ('*****@*****.**', '*****@*****.**'):
            bad_data[0]['email'] = email
            bad_data[0]['personal'] = 'Harry'
            bad_data[0]['family'] = 'Potter'

            has_errors = verify_upload_person_task(bad_data, match=True)
            self.assertFalse(has_errors, 'Bad email: {}'.format(email))
Exemple #21
0
    def test_verify_role_doesnt_exist(self):
        bad_data = self.make_data()
        bad_data[0]["role"] = "foobar"

        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertTrue(has_errors)

        errors = bad_data[0]["errors"]
        self.assertTrue(len(errors) == 1)
        self.assertTrue("Role with name" in errors[0])
Exemple #22
0
    def test_email_missing(self):
        """This tests against regression in:
        https://github.com/swcarpentry/amy/issues/1394

        The issue: entries without emails (email=None) were caught in
        `Person.objects.get(email=email)`, which returned multiple objects
        (because we have many users with empty emails, and it doesn't violate
        UNIQUE constraint."""

        # make existing users loose their emails
        usernames = ["potter_harry", "granger_hermione", "weasley_ron"]
        Person.objects.filter(username__in=usernames).update(email=None)

        bad_data = [
            {
                "email": None,
                "personal": "Harry",
                "family": "Potter",
                "event": "foobar",
                "role": "learner",
            },
            {
                "email": None,
                "personal": "Hermione",
                "family": "Granger",
                "event": "foobar",
                "role": "learner",
            },
            {
                "email": None,
                "personal": "Ron",
                "family": "Weasley",
                "event": "foobar",
                "role": "learner",
            },
        ]
        # test for first occurrence of the error
        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertFalse(has_errors)
        # test for second occurrence of the error
        has_errors = verify_upload_person_task(bad_data, match=False)
        self.assertFalse(has_errors)
Exemple #23
0
    def test_email_missing(self):
        """This tests against regression in:
        https://github.com/swcarpentry/amy/issues/1394

        The issue: entries without emails (email=None) were caught in
        `Person.objects.get(email=email)`, which returned multiple objects
        (because we have many users with empty emails, and it doesn't violate
        UNIQUE constraint."""

        # make existing users loose their emails
        usernames = ['potter_harry', 'granger_hermione', 'weasley_ron']
        Person.objects.filter(username__in=usernames).update(email=None)

        bad_data = [
            {
                'email': None,
                'personal': 'Harry',
                'family': 'Potter',
                'event': 'foobar',
                'role': 'learner'
            },
            {
                'email': None,
                'personal': 'Hermione',
                'family': 'Granger',
                'event': 'foobar',
                'role': 'learner'
            },
            {
                'email': None,
                'personal': 'Ron',
                'family': 'Weasley',
                'event': 'foobar',
                'role': 'learner'
            },
        ]
        # test for first occurrence of the error
        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertFalse(has_errors)
        # test for second occurrence of the error
        has_errors = verify_upload_person_task(bad_data, match=False)
        self.assertFalse(has_errors)
Exemple #24
0
    def test_email_missing(self):
        """This tests against regression in:
        https://github.com/swcarpentry/amy/issues/1394

        The issue: entries without emails (email=None) were caught in
        `Person.objects.get(email=email)`, which returned multiple objects
        (because we have many users with empty emails, and it doesn't violate
        UNIQUE constraint."""

        # make existing users loose their emails
        usernames = ['potter_harry', 'granger_hermione', 'weasley_ron']
        Person.objects.filter(username__in=usernames).update(email=None)

        bad_data = [
            {
                'email': None,
                'personal': 'Harry',
                'family': 'Potter',
                'event': 'foobar',
                'role': 'learner'
            },
            {
                'email': None,
                'personal': 'Hermione',
                'family': 'Granger',
                'event': 'foobar',
                'role': 'learner'
            },
            {
                'email': None,
                'personal': 'Ron',
                'family': 'Weasley',
                'event': 'foobar',
                'role': 'learner'
            },
        ]
        # test for first occurrence of the error
        has_errors = verify_upload_person_task(bad_data, match=True)
        self.assertFalse(has_errors)
        # test for second occurrence of the error
        has_errors = verify_upload_person_task(bad_data, match=False)
        self.assertFalse(has_errors)
Exemple #25
0
 def test_verify_existing_user_has_workshop_role_provided(self):
     bad_data = [{
         'email': '*****@*****.**',
         'personal': 'Harry',
         'family': 'Potter',
         'event': '',
         'role': '',
     }]
     has_errors = verify_upload_person_task(bad_data, match=True)
     self.assertTrue(has_errors)
     errors = bad_data[0]['errors']
     self.assertEqual(len(errors), 2)
     self.assertIn('Must have a role', errors[0])
     self.assertIn('Must have an event', errors[1])
Exemple #26
0
 def test_verify_existing_user_has_workshop_role_provided(self):
     bad_data = [
         {
             "email": "*****@*****.**",
             "personal": "Harry",
             "family": "Potter",
             "event": "",
             "role": "",
         }
     ]
     has_errors = verify_upload_person_task(bad_data, match=True)
     self.assertTrue(has_errors)
     errors = bad_data[0]["errors"]
     self.assertEqual(len(errors), 2)
     self.assertIn("Must have a role", errors[0])
     self.assertIn("Must have an event", errors[1])
Exemple #27
0
 def test_verify_existing_user_has_workshop_role_provided(self):
     bad_data = [
         {
             'email': '*****@*****.**',
             'personal': 'Harry',
             'family': 'Potter',
             'event': '',
             'role': '',
         }
     ]
     has_errors = verify_upload_person_task(bad_data, match=True)
     self.assertTrue(has_errors)
     errors = bad_data[0]['errors']
     self.assertEqual(len(errors), 2)
     self.assertIn('Must have a role', errors[0])
     self.assertIn('Must have an event', errors[1])
Exemple #28
0
def person_bulk_add_confirmation(request):
    """
    This view allows for manipulating and saving session-stored upload data.
    """
    persons_tasks = request.session.get('bulk-add-people')

    # if the session is empty, add message and redirect
    if not persons_tasks:
        messages.warning(request, "Could not locate CSV data, please try the upload again.")
        return redirect('person_bulk_add')

    if request.method == 'POST':
        # update values if user wants to change them
        personals = request.POST.getlist("personal")
        middles = request.POST.getlist("middle")
        families = request.POST.getlist("family")
        emails = request.POST.getlist("email")
        events = request.POST.getlist("event")
        roles = request.POST.getlist("role")
        data_update = zip(personals, middles, families, emails, events, roles)
        for k, record in enumerate(data_update):
            personal, middle, family, email, event, role = record
            # "field or None" converts empty strings to None values
            persons_tasks[k] = {
                'personal': personal,
                'middle': middle or None,
                'family': family,
                'email': email or None
            }
            # when user wants to drop related event they will send empty string
            # so we should unconditionally accept new value for event even if
            # it's an empty string
            persons_tasks[k]['event'] = event
            persons_tasks[k]['role'] = role
            persons_tasks[k]['errors'] = None  # reset here

        # save updated data to the session
        request.session['bulk-add-people'] = persons_tasks

        # check if user wants to verify or save, or cancel

        if request.POST.get('verify', None):
            # if there's "verify" in POST, then do only verification
            any_errors = verify_upload_person_task(persons_tasks)
            if any_errors:
                messages.add_message(request, messages.ERROR,
                                     "Please make sure to fix all errors "
                                     "listed below.")

            context = {'title': 'Confirm uploaded data',
                       'persons_tasks': persons_tasks}
            return render(request, 'workshops/person_bulk_add_results.html',
                          context)

        # there must be "confirm" and no "cancel" in POST in order to save
        elif (request.POST.get('confirm', None) and
              not request.POST.get('cancel', None)):
            try:
                # verification now makes something more than database
                # constraints so we should call it first
                verify_upload_person_task(persons_tasks)
                persons_created, tasks_created = \
                    create_uploaded_persons_tasks(persons_tasks)
            except (IntegrityError, ObjectDoesNotExist, InternalError) as e:
                messages.add_message(request, messages.ERROR,
                                     "Error saving data to the database: {}. "
                                     "Please make sure to fix all errors "
                                     "listed below.".format(e))
                verify_upload_person_task(persons_tasks)
                context = {'title': 'Confirm uploaded data',
                           'persons_tasks': persons_tasks}
                return render(request,
                              'workshops/person_bulk_add_results.html',
                              context, status=400)

            else:
                request.session['bulk-add-people'] = None
                messages.add_message(request, messages.SUCCESS,
                                     "Successfully uploaded {0} persons and {1} tasks."
                                     .format(len(persons_created), len(tasks_created)))
                return redirect('person_bulk_add')

        else:
            # any "cancel" or no "confirm" in POST cancels the upload
            request.session['bulk-add-people'] = None
            return redirect('person_bulk_add')

    else:
        # alters persons_tasks via reference
        verify_upload_person_task(persons_tasks)

        context = {'title': 'Confirm uploaded data',
                   'persons_tasks': persons_tasks}
        return render(request, 'workshops/person_bulk_add_results.html',
                      context)
Exemple #29
0
def person_bulk_add_confirmation(request):
    """
    This view allows for manipulating and saving session-stored upload data.
    """
    persons_tasks = request.session.get('bulk-add-people')

    # if the session is empty, add message and redirect
    if not persons_tasks:
        messages.warning(
            request, "Could not locate CSV data, please try the upload again.")
        return redirect('person_bulk_add')

    if request.method == 'POST':
        # update values if user wants to change them
        personals = request.POST.getlist("personal")
        middles = request.POST.getlist("middle")
        families = request.POST.getlist("family")
        emails = request.POST.getlist("email")
        events = request.POST.getlist("event")
        roles = request.POST.getlist("role")
        data_update = zip(personals, middles, families, emails, events, roles)
        for k, record in enumerate(data_update):
            personal, middle, family, email, event, role = record
            persons_tasks[k]['person'] = {
                'personal': personal,
                'middle': middle,
                'family': family,
                'email': email
            }
            # when user wants to drop related event they will send empty string
            # so we should unconditionally accept new value for event even if
            # it's an empty string
            persons_tasks[k]['event'] = event
            persons_tasks[k]['role'] = role
            persons_tasks[k]['errors'] = None  # reset here

        # save updated data to the session
        request.session['bulk-add-people'] = persons_tasks

        # check if user wants to verify or save, or cancel

        if request.POST.get('verify', None):
            # if there's "verify" in POST, then do only verification
            any_errors = verify_upload_person_task(persons_tasks)
            if any_errors:
                messages.add_message(
                    request, messages.ERROR,
                    "Please make sure to fix all errors "
                    "listed below.")

            context = {
                'title': 'Confirm uploaded data',
                'persons_tasks': persons_tasks
            }
            return render(request, 'workshops/person_bulk_add_results.html',
                          context)

        elif (request.POST.get('confirm', None)
              and not request.POST.get('cancel', None)):
            # there must be "confirm" and no "cancel" in POST in order to save

            try:
                records = 0
                with transaction.atomic():
                    for row in persons_tasks:
                        # create person
                        p = Person(**row['person'])
                        p.save()
                        records += 1

                        # create task if data supplied
                        if row['event'] and row['role']:
                            e = Event.objects.get(slug=row['event'])
                            r = Role.objects.get(name=row['role'])
                            t = Task(person=p, event=e, role=r)
                            t.save()
                            records += 1

            except (IntegrityError, ObjectDoesNotExist) as e:
                messages.add_message(
                    request, messages.ERROR,
                    "Error saving data to the database: {}. "
                    "Please make sure to fix all errors "
                    "listed below.".format(e))
                verify_upload_person_task(persons_tasks)
                context = {
                    'title': 'Confirm uploaded data',
                    'persons_tasks': persons_tasks
                }
                return render(request,
                              'workshops/person_bulk_add_results.html',
                              context)

            else:
                request.session['bulk-add-people'] = None
                messages.add_message(
                    request, messages.SUCCESS,
                    "Successfully bulk-loaded {} records.".format(records))
                return redirect('person_bulk_add')

        else:
            # any "cancel" or no "confirm" in POST cancels the upload
            request.session['bulk-add-people'] = None
            return redirect('person_bulk_add')

    else:
        # alters persons_tasks via reference
        verify_upload_person_task(persons_tasks)

        context = {
            'title': 'Confirm uploaded data',
            'persons_tasks': persons_tasks
        }
        return render(request, 'workshops/person_bulk_add_results.html',
                      context)