From b70151a30f4114ccb5f7d4e8b4cb570a2f403c13 Mon Sep 17 00:00:00 2001 From: Matthew Elwell Date: Thu, 2 Apr 2026 18:12:03 +0100 Subject: [PATCH 1/2] fix(tests): use unique email in flaky custom auth integration test The test was using a hardcoded `test@example.com` that appears in 15+ other tests in the same file. Under certain xdist worker orderings this caused a 400 "Email already exists" validation error instead of the expected 201, making the test flaky. Co-Authored-By: Claude Sonnet 4.6 --- .../custom_auth/end_to_end/test_custom_auth_integration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py b/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py index 85dbadb3e975..2d1c2b330f04 100644 --- a/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py +++ b/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py @@ -619,11 +619,11 @@ def test_delete_token__valid_token__returns_no_content_and_invalidates( assert client.delete(delete_token_url).status_code == status.HTTP_401_UNAUTHORIZED -def test_register__with_sign_up_type__stores_sign_up_type(client, db, settings): # type: ignore[no-untyped-def] +def test_register__with_sign_up_type__stores_sign_up_type(client, db): # type: ignore[no-untyped-def] # Given password = FFAdminUser.objects.make_random_password() sign_up_type = "NO_INVITE" - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" register_data = { "email": email, "password": password, From 0ca558c236ba3be23b04e9d3beab92828d23b97f Mon Sep 17 00:00:00 2001 From: Matthew Elwell Date: Mon, 6 Apr 2026 15:47:48 +0100 Subject: [PATCH 2/2] Replace all remaining non-unique email addresses --- .../test_custom_auth_integration.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py b/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py index 2d1c2b330f04..620025537176 100644 --- a/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py +++ b/api/tests/integration/custom_auth/end_to_end/test_custom_auth_integration.py @@ -26,7 +26,7 @@ def test_register_and_login__full_workflow__succeeds_with_password_reset( ) -> None: # Given # try to register without first_name / last_name - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -105,7 +105,7 @@ def test_register__without_invite_when_disabled__returns_forbidden( db: None, api_client: APIClient ) -> None: # Given - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -128,7 +128,7 @@ def test_register__with_invite_when_registration_disabled__returns_created( api_client: APIClient, ) -> None: # Given - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() organisation = Organisation.objects.create(name="Test Organisation") register_data = { @@ -164,7 +164,7 @@ def test_register_and_login__activation_flow_enabled__succeeds_after_activation( """ # Given user registration data - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -226,7 +226,7 @@ def test_login__mfa_enabled__succeeds_with_totp_and_backup_code( api_client: APIClient, ) -> None: # Given - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -307,7 +307,7 @@ def test_register_and_login__jwt_cookie_enabled__sets_and_clears_cookies( api_client: APIClient, ) -> None: # Given - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_url = reverse("api-v1:custom_auth:ffadminuser-list") login_url = reverse("api-v1:custom_auth:custom-mfa-authtoken-login") @@ -377,7 +377,7 @@ def test_login_workflow__jwt_cookie__mfa_enabled( api_client: APIClient, ) -> None: # Given - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_url = reverse("api-v1:custom_auth:ffadminuser-list") create_mfa_method_url = reverse( @@ -438,7 +438,7 @@ def test_login_workflow__jwt_cookie__cors_headers_expected( api_client: APIClient, ) -> None: # Given - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_url = reverse("api-v1:custom_auth:ffadminuser-list") protected_resource_url = reverse("api-v1:projects:project-list") @@ -467,7 +467,7 @@ def test_login__jwt_cookie_with_invalid_token__returns_unauthorized_without_cook api_client: APIClient, ) -> None: # Given - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_url = reverse("api-v1:custom_auth:ffadminuser-list") protected_resource_url = reverse("api-v1:projects:project-list") @@ -504,7 +504,7 @@ def test_login__exceeds_throttle_rate__returns_too_many_requests( mocker.patch( "rest_framework.throttling.ScopedRateThrottle.get_rate", return_value="1/minute" ) - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -655,7 +655,7 @@ def test_register__superuser_flag_on_selfhosted__creates_superuser( # Given mocker.patch("custom_auth.serializers.is_saas", return_value=False) - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -683,7 +683,7 @@ def test_register__superuser_flag_on_saas__does_not_create_superuser( # Given mocker.patch("custom_auth.serializers.is_saas", return_value=True) - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -710,7 +710,7 @@ def test_register__superuser_flag_when_users_exist__returns_bad_request( # Given mocker.patch("custom_auth.serializers.is_saas", return_value=False) - email = "test@example.com" + email = f"test-{uuid.uuid4()}@example.com" password = FFAdminUser.objects.make_random_password() register_data = { "email": email, @@ -742,7 +742,7 @@ def test_register__marketing_consent_given__defaults_to_true( # Given password = FFAdminUser.objects.make_random_password() register_data = { - "email": "test@example.com", + "email": f"test-{uuid.uuid4()}@example.com", "password": password, "re_password": password, "first_name": "user",