veza/apps/web/src/features/playlists/hooks/usePlaylistPermissions.test.tsx

329 lines
10 KiB
TypeScript

/**
* Tests pour le hook usePlaylistPermissions
* T0485: Create Playlist Permission Frontend Checks
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { renderHook } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { usePlaylistPermissions } from './usePlaylistPermissions';
import { useCollaborators } from './usePlaylist';
import { useAuthStore } from '@/features/auth/store/authStore';
import type { Playlist } from '../types';
// Mock des hooks
vi.mock('./usePlaylist', () => ({
useCollaborators: vi.fn(),
usePlaylist: vi.fn(),
useCreatePlaylist: vi.fn(),
useUpdatePlaylist: vi.fn(),
useDeletePlaylist: vi.fn(),
usePlaylists: vi.fn(),
useAddCollaborator: vi.fn(),
useRemoveCollaborator: vi.fn(),
useUpdateCollaboratorPermission: vi.fn(),
}));
vi.mock('@/features/auth/store/authStore', () => ({
useAuthStore: vi.fn((selector) => {
const state = { user: { id: 1 } };
return selector(state);
}),
}));
function createWrapper() {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
});
return ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
}
const mockPlaylist: Playlist = {
id: 1,
user_id: 1,
title: 'Test Playlist',
description: 'Test Description',
is_public: false,
cover_url: null,
track_count: 0,
created_at: '2024-01-01T00:00:00Z',
updated_at: '2024-01-01T00:00:00Z',
tracks: [],
};
describe('usePlaylistPermissions', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should return all false permissions when playlist is null', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 1 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(null), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(false);
expect(result.current.canDelete).toBe(false);
expect(result.current.canAddTracks).toBe(false);
expect(result.current.canRemoveTracks).toBe(false);
expect(result.current.canManageCollaborators).toBe(false);
expect(result.current.canRead).toBe(false);
expect(result.current.isOwner).toBe(false);
});
it('should return all false permissions when playlist is undefined', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 1 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(undefined), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(false);
expect(result.current.canDelete).toBe(false);
expect(result.current.canAddTracks).toBe(false);
expect(result.current.canRemoveTracks).toBe(false);
expect(result.current.canManageCollaborators).toBe(false);
expect(result.current.canRead).toBe(false);
expect(result.current.isOwner).toBe(false);
});
it('should return true for all permissions when user is owner', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 1 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(mockPlaylist), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(true);
expect(result.current.canDelete).toBe(true);
expect(result.current.canAddTracks).toBe(true);
expect(result.current.canRemoveTracks).toBe(true);
expect(result.current.canManageCollaborators).toBe(true);
expect(result.current.canRead).toBe(true);
expect(result.current.isOwner).toBe(true);
});
it('should return correct permissions for collaborator with admin permission', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 4 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [
{
id: 1,
playlist_id: 1,
user_id: 4,
permission: 'admin',
created_at: '2024-01-01T00:00:00Z',
updated_at: '2024-01-01T00:00:00Z',
},
],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(mockPlaylist), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(true);
expect(result.current.canDelete).toBe(false);
expect(result.current.canAddTracks).toBe(true);
expect(result.current.canRemoveTracks).toBe(true);
expect(result.current.canManageCollaborators).toBe(false);
expect(result.current.canRead).toBe(true);
expect(result.current.isOwner).toBe(false);
});
it('should return correct permissions for collaborator with write permission', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 3 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [
{
id: 1,
playlist_id: 1,
user_id: 3,
permission: 'write',
created_at: '2024-01-01T00:00:00Z',
updated_at: '2024-01-01T00:00:00Z',
},
],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(mockPlaylist), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(true);
expect(result.current.canDelete).toBe(false);
expect(result.current.canAddTracks).toBe(true);
expect(result.current.canRemoveTracks).toBe(true);
expect(result.current.canManageCollaborators).toBe(false);
expect(result.current.canRead).toBe(true);
expect(result.current.isOwner).toBe(false);
});
it('should return correct permissions for collaborator with read permission', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 2 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [
{
id: 1,
playlist_id: 1,
user_id: 2,
permission: 'read',
created_at: '2024-01-01T00:00:00Z',
updated_at: '2024-01-01T00:00:00Z',
},
],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(mockPlaylist), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(false);
expect(result.current.canDelete).toBe(false);
expect(result.current.canAddTracks).toBe(false);
expect(result.current.canRemoveTracks).toBe(false);
expect(result.current.canManageCollaborators).toBe(false);
expect(result.current.canRead).toBe(true);
expect(result.current.isOwner).toBe(false);
});
it('should return false permissions for non-collaborator on private playlist', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 5 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(mockPlaylist), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(false);
expect(result.current.canDelete).toBe(false);
expect(result.current.canAddTracks).toBe(false);
expect(result.current.canRemoveTracks).toBe(false);
expect(result.current.canManageCollaborators).toBe(false);
expect(result.current.canRead).toBe(false);
expect(result.current.isOwner).toBe(false);
});
it('should return canRead true for public playlist even for non-collaborator', () => {
const publicPlaylist: Playlist = {
...mockPlaylist,
is_public: true,
};
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: { id: 5 } };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(
() => usePlaylistPermissions(publicPlaylist),
{
wrapper: createWrapper(),
},
);
expect(result.current.canRead).toBe(true);
expect(result.current.canEdit).toBe(false);
expect(result.current.canDelete).toBe(false);
});
it('should return false permissions when user is null', () => {
vi.mocked(useAuthStore).mockImplementation((selector: any) => {
const state = { user: null };
return selector(state);
});
vi.mocked(useCollaborators).mockReturnValue({
data: [],
isLoading: false,
isError: false,
error: null,
refetch: vi.fn(),
} as any);
const { result } = renderHook(() => usePlaylistPermissions(mockPlaylist), {
wrapper: createWrapper(),
});
expect(result.current.canEdit).toBe(false);
expect(result.current.canDelete).toBe(false);
expect(result.current.canAddTracks).toBe(false);
expect(result.current.canRemoveTracks).toBe(false);
expect(result.current.canManageCollaborators).toBe(false);
expect(result.current.canRead).toBe(false);
expect(result.current.isOwner).toBe(false);
});
});