def test_search_advising_notes_paginates_new_and_old(self, app, fake_auth): fake_auth.login(coe_advisor) for i in range(0, 5): _create_coe_advisor_note( sid='11667051', subject='Planned redundancy', body=f'Confounded note {i + 1}', ) response = search_advising_notes(search_phrase='confound', offset=0, limit=4) assert len(response) == 4 assert response[0][ 'noteSnippet'] == 'Planned redundancy - <strong>Confounded</strong> note 1' assert response[1][ 'noteSnippet'] == 'Planned redundancy - <strong>Confounded</strong> note 2' assert response[2][ 'noteSnippet'] == 'Planned redundancy - <strong>Confounded</strong> note 3' assert response[3][ 'noteSnippet'] == 'Planned redundancy - <strong>Confounded</strong> note 4' response = search_advising_notes(search_phrase='confound', offset=4, limit=4) assert len(response) == 3 assert response[0][ 'noteSnippet'] == 'Planned redundancy - <strong>Confounded</strong> note 5' assert response[1]['noteSnippet'].startswith( 'I am <strong>confounded</strong>') assert response[2]['noteSnippet'].startswith('...pity the founder')
def test_search_advising_notes_narrowed_by_author(self, app, fake_auth): """Narrows results for both new and legacy advising notes by author SID.""" joni = { 'name': 'Joni Mitchell', 'uid': '1133399', 'sid': '800700600', } not_joni = { 'name': 'Oliver Heyer', 'uid': '2040', } for author in [joni, not_joni]: _create_coe_advisor_note( author_uid=author['uid'], author_name=author['name'], sid='11667051', subject='Futher on France', body='Brigitte has been molded to middle class circumstance', ) fake_auth.login(coe_advisor) wide_response = search_advising_notes(search_phrase='Brigitte') assert len(wide_response) == 4 narrow_response = search_advising_notes(search_phrase='Brigitte', author_csid=joni['sid']) assert len(narrow_response) == 2 new_note, legacy_note = narrow_response[0], narrow_response[1] assert new_note['advisorUid'] == joni['uid'] assert legacy_note['advisorSid'] == joni['sid']
def test_search_advising_notes_stemming(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='spare') assert len(response) == 1 assert '<strong>spared</strong>' in response[0]['noteSnippet'] response = search_advising_notes(search_phrase='felicity') assert len(response) == 1 assert '<strong>felicities</strong>' in response[0]['noteSnippet']
def test_search_dates(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='2/1/2019 1:30') assert len(response) == 1 assert 'next appt. <strong>2/1/2019</strong> @ <strong>1:30</strong>. Student continued' in response[0]['noteSnippet'] response = search_advising_notes(search_phrase='1-24-19') assert len(response) == 1 assert 'drop Eng. 123 by <strong>1-24-19</strong>' in response[0]['noteSnippet']
def test_search_advising_notes_narrowed_by_topic(self, app, fake_auth): for topic in ['Good Show', 'Bad Show']: _create_coe_advisor_note( sid='11667051', topics=[topic], subject='Brigitte', ) fake_auth.login(coe_advisor) wide_response = search_advising_notes(search_phrase='Brigitte') assert len(wide_response) == 4 narrow_response = search_advising_notes(search_phrase='Brigitte', topic='Good Show') assert len(narrow_response) == 2
def test_search_advising_notes_restricted_to_students_in_loch(self, app, fake_auth): fake_auth.login(coe_advisor) _create_coe_advisor_note( sid='6767676767', subject='Who is this?', body="Not a student in the loch, that's for sure", ) assert len(search_advising_notes(search_phrase='loch')) == 0 _create_coe_advisor_note( sid='11667051', subject='A familiar face', body='Whereas this student is a most distinguished denizen of the loch', ) assert len(search_advising_notes(search_phrase='loch')) == 1
def test_search_for_asc_advising_notes(self, app, fake_auth): fake_auth.login(asc_advisor) response = search_advising_notes(search_phrase='kilmister') assert len(response) == 1 assert response[0]['noteSnippet'] == '' assert response[0]['advisorName'] == 'Lemmy Kilmister' assert parse(response[0]['createdAt']) == parse('2014-01-03T20:30:00+00') assert response[0]['updatedAt'] is None response = search_advising_notes(search_phrase='academic') assert len(response) == 1 assert response[0]['noteSnippet'] == '' assert response[0]['advisorName'] == 'Lemmy Kilmister' assert parse(response[0]['createdAt']) == parse('2014-01-03T20:30:00+00') assert response[0]['updatedAt'] is None
def test_search_advising_notes_narrowed_by_student(self, app, fake_auth): """Narrows results for both new and legacy advising notes by student SID.""" for sid in ['9000000000', '9100000000']: _create_coe_advisor_note( sid=sid, subject='Case load', body='Another day, another student', ) fake_auth.login(coe_advisor) wide_response = search_advising_notes(search_phrase='student') assert len(wide_response) == 5 narrow_response = search_advising_notes(search_phrase='student', student_csid='9100000000') assert len(narrow_response) == 2 new_note, legacy_note = narrow_response[0], narrow_response[1] assert new_note['studentSid'] == '9100000000' assert legacy_note['studentSid'] == '9100000000'
def test_search_email_address(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes( search_phrase='E-mailed [email protected]') assert len(response) == 1 assert "until Sp '19. <strong>E-mailed</strong> <strong>[email protected]</strong>: told her she'll need to drop Eng. 123" \ in response[0]['noteSnippet']
def test_search_advising_notes_by_category(self, app, fake_auth): """Matches legacy category/subcategory for SIS advising notes only if body is blank.""" fake_auth.login(coe_advisor) notes = search_advising_notes(search_phrase='Quick Question') assert len(notes) == 1 assert notes[0][ 'noteSnippet'] == '<strong>Quick</strong> <strong>Question</strong>, Unanswered'
def test_search_advising_notes_ordered_by_relevance(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='confound') assert len(response) == 2 assert response[0][ 'noteSnippet'] == 'I am <strong>confounded</strong> by this <strong>confounding</strong> student' assert '<strong>confounded</strong> that of himself' in response[1][ 'noteSnippet']
def test_search_legacy_advising_notes_narrowed_by_date(self, app, fake_auth): halloween_2017 = datetime(2017, 10, 31, tzinfo=pytz.timezone(app.config['TIMEZONE'])).astimezone(pytz.utc) days = [ halloween_2017 - timedelta(days=1), halloween_2017, halloween_2017 + timedelta(days=1), halloween_2017 + timedelta(days=2), halloween_2017 + timedelta(days=3), ] fake_auth.login(coe_advisor) unbounded = search_advising_notes(search_phrase='Brigitte') assert len(unbounded) == 2 lower_bound = search_advising_notes(search_phrase='Brigitte', datetime_from=days[2]) assert len(lower_bound) == 1 upper_bound = search_advising_notes(search_phrase='Brigitte', datetime_to=days[2]) assert len(upper_bound) == 1 closed_1 = search_advising_notes(search_phrase='Brigitte', datetime_from=days[0], datetime_to=days[2]) assert len(closed_1) == 1 closed_2 = search_advising_notes(search_phrase='Brigitte', datetime_from=days[2], datetime_to=days[3]) assert len(closed_2) == 1 closed_3 = search_advising_notes(search_phrase='Brigitte', datetime_from=days[0], datetime_to=days[3]) assert len(closed_3) == 2 closed_4 = search_advising_notes(search_phrase='Brigitte', datetime_from=days[3], datetime_to=days[4]) assert len(closed_4) == 0
def test_search_advising_notes_timestamp_format(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='confound') ucbconversion_note = response[0] cs_note = response[1] assert ucbconversion_note['createdAt'] assert ucbconversion_note['updatedAt'] is None assert cs_note['createdAt'] assert cs_note['updatedAt'] is None
def test_search_advising_notes_narrowed_by_topic(self, app, fake_auth): for topic in ['Good Show', 'Bad Show']: Note.create( author_uid='1133399', author_name='Joni Mitchell', author_role='Advisor', author_dept_codes='COENG', sid='11667051', topics=[topic], subject='Brigitte', body='', ) fake_auth.login(coe_advisor) wide_response = search_advising_notes(search_phrase='Brigitte') assert len(wide_response) == 4 narrow_response = search_advising_notes(search_phrase='Brigitte', topic='Good Show') assert len(narrow_response) == 2
def test_search_advising_notes_narrowed_by_student(self, app, fake_auth): """Narrows results for both new and legacy advising notes by student SID.""" for sid in ['9100000000', '9100000001']: Note.create( author_uid='1133399', author_name='Joni Mitchell', author_role='Advisor', author_dept_codes='COENG', sid=sid, subject='Case load', body='Another day, another student', ) fake_auth.login(coe_advisor) wide_response = search_advising_notes(search_phrase='student') assert len(wide_response) == 5 narrow_response = search_advising_notes(search_phrase='student', student_csid='9100000000') assert len(narrow_response) == 2 new_note, legacy_note = narrow_response[0], narrow_response[1] assert new_note['studentSid'] == '9100000000' assert legacy_note['studentSid'] == '9100000000'
def test_search_advising_notes_includes_newly_created(self, app, fake_auth): fake_auth.login(coe_advisor) _create_coe_advisor_note( sid='11667051', subject='Confound this note', body='and its successors and assigns', ) response = search_advising_notes(search_phrase='confound') assert len(response) == 3 assert response[0]['noteSnippet'] == '<strong>Confound</strong> this note - and its successors and assigns' assert response[1]['noteSnippet'].startswith('I am <strong>confounded</strong>') assert response[2]['noteSnippet'].startswith('...pity the founder')
def _notes_search(search_phrase, params): note_options = util.get(params, 'noteOptions', {}) author_csid = note_options.get('advisorCsid') author_uid = note_options.get('advisorUid') student_csid = note_options.get('studentCsid') topic = note_options.get('topic') limit = int(util.get(note_options, 'limit', 20)) offset = int(util.get(note_options, 'offset', 0)) date_from = note_options.get('dateFrom') date_to = note_options.get('dateTo') if not len(search_phrase) and not (author_uid or author_csid or student_csid or topic or date_from or date_to): raise BadRequestError('Invalid or empty search input') if date_from: try: datetime_from = util.localized_timestamp_to_utc( f'{date_from}T00:00:00') except ValueError: raise BadRequestError('Invalid dateFrom value') else: datetime_from = None if date_to: try: datetime_to = util.localized_timestamp_to_utc( f'{date_to}T00:00:00') + timedelta(days=1) except ValueError: raise BadRequestError('Invalid dateTo value') else: datetime_to = None if datetime_from and datetime_to and datetime_to <= datetime_from: raise BadRequestError('dateFrom must be less than dateTo') notes_results = search_advising_notes( search_phrase=search_phrase, author_csid=author_csid, author_uid=author_uid, student_csid=student_csid, topic=topic, datetime_from=datetime_from, datetime_to=datetime_to, offset=offset, limit=limit, ) return { 'notes': notes_results, }
def test_search_advising_notes(self, app, fake_auth): fake_auth.login(coe_advisor) notes = search_advising_notes(search_phrase='herostratus') assert len(notes) == 1 assert '<strong>Herostratus</strong> lives' in notes[0]['noteSnippet'] assert notes[0]['noteSnippet'].startswith('...iniquity of oblivion blindely scattereth her poppy') assert notes[0]['noteSnippet'].endswith('confounded that of himself. In vain we...') assert notes[0]['studentSid'] == '11667051' assert notes[0]['studentUid'] == '61889' assert notes[0]['studentName'] == 'Deborah Davies' assert notes[0]['advisorSid'] == '600500400' assert notes[0]['id'] == '11667051-00003' assert parse(notes[0]['createdAt']) == parse('2017-11-05T12:00:00+00') assert notes[0]['updatedAt'] is None
def test_search_new_advising_notes_narrowed_by_date(self, app, fake_auth): today = datetime.now().replace( hour=0, minute=0, second=0, tzinfo=pytz.timezone(app.config['TIMEZONE'])).astimezone(pytz.utc) yesterday = today - timedelta(days=1) tomorrow = today + timedelta(days=1) fake_auth.login(coe_advisor) Note.create( author_uid=coe_advisor, author_name='Balloon Man', author_role='Spherical', author_dept_codes='COENG', sid='11667051', subject='Bryant Park', body='There were loads of them', ) assert len(search_advising_notes(search_phrase='Bryant')) == 1 assert len( search_advising_notes(search_phrase='Bryant', datetime_from=yesterday)) == 1 assert len( search_advising_notes(search_phrase='Bryant', datetime_to=yesterday)) == 0 assert len( search_advising_notes(search_phrase='Bryant', datetime_from=yesterday, datetime_to=yesterday)) == 0 assert len( search_advising_notes(search_phrase='Bryant', datetime_from=tomorrow)) == 0 assert len( search_advising_notes(search_phrase='Bryant', datetime_to=tomorrow)) == 1 assert len( search_advising_notes(search_phrase='Bryant', datetime_from=tomorrow, datetime_to=tomorrow)) == 0 assert len( search_advising_notes(search_phrase='Bryant', datetime_from=yesterday, datetime_to=tomorrow)) == 1
def test_search_advising_notes_includes_newly_created( self, app, fake_auth): fake_auth.login(coe_advisor) Note.create( author_uid=coe_advisor, author_name='Balloon Man', author_role='Spherical', author_dept_codes='COENG', sid='11667051', subject='Confound this note', body='and its successors and assigns', ) response = search_advising_notes(search_phrase='confound') assert len(response) == 3 assert response[0][ 'noteSnippet'] == '<strong>Confound</strong> this note - and its successors and assigns' assert response[1]['noteSnippet'].startswith( 'I am <strong>confounded</strong>') assert response[2]['noteSnippet'].startswith('...pity the founder')
def test_search_advising_notes_too_short_to_snippet(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='campus') assert len(response) == 1 assert response[0][ 'noteSnippet'] == 'Is this student even on <strong>campus</strong>?'
def test_search_advising_notes_multiple_terms(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='burnt diana temple') assert len(response) == 1 assert 'Herostratus lives that <strong>burnt</strong> the <strong>Temple</strong> of <strong>Diana</strong>' in response[ 0]['noteSnippet']
def test_search_decimals(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='2.0') assert len(response) == 1 assert "Student continued on <strong>2.0</strong> prob (COP) until Sp '19." in response[ 0]['noteSnippet']
def test_search_advising_notes_funny_characters(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='horse; <- epitaph? ->') assert len(response) == 1 assert 'Time hath spared the <strong>Epitaph</strong> of Adrians <strong>horse</strong>' in response[ 0]['noteSnippet']
def test_search_advising_notes_no_match(self, app, fake_auth): fake_auth.login(coe_advisor) response = search_advising_notes(search_phrase='pyramid octopus') assert len(response) == 0