Example #1
0
 def test_undefined_filter_criteria(self):
     with pytest.raises(InternalServerError):
         CohortFilter.create(
             uid=asc_advisor_uid,
             label='Cohort with undefined filter criteria',
             genders=[],
             in_intensive_cohort=None,
         )
Example #2
0
 def test_undefined_filter_criteria(self):
     with pytest.raises(InternalServerError):
         CohortFilter.create(
             uid=asc_advisor_uid,
             name='Cohort with undefined filter criteria',
             filter_criteria={
                 'genders': [],
                 'inIntensiveCohort': None,
             },
         )
Example #3
0
def create_cohort():
    params = request.get_json()
    domain = get_param(params, 'domain', 'default')
    if is_unauthorized_domain(domain):
        raise ForbiddenRequestError(
            f'You are unauthorized to query the \'{domain}\' domain')
    name = get_param(params, 'name', None)
    filters = get_param(params, 'filters', None)
    order_by = params.get('orderBy')
    # Authorization check
    filter_keys = list(map(lambda f: f['key'], filters))
    if is_unauthorized_search(filter_keys, order_by):
        raise ForbiddenRequestError(
            'You are unauthorized to access student data managed by other departments'
        )
    filter_criteria = _translate_filters_to_cohort_criteria(filters, domain)
    if not name or not filter_criteria:
        raise BadRequestError(
            'Cohort creation requires \'name\' and \'filters\'')
    cohort = CohortFilter.create(
        uid=current_user.get_uid(),
        name=name,
        filter_criteria=filter_criteria,
        domain=domain,
        order_by=order_by,
        include_alerts_for_user_id=current_user.get_id(),
    )
    _decorate_cohort(cohort)
    return tolerant_jsonify(cohort)
Example #4
0
    def test_create_and_delete_cohort(self):
        """Cohort_filter record to Flask-Login for recognized UID."""
        owner = AuthorizedUser.find_by_uid(asc_advisor_uid).uid
        shared_with = AuthorizedUser.find_by_uid(coe_advisor_uid).uid
        # Check validity of UIDs
        assert owner
        assert shared_with

        # Create and share cohort
        group_codes = ['MFB-DB', 'MFB-DL', 'MFB-MLB', 'MFB-OLB']
        cohort = CohortFilter.create(
            uid=owner,
            name='Football, Defense',
            filter_criteria={
                'groupCodes': group_codes,
            },
        )
        cohort_id = cohort['id']
        CohortFilter.share(cohort_id, shared_with)
        owners = CohortFilter.find_by_id(cohort_id)['owners']
        assert len(owners) == 2
        assert owner, shared_with in [user['uid'] for user in owners]
        assert cohort['totalStudentCount'] == len(
            CohortFilter.get_sids(cohort_id))

        # Delete cohort and verify
        previous_owner_count = cohort_count(owner)
        previous_shared_count = cohort_count(shared_with)
        CohortFilter.delete(cohort_id)
        assert cohort_count(owner) == previous_owner_count - 1
        assert cohort_count(shared_with) == previous_shared_count - 1
Example #5
0
    def test_filter_criteria(self):
        gpa_ranges = [
            'numrange(0, 2, \'[)\')',
            'numrange(2, 2.5, \'[)\')',
        ]
        group_codes = ['MFB-DB', 'MFB-DL']
        levels = ['Junior']
        majors = ['Environmental Economics & Policy', 'Gender and Women\'s Studies']
        unit_ranges = [
            'numrange(0, 5, \'[]\')',
            'numrange(30, NULL, \'[)\')',
        ]
        cohort = CohortFilter.create(
            uid='1022796',
            label='All criteria, all the time',
            gpa_ranges=gpa_ranges,
            group_codes=group_codes,
            in_intensive_cohort=None,
            levels=levels,
            majors=majors,
            unit_ranges=unit_ranges,
        )
        cohort = CohortFilter.find_by_id(cohort.id)
        expected = {
            'gpaRanges': gpa_ranges,
            'groupCodes': group_codes,
            'inIntensiveCohort': None,
            'levels': levels,
            'majors': majors,
            'unitRanges': unit_ranges,
        }

        def sort_and_format(filter_criteria):
            return json.dumps(filter_criteria, sort_keys=True, indent=2)
        assert sort_and_format(expected) == sort_and_format(cohort.filter_criteria)
