To test the API endpoint that verifies the verification link click, I needed to do some research on Pytest fixtures. Though I could have used fixtures in the previous tests, now there is a good use case as in order for the verification link to work, there must be a user already in the database and for this user we need to create a verification token. Both of these tasks would be best handled by a fixture to keep the test DRY.
For the creation of a user:@pytest.fixture def test_user(): '''Create sample user for test''' sample_user = User.objects.create(username='someuser@somedomain.com') sample_user.set_password('somepassword') sample_user.save() return sample_user
All the fixture
needs is the @pytest.fixture decorator and the return value of the function can
be used directly as an object in the test function or another fixture. The
fixture for creating the verification token will however be a little more
complicated as the expiration time of the token needs to be dynamic. For this I
use the “Factories as fixtures” feature with fixtures as described in the
documentation:
@pytest.fixture def verification_token(test_user): '''Creating tokens with JWT''' def _create_token(exp_time): '''Token with variable expiry time''' verification_token = RefreshToken.for_user(test_user) verification_token.set_exp( from_time=verification_token.current_time, lifetime=timedelta(seconds=exp_time) ) return verification_token return _create_token
This fixture uses the test_user fixture. Instead of returning a token, the fixture returns another method which accepts the expiry time as an argument and returns the verification token. This can be used in the test function as:
def test_user_verification_endpoint(verification_token, test_user): '''Testing the verify-email endpoint''' client = APIClient() # Token with 60sec validity test_token1 = verification_token(60) api_response = client.get( '/user/verify-user/{token}'.format( token=test_token1 ), format='json' ) assert api_response.status_code == 200 assert test_user.is_active == True
So here invoking the fixture name verification_token produces a function as the fixture does not return a value but rather a function. This function can be passed the expiration time. The above test verifies that the verification link works - is linked to a user in the database and also it results in the user becoming active. A few failing API requests can also be tested:
# Token with 1sec validity - expired token test test_token2 = verification_token(1) # Sleep for 2sec time.sleep(2) api_response = client.get( '/user/verify-user/{token}'.format( token=test_token2 ), format='json' ) print(api_response.data) assert api_response.status_code == 400 # Tampered token test test_token3 = str(verification_token(60)) test_token3 = test_token3[:-1] api_response = client.get( '/user/verify-user/{token}'.format( token=test_token3 ), format='json' ) print(api_response.data) assert api_response.status_code == 400 # Deleted user test test_token4 = verification_token(60) test_user.delete() api_response = client.get( '/user/verify-user/{token}'.format( token=test_token4 ), format='json' ) print(api_response.data) assert api_response.status_code == 400
I printed out the error messages and the last message is interesting:
Token is invalid or expired Token is invalid or expired User matching query does not exist.
This is because I am trying to fetch the user from the database with the user_id found in the JWT payload.
No comments:
Post a Comment