Ctrl K
ComunidadGuías…

src/router.test.tsx

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { cleanup, render, screen, waitFor } from '@testing-library/react'
import type { ReactNode } from 'react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { AppRouter, queryClient } from '@/router'

vi.mock('@/features/account/account-center', () => ({
  AccountCenterLayout: ({ children }: { children: ReactNode }) => children,
  AccountAgentsPage: () => <h1>Agents route</h1>,
  AccountApplicationsPage: () => <h1>Applications route</h1>,
  AccountConnectionsPage: () => <h1>Connections route</h1>,
  AccountDataPrivacyPage: () => <h1>Data & privacy route</h1>,
  AccountOrganizationDetailPage: () => <h1>Organization route</h1>,
  AccountOrganizationsPage: () => <h1>Organizations route</h1>,
  AccountOverviewPage: () => <h1>Account overview route</h1>,
  AccountProfilePage: () => <h1>Profile route</h1>,
  AccountSecurityPage: () => <h1>Profile route</h1>,
}))

vi.mock('@/features/agents/agent-identity-approval', () => ({
  AgentIdentityApproval: () => <h1>Agent enrollment route</h1>,
}))

vi.mock('@/features/auth/onboarding-page', () => ({
  OnboardingRoute: () => <h1>First-admin onboarding</h1>,
}))

vi.mock('@/features/auth/pages/recovery', () => ({
  AuthCallbackPage: () => <h1>Auth callback route</h1>,
  EmailVerificationPage: () => <h1>Email verification route</h1>,
  ForgotPasswordPage: () => <h1>Forgot password route</h1>,
}))

vi.mock('@/features/auth/pages/sign-in', () => ({
  SignInPage: () => <h1>Sign in route</h1>,
}))

vi.mock('@/features/auth/pages/sign-up', () => ({
  SignUpPage: () => <h1>Sign up route</h1>,
}))

vi.mock('@/features/auth/device-authorization', () => ({
  DeviceVerification: () => <h1>Device approval route</h1>,
}))

afterEach(() => {
  cleanup()
  queryClient.clear()
  vi.restoreAllMocks()
  window.history.pushState(null, '', '/')
})