Example #6
0
    def test_cohort_update_filter_criteria(self, client, asc_advisor_session):
        label = 'Swimming, Men\'s'
        original_student_count = 4
        cohort = CohortFilter.create(
            uid=asc_advisor_uid,
            label=label,
            group_codes=['MSW', 'MSW-DV', 'MSW-SW'],
            student_count=original_student_count,
        )
        assert original_student_count > 0
        updated_filter_criteria = {
            'groupCodes': ['MSW-DV', 'MSW-SW'],
        }
        data = {
            'id': cohort.id,
            'filterCriteria': updated_filter_criteria,
            'studentCount': original_student_count - 1,
        }
        response = client.post('/api/filtered_cohort/update', data=json.dumps(data), content_type='application/json')
        assert 200 == response.status_code

        updated_cohort = CohortFilter.find_by_id(int(response.json['id']))
        assert updated_cohort.label == label
        assert updated_cohort.student_count == original_student_count - 1

        def remove_empties(filter_criteria):
            return {k: v for k, v in filter_criteria.items() if v is not None}

        expected = remove_empties(cohort.filter_criteria)
        actual = remove_empties(updated_cohort.filter_criteria)
        assert expected == actual
Example #7
0
def create_cohort():
    params = request.get_json()
    if is_unauthorized_search(params):
        raise ForbiddenRequestError(
            'You are unauthorized to access student data managed by other departments'
        )
    label = util.get(params, 'label', None)
    if not label:
        raise BadRequestError('Cohort creation requires \'label\'')
    cohort = CohortFilter.create(
        advisor_ldap_uids=util.get(params, 'advisorLdapUids'),
        coe_prep_statuses=util.get(params, 'coePrepStatuses'),
        ethnicities=util.get(params, 'ethnicities'),
        genders=util.get(params, 'genders'),
        gpa_ranges=util.get(params, 'gpaRanges'),
        group_codes=util.get(params, 'groupCodes'),
        in_intensive_cohort=util.to_bool_or_none(
            params.get('inIntensiveCohort')),
        is_inactive_asc=util.to_bool_or_none(params.get('isInactiveAsc')),
        label=label,
        last_name_range=util.get(params, 'lastNameRange'),
        levels=util.get(params, 'levels'),
        majors=util.get(params, 'majors'),
        uid=current_user.get_id(),
        underrepresented=util.get(params, 'underrepresented'),
        unit_ranges=util.get(params, 'unitRanges'),
    )
    return tolerant_jsonify(decorate_cohort(cohort))
Example #8
0
 def test_cohort_update(self):
     cohort = CohortFilter.create(label='Football teams',
                                  team_codes=['FBM', 'FBW'],
                                  uid='2040')
     foosball_label = 'Foosball teams'
     cohort = CohortFilter.update(cohort['id'], foosball_label)
     assert cohort['label'] == foosball_label
Example #9
0
    def test_create_and_delete_cohort(self):
        """Cohort_filter record to Flask-Login for recognized UID."""
        owner = AuthorizedUser.find_by_uid(asc_advisor_uid).uid
        # Check validity of UID
        assert owner

        # Create cohort
        group_codes = ['MFB-DB', 'MFB-DL', 'MFB-MLB', 'MFB-OLB']
        cohort = CohortFilter.create(
            uid=owner,
            name='Football, Defense',
            filter_criteria={
                'groupCodes': group_codes,
            },
        )
        cohort_id = cohort['id']
        assert CohortFilter.find_by_id(cohort_id)['owner']['uid'] == owner
        assert cohort['totalStudentCount'] == len(
            CohortFilter.get_sids(cohort_id))

        # Delete cohort and verify
        previous_owner_count = cohort_count(owner)
        CohortFilter.delete(cohort_id)
        std_commit(allow_test_environment=True)
        assert cohort_count(owner) == previous_owner_count - 1
