import { describe, it, expect, beforeEach } from 'vitest' import { renderHook } from '@testing-library/react' import { usePermissions } from './usePermissions' import { useAuthStore } from '@/store/authStore' import type { User } from '@/types' function makeUser(overrides: Partial = {}): User { return { id: 'user-1', email: 'test@example.com', name: 'Test User', role: 'engineer', is_super_admin: false, account_id: 'acct-1', account_role: 'engineer', created_at: '2026-01-01T00:00:00Z', last_login: null, ...overrides, } } describe('usePermissions', () => { beforeEach(() => { useAuthStore.setState({ user: null, token: null, isAuthenticated: false }) }) describe('when not authenticated', () => { it('defaults to viewer role', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.effectiveRole).toBe('viewer') expect(result.current.isViewer).toBe(true) }) it('cannot create trees', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canCreateTrees).toBe(false) }) it('cannot create steps', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canCreateSteps).toBe(false) }) it('cannot delete trees', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canDeleteTree()).toBe(false) }) }) describe('viewer role', () => { beforeEach(() => { useAuthStore.setState({ user: makeUser({ role: 'viewer', account_role: 'viewer' }) }) }) it('has viewer effective role', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.effectiveRole).toBe('viewer') expect(result.current.isViewer).toBe(true) }) it('cannot create trees', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canCreateTrees).toBe(false) }) it('cannot edit any tree', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditTree({ author_id: 'user-1' })).toBe(false) }) it('cannot manage categories', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canManageCategories).toBe(false) }) }) describe('engineer role', () => { beforeEach(() => { useAuthStore.setState({ user: makeUser() }) }) it('has engineer effective role', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.effectiveRole).toBe('engineer') expect(result.current.isEngineer).toBe(true) }) it('can create trees', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canCreateTrees).toBe(true) }) it('can edit own tree', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditTree({ author_id: 'user-1' })).toBe(true) }) it('cannot edit other user tree', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditTree({ author_id: 'other-user' })).toBe(false) }) it('cannot delete trees', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canDeleteTree()).toBe(false) }) it('can edit own step', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditStep({ created_by: 'user-1' })).toBe(true) }) it('cannot edit other step', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditStep({ created_by: 'other' })).toBe(false) }) it('cannot manage categories', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canManageCategories).toBe(false) }) }) describe('owner role', () => { beforeEach(() => { useAuthStore.setState({ user: makeUser({ account_role: 'owner' }) }) }) it('has owner effective role', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.effectiveRole).toBe('owner') expect(result.current.isAccountOwner).toBe(true) }) it('can edit account tree', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditTree({ author_id: 'other', account_id: 'acct-1' })).toBe(true) }) it('cannot edit other account tree', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditTree({ author_id: 'other', account_id: 'other-acct' })).toBe(false) }) it('can manage categories', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canManageCategories).toBe(true) }) it('cannot manage global categories', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canManageGlobalCategories).toBe(false) }) }) describe('super admin', () => { beforeEach(() => { useAuthStore.setState({ user: makeUser({ is_super_admin: true }) }) }) it('has super_admin effective role', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.effectiveRole).toBe('super_admin') expect(result.current.isSuperAdmin).toBe(true) }) it('can edit any tree', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditTree({ author_id: 'anyone', account_id: 'any' })).toBe(true) }) it('can delete trees', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canDeleteTree()).toBe(true) }) it('can edit any step', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canEditStep({ created_by: 'anyone' })).toBe(true) }) it('can manage global categories', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canManageGlobalCategories).toBe(true) }) it('can manage account', () => { const { result } = renderHook(() => usePermissions()) expect(result.current.canManageAccount).toBe(true) }) }) })