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');
});
});
});