Example #10
0
 def test_unauthorized_cohort_update(self, client, coe_advisor_session):
     cohort = CohortFilter.create(uid=asc_advisor_uid, label='Swimming, Men\'s', group_codes=['MSW', 'MSW-DV', 'MSW-SW'])
     data = {
         'id': cohort.id,
         'label': 'Hack the label!',
     }
     response = client.post('/api/filtered_cohort/update', data=json.dumps(data), content_type='application/json')
     assert 403 == response.status_code
Example #11
0
 def test_delete_cohort(self, client, coe_advisor_session):
     """Deletes existing custom cohort while enforcing rules of ownership."""
     label = 'Water polo teams'
     cohort = CohortFilter.create(uid=coe_advisor_uid, label=label, group_codes=['WWP', 'MWP'])
     # Verify deletion
     response = client.delete(f'/api/filtered_cohort/delete/{cohort.id}')
     assert response.status_code == 200
     cohorts = CohortFilter.all_owned_by(coe_advisor_uid)
     assert not next((c for c in cohorts if c.id == cohort.id), None)
Example #12
0
    def test_delete_cohort_wrong_user(self, client, fake_auth):
        """custom cohort deletion is only available to owners"""
        cohort = CohortFilter.create(label='Badminton teams', team_codes=['MBK', 'WBK'], uid=test_uid)
        assert cohort and 'id' in cohort

        # This user does not own the custom cohort above
        fake_auth.login('2040')
        response = client.delete('/api/cohort/delete/{}'.format(cohort['id']))
        assert response.status_code == 400
        assert '2040 does not own' in str(response.data)
Example #13
0
def create_cohort():
    params = request.get_json()
    label = params['label']
    team_codes = params['team_codes']
    if not label or not team_codes:
        raise BadRequestError(
            'Cohort creation requires \'label\' and \'teams\'')

    cohort = CohortFilter.create(label=label,
                                 team_codes=team_codes,
                                 uid=current_user.get_id())
    return tolerant_jsonify(cohort)
Example #14
0
 def test_filter_criteria(self):
     gpa_ranges = [
         {
             'min': 0,
             'max': 1.999
         },
         {
             'min': 2,
             'max': 2.499
         },
     ]
     group_codes = ['MFB-DB', 'MFB-DL']
     intended_majors = ['Public Health BA']
     levels = ['Junior']
     majors = [
         'Environmental Economics & Policy', 'Gender and Women\'s Studies'
     ]
     minors = ['Physics UG']
     unit_ranges = [
         'numrange(0, 5, \'[]\')',
         'numrange(30, NULL, \'[)\')',
     ]
     cohort = CohortFilter.create(
         uid='1022796',
         name='All criteria, all the time',
         filter_criteria={
             'gpaRanges': gpa_ranges,
             'groupCodes': group_codes,
             'inIntensiveCohort': None,
             'intendedMajors': intended_majors,
             'levels': levels,
             'majors': majors,
             'minors': minors,
             'unitRanges': unit_ranges,
         },
     )
     cohort_id = cohort['id']
     cohort = CohortFilter.find_by_id(cohort_id)
     expected = {
         'gpaRanges': gpa_ranges,
         'groupCodes': group_codes,
         'inIntensiveCohort': None,
         'intendedMajors': intended_majors,
         'levels': levels,
         'majors': majors,
         'minors': minors,
         'unitRanges': unit_ranges,
     }
     for key, value in expected.items():
         assert cohort['criteria'][key] == expected[key]
     assert cohort['totalStudentCount'] == len(
         CohortFilter.get_sids(cohort_id))
