4 Commits

10 changed files with 60 additions and 20 deletions

View File

@@ -4,6 +4,25 @@ import React from 'react';
import { MantineProvider } from '@mantine/core'; import { MantineProvider } from '@mantine/core';
import ProfileSettings from './ProfileSettings'; import ProfileSettings from './ProfileSettings';
import type { UserProfileSettings } from '@/types/models'; import type { UserProfileSettings } from '@/types/models';
import { Theme, UserRole, type User } from '@/types/models';
// Mock user for AuthContext
const mockUser: User = {
id: 1,
email: 'test@example.com',
displayName: 'Test User',
role: UserRole.Editor,
theme: Theme.Dark,
createdAt: '2024-01-01T00:00:00Z',
lastWorkspaceId: 1,
};
// Mock the auth context
vi.mock('../../../contexts/AuthContext', () => ({
useAuth: () => ({
user: mockUser,
}),
}));
// Helper wrapper component for testing // Helper wrapper component for testing
const TestWrapper = ({ children }: { children: React.ReactNode }) => ( const TestWrapper = ({ children }: { children: React.ReactNode }) => (

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { Box, Stack, TextInput, Group, Text, Switch } from '@mantine/core'; import { Box, Stack, TextInput, Group, Text, Switch } from '@mantine/core';
import { IconMoon, IconSun } from '@tabler/icons-react';
import { useAuth } from '@/contexts/AuthContext'; import { useAuth } from '@/contexts/AuthContext';
import { Theme, type UserProfileSettings } from '@/types/models'; import { Theme, type UserProfileSettings } from '@/types/models';
@@ -44,11 +43,10 @@ const ProfileSettings: React.FC<ProfileSettingsProps> = ({
placeholder="Enter email" placeholder="Enter email"
data-testid="email-input" data-testid="email-input"
/> />
<Group justify="space-between" align="flex-start"> <Box mb="md">
<Group justify="space-between" align="center">
<div> <div>
<Text size="sm" fw={500}> <Text size="sm">Default Dark Mode</Text>
Default Theme
</Text>
<Text size="xs" c="dimmed"> <Text size="xs" c="dimmed">
Sets the default theme for new workspaces Sets the default theme for new workspaces
</Text> </Text>
@@ -56,12 +54,10 @@ const ProfileSettings: React.FC<ProfileSettingsProps> = ({
<Switch <Switch
checked={currentTheme === Theme.Dark} checked={currentTheme === Theme.Dark}
onChange={handleThemeToggle} onChange={handleThemeToggle}
size="lg"
onLabel={<IconMoon size={16} />}
offLabel={<IconSun size={16} />}
data-testid="theme-toggle" data-testid="theme-toggle"
/> />
</Group> </Group>
</Box>
</Stack> </Stack>
</Box> </Box>
); );

View File

@@ -188,6 +188,7 @@ describe('Models Type Guards', () => {
id: 1, id: 1,
email: 'test@example.com', email: 'test@example.com',
role: UserRole.Editor, role: UserRole.Editor,
theme: Theme.Dark,
createdAt: '2024-01-01T00:00:00Z', createdAt: '2024-01-01T00:00:00Z',
lastWorkspaceId: 1, lastWorkspaceId: 1,
__proto__: { malicious: true }, __proto__: { malicious: true },
@@ -773,6 +774,7 @@ describe('Models Type Guards', () => {
id: 1, id: 1,
email: 'test@example.com', email: 'test@example.com',
role: UserRole.Editor, role: UserRole.Editor,
theme: Theme.Dark,
createdAt: '2024-01-01T00:00:00Z', createdAt: '2024-01-01T00:00:00Z',
lastWorkspaceId: 1, lastWorkspaceId: 1,
}; };
@@ -806,6 +808,7 @@ describe('Models Type Guards', () => {
id: 1, id: 1,
email: 'test@example.com', email: 'test@example.com',
role: UserRole.Editor, role: UserRole.Editor,
theme: Theme.Dark,
createdAt: '2024-01-01T00:00:00Z', createdAt: '2024-01-01T00:00:00Z',
lastWorkspaceId: 1, lastWorkspaceId: 1,
}); });
@@ -854,6 +857,7 @@ describe('Models Type Guards', () => {
id: 1, id: 1,
email: longString, email: longString,
role: UserRole.Editor, role: UserRole.Editor,
theme: Theme.Dark,
createdAt: '2024-01-01T00:00:00Z', createdAt: '2024-01-01T00:00:00Z',
lastWorkspaceId: 1, lastWorkspaceId: 1,
}; };

View File

@@ -30,7 +30,8 @@ export function isUser(value: unknown): value is User {
'role' in value && 'role' in value &&
isUserRole((value as User).role) && isUserRole((value as User).role) &&
'theme' in value && 'theme' in value &&
(value as User).theme in Theme && typeof (value as User).theme === 'string' &&
Object.values(Theme).includes((value as User).theme) &&
'createdAt' in value && 'createdAt' in value &&
typeof (value as User).createdAt === 'string' && typeof (value as User).createdAt === 'string' &&
'lastWorkspaceId' in value && 'lastWorkspaceId' in value &&

View File

@@ -29,6 +29,7 @@ func TestSessionOperations(t *testing.T) {
DisplayName: "Test User", DisplayName: "Test User",
PasswordHash: "hash", PasswordHash: "hash",
Role: "editor", Role: "editor",
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("failed to create test user: %v", err) t.Fatalf("failed to create test user: %v", err)

View File

@@ -156,6 +156,7 @@ func TestStructQueries(t *testing.T) {
DisplayName: "Struct Query Test", DisplayName: "Struct Query Test",
PasswordHash: "hashed_password", PasswordHash: "hashed_password",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
} }
t.Run("InsertStructQuery", func(t *testing.T) { t.Run("InsertStructQuery", func(t *testing.T) {
@@ -243,6 +244,7 @@ func TestStructQueries(t *testing.T) {
DisplayName: "Struct Query Test 2", DisplayName: "Struct Query Test 2",
PasswordHash: "hashed_password2", PasswordHash: "hashed_password2",
Role: models.RoleViewer, Role: models.RoleViewer,
Theme: "light",
} }
createdUser2, err := database.CreateUser(secondUser) createdUser2, err := database.CreateUser(secondUser)
@@ -437,6 +439,7 @@ func TestEncryptedFields(t *testing.T) {
DisplayName: "Encryption Test", DisplayName: "Encryption Test",
PasswordHash: "hash", PasswordHash: "hash",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("Failed to create test user: %v", err) t.Fatalf("Failed to create test user: %v", err)

View File

@@ -31,12 +31,14 @@ func TestSystemOperations(t *testing.T) {
DisplayName: "User 1", DisplayName: "User 1",
PasswordHash: "hash1", PasswordHash: "hash1",
Role: "editor", Role: "editor",
Theme: "dark",
}, },
{ {
Email: "user2@test.com", Email: "user2@test.com",
DisplayName: "User 2", DisplayName: "User 2",
PasswordHash: "hash2", PasswordHash: "hash2",
Role: "viewer", Role: "viewer",
Theme: "light",
}, },
} }

View File

@@ -34,6 +34,7 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Test User", DisplayName: "Test User",
PasswordHash: "hashed_password", PasswordHash: "hashed_password",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}, },
wantErr: false, wantErr: false,
}, },
@@ -44,6 +45,7 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Another User", DisplayName: "Another User",
PasswordHash: "different_hash", PasswordHash: "different_hash",
Role: models.RoleViewer, Role: models.RoleViewer,
Theme: "light",
}, },
wantErr: true, wantErr: true,
errContains: "UNIQUE constraint failed", errContains: "UNIQUE constraint failed",
@@ -108,6 +110,7 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Get By ID User", DisplayName: "Get By ID User",
PasswordHash: "hash", PasswordHash: "hash",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("failed to create test user: %v", err) t.Fatalf("failed to create test user: %v", err)
@@ -159,6 +162,7 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Get By Email User", DisplayName: "Get By Email User",
PasswordHash: "hash", PasswordHash: "hash",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("failed to create test user: %v", err) t.Fatalf("failed to create test user: %v", err)
@@ -210,6 +214,7 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Original Name", DisplayName: "Original Name",
PasswordHash: "original_hash", PasswordHash: "original_hash",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("failed to create test user: %v", err) t.Fatalf("failed to create test user: %v", err)
@@ -249,12 +254,14 @@ func TestUserOperations(t *testing.T) {
DisplayName: "User One", DisplayName: "User One",
PasswordHash: "hash1", PasswordHash: "hash1",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}, },
{ {
Email: "user2@example.com", Email: "user2@example.com",
DisplayName: "User Two", DisplayName: "User Two",
PasswordHash: "hash2", PasswordHash: "hash2",
Role: models.RoleViewer, Role: models.RoleViewer,
Theme: "light",
}, },
} }
@@ -305,6 +312,7 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Workspace User", DisplayName: "Workspace User",
PasswordHash: "hash", PasswordHash: "hash",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("failed to create test user: %v", err) t.Fatalf("failed to create test user: %v", err)
@@ -343,6 +351,7 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Delete User", DisplayName: "Delete User",
PasswordHash: "hash", PasswordHash: "hash",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("failed to create test user: %v", err) t.Fatalf("failed to create test user: %v", err)
@@ -377,18 +386,21 @@ func TestUserOperations(t *testing.T) {
DisplayName: "Admin One", DisplayName: "Admin One",
PasswordHash: "hash1", PasswordHash: "hash1",
Role: models.RoleAdmin, Role: models.RoleAdmin,
Theme: "dark",
}, },
{ {
Email: "admin2@example.com", Email: "admin2@example.com",
DisplayName: "Admin Two", DisplayName: "Admin Two",
PasswordHash: "hash2", PasswordHash: "hash2",
Role: models.RoleAdmin, Role: models.RoleAdmin,
Theme: "light",
}, },
{ {
Email: "editor@example.com", Email: "editor@example.com",
DisplayName: "Editor", DisplayName: "Editor",
PasswordHash: "hash3", PasswordHash: "hash3",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}, },
} }

View File

@@ -26,6 +26,7 @@ func TestWorkspaceOperations(t *testing.T) {
DisplayName: "Test User", DisplayName: "Test User",
PasswordHash: "hash", PasswordHash: "hash",
Role: models.RoleEditor, Role: models.RoleEditor,
Theme: "dark",
}) })
if err != nil { if err != nil {
t.Fatalf("failed to create test user: %v", err) t.Fatalf("failed to create test user: %v", err)

View File

@@ -213,6 +213,7 @@ func (h *testHarness) createTestUser(t *testing.T, email, password string, role
DisplayName: "Test User", DisplayName: "Test User",
PasswordHash: string(hashedPassword), PasswordHash: string(hashedPassword),
Role: role, Role: role,
Theme: "dark",
} }
user, err = h.DB.CreateUser(user) user, err = h.DB.CreateUser(user)