I am trying to test signup form of my application. If same email or phone is used again, the request should be rejected. However, when firing multiple requests in a single method, the second request doesn't seem to get executed. My code
signup code
@user.route('/signup', methods=['GET', 'POST'])
@anonymous_required()
def signup():
form = SignupForm()
return_code = 200
if form.validate_on_submit():
if not User.find_by_email(form.email.data) and not User.find_by_phone(form.phone.data):
usr = User()
form.populate_obj(usr)
usr.password = request.form.get('password')
usr.alternate_id = int(time())
usr.save()
if login_user(usr):
usr.update_activity_tracking(request.remote_addr)
# flash('Thanks for signing up!')
return redirect(url_for('user.welcome'))
else:
flash('The email or phone is already registered')
return_code = 409
else:
return_code = 200 if request.method == 'GET' else 400
return render_template('user/signup.html', form=form), return_code
Test code
@pytest.mark.usefixtures('empty_db')
def test_multiple_requests_failing(client, user):
resp_one = client.post(url_for('user.signup'), data=user)
assert resp_one.status_code == 302 # due to redirection
assert User.query.count() == 1
resp_two = client.post(url_for('user.signup'), data=user)
assert resp_two.status_code == 409 # failing here. status code is still 302
response_html = resp_two.data.decode('utf-8')
assert 'The email or phone is already registered' in response_html
Fixture code
I am using pytest
with pytest-flask
plugin. However, I did try the same thing using naive test_client
as well. I will post a case of that as well if required. The client
fixture is provided by pytest itself.
@pytest.fixture(scope="session", autouse=True)
def app(tmpdir_factory):
db_temp_dir = tmpdir_factory.mktemp('db_temp_dir')
db_temp_path = os.path.abspath(os.path.join(db_temp_dir, 'test-db.sqlite'))
db_uri = f'sqlite:///{db_temp_path}'
override_settings = {
'TESTING': True,
'WTF_CSRF_ENABLED': False,
'SQLALCHEMY_DATABASE_URI': db_uri
}
_app = create_app(settings_override=override_settings)
ctx = _app.app_context()
ctx.push()
db.drop_all()
db.create_all()
yield _app
ctx.pop()
@pytest.fixture()
def empty_db():
meta = db.metadata
for table in reversed(meta.sorted_tables):
db.session.execute(table.delete())
db.session.commit()
@pytest.fixture(scope="session")
def user():
return dict(
first_name='siddharth',
last_name='gupta',
email='check.sid@gmail.com',
phone='1234123412',
dob_date='12',
dob_month='12',
dob_year='1997',
password='something',
confirm_password='something',
gender='male'
)
I tried placing debugger on my application code. It turns out that the application code is called only on the first request and not on the second one. That clearly explains why the error is coming. But I don't understand how is resp_two
getting the values that are present in resp_one
and also the main thing of why the second request is not having any effect and is not getting called. I have a feeling that it might be related to the request context and application context being in scope but I am not sure. Please help. Thanks for taking the time.
Aucun commentaire:
Enregistrer un commentaire