Example #15
0
    def test_delete_cohort(self, authenticated_session, client):
        """deletes existing custom cohort while enforcing rules of ownership"""
        label = 'Water polo teams'
        cohort = CohortFilter.create(label=label, team_codes=['WPW', 'WPM'], uid=test_uid)

        assert cohort and 'id' in cohort
        id_of_created_cohort = cohort['id']

        # Verify deletion
        response = client.delete('/api/cohort/delete/{}'.format(id_of_created_cohort))
        assert response.status_code == 200
        cohorts = CohortFilter.all_owned_by(test_uid)
        assert not next((c for c in cohorts if c['id'] == id_of_created_cohort), None)
Example #16
0
    def test_delete_cohort_wrong_user(self, client, fake_auth):
        """Custom cohort deletion is only available to owners."""
        cohort = CohortFilter.create(uid=coe_advisor_uid, label='Badminton teams', group_codes=['WWP', 'MWP'])
        assert cohort

        # This user does not own the custom cohort above
        fake_auth.login('2040')
        response = client.get(f'/api/filtered_cohort/{cohort.id}')
        assert response.status_code == 200
        _cohort = json.loads(response.data)
        assert _cohort['isOwnedByCurrentUser'] is False

        response = client.delete(f'/api/filtered_cohort/delete/{cohort.id}')
        assert response.status_code == 400
        assert '2040 does not own' in str(response.data)
Example #17
0
def main(app):
    from boac.models.cohort_filter import CohortFilter

    uid = sys.argv[1]
    first_name = sys.argv[2]

    if uid:
        label = f'{first_name}\'s Students' if first_name else 'My Students'
        cohort = CohortFilter.create(
            uid=uid,
            label=label,
            advisor_ldap_uid=uid,
        )
        print(f'Cohort created: {cohort}')
    else:
        print(f'ERROR: Failed to create cohort')

    print('\nDone.\n')
Example #18
0
def create_cohort():
    params = request.get_json()
    name = get_param(params, 'name', None)
    filters = get_param(params, 'filters', None)
    order_by = params.get('orderBy')
    filter_criteria = _filters_to_filter_criteria(filters, order_by)
    if not name or not filter_criteria:
        raise BadRequestError(
            'Cohort creation requires \'name\' and \'filters\'')
    cohort = CohortFilter.create(
        uid=current_user.get_uid(),
        name=name,
        filter_criteria=filter_criteria,
        order_by=order_by,
        include_alerts_for_user_id=current_user.get_id(),
    )
    _decorate_cohort(cohort)
    return tolerant_jsonify(cohort)
Example #19
0
    def test_create_and_delete_cohort(self):
        """Cohort_filter record to Flask-Login for recognized UID."""
        owner = AuthorizedUser.find_by_uid(asc_advisor_uid).uid
        shared_with = AuthorizedUser.find_by_uid(coe_advisor_uid).uid
        # Check validity of UIDs
        assert owner
        assert shared_with

        # Create and share cohort
        group_codes = ['MFB-DB', 'MFB-DL', 'MFB-MLB', 'MFB-OLB']
        cohort = CohortFilter.create(uid=owner, label='Football, Defense', group_codes=group_codes)
        cohort = CohortFilter.share(cohort.id, shared_with)
        assert len(cohort.owners) == 2
        assert owner, shared_with in [user.uid for user in cohort.owners]

        # Delete cohort and verify
        previous_owner_count = cohort_count(owner)
        previous_shared_count = cohort_count(shared_with)
        CohortFilter.delete(cohort.id)
        assert cohort_count(owner) == previous_owner_count - 1
        assert cohort_count(shared_with) == previous_shared_count - 1
