Skip to content

Commit 4582060

Browse files
committed
✨ [#157] Relocate shared test utilities
1 parent 1c9105e commit 4582060

File tree

5 files changed

+60
-50
lines changed

5 files changed

+60
-50
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""
2+
Keycloak helpers taken from mozilla-django-oidc-db::tests/utils.py & pytest fixtures.
3+
4+
These help dealing with/stubbing out OpenID Provider configuration.
5+
6+
The Keycloak client ID/secret and URLs are set up for the config in
7+
docker/docker-compose.keycloak.yml. See the README.md in docker/keycloak/ for more
8+
information.
9+
"""
10+
11+
from contextlib import nullcontext
12+
13+
from pyquery import PyQuery as pq
14+
from requests import Session
15+
16+
17+
def keycloak_login(
18+
login_url: str,
19+
username: str = "testuser",
20+
password: str = "testuser",
21+
host: str = "http://testserver/",
22+
session: Session | None = None,
23+
) -> str:
24+
"""
25+
Test helper to perform a keycloak login.
26+
27+
:param login_url: A login URL for keycloak with all query string parameters. E.g.
28+
`client.get(reverse("login"))["Location"]`.
29+
:returns: The redirect URI to consume in the django application, with the ``code``
30+
``state`` query parameters. Consume this with ``response = client.get(url)``.
31+
"""
32+
cm = Session() if session is None else nullcontext(session)
33+
with cm as session:
34+
login_page = session.get(login_url)
35+
assert login_page.status_code == 200
36+
37+
# process keycloak's login form and submit the username + password to
38+
# authenticate
39+
document = pq(login_page.text)
40+
login_form = document("form#kc-form-login")
41+
submit_url = login_form.attr("action")
42+
assert isinstance(submit_url, str)
43+
login_response = session.post(
44+
submit_url,
45+
data={
46+
"username": username,
47+
"password": password,
48+
"credentialId": "",
49+
"login": "Sign In",
50+
},
51+
allow_redirects=False,
52+
)
53+
54+
assert login_response.status_code == 302
55+
assert (redirect_uri := login_response.headers["Location"]).startswith(host)
56+
57+
return redirect_uri

tests/test_integration_multiple_configs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
from requests import Session
66

77
from mozilla_django_oidc_db.models import OIDCClient
8+
from mozilla_django_oidc_db.tests.utils import keycloak_login
89

910
from .conftest import oidcconfig
10-
from .utils import keycloak_login
1111

1212

1313
@pytest.mark.vcr

tests/test_integration_oidc_flow_variants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
OIDCClient,
88
UserInformationClaimsSources,
99
)
10+
from mozilla_django_oidc_db.tests.utils import keycloak_login
1011

1112
from .conftest import oidcconfig
12-
from .utils import keycloak_login
1313

1414
KEYCLOAK_BASE_URL = "http://localhost:8080/realms/test/"
1515

tests/test_logout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from requests import Session
66

77
from mozilla_django_oidc_db.models import OIDCClient
8+
from mozilla_django_oidc_db.tests.utils import keycloak_login
89
from mozilla_django_oidc_db.utils import do_op_logout
910

1011
from .conftest import oidcconfig
11-
from .utils import keycloak_login
1212

1313

1414
@pytest.fixture

tests/utils.py

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
from collections.abc import Sequence
2-
from contextlib import nullcontext
32
from typing import TypedDict
43

54
from glom import assign
6-
from pyquery import PyQuery as pq
7-
from requests import Session
85

96
from mozilla_django_oidc_db.models import (
107
OIDCClient,
@@ -14,50 +11,6 @@
1411
from mozilla_django_oidc_db.typing import JSONObject
1512

1613

17-
def keycloak_login(
18-
login_url: str,
19-
username: str = "testuser",
20-
password: str = "testuser",
21-
session: Session | None = None,
22-
) -> str:
23-
"""
24-
Test helper to perform a keycloak login.
25-
26-
:param login_url: A login URL for keycloak with all query string parameters. E.g.
27-
`client.get(reverse("login"))["Location"]`.
28-
:returns: The redirect URI to consume in the django application, with the ``code``
29-
``state`` query parameters. Consume this with ``response = client.get(url)``.
30-
"""
31-
cm = Session() if session is None else nullcontext(session)
32-
with cm as session:
33-
login_page = session.get(login_url)
34-
assert login_page.status_code == 200
35-
36-
# process keycloak's login form and submit the username + password to
37-
# authenticate
38-
document = pq(login_page.text)
39-
login_form = document("form#kc-form-login")
40-
submit_url = login_form.attr("action")
41-
assert isinstance(submit_url, str)
42-
login_response = session.post(
43-
submit_url,
44-
data={
45-
"username": username,
46-
"password": password,
47-
"credentialId": "",
48-
"login": "Sign In",
49-
},
50-
allow_redirects=False,
51-
)
52-
53-
assert login_response.status_code == 302
54-
assert (redirect_uri := login_response.headers["Location"]).startswith(
55-
"http://testserver/"
56-
)
57-
58-
return redirect_uri
59-
60-
6114
class OIDCConfigOptions(TypedDict, total=False):
6215
"""
6316
Provider and/or client configuration options, which map to model fields.

0 commit comments

Comments
 (0)