329 lines
10 KiB
TypeScript
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);
|
|
});
|
|
});
|