Example #20
0
    def test_cohort_update_name(self, client, asc_advisor_session):
        cohort = CohortFilter.create(uid=asc_advisor_uid, label='Swimming, Men\'s', group_codes=['MSW', 'MSW-DV', 'MSW-SW'])
        updated_label = 'Splashing, Men\'s'
        # First, we POST an empty label
        response = client.post('/api/filtered_cohort/update', data=json.dumps({'id': cohort.id}), content_type='application/json')
        assert 400 == response.status_code
        # Now, we POST a valid label
        data = {
            'id': cohort.id,
            'label': updated_label,
        }
        response = client.post('/api/filtered_cohort/update', data=json.dumps(data), content_type='application/json')
        assert 200 == response.status_code
        update = response.json
        assert update['label'] == updated_label

        def remove_empties(filter_criteria):
            return {k: v for k, v in filter_criteria.items() if v is not None}
        expected = remove_empties(cohort.filter_criteria)
        actual = remove_empties(update['filterCriteria'])
        assert expected == actual
Example #21
0
    def test_create_and_delete_cohort(self):
        """cohort_filter record to Flask-Login for recognized UID"""
        owner = AuthorizedUser.find_by_uid('2040')
        shared_with = AuthorizedUser.find_by_uid('1133399')
        # Check validity of UIDs
        assert owner
        assert shared_with

        # Create and share cohort
        cohort = CohortFilter.create(label='High-risk Badminton',
                                     team_codes=['MBK', 'WBK'],
                                     uid=owner.uid)
        cohort = CohortFilter.share(cohort['id'], shared_with.uid)
        assert len(cohort['owners']) == 2
        assert owner, shared_with in cohort['owners']

        # Delete cohort and verify
        previous_owner_count = cohort_count(owner)
        previous_shared_count = cohort_count(shared_with)
        CohortFilter.delete(cohort['id'])
        assert cohort_count(owner) == previous_owner_count - 1
        assert cohort_count(shared_with) == previous_shared_count - 1
Example #22
0
 def test_ce3_filter_criteria(self):
     colleges = ['College of Letters and Science', 'College of Engineering']
     family_dependent_ranges = [
         {
             'min': 0,
             'max': 2
         },
         {
             'min': 5,
             'max': 5
         },
     ]
     freshman_or_transfer = ['Transfer']
     has_fee_waiver = True
     cohort = CohortFilter.create(
         uid=ce3_advisor_uid,
         name='All my admits',
         filter_criteria={
             'colleges': colleges,
             'familyDependentRanges': family_dependent_ranges,
             'freshmanOrTransfer': freshman_or_transfer,
             'hasFeeWaiver': has_fee_waiver,
         },
         domain='admitted_students',
     )
     cohort_id = cohort['id']
     cohort = CohortFilter.find_by_id(cohort_id)
     expected = {
         'colleges': colleges,
         'familyDependentRanges': family_dependent_ranges,
         'freshmanOrTransfer': freshman_or_transfer,
         'hasFeeWaiver': has_fee_waiver,
     }
     for key, value in expected.items():
         assert cohort['criteria'][key] == expected[key]
     assert cohort['totalStudentCount'] == len(
         CohortFilter.get_sids(cohort_id))
     assert cohort['students']
