def test_inviting_a_speaker_adds_the_speaker(client: Client, user: User, send_mail: Mock) -> None: talk = Talk(title="My Talk", length=25) talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(talk) alice = User(email="*****@*****.**", fullname="Alice Example") db.session.add(alice) db.session.commit() # reload from DB to avoid "not attached to session" error talk = Talk.query.filter_by(title="My Talk").one() client.get("/test-login/{}".format(user.user_id)) resp = client.get("/talks/{}/speakers".format(talk.talk_id)) assert_html_response(resp) csrf_token = extract_csrf_from(resp) postdata = {"email": "*****@*****.**", "csrf_token": csrf_token} resp = client.post("/talks/{}/speakers".format(talk.talk_id), data=postdata, follow_redirects=True) assert_html_response_contains(resp, "Alice Example") send_mail.assert_called_once_with(to=["*****@*****.**"], template="email/co-presenter-invite", talk=ANY) _, kwargs = send_mail.call_args assert kwargs["talk"].talk_id == talk.talk_id assert_talk_has_speakers(talk, ["*****@*****.**"])
def test_inviting_a_speaker_emails_the_speaker(client: Client, user: User, send_mail: Mock) -> None: talk = Talk(title="My Talk", length=25) talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(talk) db.session.commit() assert User.query.filter_by( email="*****@*****.**").one_or_none() is None # reload from DB to avoid "not attached to session" error talk = Talk.query.filter_by(title="My Talk").one() client.get("/test-login/{}".format(user.user_id)) resp = client.get("/talks/{}/speakers".format(talk.talk_id)) assert_html_response(resp) csrf_token = extract_csrf_from(resp) # this speaker doesn't exist, but we should still send the email postdata = {"email": "*****@*****.**", "csrf_token": csrf_token} resp = client.post("/talks/{}/speakers".format(talk.talk_id), data=postdata, follow_redirects=True) assert_html_response_contains(resp, "*****@*****.**") send_mail.assert_called_once_with(to=["*****@*****.**"], template="email/co-presenter-invite", talk=ANY) _, kwargs = send_mail.call_args assert kwargs["talk"].talk_id == talk.talk_id # this also implies a user with that email was created assert_talk_has_speakers(talk, ["*****@*****.**"])
def test_demographic_survey_skips_blank_other_values( client: Client, user: User ) -> None: assert user.demographic_survey is None client.get("/test-login/{}".format(user.user_id)) resp = client.get("/profile/demographic_survey") assert_html_response_contains( resp, "I identify as a:", "I identify my ethnicity as:", "About my past speaking experience:", "My age is:", "I have been programming for:", ) csrf_token = extract_csrf_from(resp) postdata = {"gender": ["MAN", ""], "csrf_token": csrf_token} resp = client.post( "/profile/demographic_survey", data=postdata, follow_redirects=True ) assert_html_response_contains(resp, "Thanks For Completing") survey = DemographicSurvey.query.filter_by(user_id=user.user_id).one() assert survey.gender == ["MAN"]
def test_profile_updates_name_and_bio_not_email(client: Client, user: User) -> None: resp = client.get("/test-login/{}".format(user.user_id), follow_redirects=True) resp = client.get("/profile") assert_html_response_contains( resp, re.compile('<input[^>]*name="fullname"'), re.compile('<input[^>]*id="email"[^>]*disabled'), re.compile('<textarea[^>]*name="speaker_bio"'), ) csrf_token = extract_csrf_from(resp) postdata = { "email": "*****@*****.**", "fullname": "Jane Doe", "speaker_bio": "This is Jane's biography.", "csrf_token": csrf_token, } resp = client.post("/profile", data=postdata, follow_redirects=True) assert_html_response_contains(resp, "Talks") db.session.add(user) db.session.refresh(user) assert user.fullname == "Jane Doe" assert user.speaker_bio == "This is Jane's biography." assert user.email == "*****@*****.**" # the old address
def test_talk_anonymization(client: Client, user: User, send_mail: Mock) -> None: user.site_admin = True db.session.add(user) talk = Talk( title="Alice's Identifying Talk", description="This talk is by Alice", outline="Alice!", take_aways="Alice's point.", length=25, ) talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(talk) db.session.commit() db.session.refresh(talk) client.get("/test-login/{}".format(user.user_id), follow_redirects=True) resp = client.get(f"/manage/anonymize/{talk.talk_id}") assert_html_response_contains(resp, "Alice's Identifying Talk") postdata = { "title": "(Speaker name redacted)'s Identifying Talk", "description": "This talk is by (Speaker name redacted)", "outline": "(Speaker name redacted)!", "take_aways": "(The speaker's) point.", "csrf_token": extract_csrf_from(resp), } client.post(f"/manage/anonymize/{talk.talk_id}", data=postdata) talk = Talk.query.get(talk.talk_id) assert talk.is_anonymized is True assert talk.has_anonymization_changes is True assert talk.anonymized_title == "(Speaker name redacted)'s Identifying Talk" assert talk.anonymized_description == "This talk is by (Speaker name redacted)" assert talk.anonymized_outline == "(Speaker name redacted)!" assert talk.anonymized_take_aways == "(The speaker's) point." assert talk.title == "Alice's Identifying Talk" assert talk.description == "This talk is by Alice" assert talk.outline == "Alice!" assert talk.take_aways == "Alice's point." send_mail.assert_called_once_with( to=[user.email], template="email/talk-anonymized", talk_id=talk.talk_id, title=talk.title, # the original title )
def test_demographic_survey_saves_data(client: Client, user: User) -> None: assert user.demographic_survey is None client.get("/test-login/{}".format(user.user_id)) resp = client.get("/profile/demographic_survey") assert_html_response_contains( resp, "I identify as a:", "I identify my ethnicity as:", "About my past speaking experience:", "My age is:", "I have been programming for:", ) csrf_token = extract_csrf_from(resp) postdata = { "gender": ["MAN", "WOMAN", "NONBINARY", "free form text for 'other' gender"], "ethnicity": [ "ASIAN", "BLACK_AFRICAN_AMERICAN", "HISPANIC_LATINX", "NATIVE_AMERICAN", "PACIFIC_ISLANDER", "WHITE_CAUCASIAN", "free form text for 'other' ethnicity", ], "past_speaking": [ "NEVER", "PYCONCA", "OTHER_PYTHON", "OTHER_NONPYTHON", ], "age_group": "UNDER_45", "programming_experience": "UNDER_10YR", "csrf_token": csrf_token, } resp = client.post( "/profile/demographic_survey", data=postdata, follow_redirects=True ) assert_html_response_contains(resp, "Thanks For Completing") survey = DemographicSurvey.query.filter_by(user_id=user.user_id).one() assert sorted(survey.gender) == sorted(postdata["gender"]) assert sorted(survey.ethnicity) == sorted(postdata["ethnicity"]) assert sorted(survey.past_speaking) == sorted(postdata["past_speaking"]) assert survey.age_group == AgeGroup.UNDER_45 assert survey.programming_experience == ProgrammingExperience.UNDER_10YR
def test_email_magic_link_form(client: Client, send_mail: Mock) -> None: resp = client.get("/login/email") assert_html_response_contains(resp, re.compile('<input.*name="email"')) csrf_token = extract_csrf_from(resp) postdata = {"email": "*****@*****.**", "csrf_token": csrf_token} resp = client.post("/login/email", data=postdata, follow_redirects=True) assert_html_response_contains(resp, "We have sent a link to you") send_mail.assert_called_once_with( to=["*****@*****.**"], template="email/magic-link", magic_link=ANY, magic_link_expiration="30 minutes", )
def test_talk_editing_not_allowed_while_voting(user: User, client: Client) -> None: conf = Conference.query.get(1) conf.voting_begin = datetime.utcnow() - timedelta(days=1) conf.voting_end = datetime.utcnow() + timedelta(days=1) db.session.add(conf) talk = Talk(title="My Talk", length=25) talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(talk) db.session.commit() db.session.refresh(talk) client.get("/test-login/{}".format(user.user_id), follow_redirects=True) resp = client.get(f"/talks/{talk.talk_id}") assert_html_response(resp, status=200) postdata = {"csrf_token": extract_csrf_from(resp)} resp = client.post(f"/talks/{talk.talk_id}", data=postdata) assert_html_response(resp, status=400)
def test_create_talk_goes_to_preview(client: Client, user: User) -> None: client.get("/test-login/{}".format(user.user_id)) resp = client.get("/talks/new") csrf_token = extract_csrf_from(resp) postdata = {"title": "My Awesome Talk", "length": "25", "csrf_token": csrf_token} resp = client.post("/talks/new", data=postdata, follow_redirects=True) assert_html_response_contains( resp, "Reviewers will see voting instructions here", "Save & Return", "Edit Again", ) # but at this point the talk is saved speakers_predicate = Talk.speakers.any(user_id=user.user_id) # type: ignore talks = Talk.query.filter(speakers_predicate).all() assert len(talks) == 1 assert talks[0].title == "My Awesome Talk"
def test_talk_anonymization_doesnt_set_is_anonymized_if_no_changes( client: Client, user: User, send_mail: Mock) -> None: user.site_admin = True db.session.add(user) talk = Talk( title="Alice's Identifying Talk", description="This talk is by Alice", outline="Alice!", take_aways="Alice's point.", length=25, ) talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(talk) db.session.commit() db.session.refresh(talk) client.get("/test-login/{}".format(user.user_id), follow_redirects=True) resp = client.get(f"/manage/anonymize/{talk.talk_id}") assert_html_response_contains(resp, "Alice's Identifying Talk") postdata = { "title": talk.title, "description": talk.description, "outline": talk.outline, "take_aways": talk.take_aways, "csrf_token": extract_csrf_from(resp), } client.post(f"/manage/anonymize/{talk.talk_id}", data=postdata) talk = Talk.query.get(talk.talk_id) assert talk.is_anonymized is True assert talk.has_anonymization_changes is False assert talk.anonymized_title == talk.title assert talk.anonymized_description == talk.anonymized_description assert talk.anonymized_outline == talk.outline assert talk.anonymized_take_aways == talk.take_aways assert not send_mail.called
def test_email_magic_link_tokens_only_work_once( client: Client, send_mail: Mock ) -> None: resp = client.get("/login/email") csrf_token = extract_csrf_from(resp) postdata = {"email": "*****@*****.**", "csrf_token": csrf_token} client.post("/login/email", data=postdata, follow_redirects=True) _, kwargs = send_mail.call_args magic_link_url = kwargs["magic_link"] assert not urlparse(magic_link_url).query magic_link_path = urlparse(magic_link_url).path # first time should work resp = client.get(magic_link_path) assert_redirected(resp, "/profile") # new user, go to profile # second time should get a 401 resp = client.get(magic_link_path) assert_html_response(resp, status=401)
def test_saving_a_talk_clears_categories( client: Client, conference: Conference, user: User ) -> None: category = Category(conference=conference, name="The Category") talk = Talk(title="Old Title", length=25) talk.categories.append(category) talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(talk) db.session.add(category) db.session.commit() client.get("/test-login/{}".format(user.user_id)) resp = client.get("/talks/1") csrf_token = extract_csrf_from(resp) postdata = {"title": "New Title", "csrf_token": csrf_token} resp = client.post("/talks/1", data=postdata, follow_redirects=True) assert_html_response(resp, status=200) talk = Talk.query.first() assert talk.title == "New Title" assert talk.categories == []
def test_demographic_survey_bug_with_age_field(client: Client, user: User) -> None: # see https://gitlab.com/bigapplepy/yak-bak/issues/29 assert user.demographic_survey is None client.get("/test-login/{}".format(user.user_id)) resp = client.get("/profile/demographic_survey") csrf_token = extract_csrf_from(resp) postdata = { "age_group": "UNDER_45", "programming_experience": "UNDER_10YR", "csrf_token": csrf_token, } resp = client.post( "/profile/demographic_survey", data=postdata, follow_redirects=True ) assert_html_response_contains(resp, "Thanks For Completing") resp = client.get("/profile/demographic_survey") assert_html_response_contains( resp, re.compile('<input checked[^>]* value="UNDER_45">'), re.compile('<input checked[^>]* value="UNDER_10YR">'), )
def test_profile_lets_you_delete_speaker_bio(client: Client, user: User) -> None: user.speaker_bio = "This is the speaker bio" db.session.add(user) db.session.commit() client.get("/test-login/{}".format(user.user_id), follow_redirects=True) resp = client.get("/profile") assert_html_response_contains(resp, "This is the speaker bio") csrf_token = extract_csrf_from(resp) postdata = { "email": "*****@*****.**", "fullname": "Jane Doe", "speaker_bio": "", "csrf_token": csrf_token, } resp = client.post("/profile", data=postdata, follow_redirects=True) assert_html_response_contains(resp, "Talks") db.session.add(user) db.session.refresh(user) assert user.fullname == "Jane Doe" assert user.speaker_bio == "" assert user.email == "*****@*****.**" # the old address