bcgov / lcfs

An online application for fuel suppliers to manage their compliance obligations under the Low Carbon Fuels Act
Apache License 2.0
5 stars 3 forks source link

LCFS - Develop Pytest Unit Tests for Auth Middleware in FastAPI #183

Closed AlexZorkin closed 8 months ago

AlexZorkin commented 10 months ago

Description: We need to create a comprehensive set of unit tests using Pytest for our newly developed authentication middleware within our FastAPI application. The middleware integrates with Keycloak and uses JWT tokens for user authentication. The objective is to ensure that each branch of the authentication logic is covered, including but not limited to token retrieval and validation, JWKS fetching and caching, user lookups, and error handling.

Acceptance Criteria:

  1. All public and private methods in the UserAuthentication class must have corresponding test cases.
  2. Tests must cover successful authentication, failure due to various reasons (invalid token, expired token, etc.), and correct handling of edge cases.
  3. The JWT token's interaction with Keycloak should be mocked to ensure tests are not reliant on external systems.
  4. Use fixtures to simulate Redis and database sessions.
  5. Test cases must assert the correct HTTP status codes and responses for various scenarios.
  6. Authentication flow must be verified to ensure a user is correctly authenticated through the middleware.
  7. Tests must verify that JWKS caching works as intended and that JWKS is fetched from the cache or endpoint as required.
  8. Ensure the proper creation of user login history records following authentication attempts.
  9. Code coverage should be no less than 90%.

Task Breakdown:


# Example Pytest fixture for Redis
@pytest.fixture
def mock_redis(mocker):
    mocker.patch('redis.asyncio.Redis', autospec=True)

# Example Pytest fixture for AsyncSession
@pytest.fixture
def mock_async_session(mocker):
    mocker.patch('sqlalchemy.ext.asyncio.AsyncSession', autospec=True)

# Example test case for successful authentication
def test_successful_authentication(mock_redis, mock_async_session):
    # Setup mock return values for Redis and AsyncSession
    ...
    # Call the authenticate method
    ...
    # Assert the user is authenticated and a proper AuthCredentials object is returned
    ...

# Example test case for expired JWT token
def test_expired_jwt_token(mock_redis):
    # Setup mock return value for Redis containing the JWKS data
    ...
    # Pass an expired token to the authenticate method
    ...
    # Assert an HTTPException is raised with status code 401
    ...

# Example test case for user login history recording
def test_user_login_history_recorded(mock_async_session):
    # Setup mock AsyncSession with a user object
    ...
    # Trigger a successful/unsuccessful authentication attempt
    ...
    # Assert that a UserLoginHistory entry is created with the correct details
    ...
`
prv-proton commented 10 months ago

Hey team! Please add your planning poker estimate with Zenhub @AlexZorkin @hamed-valiollahi @jig-patel @kevin-hashimoto @prv-proton

justin-lepitzki commented 8 months ago

Nothing for PO to test