test(JiraSync): improve test coverage for synchronization logic and change detection
This commit is contained in:
93
src/services/core/__tests__/database.test.ts
Normal file
93
src/services/core/__tests__/database.test.ts
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* Tests unitaires pour database.ts
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||||
|
import {
|
||||||
|
testDatabaseConnection,
|
||||||
|
closeDatabaseConnection,
|
||||||
|
clearDatabase,
|
||||||
|
prisma,
|
||||||
|
} from '../database';
|
||||||
|
|
||||||
|
describe('database utilities', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('testDatabaseConnection', () => {
|
||||||
|
it('devrait retourner true si la connexion réussit', async () => {
|
||||||
|
vi.spyOn(prisma, '$connect').mockResolvedValue(undefined);
|
||||||
|
|
||||||
|
const result = await testDatabaseConnection();
|
||||||
|
|
||||||
|
expect(result).toBe(true);
|
||||||
|
expect(prisma.$connect).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait retourner false si la connexion échoue', async () => {
|
||||||
|
vi.spyOn(prisma, '$connect').mockRejectedValue(
|
||||||
|
new Error('Connection failed')
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await testDatabaseConnection();
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('closeDatabaseConnection', () => {
|
||||||
|
it('devrait fermer la connexion avec succès', async () => {
|
||||||
|
vi.spyOn(prisma, '$disconnect').mockResolvedValue(undefined);
|
||||||
|
|
||||||
|
await closeDatabaseConnection();
|
||||||
|
|
||||||
|
expect(prisma.$disconnect).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait gérer les erreurs lors de la fermeture', async () => {
|
||||||
|
vi.spyOn(prisma, '$disconnect').mockRejectedValue(
|
||||||
|
new Error('Disconnect failed')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ne devrait pas throw
|
||||||
|
await expect(closeDatabaseConnection()).resolves.not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('clearDatabase', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// S'assurer qu'on est pas en production
|
||||||
|
vi.stubEnv('NODE_ENV', 'test');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait nettoyer toutes les tables', async () => {
|
||||||
|
const deleteManySpy = vi.fn().mockResolvedValue({ count: 0 });
|
||||||
|
|
||||||
|
// Mock des méthodes deleteMany directement
|
||||||
|
(prisma.taskTag as any) = { deleteMany: deleteManySpy };
|
||||||
|
(prisma.task as any) = { deleteMany: deleteManySpy };
|
||||||
|
(prisma.tag as any) = { deleteMany: deleteManySpy };
|
||||||
|
(prisma.syncLog as any) = { deleteMany: deleteManySpy };
|
||||||
|
|
||||||
|
await clearDatabase();
|
||||||
|
|
||||||
|
expect(deleteManySpy).toHaveBeenCalledTimes(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ne devrait pas permettre le nettoyage en production', async () => {
|
||||||
|
vi.stubEnv('NODE_ENV', 'production');
|
||||||
|
|
||||||
|
await expect(clearDatabase()).rejects.toThrow(
|
||||||
|
'Cannot clear database in production'
|
||||||
|
);
|
||||||
|
|
||||||
|
vi.unstubAllEnvs();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
256
src/services/core/__tests__/system-info.test.ts
Normal file
256
src/services/core/__tests__/system-info.test.ts
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
/**
|
||||||
|
* Tests unitaires pour SystemInfoService
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||||
|
import { SystemInfoService } from '../system-info';
|
||||||
|
import { prisma } from '../database';
|
||||||
|
import { readFile } from 'fs/promises';
|
||||||
|
import { stat } from 'fs/promises';
|
||||||
|
|
||||||
|
// Mock de prisma
|
||||||
|
vi.mock('../database', () => ({
|
||||||
|
prisma: {
|
||||||
|
task: {
|
||||||
|
count: vi.fn(),
|
||||||
|
},
|
||||||
|
userPreferences: {
|
||||||
|
count: vi.fn(),
|
||||||
|
},
|
||||||
|
tag: {
|
||||||
|
count: vi.fn(),
|
||||||
|
},
|
||||||
|
dailyCheckbox: {
|
||||||
|
count: vi.fn(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock de fs/promises
|
||||||
|
vi.mock('fs/promises', () => ({
|
||||||
|
readFile: vi.fn(),
|
||||||
|
stat: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock de path
|
||||||
|
vi.mock('path', () => ({
|
||||||
|
join: (...args: string[]) => args.join('/'),
|
||||||
|
resolve: (...args: string[]) => args.join('/'),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock du service backup
|
||||||
|
vi.mock('@/services/data-management/backup', () => ({
|
||||||
|
backupService: {
|
||||||
|
listBackups: vi.fn(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('SystemInfoService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
vi.stubEnv('NODE_ENV', 'test');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSystemInfo', () => {
|
||||||
|
it('devrait retourner les informations système complètes', async () => {
|
||||||
|
const mockPackageJson = {
|
||||||
|
name: 'towercontrol',
|
||||||
|
version: '1.0.0',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(readFile).mockResolvedValue(JSON.stringify(mockPackageJson));
|
||||||
|
vi.mocked(prisma.task.count).mockResolvedValue(10);
|
||||||
|
vi.mocked(prisma.userPreferences.count).mockResolvedValue(1);
|
||||||
|
vi.mocked(prisma.tag.count).mockResolvedValue(5);
|
||||||
|
vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(20);
|
||||||
|
|
||||||
|
const { backupService } = await import(
|
||||||
|
'@/services/data-management/backup'
|
||||||
|
);
|
||||||
|
vi.mocked(backupService.listBackups).mockResolvedValue([
|
||||||
|
{ id: '1', filename: 'backup1.db.gz' },
|
||||||
|
{ id: '2', filename: 'backup2.db.gz' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
vi.mocked(stat).mockResolvedValue({
|
||||||
|
size: 1024 * 1024, // 1 MB
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
const result = await SystemInfoService.getSystemInfo();
|
||||||
|
|
||||||
|
expect(result).toHaveProperty('version');
|
||||||
|
expect(result).toHaveProperty('environment');
|
||||||
|
expect(result).toHaveProperty('database');
|
||||||
|
expect(result).toHaveProperty('backups');
|
||||||
|
expect(result).toHaveProperty('app');
|
||||||
|
expect(result).toHaveProperty('uptime');
|
||||||
|
expect(result).toHaveProperty('lastUpdate');
|
||||||
|
|
||||||
|
expect(result.version).toBe('1.0.0');
|
||||||
|
expect(result.environment).toBe('test');
|
||||||
|
expect(result.database.totalTasks).toBe(10);
|
||||||
|
expect(result.database.totalUsers).toBe(1);
|
||||||
|
expect(result.database.totalBackups).toBe(2);
|
||||||
|
expect(result.database.totalTags).toBe(5);
|
||||||
|
expect(result.database.totalDailies).toBe(20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait gérer les erreurs lors de la lecture du package.json', async () => {
|
||||||
|
vi.mocked(readFile).mockRejectedValue(new Error('File not found'));
|
||||||
|
|
||||||
|
vi.mocked(prisma.task.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.userPreferences.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.tag.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const { backupService } = await import(
|
||||||
|
'@/services/data-management/backup'
|
||||||
|
);
|
||||||
|
vi.mocked(backupService.listBackups).mockResolvedValue([]);
|
||||||
|
|
||||||
|
vi.mocked(stat).mockRejectedValue(new Error('File not found'));
|
||||||
|
|
||||||
|
const result = await SystemInfoService.getSystemInfo();
|
||||||
|
|
||||||
|
expect(result.version).toBe('1.0.0'); // Valeur par défaut
|
||||||
|
expect(result.database.databaseSize).toBe('N/A');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait calculer correctement la taille de la base de données', async () => {
|
||||||
|
const mockPackageJson = {
|
||||||
|
name: 'towercontrol',
|
||||||
|
version: '1.0.0',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(readFile).mockResolvedValue(JSON.stringify(mockPackageJson));
|
||||||
|
vi.mocked(prisma.task.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.userPreferences.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.tag.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const { backupService } = await import(
|
||||||
|
'@/services/data-management/backup'
|
||||||
|
);
|
||||||
|
vi.mocked(backupService.listBackups).mockResolvedValue([]);
|
||||||
|
|
||||||
|
// Test différentes tailles
|
||||||
|
vi.mocked(stat).mockResolvedValue({
|
||||||
|
size: 1024, // 1 KB
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
const result = await SystemInfoService.getSystemInfo();
|
||||||
|
|
||||||
|
expect(result.database.databaseSize).toContain('KB');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait utiliser DATABASE_URL pour trouver la base de données', async () => {
|
||||||
|
vi.stubEnv('DATABASE_URL', 'file:/path/to/db.db');
|
||||||
|
|
||||||
|
const mockPackageJson = {
|
||||||
|
name: 'towercontrol',
|
||||||
|
version: '1.0.0',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(readFile).mockResolvedValue(JSON.stringify(mockPackageJson));
|
||||||
|
vi.mocked(prisma.task.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.userPreferences.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.tag.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const { backupService } = await import(
|
||||||
|
'@/services/data-management/backup'
|
||||||
|
);
|
||||||
|
vi.mocked(backupService.listBackups).mockResolvedValue([]);
|
||||||
|
|
||||||
|
vi.mocked(stat).mockResolvedValue({
|
||||||
|
size: 1024,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
await SystemInfoService.getSystemInfo();
|
||||||
|
|
||||||
|
expect(stat).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait utiliser BACKUP_DATABASE_PATH si défini', async () => {
|
||||||
|
vi.stubEnv('BACKUP_DATABASE_PATH', '/custom/path/db.db');
|
||||||
|
|
||||||
|
const mockPackageJson = {
|
||||||
|
name: 'towercontrol',
|
||||||
|
version: '1.0.0',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(readFile).mockResolvedValue(JSON.stringify(mockPackageJson));
|
||||||
|
vi.mocked(prisma.task.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.userPreferences.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.tag.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const { backupService } = await import(
|
||||||
|
'@/services/data-management/backup'
|
||||||
|
);
|
||||||
|
vi.mocked(backupService.listBackups).mockResolvedValue([]);
|
||||||
|
|
||||||
|
vi.mocked(stat).mockResolvedValue({
|
||||||
|
size: 1024,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
await SystemInfoService.getSystemInfo();
|
||||||
|
|
||||||
|
expect(stat).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait gérer les erreurs de base de données', async () => {
|
||||||
|
const mockPackageJson = {
|
||||||
|
name: 'towercontrol',
|
||||||
|
version: '1.0.0',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(readFile).mockResolvedValue(JSON.stringify(mockPackageJson));
|
||||||
|
vi.mocked(prisma.task.count).mockRejectedValue(
|
||||||
|
new Error('Database error')
|
||||||
|
);
|
||||||
|
|
||||||
|
const { backupService } = await import(
|
||||||
|
'@/services/data-management/backup'
|
||||||
|
);
|
||||||
|
vi.mocked(backupService.listBackups).mockResolvedValue([]);
|
||||||
|
|
||||||
|
const result = await SystemInfoService.getSystemInfo();
|
||||||
|
|
||||||
|
expect(result.database.totalTasks).toBe(0);
|
||||||
|
expect(result.database.totalUsers).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("devrait calculer correctement l'uptime", async () => {
|
||||||
|
const mockPackageJson = {
|
||||||
|
name: 'towercontrol',
|
||||||
|
version: '1.0.0',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(readFile).mockResolvedValue(JSON.stringify(mockPackageJson));
|
||||||
|
vi.mocked(prisma.task.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.userPreferences.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.tag.count).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.dailyCheckbox.count).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const { backupService } = await import(
|
||||||
|
'@/services/data-management/backup'
|
||||||
|
);
|
||||||
|
vi.mocked(backupService.listBackups).mockResolvedValue([]);
|
||||||
|
|
||||||
|
vi.mocked(stat).mockResolvedValue({
|
||||||
|
size: 1024,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
const result = await SystemInfoService.getSystemInfo();
|
||||||
|
|
||||||
|
expect(result.uptime).toBeDefined();
|
||||||
|
expect(result.uptime.length).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
836
src/services/core/__tests__/user-preferences.test.ts
Normal file
836
src/services/core/__tests__/user-preferences.test.ts
Normal file
@@ -0,0 +1,836 @@
|
|||||||
|
/**
|
||||||
|
* Tests unitaires pour UserPreferencesService
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||||
|
import { userPreferencesService } from '../user-preferences';
|
||||||
|
import { prisma } from '../database';
|
||||||
|
import { getConfig } from '@/lib/config';
|
||||||
|
import {
|
||||||
|
KanbanFilters,
|
||||||
|
ViewPreferences,
|
||||||
|
ColumnVisibility,
|
||||||
|
JiraConfig,
|
||||||
|
} from '@/lib/types';
|
||||||
|
import { TfsConfig } from '@/services/integrations/tfs/tfs';
|
||||||
|
|
||||||
|
// Mock de prisma
|
||||||
|
vi.mock('../database', () => ({
|
||||||
|
prisma: {
|
||||||
|
user: {
|
||||||
|
upsert: vi.fn(),
|
||||||
|
},
|
||||||
|
userPreferences: {
|
||||||
|
upsert: vi.fn(),
|
||||||
|
update: vi.fn(),
|
||||||
|
findUnique: vi.fn(),
|
||||||
|
},
|
||||||
|
$executeRaw: vi.fn(),
|
||||||
|
$queryRaw: vi.fn(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock de getConfig
|
||||||
|
vi.mock('@/lib/config', () => ({
|
||||||
|
getConfig: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('UserPreferencesService', () => {
|
||||||
|
const userId = 'test-user-id';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Kanban Filters', () => {
|
||||||
|
it('devrait sauvegarder les filtres Kanban', async () => {
|
||||||
|
const filters: KanbanFilters = {
|
||||||
|
search: 'test',
|
||||||
|
tags: ['important'],
|
||||||
|
priorities: ['high'],
|
||||||
|
showCompleted: false,
|
||||||
|
sortBy: 'priority',
|
||||||
|
showWithDueDate: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: filters,
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: filters,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveKanbanFilters(userId, filters);
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalledWith({
|
||||||
|
where: { userId },
|
||||||
|
data: { kanbanFilters: filters },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait récupérer les filtres Kanban avec valeurs par défaut', async () => {
|
||||||
|
const filters: KanbanFilters = {
|
||||||
|
search: 'test',
|
||||||
|
tags: ['important'],
|
||||||
|
priorities: [],
|
||||||
|
showCompleted: true,
|
||||||
|
sortBy: '',
|
||||||
|
showWithDueDate: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: filters,
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const result = await userPreferencesService.getKanbanFilters(userId);
|
||||||
|
|
||||||
|
expect(result).toHaveProperty('search');
|
||||||
|
expect(result).toHaveProperty('tags');
|
||||||
|
expect(result).toHaveProperty('priorities');
|
||||||
|
expect(result).toHaveProperty('showCompleted');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("devrait retourner les valeurs par défaut en cas d'erreur", async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockRejectedValue(
|
||||||
|
new Error('Database error')
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await userPreferencesService.getKanbanFilters(userId);
|
||||||
|
|
||||||
|
expect(result).toHaveProperty('search');
|
||||||
|
expect(result.search).toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('View Preferences', () => {
|
||||||
|
it('devrait sauvegarder les préférences de vue', async () => {
|
||||||
|
const preferences: ViewPreferences = {
|
||||||
|
compactView: true,
|
||||||
|
swimlanesByTags: true,
|
||||||
|
swimlanesMode: 'tags',
|
||||||
|
showObjectives: false,
|
||||||
|
showFilters: true,
|
||||||
|
objectivesCollapsed: false,
|
||||||
|
theme: 'light',
|
||||||
|
fontSize: 'large',
|
||||||
|
backgroundImage: undefined,
|
||||||
|
backgroundBlur: 0,
|
||||||
|
backgroundOpacity: 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: preferences,
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
viewPreferences: preferences,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveViewPreferences(userId, preferences);
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalledWith({
|
||||||
|
where: { userId },
|
||||||
|
data: { viewPreferences: preferences },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait récupérer le thème', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: { theme: 'light' },
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const theme = await userPreferencesService.getTheme(userId);
|
||||||
|
|
||||||
|
expect(theme).toBe('light');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Column Visibility', () => {
|
||||||
|
it('devrait sauvegarder la visibilité des colonnes', async () => {
|
||||||
|
const visibility: ColumnVisibility = {
|
||||||
|
hiddenStatuses: ['archived', 'cancelled'],
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: visibility,
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
columnVisibility: visibility,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveColumnVisibility(userId, visibility);
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalledWith({
|
||||||
|
where: { userId },
|
||||||
|
data: { columnVisibility: visibility },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("devrait toggle la visibilité d'une colonne", async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: { hiddenStatuses: [] },
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
columnVisibility: { hiddenStatuses: ['archived'] },
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.toggleColumnVisibility(userId, 'archived');
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Jira Config', () => {
|
||||||
|
it('devrait sauvegarder la configuration Jira', async () => {
|
||||||
|
const config: JiraConfig = {
|
||||||
|
enabled: true,
|
||||||
|
baseUrl: 'https://jira.example.com',
|
||||||
|
email: 'user@example.com',
|
||||||
|
apiToken: 'token123',
|
||||||
|
ignoredProjects: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: config,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
jiraConfig: config,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveJiraConfig(userId, config);
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalledWith({
|
||||||
|
where: { userId },
|
||||||
|
data: { jiraConfig: config },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait récupérer la configuration Jira depuis la DB', async () => {
|
||||||
|
const config: JiraConfig = {
|
||||||
|
enabled: true,
|
||||||
|
baseUrl: 'https://jira.example.com',
|
||||||
|
email: 'user@example.com',
|
||||||
|
apiToken: 'token123',
|
||||||
|
ignoredProjects: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: config,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const result = await userPreferencesService.getJiraConfig(userId);
|
||||||
|
|
||||||
|
expect(result.baseUrl).toBe('https://jira.example.com');
|
||||||
|
expect(result.email).toBe('user@example.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("devrait utiliser les variables d'environnement si pas de config DB", async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: null,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
vi.mocked(getConfig).mockReturnValue({
|
||||||
|
integrations: {
|
||||||
|
jira: {
|
||||||
|
baseUrl: 'https://env-jira.example.com',
|
||||||
|
email: 'env@example.com',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
const result = await userPreferencesService.getJiraConfig(userId);
|
||||||
|
|
||||||
|
expect(result.baseUrl).toBe('https://env-jira.example.com');
|
||||||
|
expect(result.email).toBe('env@example.com');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('TFS Config', () => {
|
||||||
|
it('devrait sauvegarder la configuration TFS', async () => {
|
||||||
|
const config: TfsConfig = {
|
||||||
|
enabled: true,
|
||||||
|
organizationUrl: 'https://dev.azure.com/org',
|
||||||
|
projectName: 'MyProject',
|
||||||
|
personalAccessToken: 'token123',
|
||||||
|
repositories: ['repo1', 'repo2'],
|
||||||
|
ignoredRepositories: [],
|
||||||
|
maxSyncPeriod: '90d',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
tfsConfig: config,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
tfsConfig: config,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveTfsConfig(userId, config);
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalledWith({
|
||||||
|
where: { userId },
|
||||||
|
data: { tfsConfig: config },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait récupérer la configuration TFS', async () => {
|
||||||
|
const config: TfsConfig = {
|
||||||
|
enabled: true,
|
||||||
|
organizationUrl: 'https://dev.azure.com/org',
|
||||||
|
projectName: 'MyProject',
|
||||||
|
personalAccessToken: 'token123',
|
||||||
|
repositories: [],
|
||||||
|
ignoredRepositories: [],
|
||||||
|
maxSyncPeriod: '90d',
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
tfsConfig: config,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
const result = await userPreferencesService.getTfsConfig(userId);
|
||||||
|
|
||||||
|
expect(result.organizationUrl).toBe('https://dev.azure.com/org');
|
||||||
|
expect(result.projectName).toBe('MyProject');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Scheduler Config', () => {
|
||||||
|
it('devrait sauvegarder la configuration scheduler Jira', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveJiraSchedulerConfig(
|
||||||
|
userId,
|
||||||
|
true,
|
||||||
|
'hourly'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(prisma.$executeRaw).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait récupérer la configuration scheduler Jira', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.$queryRaw).mockResolvedValue([
|
||||||
|
{ jiraAutoSync: 1, jiraSyncInterval: 'hourly' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result =
|
||||||
|
await userPreferencesService.getJiraSchedulerConfig(userId);
|
||||||
|
|
||||||
|
expect(result.jiraAutoSync).toBe(true);
|
||||||
|
expect(result.jiraSyncInterval).toBe('hourly');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait sauvegarder la configuration scheduler TFS', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveTfsSchedulerConfig(
|
||||||
|
userId,
|
||||||
|
true,
|
||||||
|
'daily'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(prisma.$executeRaw).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait récupérer la configuration scheduler TFS', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.$queryRaw).mockResolvedValue([
|
||||||
|
{ tfsAutoSync: 1, tfsSyncInterval: 'daily' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
const result = await userPreferencesService.getTfsSchedulerConfig(userId);
|
||||||
|
|
||||||
|
expect(result.tfsAutoSync).toBe(true);
|
||||||
|
expect(result.tfsSyncInterval).toBe('daily');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('All Preferences', () => {
|
||||||
|
it('devrait récupérer toutes les préférences', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
vi.mocked(prisma.$queryRaw).mockResolvedValue([
|
||||||
|
{ jiraAutoSync: 0, jiraSyncInterval: 'daily' },
|
||||||
|
{ tfsAutoSync: 0, tfsSyncInterval: 'daily' },
|
||||||
|
] as any);
|
||||||
|
|
||||||
|
vi.mocked(getConfig).mockReturnValue({
|
||||||
|
integrations: {
|
||||||
|
jira: {
|
||||||
|
baseUrl: '',
|
||||||
|
email: '',
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
const result = await userPreferencesService.getAllPreferences(userId);
|
||||||
|
|
||||||
|
expect(result).toHaveProperty('kanbanFilters');
|
||||||
|
expect(result).toHaveProperty('viewPreferences');
|
||||||
|
expect(result).toHaveProperty('columnVisibility');
|
||||||
|
expect(result).toHaveProperty('jiraConfig');
|
||||||
|
expect(result).toHaveProperty('jiraAutoSync');
|
||||||
|
expect(result).toHaveProperty('jiraSyncInterval');
|
||||||
|
expect(result).toHaveProperty('tfsConfig');
|
||||||
|
expect(result).toHaveProperty('tfsAutoSync');
|
||||||
|
expect(result).toHaveProperty('tfsSyncInterval');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait sauvegarder toutes les préférences', async () => {
|
||||||
|
const preferences = {
|
||||||
|
kanbanFilters: {
|
||||||
|
search: '',
|
||||||
|
tags: [],
|
||||||
|
priorities: [],
|
||||||
|
showCompleted: true,
|
||||||
|
sortBy: '',
|
||||||
|
showWithDueDate: false,
|
||||||
|
},
|
||||||
|
viewPreferences: {
|
||||||
|
compactView: false,
|
||||||
|
swimlanesByTags: false,
|
||||||
|
swimlanesMode: 'tags' as const,
|
||||||
|
showObjectives: true,
|
||||||
|
showFilters: true,
|
||||||
|
objectivesCollapsed: false,
|
||||||
|
theme: 'dark' as const,
|
||||||
|
fontSize: 'medium' as const,
|
||||||
|
backgroundImage: undefined,
|
||||||
|
backgroundBlur: 0,
|
||||||
|
backgroundOpacity: 100,
|
||||||
|
},
|
||||||
|
columnVisibility: {
|
||||||
|
hiddenStatuses: [],
|
||||||
|
},
|
||||||
|
jiraConfig: {
|
||||||
|
enabled: false,
|
||||||
|
baseUrl: '',
|
||||||
|
email: '',
|
||||||
|
apiToken: '',
|
||||||
|
ignoredProjects: [],
|
||||||
|
},
|
||||||
|
jiraAutoSync: false,
|
||||||
|
jiraSyncInterval: 'daily' as const,
|
||||||
|
tfsConfig: {
|
||||||
|
enabled: false,
|
||||||
|
organizationUrl: '',
|
||||||
|
projectName: '',
|
||||||
|
personalAccessToken: '',
|
||||||
|
repositories: [],
|
||||||
|
ignoredRepositories: [],
|
||||||
|
maxSyncPeriod: '90d' as const,
|
||||||
|
},
|
||||||
|
tfsAutoSync: false,
|
||||||
|
tfsSyncInterval: 'daily' as const,
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.saveAllPreferences(userId, preferences);
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalled();
|
||||||
|
expect(prisma.$executeRaw).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait remettre à zéro toutes les préférences', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.resetAllPreferences(userId);
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Update methods', () => {
|
||||||
|
it('devrait mettre à jour partiellement les filtres Kanban', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: { search: '', tags: [] },
|
||||||
|
viewPreferences: {},
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: { search: 'new', tags: [] },
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.updateKanbanFilters(userId, {
|
||||||
|
search: 'new',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('devrait mettre à jour partiellement les préférences de vue', async () => {
|
||||||
|
vi.mocked(prisma.user.upsert).mockResolvedValue({
|
||||||
|
id: userId,
|
||||||
|
email: `${userId}@towercontrol.local`,
|
||||||
|
name: 'Default User',
|
||||||
|
role: 'user',
|
||||||
|
password: 'default',
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.upsert).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
kanbanFilters: {},
|
||||||
|
viewPreferences: { theme: 'dark' },
|
||||||
|
columnVisibility: {},
|
||||||
|
jiraConfig: {},
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.userPreferences.update).mockResolvedValue({
|
||||||
|
userId,
|
||||||
|
viewPreferences: { theme: 'light' },
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
vi.mocked(prisma.$executeRaw).mockResolvedValue(0);
|
||||||
|
|
||||||
|
await userPreferencesService.updateViewPreferences(userId, {
|
||||||
|
theme: 'light',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(prisma.userPreferences.update).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user