rayluo / identity

This is an authentication/authorization library optimized for web apps. It provides some higher level APIs built on top of Microsoft's MSAL Python. Read its documentation here: https://identity-library.readthedocs.io
https://identity-library.readthedocs.io
MIT License
41 stars 5 forks source link

Testing Auth with PyTest #33

Open 1jamesthompson1 opened 4 days ago

1jamesthompson1 commented 4 days ago

Firstly thanks for your project, it is making it much easier to setup a login then doing it through MSAL.

I am new to working with AZURE and trying to do basic login etc. I am trying to update my tests. How can I simulate a login to then allow the testing of protected api?

Curerntly they looks like:

def test_form_submit_filtered():
    with app.app.test_client() as c:
        rv = c.post(
            "/search",
            data={
                "searchQuery": "",
                "includeModeRail": "on",
                "includeModeMarine": "on",
                "yearSlider-min": "2010",
                "yearSlider-max": "2024",
                "relevanceCutoff": "0.7",
                "includeSafetyIssues": "on",
                "includeRecommendations": "on",
                "includeReportSection": "on",
            },
            follow_redirects=True,
        )

        assert rv.status == "200 OK"

        df = pd.read_html(StringIO(json.loads(rv.data)["html_table"]))[0]

        assert df["year"].isin(range(2010, 2025)).all()
        assert df["mode"].isin(["Rail", "Marine"]).all()
rayluo commented 3 days ago

How can I simulate a login to then allow the testing of protected api?

Simulating a login is not easy (you could use UI simulation tools such as Selenium), and sometimes impossible by design (when the Identity Provider enforces multi-factor authentication).

In your case, you try to test some APIs. You shall consider manually test them once, and then reuse the test input and output via mocking.

ajstewart commented 2 days ago

I wanted to say I also was met with this problem recently and wasn't sure how to go about it, so anything you find I'd be interested to see!

I ended up with two versions of the app to test. I tested one with the auth in place and checked that the response was the beginning of the auth flow.

Then for endpoint tests I mocked the Auth object with my own mocked Auth class that used session info that I injected to build the similar user and access_token to the context.

Though the app I was testing is not critical or large so this method was enough to satisfy me.

rayluo commented 2 days ago

Then for endpoint tests I mocked the Auth object with my own mocked Auth class that used session info that I injected to build the similar user and access_token to the context.

Sounds interesting. If you can share your implementation, that would be helpful.

Also, keep in mind that you can mock an Auth object and/or its context for the login only, you won't be able to mock it with an access token to call other APIs. Those APIs would need a real token to access.