From 47aeab76a5b70d8cdcae1292414bf4d9a740eead Mon Sep 17 00:00:00 2001 From: Lebaud Antoine Date: Sat, 24 Feb 2024 12:56:28 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=85(backend)=20test=20the=20authenticatio?= =?UTF-8?q?n=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests on get_or_create method. --- .../test_authentication_get_or_create_user.py | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/backend/core/tests/test_authentication_get_or_create_user.py diff --git a/src/backend/core/tests/test_authentication_get_or_create_user.py b/src/backend/core/tests/test_authentication_get_or_create_user.py new file mode 100644 index 00000000..83c44612 --- /dev/null +++ b/src/backend/core/tests/test_authentication_get_or_create_user.py @@ -0,0 +1,101 @@ +"""Unit tests for the `get_or_create_user` function.""" + +from django.core.exceptions import SuspiciousOperation + +import pytest + +from core import models +from core.authentication import OIDCAuthenticationBackend +from core.factories import UserFactory + +pytestmark = pytest.mark.django_db + + +def test_authentication_getter_existing_user_no_email( + django_assert_num_queries, monkeypatch +): + """ + If an existing user matches the user's info sub, the user should be returned. + """ + + klass = OIDCAuthenticationBackend() + db_user = UserFactory() + + def get_userinfo_mocked(*args): + return {"sub": db_user.sub} + + monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked) + + with django_assert_num_queries(1): + user = klass.get_or_create_user( + access_token="test-token", id_token=None, payload=None + ) + + assert user == db_user + + +def test_authentication_getter_new_user_no_email(monkeypatch): + """ + If no user matches the user's info sub, a user should be created. + User's info doesn't contain an email, created user's email should be empty. + """ + klass = OIDCAuthenticationBackend() + + def get_userinfo_mocked(*args): + return {"sub": "123"} + + monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked) + + user = klass.get_or_create_user( + access_token="test-token", id_token=None, payload=None + ) + + assert user.sub == "123" + assert user.email is None + assert user.password == "!" + assert models.User.objects.count() == 1 + + +def test_authentication_getter_new_user_with_email(monkeypatch): + """ + If no user matches the user's info sub, a user should be created. + User's email and name should be set on the identity. + The "email" field on the User model should not be set as it is reserved for staff users. + """ + klass = OIDCAuthenticationBackend() + + email = "impress@example.com" + + def get_userinfo_mocked(*args): + return {"sub": "123", "email": email, "first_name": "John", "last_name": "Doe"} + + monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked) + + user = klass.get_or_create_user( + access_token="test-token", id_token=None, payload=None + ) + + assert user.sub == "123" + assert user.email == email + assert user.password == "!" + assert models.User.objects.count() == 1 + + +def test_models_oidc_user_getter_invalid_token(django_assert_num_queries, monkeypatch): + """The user's info doesn't contain a sub.""" + klass = OIDCAuthenticationBackend() + + def get_userinfo_mocked(*args): + return { + "test": "123", + } + + monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked) + + with django_assert_num_queries(0), pytest.raises( + SuspiciousOperation, + match="User info contained no recognizable user identification", + ): + klass.get_or_create_user(access_token="test-token", id_token=None, payload=None) + + assert models.User.objects.exists() is False