Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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"],
    }
Exemplo n.º 4
0
def logout():
    verification_token = flask_login.current_user
    verification_token.logged_out = True
    save(verification_token)

    flask_login.logout_user()

    return {}
Exemplo n.º 5
0
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"]}
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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))
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
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
Exemplo n.º 11
0
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": []}
Exemplo n.º 12
0
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})
Exemplo n.º 13
0
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"]}
Exemplo n.º 14
0
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})
Exemplo n.º 15
0
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": [],
    }
Exemplo n.º 16
0
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': []}
Exemplo n.º 17
0
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
Exemplo n.º 18
0
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
Exemplo n.º 19
0
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
Exemplo n.º 20
0
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"]
Exemplo n.º 21
0
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": [],
        }
    }
Exemplo n.º 22
0
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": [],
    }
Exemplo n.º 23
0
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,
    }
Exemplo n.º 24
0
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)
Exemplo n.º 25
0
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"]
Exemplo n.º 26
0
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))
Exemplo n.º 27
0
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
Exemplo n.º 28
0
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
Exemplo n.º 29
0
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))
Exemplo n.º 30
0
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"]