fix(frontend): restore member self-assignment for shifts and tasks
All checks were successful
CI Pipeline / Backend Build & Test (push) Successful in 1m12s
CI Pipeline / Frontend Lint, Test & Build (push) Successful in 35s
CI Pipeline / Infrastructure Validation (push) Successful in 4s
CI Pipeline / Backend Build & Test (pull_request) Successful in 52s
CI Pipeline / Frontend Lint, Test & Build (pull_request) Successful in 33s
CI Pipeline / Infrastructure Validation (pull_request) Successful in 4s

Root Cause:
- Shift: Next.js 16.1.6 incompatible rewrite pattern caused runtime SyntaxError
- Task: Missing self-assignment UI for member role

Fix:
- Updated next.config.ts rewrite pattern from regex to wildcard syntax
- Added "Assign to Me" button to task detail page with useSession integration
- Added test coverage for self-assignment behavior with session mocks

Testing:
- Lint:  PASS (ESLint v9)
- Tests:  47/47 PASS (Vitest v4.0.18)
- Build:  PASS (Next.js 16.1.6, 12 routes)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
WorkClub Automation
2026-03-08 19:07:19 +01:00
parent 785502f113
commit add4c4c627
5 changed files with 159 additions and 2 deletions

View File

@@ -11,6 +11,13 @@ vi.mock('next/navigation', () => ({
})),
}));
vi.mock('next-auth/react', () => ({
useSession: vi.fn(() => ({
data: { user: { id: 'user-123' } },
status: 'authenticated',
})),
}));
vi.mock('@/hooks/useTasks', () => ({
useTask: vi.fn(),
useUpdateTask: vi.fn(),
@@ -74,4 +81,63 @@ describe('TaskDetailPage', () => {
expect(screen.getByText('Mark as Done')).toBeInTheDocument();
expect(screen.getByText('Back to InProgress')).toBeInTheDocument();
});
it('renders Assign to Me button when task unassigned and session exists', async () => {
(useTask as ReturnType<typeof vi.fn>).mockReturnValue({
data: {
id: '1',
title: 'Task 1',
status: 'Open',
assigneeId: null,
description: 'Desc',
createdAt: '2024-01-01',
updatedAt: '2024-01-01'
},
isLoading: false,
error: null,
});
const params = Promise.resolve({ id: '1' });
await act(async () => {
render(<TaskDetailPage params={params} />);
});
expect(screen.getByText('Assign to Me')).toBeInTheDocument();
});
it('calls updateTask with assigneeId when Assign to Me clicked', async () => {
const mockMutate = vi.fn();
(useTask as ReturnType<typeof vi.fn>).mockReturnValue({
data: {
id: '1',
title: 'Task 1',
status: 'Open',
assigneeId: null,
description: 'Desc',
createdAt: '2024-01-01',
updatedAt: '2024-01-01'
},
isLoading: false,
error: null,
});
(useUpdateTask as ReturnType<typeof vi.fn>).mockReturnValue({
mutate: mockMutate,
isPending: false,
});
const params = Promise.resolve({ id: '1' });
await act(async () => {
render(<TaskDetailPage params={params} />);
});
const button = screen.getByText('Assign to Me');
await act(async () => {
button.click();
});
expect(mockMutate).toHaveBeenCalledWith({
id: '1',
data: { assigneeId: 'user-123' },
});
});
});