def test_set_unavailable_to_mentor(client, auth): token = "123" email = "*****@*****.**" verification_email = save(VerificationEmail(email=email, is_faculty=True)) save(VerificationToken(token=token, email_id=verification_email.id)) save( FacultyProfile( name="Test", contact_email=email, verification_email_id=verification_email.id, cadence="monthly", )) auth.login(token) data = {"available": False} response = client.post("/api/availability", json=data) assert response.status_code == HTTPStatus.OK.value assert response.json["available"] is False assert FacultyProfile.query.all()[0].available_for_mentoring is False
def save_verification_token(email_id, token, is_personal_device): verification_token = VerificationToken( email_id=email_id, token=token, is_personal_device=is_personal_device) save(verification_token) return verification_token
def test_query_searchable_tags_duplicate_tags(db_session): profile = create_test_profile(available_for_mentoring=True) options = [ ActivityOption(value="duplicate", public=True), ClinicalSpecialtyOption(value="duplicate", public=True), ] for option in options: save(option) relation_classes = [FacultyProfileActivity, FacultyClinicalSpecialty] profile_relations = [ cls(tag_id=option.id, profile_id=profile.id) for cls, option in zip(relation_classes, options) ] for relation in profile_relations: save(relation) tags = query_faculty_searchable_tags() assert tags == { **EMPTY_TAGS, "activities": ["duplicate"], "clinical_specialties": ["duplicate"], }
def logout(): verification_token = flask_login.current_user verification_token.logged_out = True save(verification_token) flask_login.logout_user() return {}
def test_does_not_verify_logged_out_token(client): verification_token = create_test_verification_token() verification_token.logged_out = True save(verification_token) response = client.post("/api/verify-token", json={"token": verification_token.token}) assert response.status_code == HTTPStatus.UNAUTHORIZED.value assert response.json == {"token": ["logged out"]}
def test_non_public_tags_excluded(db_session): options = [ActivityOption(value="Activity", public=False)] for option in options: save(option) tags = query_faculty_searchable_tags() assert tags == EMPTY_TAGS
def test_only_available_profile_tags(db_session): profile = create_test_profile() tag = save(ActivityOption(value="duplicate", public=True)) save(FacultyProfileActivity(tag=tag, profile=profile)) tags = query_faculty_searchable_tags() assert tags == EMPTY_TAGS
def update_faculty_profile(profile_id=None): try: schema = faculty_profile_schema.load(request.json) except ValidationError as err: capture_exception(err) raise InvalidPayloadError(err.messages) verification_token = flask_login.current_user profile = FacultyProfile.query.get(profile_id) is_admin = VerificationEmail.query.filter( VerificationEmail.id == verification_token.email_id).value( VerificationEmail.is_admin) log.info( "Edit faculty profile", profile_id=profile_id, is_admin=is_admin, token_id=verification_token.id, email=verification_token.email.email, ) assert is_admin or profile.verification_email_id == verification_token.email_id profile_data = basic_faculty_profile_data(schema) for key, value in profile_data.items(): setattr(profile, key, value) editing_as_admin = ( is_admin and profile.verification_email_id != verification_token.email_id) if not editing_as_admin: profile.date_updated = datetime.datetime.utcnow() save(profile) # TODO rather than deleting all, delete only ones that haven't changed profile_relation_classes = { FacultyProfessionalInterest, FacultyProfileActivity, FacultyHospitalAffiliation, FacultyPartsOfMe, FacultyClinicalSpecialty, FacultyProfileDegree, } for profile_relation_class in profile_relation_classes: profile_relation_class.query.filter( profile_relation_class.profile_id == profile.id).delete() save_all_tags(profile, schema) return jsonify(faculty_profile_schema.dump(profile))
def test_create_profile_with_custom_tag(client, auth): token = "1234" name = "New User" email = "*****@*****.**" verification_email = save(VerificationEmail(email=email)) save(VerificationToken(token=token, email_id=verification_email.id)) clinical_specialties = ["Endocrinology, Diabetes & Metabolism"] affiliations = ["Brigham and Women's Hospital"] professional_interests = ["Advocacy"] parts_of_me = ["African American"] activities = ["Surfing the web"] degrees = ["MBA"] profile = { "name": name, "contact_email": email, "clinical_specialties": clinical_specialties, "affiliations": affiliations, "professional_interests": professional_interests, "parts_of_me": parts_of_me, "activities": activities, "degrees": degrees, "cadence": "monthly", } auth.login(token) response = client.post("/api/profile", json=profile) assert response.status_code == http.HTTPStatus.CREATED.value profile_id = FacultyProfile.query.all()[0].id expected_fields = { "id": profile_id, "date_updated": MOCK_DATE.isoformat(), "activities": activities, "professional_interests": professional_interests, "affiliations": affiliations, "clinical_specialties": clinical_specialties, "contact_email": email, "degrees": degrees, "name": name, "parts_of_me": parts_of_me, } assert expected_fields.items() <= response.json.items() assert ActivityOption.query.filter(ActivityOption.value == activities[0]).one()
def get_or_create_verification_email(email: str, is_faculty: bool) -> VerificationEmail: existing_email = get_verification_email_by_email(email) if existing_email: return existing_email verification_email = VerificationEmail(email=email, is_faculty=is_faculty) save(verification_email) return verification_email
def test_get_profiles_empty(client, auth): verification_email = save(VerificationEmail(email="*****@*****.**")) verification_token = save( VerificationToken(token="1234", email_id=verification_email.id)) auth.login(verification_token.token) response = client.get("/api/profiles") assert response.status_code == http.HTTPStatus.OK.value assert response.json == {"profile_count": 0, "profiles": []}
def availability(): verification_token = flask_login.current_user profile = get_profile_by_token(verification_token) available = request.json["available"] profile.available_for_mentoring = available profile.date_updated = datetime.datetime.utcnow() save(profile) return jsonify({"available": available})
def test_get_expired_account(client, auth): verification_token = create_test_verification_token() auth.login(verification_token.token) verification_token.date_created = datetime.datetime(2000, 1, 1) save(verification_token) response = client.get("/api/account") assert response.status_code == 440 assert response.json == {"token": ["expired"]}
def star_profile(): verification_token = flask_login.current_user from_email_id = verification_token.email_id if "profile_id" not in request.json: return ( jsonify({"profile_id": ["`profile_id` missing from request"]}), HTTPStatus.UNPROCESSABLE_ENTITY.value, ) to_profile_id = request.json["profile_id"] to_profile = FacultyProfile.query.get( to_profile_id) or StudentProfile.query.get(to_profile_id) if to_profile is None: return ( jsonify({"profile_id": ["`profile_id` invalid"]}), HTTPStatus.UNPROCESSABLE_ENTITY.value, ) to_verification_email_id = to_profile.verification_email.id if to_verification_email_id == from_email_id: return ( jsonify({"profile_id": ["Cannot star own profile"]}), HTTPStatus.UNPROCESSABLE_ENTITY.value, ) profile_star = ProfileStar( from_verification_email_id=from_email_id, to_verification_email_id=to_verification_email_id, ) preexisting_star = db.session.query(exists().where( and_( ProfileStar.from_verification_email_id == profile_star.from_verification_email_id, ProfileStar.to_verification_email_id == profile_star.to_verification_email_id, ))).scalar() if preexisting_star: return ( jsonify({"profile_id": ["Already starred"]}), HTTPStatus.UNPROCESSABLE_ENTITY.value, ) save(profile_star) return jsonify({"profile_id": to_profile_id})
def test_query_profile_tags_not_related_to_profile(db_session): save(HospitalAffiliationOption(value="Hospital")) tags = query_profile_tags() assert tags == { "activities": [], "clinical_specialties": [], "degrees": [], "hospital_affiliations": ["Hospital"], "professional_interests": [], "programs": [], "pce_site_options": [], "current_year_options": [], }
def test_get_profiles_empty(client): verification_email = VerificationEmail(email='*****@*****.**') save(verification_email) verification_token = VerificationToken(token='1234', email_id=verification_email.id) save(verification_token) response = client.get( '/api/profiles', headers={'Authorization': f'Token {verification_token.token}'}) assert response.status_code == http.HTTPStatus.OK.value assert response.json == {'profileCount': 0, 'profiles': []}
def test_verify_token_logs_out_other_tokens(client): token = "123" email = "*****@*****.**" verification_email = save(VerificationEmail(email=email, is_faculty=True)) prior_token = save( VerificationToken(token="1010", email_id=verification_email.id)) save(VerificationToken(token=token, email_id=verification_email.id)) response = client.post("/api/verify-token", json={"token": token}) assert response.status_code == HTTPStatus.OK.value assert prior_token.logged_out
def create_faculty_profile(): verification_token = flask_login.current_user try: schema = faculty_profile_schema.load(request.json) except ValidationError as err: capture_exception(err) raise InvalidPayloadError(err.messages) if db.session.query(exists().where( FacultyProfile.contact_email == schema["contact_email"])).scalar(): raise UserError( {"email": ["This email already exists in the database"]}) profile_data = { "verification_email_id": verification_token.email_id, **basic_faculty_profile_data(schema), } profile = save(FacultyProfile(**profile_data)) save_all_tags(profile, schema) return jsonify( faculty_profile_schema.dump(profile)), HTTPStatus.CREATED.value
def create_student_profile(): verification_token = flask_login.current_user try: schema = student_profile_schema.load(request.json) except ValidationError as err: capture_exception(err) raise InvalidPayloadError(err.messages) if db.session.query(exists().where( StudentProfile.contact_email == schema["contact_email"])).scalar(): raise UserError( {"email": ["This email already exists in the database"]}) program_id = schema["program"].id if schema["program"] else None current_year_id = schema["current_year"].id if schema[ "current_year"] else None pce_site_id = schema["pce_site"].id if schema["pce_site"] else None profile_data = { "verification_email_id": verification_token.email_id, "program_id": program_id, "current_year_id": current_year_id, "pce_site_id": pce_site_id, **basic_student_profile_data(schema), } profile = save(StudentProfile(**profile_data)) save_student_tags(profile, schema) return jsonify( student_profile_schema.dump(profile)), http.HTTPStatus.CREATED.value
def test_get_starred_profile(client, auth): verification_token = create_test_verification_token() starred_profile = create_test_profile(available_for_mentoring=True) save( ProfileStar( from_verification_email_id=verification_token.email.id, to_verification_email_id=starred_profile.verification_email_id, )) auth.login(verification_token.token) response = client.get("/api/profiles") assert response.json["profiles"][0]["starred"]
def test_get_public_tags(client, auth): token = "1234" verification_email = save(VerificationEmail(email="*****@*****.**")) save(VerificationToken(token=token, email_id=verification_email.id)) profile = save( FacultyProfile( verification_email=verification_email, name="Test User", cadence="monthly", contact_email="*****@*****.**", ) ) activity_option = save(ActivityOption(value="activity", public=True)) save(FacultyProfileActivity(profile=profile, tag=activity_option)) auth.login(token) response = client.get("/api/faculty-search-tags") assert response.status_code == HTTPStatus.OK.value assert response.json == { "tags": { "activities": ["activity"], "clinical_specialties": [], "degrees": [], "hospital_affiliations": [], "parts_of_me": [], "professional_interests": [], } }
def test_query_profile_tags(db_session): profile = create_test_profile(available_for_mentoring=True) options = [ HospitalAffiliationOption(value="Hospital"), DegreeOption(value="Degree"), ActivityOption(value="Activity", public=True), ClinicalSpecialtyOption(value="Specialty", public=True), PartsOfMeOption(value="Part", public=True), ProfessionalInterestOption(value="Interest", public=True), ] relation_classes = [ FacultyHospitalAffiliation, FacultyProfileDegree, FacultyProfileActivity, FacultyClinicalSpecialty, FacultyPartsOfMe, FacultyProfessionalInterest, ] for option in options: save(option) profile_relations = [ cls(tag_id=option.id, profile_id=profile.id) for cls, option in zip(relation_classes, options) ] for relation in profile_relations: save(relation) tags = query_profile_tags() assert tags == { "activities": ["Activity"], "clinical_specialties": ["Specialty"], "degrees": ["Degree"], "hospital_affiliations": ["Hospital"], "professional_interests": ["Interest"], "programs": [], "pce_site_options": [], "current_year_options": [], }
def test_verify_valid_token(client): token = "123" email = "*****@*****.**" verification_email = save(VerificationEmail(email=email, is_faculty=True)) save(VerificationToken(token=token, email_id=verification_email.id)) response = client.post("/api/verify-token", json={"token": token}) assert response.status_code == HTTPStatus.OK.value assert response.json == { "available_for_mentoring": None, "email": "*****@*****.**", "is_admin": None, "profile_id": None, "is_faculty": True, }
def send_token(verification_email, email_function, is_personal_device): token = generate_token() verification_token = save_verification_token(verification_email.id, token, is_personal_device) email_log = email_function(verification_email.email, verification_token) verification_token.email_log = email_log return save(verification_token)
def test_get_profile_starred_by_other_user(client, auth): verification_token = create_test_verification_token() other_verification_token = create_test_verification_token() profile = create_test_profile(available_for_mentoring=True) save( ProfileStar( from_verification_email_id=other_verification_token.email_id, to_verification_email_id=profile.verification_email_id, )) auth.login(verification_token.token) response = client.get(f"/api/profiles/{profile.id}") assert response.status_code == HTTPStatus.OK.value assert not response.json["starred"]
def create_test_verification_email( email: Optional[str] = None, is_admin: bool = False, is_faculty: bool = True) -> VerificationEmail: if email is None: email = generate_test_email() return save( VerificationEmail(email=email, is_admin=is_admin, is_faculty=is_faculty))
def test_save_student_profile(db_session): verification_email = create_test_verification_email(is_faculty=False) profile = save( StudentProfile( name="A Student", verification_email=verification_email, contact_email="*****@*****.**", cadence="monthly", )) assert profile.id
def test_cannot_star_profile_twice(client, auth): verification_token = create_test_verification_token() profile = create_test_profile() save( ProfileStar( from_verification_email_id=verification_token.email_id, to_verification_email_id=profile.verification_email_id, )) data = {"profile_id": profile.id} auth.login(verification_token.token) response = client.post( "/api/star_profile", json=data, ) assert response.status_code == HTTPStatus.UNPROCESSABLE_ENTITY.value
def create_test_verification_token( token: Optional[str] = None, verification_email: Optional[VerificationEmail] = None, is_admin: bool = False, is_faculty: bool = True, ) -> VerificationToken: if token is None: token = str(uuid.uuid4()) if verification_email is None: verification_email = create_test_verification_email( is_faculty=is_faculty) return save(VerificationToken(token=token, email_id=verification_email.id))
def test_get_starred_profile(client, auth): verification_token = create_test_verification_token() profile = create_test_profile(available_for_mentoring=True) # Do queries here so that they don't add to the count later profile_id = profile.id auth.login(verification_token.token) save( ProfileStar( from_verification_email_id=verification_token.email_id, to_verification_email_id=profile.verification_email_id, )) # from sqlalchemy import event # qs = [] # def count_queries(*args): # # __import__('pdb').set_trace() # print('--------------------q') # print(str(args[1])) # print('--------------------end.\n\n ') # nonlocal qs # # __import__('pdb').set_trace() # qs.append(args[1]) # event.listen(db.engine, 'after_execute', count_queries) response = client.get(f"/api/profiles/{profile_id}") assert response.status_code == HTTPStatus.OK.value assert response.json["starred"]