3
3
import json
4
4
from base64 import b64encode
5
5
from unittest .mock import MagicMock
6
+ from urllib .parse import urljoin
6
7
7
8
import pytest
8
- from django .conf import settings
9
9
from django .test import RequestFactory
10
10
from django .urls import reverse
11
11
@@ -28,10 +28,18 @@ def test_custom_login(mocker, next_url, allowed):
28
28
assert get_redirect_url (mock_request ) == (next_url if allowed else "/app" )
29
29
30
30
31
- @pytest .mark .parametrize ("has_apisix_header" , [True , False ])
32
- @pytest .mark .parametrize ("next_url" , ["/search" , None ])
33
- def test_logout (mocker , next_url , client , user , has_apisix_header ):
31
+ @pytest .mark .parametrize (
32
+ "test_params" ,
33
+ [
34
+ (True , "/search" ),
35
+ (True , None ),
36
+ (False , "/search" ),
37
+ (False , None ),
38
+ ],
39
+ )
40
+ def test_logout (mocker , client , user , test_params , settings ):
34
41
"""User should be properly redirected and logged out"""
42
+ has_apisix_header , next_url = test_params
35
43
header_str = b64encode (
36
44
json .dumps (
37
45
{
@@ -55,10 +63,10 @@ def test_logout(mocker, next_url, client, user, has_apisix_header):
55
63
mock_logout .assert_called_once ()
56
64
57
65
58
- @pytest .mark .parametrize ("is_authenticated" , [True ])
59
- @pytest .mark .parametrize ("has_next" , [False ])
60
- def test_next_logout (mocker , client , user , is_authenticated , has_next ):
66
+ @pytest .mark .parametrize ("test_params" , [(True , False )])
67
+ def test_next_logout (mocker , client , user , test_params , settings ):
61
68
"""Test logout redirect cache assignment"""
69
+ is_authenticated , has_next = test_params
62
70
next_url = "https://ocw.mit.edu"
63
71
mock_request = mocker .MagicMock (
64
72
GET = {"next" : next_url if has_next else None },
@@ -211,3 +219,60 @@ def test_custom_login_view_first_time_login_sets_has_logged_in(mocker):
211
219
212
220
# Verify redirect was called with the correct URL
213
221
mock_redirect .assert_called_once_with ("/dashboard" )
222
+
223
+
224
+ @pytest .mark .parametrize (
225
+ "test_case" ,
226
+ [
227
+ (
228
+ (False , False ),
229
+ "/dashboard/organization/test-organization" ,
230
+ ), # First-time login → org dashboard
231
+ (
232
+ (False , True ),
233
+ "/dashboard/organization/test-organization" ,
234
+ ), # First-time login → org dashboard
235
+ ((True , False ), "/app" ), # Subsequent login → normal app (not onboarding!)
236
+ ((True , True ), "/app" ), # Subsequent login → normal app
237
+ ],
238
+ )
239
+ def test_login_org_user_redirect (mocker , client , user , test_case , settings ):
240
+ """Test organization user redirect behavior - org users skip onboarding regardless of onboarding status"""
241
+ # Unpack test case
242
+ profile_state , expected_url = test_case
243
+ has_logged_in , completed_onboarding = profile_state
244
+
245
+ # Set up user profile based on test scenario
246
+ user .profile .has_logged_in = has_logged_in
247
+ user .profile .completed_onboarding = completed_onboarding
248
+ user .profile .save ()
249
+
250
+ header_str = b64encode (
251
+ json .dumps (
252
+ {
253
+ "preferred_username" : user .username ,
254
+ "email" : user .email ,
255
+ "sub" : user .global_id ,
256
+ "organization" : {
257
+ "Test Organization" : {
258
+ "role" : "member" ,
259
+ "id" : "org-123" ,
260
+ }
261
+ },
262
+ }
263
+ ).encode ()
264
+ )
265
+ client .force_login (user )
266
+ response = client .get (
267
+ "/login/" ,
268
+ follow = False ,
269
+ HTTP_X_USERINFO = header_str ,
270
+ )
271
+ assert response .status_code == 302
272
+ # Handle environment differences - in some envs it returns full URL, in others just path
273
+ expected_full_url = urljoin (settings .APP_BASE_URL , expected_url )
274
+ assert response .url in [expected_url , expected_full_url ]
275
+
276
+ # Verify that org users are never sent to onboarding
277
+ # (onboarding URL would contain settings.MITOL_NEW_USER_LOGIN_URL)
278
+ assert settings .MITOL_NEW_USER_LOGIN_URL not in response .url
0 commit comments