def test_user_event(client_session): client, session = client_session # behavior when a user is not approved yet add_user(session, 'xx', 'xx', 'xx', 'xx', 'xx', access_level='asked') with login_scope(client, 'xx', 'xx') as client: rv = client.get('/events/iris_test') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert (flash_message['message'] == "Your account has not been approved yet by the administrator") # trigger that the event does not exist with login_scope(client, 'test_user', 'test') as client: rv = client.get('/events/xxx') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "no event named" in flash_message['message'] # GET with login_scope(client, 'test_user', 'test') as client: rv = client.get('events/iris_test') assert rv.status_code == 200 assert b'Iris classification' in rv.data assert b'Rules' in rv.data assert b'RAMP on iris' in rv.data
def test_update_profile(client_session): client, session = client_session # try to change the profile without being logged-in rv = client.get('/update_profile') assert rv.status_code == 302 assert rv.location == 'http://localhost/login?next=%2Fupdate_profile' rv = client.get('/update_profile', follow_redirects=True) assert rv.status_code == 200 with login_scope(client, 'test_user', 'test') as client: # GET function once logged-in rv = client.get('/update_profile') assert rv.status_code == 200 for attr in [b'Username', b'First name', b'Last name', b'Email', b'User', b'Test', b'*****@*****.**']: assert attr in rv.data # POST function once logged-in user_profile = {'lastname': 'XXX', 'firstname': 'YYY', 'email': '*****@*****.**'} rv = client.post('/update_profile', data=user_profile) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' user = get_user_by_name(session, 'test_user') assert user.lastname == 'XXX' assert user.firstname == 'YYY' assert user.email == '*****@*****.**' user_profile = {'lastname': 'Test', 'firstname': 'User', 'email': '*****@*****.**'} rv = client.post('/update_profile', data=user_profile, follow_redirects=True) assert rv.status_code == 200
def test_ask_for_event_mail(client_session): client, session = client_session with client.application.app_context(): with mail.record_messages() as outbox: with login_scope(client, 'test_user', 'test') as client: rv = client.get('problems/iris/ask_for_event') assert rv.status_code == 200 data = { 'suffix': 'test_2', 'title': 'whatever title', 'n_students': 200, 'min_duration_between_submissions_hour': 1, 'min_duration_between_submissions_minute': 2, 'min_duration_between_submissions_second': 3, 'opening_date': '2019-01-01', 'closing_date': '2020-01-01' } rv = client.post('problems/iris/ask_for_event', data=data) assert rv.status_code == 302 # check that the email has been sent assert len(outbox) == 1 assert ('User test_user asked to add a new event' in outbox[0].body)
def test_ask_for_event(client_session): client, session = client_session with login_scope(client, 'test_user', 'test') as client: rv = client.get('/problems/xxx/ask_for_event') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "no problem named" in flash_message['message'] rv = client.get('problems/iris/ask_for_event') assert rv.status_code == 200 assert b'Ask for a new event on iris' in rv.data data = { 'suffix': 'test_2', 'title': 'whatever title', 'n_students': 200, 'min_duration_between_submissions_hour': 1, 'min_duration_between_submissions_minute': 2, 'min_duration_between_submissions_second': 3, 'opening_date': '2019-01-01', 'closing_date': '2020-01-01' } rv = client.post('problems/iris/ask_for_event', data=data) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert ("Thank you. Your request has been sent" in flash_message['Event request'])
def test_approve_single_user(client_session): client, session = client_session add_user(session, 'aa', 'aa', 'aa', 'aa', 'aa', access_level='asked') with login_scope(client, 'test_iris_admin', 'test') as client: rv = client.get('/sign_up/aa') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert re.match("User(.*aa.*) is signed up", flash_message['Successful sign-up']) # ensure that the previous change have been committed within our # session session.commit() user = get_user_by_name(session, 'aa') assert user.access_level == 'user' rv = client.get("/sign_up/unknown_user") session.commit() assert rv.status_code == 302 assert rv.location == "http://localhost/problems" with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert flash_message['message'] == 'No user unknown_user'
def test_event_status(client_session, makedrop_event, opening_date, public_date, closing_date, expected): # checks if the event status is displayed correctly client, session = client_session # change the datetime stamps for the event event = get_event(session, 'iris_test_4event') event.opening_timestamp = opening_date event.public_opening_timestamp = public_date event.closing_timestamp = closing_date session.commit() # GET: access the problems page without login rv = client.get('/problems') assert rv.status_code == 200 event_idx = rv.data.index(b'iris_test_4event') event_class_idx = rv.data[:event_idx].rfind(b'<i class') assert expected in rv.data[event_class_idx:event_idx] # GET: access the problems when logged-in with login_scope(client, 'test_user', 'test') as client: rv = client.get('/problems') assert rv.status_code == 200 event_idx = rv.data.index(b'iris_test_4event') event_class_idx = rv.data[:event_idx].rfind(b'<i class') assert expected in rv.data[event_class_idx:event_idx]
def test_problem(client_session): client, session = client_session # Access a problem that does not exist rv = client.get('/problems/xxx') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert flash_message['message'] == "Problem xxx does not exist" rv = client.get('/problems/xxx', follow_redirects=True) assert rv.status_code == 200 # GET: looking at the problem without being logged-in rv = client.get('problems/iris') assert rv.status_code == 200 assert b'Iris classification' in rv.data assert b'Registered events' in rv.data # GET: looking at the problem being logged-in with login_scope(client, 'test_user', 'test') as client: rv = client.get('problems/iris') assert rv.status_code == 200 assert b'Iris classification' in rv.data assert b'Registered events' in rv.data
def test_approve_sign_up_for_event(client_session): client, session = client_session with login_scope(client, 'test_iris_admin', 'test') as client: # check the redirection if the user or the event does not exist rv = client.get("/events/xxx/sign_up/test_user") session.commit() assert rv.status_code == 302 assert rv.location == "http://localhost/problems" with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert flash_message['message'] == 'No event xxx or no user test_user' rv = client.get("/events/iris_test/sign_up/xxxx") session.commit() assert rv.status_code == 302 assert rv.location == "http://localhost/problems" with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert flash_message['message'] == 'No event iris_test or no user xxxx' add_user(session, 'zz', 'zz', 'zz', 'zz', 'zz', access_level='user') _, _, event_team = ask_sign_up_team(session, 'iris_test', 'zz') assert not event_team.approved rv = client.get('/events/iris_test/sign_up/zz') assert rv.status_code == 302 assert rv.location == "http://localhost/problems" session.commit() event_team = get_event_team_by_name(session, 'iris_test', 'zz') assert event_team.approved with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "is signed up for Event" in flash_message['Successful sign-up']
def test_user_interactions(client_session): client, _ = client_session with login_scope(client, 'test_iris_admin', 'test') as client: rv = client.get('/user_interactions') assert rv.status_code == 200 assert b'landing' in rv.data
def test_sign_up_for_event(client_session): client, session = client_session # trigger that the event does not exist with login_scope(client, 'test_user', 'test') as client: rv = client.get('/events/xxx/sign_up') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "no event named" in flash_message['message'] # GET: sign-up to a new controlled event add_user(session, 'yy', 'yy', 'yy', 'yy', 'yy', access_level='user') with login_scope(client, 'yy', 'yy') as client: rv = client.get('/events/iris_test/sign_up') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "Sign-up request is sent" in flash_message['Request sent'] # make sure that the database has been updated for our session session.commit() event_team = get_event_team_by_name(session, 'iris_test', 'yy') assert not event_team.approved # check that we are informing the user that he has to wait for approval rv = client.get('/events/iris_test') assert rv.status_code == 200 assert b'Waiting approval...' in rv.data # GET: sign-up to a new uncontrolled event event = get_event(session, 'boston_housing_test') event.is_controled_signup = False session.commit() with login_scope(client, 'yy', 'yy') as client: rv = client.get('/events/boston_housing_test/sign_up') assert rv.status_code == 302 assert (rv.location == 'http://localhost/events/boston_housing_test/sandbox') with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "is signed up for" in flash_message['Successful sign-up'] # make sure that the database has been updated for our session session.commit() event_team = get_event_team_by_name(session, 'boston_housing_test', 'yy') assert event_team.approved
def test_view_model(client_session): client, session = client_session # unknown submission with login_scope(client, 'test_user', 'test') as client: rv = client.get('/xxxxx/xx.py') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "Missing submission" in flash_message['message'] submission = get_submission_by_name(session, 'iris_test', 'test_user', 'random_forest_10_10') submission_hash = submission.hash_ # unknown workflow element with login_scope(client, 'test_user', 'test') as client: rv = client.get('{}/{}'.format(submission_hash, 'extractor.py')) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "is not a valid workflow element" in flash_message['message'] # The file does not exist on the server # temporary rename the file os.rename(submission.path, submission.path + 'xxxxx') try: with login_scope(client, 'test_user', 'test') as client: rv = client.get('{}/{}'.format(submission_hash, 'estimator.py')) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "does not exist by" in flash_message['message'] finally: os.rename(submission.path + 'xxxxx', submission.path) # GET: normal file display with login_scope(client, 'test_user', 'test') as client: rv = client.get('{}/{}'.format(submission_hash, 'estimator.py')) assert rv.status_code == 200 assert b'file = estimator.py' in rv.data assert (b'from sklearn.ensemble import RandomForestClassifier' in rv.data)
def test_sandbox_save_file(client_session, makedrop_event): client, session = client_session sign_up_team(session, "iris_test_4event", "test_user") example_code = "example content" with login_scope(client, "test_user", "test") as client: rv = client.get("http://localhost/events/iris_test_4event/sandbox") assert rv.status_code == 200 rv = client.post( "http://localhost/events/iris_test_4event/sandbox", headers={ "Referer": "http://localhost/events/iris_test_4event/sandbox" }, data={ "estimator": example_code, "code-csrf_token": "temp_token" }, follow_redirects=False, ) assert rv.status_code == 200 # code from the db event = get_event(session, "iris_test_4event") sandbox_submission = get_submission_by_name(session, "iris_test_4event", "test_user", event.ramp_sandbox_name) submission_code = sandbox_submission.files[-1].get_code() # get user interactions from db and check if 'save' was added user_interactions = get_user_interactions_by_name(session, "test_user") assert "save" in user_interactions["interaction"].values assert example_code in submission_code # make sure that after changing the code example # and reloading the page the code is still changed with login_scope(client, "test_user", "test") as client: rv = client.get("http://localhost/events/iris_test_4event/sandbox") assert rv.status_code == 200 assert example_code.encode() in rv.data
def test_download_submission(client_session): client, session = client_session # unknown submission with login_scope(client, 'test_user', 'test') as client: rv = client.get("download/xxxxx") assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "Missing submission" in flash_message['message'] submission = (session.query(Submission).filter_by(name="starting_kit_test", event_team_id=1).first()) with login_scope(client, 'test_user', 'test') as client: rv = client.get(f"download/{submission.hash_}") assert rv.status_code == 200 assert rv.data
def test_check_unknown_events(client_session, page): client, _ = client_session # trigger that the event does not exist with login_scope(client, 'test_user', 'test') as client: rv = client.get(page) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "no event named" in flash_message['message']
def test_sign_up_already_logged_in(client_session, request_function): client, _ = client_session # sign-up when already logged-in with login_scope(client, 'test_user', 'test') as client: rv = getattr(client, request_function)('/sign_up') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' rv = getattr(client, request_function)('/sign_up', follow_redirects=True) assert rv.status_code == 200
def test_sandbox_upload_file(client_session, makedrop_event, submission_dir, filename): client, session = client_session sign_up_team(session, "iris_test_4event", "test_user") config = ramp_config_template() ramp_config = generate_ramp_config(read_config(config)) # upload file in sandbox.html path_submissions = os.path.join(ramp_config["ramp_kit_dir"], submission_dir) with login_scope(client, "test_user", "test") as client: rv = client.get("http://localhost/events/iris_test_4event/sandbox") assert rv.status_code == 200 # choose file and check if it was uploaded correctly path_submission = os.path.join(path_submissions, filename) assert os.path.isfile(path_submission) rv = client.post( "http://localhost/events/iris_test_4event/sandbox", headers={ "Referer": "http://localhost/events/iris_test_4event/sandbox" }, data={"file": (open(path_submission, "rb"), filename)}, follow_redirects=False, ) assert rv.status_code == 302 assert ( rv.location == "http://localhost/events/iris_test_4event/sandbox") # code of the saved file with open(path_submission, "r") as file: submitted_data = file.read() # code from the db event = get_event(session, "iris_test_4event") sandbox_submission = get_submission_by_name(session, "iris_test_4event", "test_user", event.ramp_sandbox_name) submission_code = sandbox_submission.files[-1].get_code() # get user interactions from db and check if 'upload' was added user_interactions = get_user_interactions_by_name(session, "test_user") # check if the code of the submitted file in the 'submission_code' assert submitted_data is not None assert submitted_data in submission_code # check if the user_interaction was added to the db assert "upload" in user_interactions["interaction"].values
def test_view_submission_error(client_session): client, session = client_session # unknown submission with login_scope(client, 'test_user', 'test') as client: rv = client.get('/xxxxx/error.txt') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert "Missing submission" in flash_message['message'] submission = get_submission_by_name(session, 'iris_test', 'test_user', 'error') submission.error_msg = 'This submission is a failure' session.commit() submission_hash = submission.hash_ # GET: normal error display with login_scope(client, 'test_user', 'test') as client: rv = client.get('{}/{}'.format(submission_hash, 'error.txt')) assert rv.status_code == 200 assert b'This submission is a failure' in rv.data
def test_check_admin_required(client_session, page, request_function): client, _ = client_session with login_scope(client, 'test_user', 'test') as client: for rf in request_function: rv = getattr(client, rf)(page) with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert (flash_message['message'] == 'Sorry User, you do not have admin rights') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' rv = getattr(client, rf)(page, follow_redirects=True) assert rv.status_code == 200
def test_problems(client_session): client, _ = client_session # GET: access the problems page without login rv = client.get('/problems') assert rv.status_code == 200 assert b'Hi User!' not in rv.data assert b'participants' in rv.data assert b'Iris classification' in rv.data assert b'Boston housing price regression' in rv.data # GET: access the problems when logged-in with login_scope(client, 'test_user', 'test') as client: rv = client.get('/problems') assert rv.status_code == 200 assert b'Hi User!' in rv.data assert b'participants' in rv.data assert b'Iris classification' in rv.data assert b'Boston housing price regression' in rv.data
def test_approve_users_remove(client_session): client, session = client_session # create 2 new users add_user(session, 'xx', 'xx', 'xx', 'xx', 'xx', access_level='user') add_user(session, 'yy', 'yy', 'yy', 'yy', 'yy', access_level='asked') # ask for sign up for an event for the first user _, _, event_team = ask_sign_up_team(session, 'iris_test', 'xx') with login_scope(client, 'test_iris_admin', 'test') as client: # GET check that we get all new user to be approved rv = client.get('/approve_users') assert rv.status_code == 200 # line for user approval assert b'yy: yy yy - yy' in rv.data # line for the event approval assert b'iris_test - xx' # POST check that we are able to approve a user and event data = ImmutableMultiDict([('submit_button', 'Remove!'), ('approve_users', 'yy'), ('approve_event_teams', str(event_team.id)) ]) rv = client.post('/approve_users', data=data) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' # ensure that the previous change have been committed within our # session session.commit() user = get_user_by_name(session, 'yy') assert user is None event_team = get_event_team_by_name(session, 'iris_test', 'xx') assert event_team is None with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) print(flash_message) assert re.match( r"Removed users:\nyy\nRemoved event_team:\n" r"Event\(iris_test\)/Team\(.*xx.*\)\n", flash_message['Removed users'])
def test_submit_button_enabled_disabled(client_session, makedrop_event, opening_date, public_date, closing_date, expected): client, session = client_session event = get_event(session, 'iris_test_4event') event.opening_timestamp = opening_date event.public_opening_timestamp = public_date event.closing_timestamp = closing_date session.commit() sign_up_team(session, 'iris_test_4event', 'test_user') with login_scope(client, 'test_user', 'test') as client: rv = client.get('http://localhost/events/iris_test_4event/sandbox') assert rv.status_code == 200 # check for update button status on the generated .html if expected == b'event-close': assert 'disabled' in str(rv.data) # should to be disabled else: assert 'disabled' not in str(rv.data) # should not be disabled
def test_sign_up_for_event_mail(client_session): client, session = client_session # GET: sign-up to a new controlled event with client.application.app_context(): with mail.record_messages() as outbox: add_user(session, 'zz', 'zz', 'zz', 'zz', 'zz@gmail', access_level='user') with login_scope(client, 'zz', 'zz') as client: rv = client.get('/events/iris_test/sign_up') assert rv.status_code == 302 session.commit() # check that the email has been sent assert len(outbox) == 1 assert ('Click on this link to approve the sign-up request' in outbox[0].body)
def test_correct_message_sandbox(client_session, makedrop_event, opening_date, public_date, closing_date, expected): client, session = client_session event = get_event(session, 'iris_test_4event') event.opening_timestamp = opening_date event.public_opening_timestamp = public_date event.closing_timestamp = closing_date session.commit() sign_up_team(session, 'iris_test_4event', 'test_user') with login_scope(client, 'test_user', 'test') as client: rv = client.get('http://localhost/events/iris_test_4event/sandbox') assert rv.status_code == 200 if NOW < opening_date: assert "Event submissions will open on the " in str(rv.data) elif NOW < closing_date: assert "Event submissions are open until " in str(rv.data) else: assert "This event closed on the " in str(rv.data)
def test_sandbox_upload_file_dont_exist(client_session, makedrop_event, submission_dir, filename): client, session = client_session sign_up_team(session, "iris_test_4event", "test_user") config = ramp_config_template() ramp_config = generate_ramp_config(read_config(config)) # upload file in sandbox.html path_submissions = os.path.join(ramp_config["ramp_kit_dir"], ) with login_scope(client, "test_user", "test") as client: rv = client.get("http://localhost/events/iris_test_4event/sandbox") assert rv.status_code == 200 # choose file and check if it was uploaded correctly path_submission = os.path.join(path_submissions, filename) assert not os.path.isfile(path_submission) with pytest.raises(FileNotFoundError): rv = client.post( "http://localhost/events/iris_test_4event/sandbox", headers={ "Referer": "http://localhost/events/iris_test_4event/sandbox" }, data={"file": (open(path_submission, "rb"), filename)}, follow_redirects=False, ) assert rv.status_code == 200 with pytest.raises(FileNotFoundError): with open(path_submission, "r") as file: submitted_data = file.read() assert not submitted_data # get user interactions from db and check if 'upload' was added user_interactions = get_user_interactions_by_name(session, "test_user") assert "upload" not in user_interactions["interaction"].values
def test_update_event(client_session): client, session = client_session with login_scope(client, 'test_iris_admin', 'test') as client: # case tha the event does not exist rv = client.get('/events/boston_housing/update') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert 'no event named "boston_housing"' in flash_message['message'] # GET: pre-fill the forms rv = client.get('/events/iris_test/update') assert rv.status_code == 200 assert b'Minimum duration between submissions' in rv.data # POST: update the event data event_info = { 'suffix': 'test', 'title': 'Iris new title', 'is_send_trained_mail': True, 'is_public': True, 'is_controled_signup': True, 'is_competitive': False, 'min_duration_between_submissions_hour': 0, 'min_duration_between_submissions_minute': 0, 'min_duration_between_submissions_second': 0, 'opening_timestamp': "2000-01-01 00:00:00", 'closing_timestamp': "2100-01-01 00:00:00", 'public_opening_timestamp': "2000-01-01 00:00:00" } rv = client.post('/events/iris_test/update', data=event_info) assert rv.status_code == 302 assert rv.location == "http://localhost/problems" event = get_event(session, 'iris_test') assert event.min_duration_between_submissions == 0
def test_login(client_session): client, session = client_session # GET without any previous login rv = client.get('/login') assert rv.status_code == 200 assert b'Login' in rv.data assert b'Username' in rv.data assert b'Password' in rv.data # GET with a previous login with login_scope(client, 'test_user', 'test') as client: rv = client.get('/login') assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' rv = client.get('/login', follow_redirects=True) assert rv.status_code == 200 # POST with unknown username login_info = {'user_name': 'unknown', 'password': '******'} rv = client.post('/login', data=login_info) with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert flash_message['message'] == 'User "unknown" does not exist' assert rv.status_code == 302 assert rv.location == 'http://localhost/login' rv = client.post('/login', data=login_info, follow_redirects=True) assert rv.status_code == 200 # POST with wrong password login_info = {'user_name': 'test_user', 'password': '******'} rv = client.post('/login', data=login_info) with client.session_transaction() as cs: flash_message = dict(cs['_flashes']) assert flash_message['message'] == 'Wrong password' assert rv.status_code == 302 assert rv.location == 'http://localhost/login' rv = client.post('/login', data=login_info, follow_redirects=True) assert rv.status_code == 200 # POST with a right login and password login_info = {'user_name': 'test_user', 'password': '******'} rv = client.post('/login', data=login_info) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' user = get_user_by_name_or_email(session, login_info['user_name']) assert user.is_authenticated logout(client) rv = client.post('/login', data=login_info, follow_redirects=True) assert rv.status_code == 200 logout(client) # POST with a right email as login and password login_info = { 'user_name': 'test_user', 'password': '******', 'email': '*****@*****.**' } rv = client.post('/login', data=login_info) assert rv.status_code == 302 assert rv.location == 'http://localhost/problems' user = get_user_by_name_or_email(session, login_info['email']) assert user.is_authenticated logout(client) rv = client.post('/login', data=login_info, follow_redirects=True) assert rv.status_code == 200 logout(client) # POST with right login and password from a different location webpage login_info = {'user_name': 'test_user', 'password': '******'} landing_page = {'next': 'http://localhost/events/iris_test'} rv = client.post('/login', data=login_info, query_string=landing_page) assert rv.status_code == 302 assert rv.location == landing_page['next'] logout(client) rv = client.post('/login', data=login_info, query_string=landing_page, follow_redirects=True) assert rv.status_code == 200 logout(client)