this repo has no description
1import { describe, it, expect, beforeEach } from 'vitest'
2import { render, screen, fireEvent, waitFor } from '@testing-library/svelte'
3import Dashboard from '../routes/Dashboard.svelte'
4import {
5 setupFetchMock,
6 mockEndpoint,
7 jsonResponse,
8 mockData,
9 clearMocks,
10 setupAuthenticatedUser,
11 setupUnauthenticatedUser,
12} from './mocks'
13const STORAGE_KEY = 'tranquil_pds_session'
14describe('Dashboard', () => {
15 beforeEach(() => {
16 clearMocks()
17 setupFetchMock()
18 })
19 describe('authentication guard', () => {
20 it('redirects to login when not authenticated', async () => {
21 setupUnauthenticatedUser()
22 render(Dashboard)
23 await waitFor(() => {
24 expect(window.location.hash).toBe('#/login')
25 })
26 })
27 it('shows loading state while checking auth', () => {
28 render(Dashboard)
29 expect(screen.getByText(/loading/i)).toBeInTheDocument()
30 })
31 })
32 describe('authenticated view', () => {
33 beforeEach(() => {
34 setupAuthenticatedUser()
35 })
36 it('displays user account info and page structure', async () => {
37 render(Dashboard)
38 await waitFor(() => {
39 expect(screen.getByRole('heading', { name: /dashboard/i })).toBeInTheDocument()
40 expect(screen.getByRole('heading', { name: /account overview/i })).toBeInTheDocument()
41 expect(screen.getByText(/@testuser\.test\.tranquil\.dev/)).toBeInTheDocument()
42 expect(screen.getByText(/did:web:test\.tranquil\.dev:u:testuser/)).toBeInTheDocument()
43 expect(screen.getByText('test@example.com')).toBeInTheDocument()
44 expect(screen.getByText('Verified')).toBeInTheDocument()
45 expect(screen.getByText('Verified')).toHaveClass('badge', 'success')
46 })
47 })
48 it('displays unverified badge when email not confirmed', async () => {
49 setupAuthenticatedUser({ emailConfirmed: false })
50 render(Dashboard)
51 await waitFor(() => {
52 expect(screen.getByText('Unverified')).toBeInTheDocument()
53 expect(screen.getByText('Unverified')).toHaveClass('badge', 'warning')
54 })
55 })
56 it('displays all navigation cards', async () => {
57 render(Dashboard)
58 await waitFor(() => {
59 const navCards = [
60 { name: /app passwords/i, href: '#/app-passwords' },
61 { name: /invite codes/i, href: '#/invite-codes' },
62 { name: /account settings/i, href: '#/settings' },
63 { name: /communication preferences/i, href: '#/comms' },
64 { name: /repository explorer/i, href: '#/repo' },
65 ]
66 for (const { name, href } of navCards) {
67 const card = screen.getByRole('link', { name })
68 expect(card).toBeInTheDocument()
69 expect(card).toHaveAttribute('href', href)
70 }
71 })
72 })
73 })
74 describe('logout functionality', () => {
75 beforeEach(() => {
76 setupAuthenticatedUser()
77 localStorage.setItem(STORAGE_KEY, JSON.stringify(mockData.session()))
78 mockEndpoint('com.atproto.server.deleteSession', () =>
79 jsonResponse({})
80 )
81 })
82 it('calls deleteSession and navigates to login on logout', async () => {
83 let deleteSessionCalled = false
84 mockEndpoint('com.atproto.server.deleteSession', () => {
85 deleteSessionCalled = true
86 return jsonResponse({})
87 })
88 render(Dashboard)
89 await waitFor(() => {
90 expect(screen.getByRole('button', { name: /sign out/i })).toBeInTheDocument()
91 })
92 await fireEvent.click(screen.getByRole('button', { name: /sign out/i }))
93 await waitFor(() => {
94 expect(deleteSessionCalled).toBe(true)
95 expect(window.location.hash).toBe('#/login')
96 })
97 })
98 it('clears session from localStorage after logout', async () => {
99 const storedSession = localStorage.getItem(STORAGE_KEY)
100 expect(storedSession).not.toBeNull()
101 render(Dashboard)
102 await waitFor(() => {
103 expect(screen.getByRole('button', { name: /sign out/i })).toBeInTheDocument()
104 })
105 await fireEvent.click(screen.getByRole('button', { name: /sign out/i }))
106 await waitFor(() => {
107 expect(localStorage.getItem(STORAGE_KEY)).toBeNull()
108 })
109 })
110 })
111})