File size: 1,593 Bytes
ce8f04a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { describe, it, expect, beforeEach } from 'vitest';
import {
  setClerkAuthState,
  shouldHardRedirectOn401,
  resolvePostAuthRedirect,
  safeSignInRedirectPath,
} from './authGate';

describe('authGate', () => {
  beforeEach(() => {
    setClerkAuthState({ isLoaded: false, isSignedIn: false });
  });

  it('does not hard-redirect while Clerk is loading', () => {
    setClerkAuthState({ isLoaded: false, isSignedIn: false });
    expect(shouldHardRedirectOn401()).toBe(false);
  });

  it('does not hard-redirect when Clerk says signed in (token race)', () => {
    setClerkAuthState({ isLoaded: true, isSignedIn: true });
    expect(shouldHardRedirectOn401()).toBe(false);
  });

  it('allows hard-redirect only when signed out and loaded', () => {
    setClerkAuthState({ isLoaded: true, isSignedIn: false });
    expect(shouldHardRedirectOn401()).toBe(true);
    // throttled
    expect(shouldHardRedirectOn401()).toBe(false);
  });

  it('resolvePostAuthRedirect maps dashboard to projects and honors redirect_url', () => {
    expect(resolvePostAuthRedirect('?redirect_url=%2Fprojects')).toBe('/projects');
    expect(resolvePostAuthRedirect('?redirect_url=%2Fdashboard')).toBe('/projects');
    expect(resolvePostAuthRedirect('')).toBe('/projects');
    expect(resolvePostAuthRedirect('?redirect_url=https://evil.com')).toBe('/projects');
  });

  it('safeSignInRedirectPath keeps public paths free of bounce params', () => {
    expect(safeSignInRedirectPath('/sign-in')).toBe('/sign-in');
    expect(safeSignInRedirectPath('/projects')).toContain('redirect_url=');
  });
});