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]: Note.create( author_uid=author['uid'], author_name=author['name'], author_role='Advisor', author_dept_codes='COENG', 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_paginates_new_and_old(self, app, fake_auth): fake_auth.login(coe_advisor) for i in range(0, 5): Note.create( author_uid=coe_advisor, author_name='Balloon Man', author_role='Spherical', author_dept_codes='COENG', 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 mock_advising_note(app, db): """Create advising note with attachment (mock s3).""" with mock_advising_note_s3_bucket(app): note_author_uid = '90412' base_dir = app.config['BASE_DIR'] path_to_file = f'{base_dir}/fixtures/mock_advising_note_attachment_1.txt' with open(path_to_file, 'r') as file: note = Note.create( author_uid=note_author_uid, author_name='Joni Mitchell', author_role='Director', author_dept_codes=['UWASC'], sid='11667051', subject='In France they kiss on main street', body=""" My darling dime store thief, in the War of Independence Rock 'n Roll rang sweet as victory, under neon signs """, attachments=[ { 'name': path_to_file.rsplit('/', 1)[-1], 'byte_stream': file.read(), }, ], ) db.session.add(note) std_commit(allow_test_environment=True) yield note Note.delete(note_id=note.id) std_commit(allow_test_environment=True)
def create_note(): params = request.form sid = params.get('sid', None) subject = params.get('subject', None) body = params.get('body', None) topics = get_note_topics_from_http_post() if not sid or not subject: raise BadRequestError('Note creation requires \'subject\' and \'sid\'') user_dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(user_dept_codes): raise ForbiddenRequestError( 'Sorry, only advisors can create advising notes.') author_profile = _get_author_profile() attachments = get_note_attachments_from_http_post(tolerate_none=True) note = Note.create( **author_profile, subject=subject, body=process_input_from_rich_text_editor(body), topics=topics, sid=sid, attachments=attachments, template_attachment_ids=get_template_attachment_ids_from_http_post(), ) note_read = NoteRead.find_or_create(current_user.get_id(), note.id) return tolerant_jsonify( _boa_note_to_compatible_json(note=note, note_read=note_read))
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 create_notes(): benchmark = get_benchmarker('create_notes') params = request.form sids = _get_sids_for_note_creation() benchmark(f'SID count: {len(sids)}') body = params.get('body', None) is_private = to_bool_or_none(params.get('isPrivate', False)) subject = params.get('subject', None) topics = get_note_topics_from_http_post() if not sids or not subject: benchmark('end (BadRequest)') raise BadRequestError( 'Note creation requires \'subject\' and \'sids\'') dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(dept_codes): benchmark('end (Forbidden)') raise ForbiddenRequestError( 'Sorry, only advisors can create advising notes') if is_private and not current_user.can_access_private_notes: benchmark('end (Forbidden)') raise ForbiddenRequestError( 'Sorry, you are not authorized to manage note privacy.') attachments = get_note_attachments_from_http_post(tolerate_none=True) benchmark(f'Attachment count: {len(attachments)}') body = process_input_from_rich_text_editor(body) template_attachment_ids = get_template_attachment_ids_from_http_post() if len(sids) == 1: note = Note.create( **_get_author_profile(), attachments=attachments, body=body, is_private=is_private, sid=sids[0], subject=subject, template_attachment_ids=template_attachment_ids, topics=topics, ) response = tolerant_jsonify( _boa_note_to_compatible_json(note, note_read=True)) else: response = tolerant_jsonify( Note.create_batch( **_get_author_profile(), attachments=attachments, author_id=current_user.to_api_json()['id'], body=body, is_private=is_private, sids=sids, subject=subject, template_attachment_ids=template_attachment_ids, topics=topics, ), ) benchmark('end') return response
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 mock_coe_advising_note(): return Note.create( author_uid=coe_advisor_uid, author_name='Balloon Man', author_role='Spherical', author_dept_codes='COENG', sid=coe_student['sid'], subject='I was walking up Sixth Avenue', body='He spattered me with tomatoes, Hummus, chick peas', )
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 _create_coe_advisor_note( sid, subject, body='', topics=(), author_uid=coe_advisor, author_name='Balloon Man', author_role='Spherical', author_dept_codes='COENG', ): Note.create( author_uid=author_uid, author_name=author_name, author_role=author_role, author_dept_codes=author_dept_codes, topics=topics, sid=sid, subject=subject, body=body, )
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 mock_asc_advising_note(app, db): return Note.create( author_uid='1133399', author_name='Roberta Joan Anderson', author_role='Advisor', author_dept_codes=['COENG'], sid='3456789012', subject='The hissing of summer lawns', body=""" She could see the valley barbecues from her window sill. See the blue pools in the squinting sun. Hear the hissing of summer lawns """, topics=['darkness', 'no color no contrast'], )
def mock_private_advising_note(app): with mock_advising_note_s3_bucket(app): base_dir = app.config['BASE_DIR'] path_to_file = f'{base_dir}/fixtures/mock_advising_note_attachment_1.txt' with open(path_to_file, 'r') as file: return Note.create( attachments=[{ 'name': path_to_file.rsplit('/', 1)[-1], 'byte_stream': file.read() }], author_uid=ce3_advisor_uid, author_name='Kate Pierson', author_role='Advisor', author_dept_codes=['ZCEEE'], body='Underground like a wild potato.', is_private=True, sid=coe_student['sid'], subject='You\'re living in your own Private Idaho.', )
def test_admin(self, client, fake_auth): """Admin user can access BOA notes report.""" notes = [] topics = [] for index in (1, 2): # Verify that both the note with topics and the one without are found in the report. note = Note.create( author_uid=l_s_advisor_uid, author_name=f'author_name {index}', author_role=f'author_role {index}', author_dept_codes=['QCADV'], sid='11667051', subject=f'subject {index}', body=f'body {index}', ) if index == 1: for topic in ('Rising', 'and', 'Three Feet High'): topics.append( NoteTopic.create(note=note, topic=topic, author_uid=admin_uid)) notes.append(note) std_commit(allow_test_environment=True) fake_auth.login(admin_uid) response = self._api_notes_report(client) assert 'csv' in response.content_type csv = str(response.data) assert 'author_name 1' in csv assert 'author_name 2' in csv assert '11667051' in csv assert 'Three Feet High, and, Rising' in csv # Clean up for item in notes + topics: db.session.delete(item) std_commit(allow_test_environment=True)