import React from 'react'; import { render, fireEvent, waitFor } from '@testing-library/react-native'; import { BeneficiaryMenu } from '@/components/ui/BeneficiaryMenu'; import { router } from 'expo-router'; // Mock expo-router jest.mock('expo-router', () => ({ router: { push: jest.fn(), }, })); describe('BeneficiaryMenu - Role-based Permissions', () => { beforeEach(() => { jest.clearAllMocks(); }); describe('Custodian Role', () => { it('shows all menu items except current page', () => { const { getByText } = render( ); // Open menu fireEvent.press(getByText('☰')); // This might need adjustment based on actual icon // Custodian should see all items except Dashboard (current page) expect(getByText('Edit')).toBeTruthy(); expect(getByText('Access')).toBeTruthy(); expect(getByText('Subscription')).toBeTruthy(); expect(getByText('Sensors')).toBeTruthy(); expect(getByText('Remove')).toBeTruthy(); }); it('allows editing beneficiary profile', async () => { const onEdit = jest.fn(); const { getByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Click Edit const editButton = getByText('Edit'); fireEvent.press(editButton); await waitFor(() => { expect(onEdit).toHaveBeenCalled(); }); }); it('allows removing beneficiary', () => { const onRemove = jest.fn(); const { getByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Click Remove const removeButton = getByText('Remove'); fireEvent.press(removeButton); expect(onRemove).toHaveBeenCalled(); }); }); describe('Guardian Role', () => { it('shows all menu items except Remove', () => { const { getByText, queryByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Guardian should see all except Remove expect(getByText('Dashboard')).toBeTruthy(); expect(getByText('Edit')).toBeTruthy(); expect(getByText('Access')).toBeTruthy(); expect(getByText('Subscription')).toBeTruthy(); expect(getByText('Sensors')).toBeTruthy(); expect(queryByText('Remove')).toBeNull(); // Remove should NOT be visible }); it('allows editing beneficiary', () => { const onEdit = jest.fn(); const { getByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Click Edit const editButton = getByText('Edit'); fireEvent.press(editButton); expect(onEdit).toHaveBeenCalled(); }); it('can navigate to access management', () => { const { getByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Click Access const accessButton = getByText('Access'); fireEvent.press(accessButton); expect(router.push).toHaveBeenCalledWith('/(tabs)/beneficiaries/42/share'); }); }); describe('Caretaker Role', () => { it('shows only Dashboard, Edit, and Sensors', () => { const { getByText, queryByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Caretaker should see limited items expect(getByText('Dashboard')).toBeTruthy(); expect(getByText('Edit')).toBeTruthy(); expect(getByText('Sensors')).toBeTruthy(); // These should NOT be visible expect(queryByText('Access')).toBeNull(); expect(queryByText('Subscription')).toBeNull(); expect(queryByText('Remove')).toBeNull(); }); it('allows editing (nickname only)', () => { const onEdit = jest.fn(); const { getByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Click Edit - should be visible even for caretaker const editButton = getByText('Edit'); fireEvent.press(editButton); expect(onEdit).toHaveBeenCalled(); }); it('cannot access subscription management', () => { const { queryByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Subscription should NOT be visible expect(queryByText('Subscription')).toBeNull(); }); it('cannot remove beneficiary', () => { const { queryByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Remove should NOT be visible expect(queryByText('Remove')).toBeNull(); }); }); describe('Default Role (Security)', () => { it('defaults to caretaker permissions when role not provided', () => { const { getByText, queryByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Should have minimum permissions (caretaker) expect(getByText('Dashboard')).toBeTruthy(); expect(getByText('Edit')).toBeTruthy(); expect(getByText('Sensors')).toBeTruthy(); // Should NOT have elevated permissions expect(queryByText('Access')).toBeNull(); expect(queryByText('Subscription')).toBeNull(); expect(queryByText('Remove')).toBeNull(); }); }); describe('Navigation', () => { it('navigates to correct routes', () => { const { getByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Test Dashboard navigation fireEvent.press(getByText('Dashboard')); expect(router.push).toHaveBeenCalledWith('/(tabs)/beneficiaries/123'); // Reopen menu fireEvent.press(menuButton); // Test Subscription navigation fireEvent.press(getByText('Subscription')); expect(router.push).toHaveBeenCalledWith('/(tabs)/beneficiaries/123/subscription'); // Reopen menu fireEvent.press(menuButton); // Test Sensors navigation fireEvent.press(getByText('Sensors')); expect(router.push).toHaveBeenCalledWith('/(tabs)/beneficiaries/123/equipment'); }); it('navigates with edit param when onEdit not provided', () => { const { getByText, getByTestId } = render( ); // Open menu const menuButton = getByTestId('menu-button'); fireEvent.press(menuButton); // Click Edit without custom handler fireEvent.press(getByText('Edit')); expect(router.push).toHaveBeenCalledWith('/(tabs)/beneficiaries/456?edit=true'); }); }); });