dorinclisu / fastapi-auth0

FastAPI authentication and authorization using auth0.com
MIT License
230 stars 37 forks source link

How to integrate the user authentication in the tests [Question] #14

Closed AlviseSembenico closed 3 years ago

AlviseSembenico commented 3 years ago

Hi, first of all thank you for your work! In the process of writing tests, I stumbled upon the user authentication. I am not sure how to proceed, is there a way to override the user from the test side therefore skipping the Auth0 check?

Thank you

dorinclisu commented 3 years ago

See https://fastapi.tiangolo.com/advanced/testing-dependencies/ You would override auth.get_user with a new function that returns a test user of your choice.

AlviseSembenico commented 3 years ago

Solved, Thanks

denzilsaldanha95 commented 3 years ago

https://stackoverflow.com/questions/48552474/auth0-obtain-access-token-for-unit-tests-in-python/48554119#48554119

That would be helpful for anyone trying to do tests for password authentication on the server side

FlorianPix commented 1 year ago

With what function would you overwrite auth.get_user ? I'd like to authenticate only once with a test username and password and then use the received user/token for all preceeding tests. Do I need to override auth.implicit scheme as well ?

FlorianPix commented 1 year ago

I found a workaround. Instead of overwriting get_user I added a pytest fixture that gets the JWT token once per module

def get_user_token(user_name):
    url = 'your-url'
    headers = {'content-type': 'application/json'}
    password = testingUsers[user_name]
    parameter = {"client_id": "your-client-id",
                 "client_secret": "your-client-secret",
                 "audience": 'your-audience',
                 "grant_type": "password",
                 "username": user_name,
                 "password": password, "scope": "openid"}
    responseDICT = json.loads(requests.post(url, json=parameter, headers=headers).text)
    return responseDICT['access_token']

def get_user_token_headers(user_name='test@test.de'):
    return {'authorization': "Bearer " + get_user_token(user_name)}

@pytest.fixture(scope="module")
def test_app_with_db():
    # set up
    app = create_application()
    app.dependency_overrides[get_settings] = get_settings_override
    register_tortoise(
        app,
        db_url=os.environ.get("DATABASE_TEST_URL"),
        modules={"models": ["app.models.tortoise"]},
        generate_schemas=True,
        add_exception_handlers=True,
    )
    with TestClient(app) as test_client:
        # testing
        yield test_client
    # tear down

@pytest.fixture(scope="module")
def headers():
    # setup
    headers = get_user_token_headers()
    yield headers
    #  teardown

In my tests I add these headers to every request I make with the client:

def test_create_summary(test_app_with_db, headers):
    response = test_app_with_db.post(
        "/summaries/", data=json.dumps({"url": "https://foo.bar"}), headers=headers
    )

    assert response.status_code == 201
    assert response.json()["url"] == "https://foo.bar"