describe('root route', () => {
  it('renders the Account Center overview at the root', async () => {
    const fetchSpy = vi.spyOn(window, 'fetch').mockImplementation(accountRouteResponse)

    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Account overview route' })).toBeTruthy()
    expect(window.location.pathname).toBe('/')
    expect(fetchSpy).toHaveBeenCalledWith('/api/account/profile', {
      body: undefined,
      headers: expect.any(Headers),
      method: 'GET',
    })
  })

  it('authenticates profile routes before rendering them', async () => {
    const fetchSpy = vi.spyOn(window, 'fetch').mockImplementation(accountRouteResponse)
    window.history.pushState(null, '', '/profile')

    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Profile route' })).toBeTruthy()
    expect(window.location.pathname).toBe('/profile')
    expect(fetchSpy).toHaveBeenCalledWith('/api/account/profile', {
      body: undefined,
      headers: expect.any(Headers),
      method: 'GET',
    })
  })

  it('authenticates Data & privacy before rendering it', async () => {
    const fetchSpy = vi.spyOn(window, 'fetch').mockImplementation(accountRouteResponse)
    window.history.pushState(null, '', '/data-privacy')

    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Data & privacy route' })).toBeTruthy()
    expect(window.location.pathname).toBe('/data-privacy')
    expect(fetchSpy).toHaveBeenCalledWith('/api/account/profile', {
      body: undefined,
      headers: expect.any(Headers),
      method: 'GET',
    })
  })

  it('routes completed account connections to their Account Center page [spec: account-center/account-section-routes]', async () => {
    const fetchSpy = vi.spyOn(window, 'fetch').mockImplementation(accountRouteResponse)
    window.history.pushState(null, '', '/connections?resource_connection=connected')

    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Connections route' })).toBeTruthy()
    expect(window.location.pathname).toBe('/connections')
    expect(fetchSpy).toHaveBeenCalledWith('/api/account/profile', {
      body: undefined,
      headers: expect.any(Headers),
      method: 'GET',
    })
  })

  it('authenticates Agent enrollment before rendering it', async () => {
    const fetchSpy = vi.spyOn(window, 'fetch').mockImplementation(accountRouteResponse)
    window.history.pushState(null, '', '/agent/enrollment?agent_id=agent-1&code=ABCD-1234')

    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Agent enrollment route' })).toBeTruthy()
    expect(fetchSpy).toHaveBeenCalledWith('/api/account/profile', {
      body: undefined,
      headers: expect.any(Headers),
      method: 'GET',
    })
  })

  it('authenticates device approval before rendering it', async () => {
    const fetchSpy = vi
      .spyOn(window, 'fetch')
      .mockImplementation((input) =>
        String(input) === '/api/configz' ? Promise.resolve(jsonResponse(configz)) : accountRouteResponse(input),
      )
    window.history.pushState(null, '', '/auth/device?user_code=ABCD-1234')

    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Device approval route' })).toBeTruthy()
    expect(fetchSpy).toHaveBeenCalledWith('/api/account/profile', {
      body: undefined,
      headers: expect.any(Headers),
      method: 'GET',
    })
  })

  it('authenticates the device code entry route', async () => {
    const fetchSpy = vi
      .spyOn(window, 'fetch')
      .mockImplementation((input) =>
        String(input) === '/api/configz' ? Promise.resolve(jsonResponse(configz)) : accountRouteResponse(input),
      )
    window.history.pushState(null, '', '/auth/device')

    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Device approval route' })).toBeTruthy()
    expect(fetchSpy).toHaveBeenCalledWith('/api/account/profile', {
      body: undefined,
      headers: expect.any(Headers),
      method: 'GET',
    })
  })

  it('preserves device approval return path when signed out', async () => {
    vi.spyOn(window, 'fetch').mockImplementation(() => Promise.resolve(jsonResponse({ error: 'unauthorized' }, 401)))
    window.history.pushState(null, '', '/auth/device?user_code=ABCD-1234')

    render(<AppRouter />)

    await waitFor(() => expect(window.location.pathname).toBe('/auth/sign-in'))
    expect(window.location.search).toBe('?return_to=%2Fauth%2Fdevice%3Fuser_code%3DABCD-1234')
  })

  it('serves hosted auth from /auth routes only', async () => {
    window.history.pushState(null, '', '/auth/sign-in')
    render(<AppRouter />)

    expect(await screen.findByRole('heading', { name: 'Sign in route' })).toBeTruthy()

    cleanup()
    window.history.pushState(null, '', '/sign-in')
    render(<AppRouter />)

    await waitFor(() => expect(screen.queryByRole('heading', { name: 'Sign in route' })).toBeNull())
    expect(await screen.findByRole('heading', { name: 'Page not found.' })).toBeTruthy()
  })
})

const user = {
  id: 'user-1',
  email: 'jane@example.com',
  name: 'Jane Stone',
  displayName: 'Jane Stone',
  username: 'jane',
  role: 'user',
}

function accountRouteResponse(input: RequestInfo | URL) {
  if (String(input) === '/api/account/security') {
    return Promise.resolve(
      jsonResponse({
        security: {
          mfa: { enabled: false, factors: [] },
          passkeys: { enabled: true, count: 0 },
          policy: { mfa: { mode: 'optional' } },
        },
      }),
    )
  }
  return Promise.resolve(
    jsonResponse({
      activeOrganizationId: null,
      user,
      access: {
        canCreateOrganization: false,
        showOrganizations: false,
        platformOperator: false,
        consoleOrganizations: [],
      },
    }),
  )
}

const configz = {
  onboarding: { required: false, href: '/onboarding' },
  signIn: {
    passwordEnabled: true,
    signupEnabled: true,
    socialLoginEnabled: false,
    emailOtpEnabled: false,
    usernameEnabled: false,
    identifierFirst: false,
  },
  builtInProviders: {
    email: { enabled: true },
    phone: { enabled: false },
    web3Wallet: { enabled: false, chains: [1], allowSignUp: false },
    passkey: { allowSignUp: false },
    oneTap: { enabled: false },
  },
  branding: {
    logoUrl: null,
    faviconUrl: null,
    primaryColor: '#007b83',
    backgroundColor: '#ffffff',
    customCss: null,
  },
  identityProviders: [],
  links: { termsUri: null, privacyUri: null, supportEmail: null },
  copy: { productName: 'Realmroot' },
}

function jsonResponse(body: unknown, status = 200) {
  return new Response(JSON.stringify(body), {
    status,
    headers: { 'Content-Type': 'application/json' },
  })
}