Example #23
0
def create_filtered_cohorts():
    # Oliver's cohorts
    CohortFilter.create(uid='2040', label='All sports', group_codes=['MFB-DL', 'WFH'])
    CohortFilter.create(uid='2040', label='Football, Defense', group_codes=['MFB-DB', 'MFB-DL'])
    CohortFilter.create(uid='2040', label='Field Hockey', group_codes=['WFH'])
    # Flint's cohorts
    asc_advisor_uid = '1081940'
    CohortFilter.create(uid=asc_advisor_uid, label='Defense Backs, Inactive', group_codes=['MFB-DB'], is_inactive_asc=True)
    CohortFilter.create(uid=asc_advisor_uid, label='Defense Backs, Active', group_codes=['MFB-DB'], is_inactive_asc=False)
    CohortFilter.create(uid=asc_advisor_uid, label='Defense Backs, All', group_codes=['MFB-DB'])
    CohortFilter.create(uid=asc_advisor_uid, label='Undeclared students', majors=['Undeclared'], is_inactive_asc=False)
    CohortFilter.create(uid=asc_advisor_uid, label='All sports', group_codes=['MFB-DL', 'WFH'], is_inactive_asc=False)
    # Sandeep's cohorts
    coe_advisor_uid = '1133399'
    CohortFilter.create(uid=coe_advisor_uid, label='Sandeep\'s Students', advisor_ldap_uids=[coe_advisor_uid])
    CohortFilter.create(uid='1133399', label='Radioactive Women and Men', majors=['Nuclear Engineering BS'])
    std_commit(allow_test_environment=True)
Example #24
0
def create_cohort(team_code1, team_code2, uid):
    name1 = TeamMember.team_definitions[team_code1]
    name2 = TeamMember.team_definitions[team_code2]
    CohortFilter.create(label=name1 + ' and ' + name2,
                        team_codes=[team_code1, team_code2],
                        uid=uid)
Example #25
0
def _create_cohorts():
    # Oliver's cohorts
    CohortFilter.create(
        uid='2040',
        name='All sports',
        filter_criteria={
            'groupCodes': ['MFB-DL', 'WFH'],
        },
    )
    CohortFilter.create(
        uid='2040',
        name='Football, Defense',
        filter_criteria={
            'groupCodes': ['MFB-DB', 'MFB-DL'],
        },
    )
    CohortFilter.create(
        uid='2040',
        name='Field Hockey',
        filter_criteria={
            'groupCodes': ['WFH'],
        },
    )
    # Flint's cohorts
    asc_advisor_uid = '1081940'
    CohortFilter.create(
        uid=asc_advisor_uid,
        name='Defense Backs, Inactive',
        filter_criteria={
            'groupCodes': ['MFB-DB'],
            'isInactiveAsc': True,
        },
    )
    CohortFilter.create(
        uid=asc_advisor_uid,
        name='Defense Backs, Active',
        filter_criteria={
            'groupCodes': ['MFB-DB'],
            'isInactiveAsc': False,
        },
    )
    CohortFilter.create(
        uid=asc_advisor_uid,
        name='Defense Backs, All',
        filter_criteria={
            'groupCodes': ['MFB-DB'],
        },
    )
    CohortFilter.create(
        uid=asc_advisor_uid,
        name='Undeclared students',
        filter_criteria={
            'majors': ['Undeclared'],
            'isInactiveAsc': False,
        },
    )
    CohortFilter.create(
        uid=asc_advisor_uid,
        name='All sports',
        filter_criteria={
            'groupCodes': ['MFB-DL', 'WFH'],
            'isInactiveAsc': False,
        },
    )
    coe_advisor_uid = '1133399'
    CohortFilter.create(
        uid=coe_advisor_uid,
        name='Roberta\'s Students',
        filter_criteria={
            'coeAdvisorLdapUids': [coe_advisor_uid],
        },
    )
    CohortFilter.create(
        uid=coe_advisor_uid,
        name='Radioactive Women and Men',
        filter_criteria={
            'majors': ['Nuclear Engineering BS'],
        },
    )
    # The CE3 advisor will create a standard cohort and a cohort with domain='admitted_students'
    ce3_advisor_uid = '2525'
    CohortFilter.create(
        uid=ce3_advisor_uid,
        name='Undeclared students',
        filter_criteria={
            'majors': ['Undeclared'],
            'isInactiveAsc': False,
        },
    )
    CohortFilter.create(
        uid=ce3_advisor_uid,
        name='First Generation Students',
        filter_criteria={
            'isFirstGenerationCollege': True,
        },
        domain='admitted_students',
    )
    std_commit(allow_test_environment=True)