import { expect, test } from './fixtures' test('supervisor creates an assigned task from Task Center', async ({ page }) => { let createdTask: Record | null = null const pageErrors: string[] = [] page.on('pageerror', (error) => pageErrors.push(error.message)) page.on('console', (message) => { if (message.type() === 'error') pageErrors.push(message.text()) }) await page.route('**/api/**', async (route) => { const request = route.request() const url = new URL(request.url()) if (!url.pathname.startsWith('/api/')) return route.continue() if (url.pathname === '/api/auth/me') { return route.fulfill({ json: { data: { id: 7, name: 'سرپرست تست', email: 'supervisor@example.test', phone: null, voip_extension: null, avatar: null, is_active: true, last_login_at: null, roles: ['supervisor'], team_id: 2, created_at: '', updated_at: '', permissions: ['view_team_tasks', 'create_tasks', 'assign_tasks', 'bulk_manage_tasks'], } } }) } if (url.pathname === '/api/users/assignable') { return route.fulfill({ json: { data: [{ id: 11, name: 'کارشناس تیم', avatar: null, role_label: 'کارشناس', team_label: 'فروش', is_active: true, open_tasks_count: 2, }] } }) } if (url.pathname === '/api/tasks' && request.method() === 'POST') { const body = request.postDataJSON() createdTask = task({ id: 31, subject: body.subject, assigned_to: body.assigned_to }) return route.fulfill({ status: 201, json: { data: createdTask } }) } if (url.pathname === '/api/tasks') { const tasks = createdTask ? [createdTask] : [] return route.fulfill({ json: { data: tasks, meta: { current_page: 1, last_page: 1, per_page: 20, total: tasks.length, from: tasks.length ? 1 : 0, to: tasks.length, } } }) } if (url.pathname === '/api/notifications/unread-count') return route.fulfill({ json: { data: { count: 0 } } }) if (url.pathname === '/api/settings/public') return route.fulfill({ json: { data: {} } }) return route.fulfill({ json: { data: [] } }) }) await page.goto('/tasks') await page.waitForTimeout(500) expect(pageErrors, `Browser errors: ${pageErrors.join(' | ')}`).toEqual([]) await expect(page).toHaveURL(/\/tasks$/) expect(await page.locator('body').innerText()).toContain('مرکز کارها') await page.getByRole('button', { name: 'کار جدید' }).click() await page.getByLabel('موضوع کار').fill('پیگیری قرارداد آزمایشی') await page.getByText('کارشناس تیم').click() await page.getByRole('button', { name: 'ادامه' }).click() await page.getByRole('button', { name: 'ایجاد کار' }).click() await expect(page.getByText('پیگیری قرارداد آزمایشی')).toBeVisible() }) test('agent opens an assignment notification, starts and completes the task, then supervisor sees it', async ({ page }) => { let role: 'agent' | 'supervisor' = 'agent' let status: 'open' | 'in_progress' | 'done' = 'open' let version = 1 let notificationRead = false await page.route('**/api/**', async (route) => { const request = route.request() const url = new URL(request.url()) if (!url.pathname.startsWith('/api/')) return route.continue() if (url.pathname === '/api/auth/me') { return route.fulfill({ json: { data: user(role, role === 'agent' ? ['view_own_tasks', 'edit_own_tasks', 'complete_tasks'] : ['view_team_tasks', 'edit_team_tasks', 'complete_tasks']) } }) } if (url.pathname === '/api/notifications') { return route.fulfill({ json: paginated([{ id: 81, title: 'کار جدید به شما تخصیص یافت', message: 'پیگیری مشتری', type: 'task_assigned', data: { url: '/tasks?task=31', task_id: 31 }, is_read: notificationRead, read_at: notificationRead ? new Date().toISOString() : null, created_at: new Date().toISOString(), }]) }) } if (url.pathname === '/api/notifications/81/read') { notificationRead = true return route.fulfill({ json: { data: { read_at: new Date().toISOString() } } }) } if (url.pathname === '/api/notifications/unread-count') { return route.fulfill({ json: { data: notificationRead ? 0 : 1 } }) } if (url.pathname === '/api/tasks/31/start') { status = 'in_progress'; version += 1 return route.fulfill({ json: { data: task({ id: 31, subject: 'پیگیری مشتری', status, version }) } }) } if (url.pathname === '/api/tasks/31/complete') { status = 'done'; version += 1 return route.fulfill({ json: { data: task({ id: 31, subject: 'پیگیری مشتری', status, version }) } }) } if (url.pathname === '/api/tasks/31') { return route.fulfill({ json: { data: task({ id: 31, subject: 'پیگیری مشتری', status, version }) } }) } if (url.pathname === '/api/tasks') { return route.fulfill({ json: paginated([task({ id: 31, subject: 'پیگیری مشتری', status, version })]) }) } if (url.pathname === '/api/users/assignable') return route.fulfill({ json: { data: [] } }) return route.fulfill({ json: { data: {} } }) }) await page.goto('/notifications') await expect(page.getByText('کار جدید به شما تخصیص یافت')).toBeVisible() await page.getByRole('link', { name: 'باز کردن' }).click() await expect(page.getByRole('dialog', { name: 'کار: پیگیری مشتری' })).toBeVisible() await page.getByRole('button', { name: 'شروع کار' }).click() await expect(page.getByRole('cell', { name: 'در حال انجام' })).toBeVisible() await page.getByRole('button', { name: 'مشاهده' }).click() await page.getByRole('button', { name: 'تکمیل کار' }).click() await page.getByRole('button', { name: 'ادامه و بررسی نهایی' }).click() await page.getByRole('button', { name: 'اجرای تغییر وضعیت' }).click() await expect(page.getByRole('cell', { name: 'انجام‌شده' })).toBeVisible() role = 'supervisor' await page.reload() await expect(page.getByRole('cell', { name: 'انجام‌شده' })).toBeVisible() }) test('agent adds a call note while out-of-scope task and call details stay closed', async ({ page }) => { let notes: Record[] = [] let denyDirectAccess = false const call = { id: 51, user_id: 11, lead_id: 21, direction: 'outbound', status: 'completed', duration_seconds: 45, result: 'answered', notes: null, started_at: null, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), agent: { id: 11, name: 'کارشناس تیم' }, lead: { id: 21, first_name: 'رضا', last_name: 'محمدی' }, } await page.route('**/api/**', async (route) => { const request = route.request() const url = new URL(request.url()) if (!url.pathname.startsWith('/api/')) return route.continue() if (url.pathname === '/api/auth/me') return route.fulfill({ json: { data: user('agent', ['view_own_calls', 'view_own_tasks', 'manage_call_notes']) } }) if (url.pathname === '/api/calls' && !denyDirectAccess) return route.fulfill({ json: paginated([call]) }) if (url.pathname === '/api/calls/51' && !denyDirectAccess) return route.fulfill({ json: { data: call } }) if (url.pathname === '/api/calls/51/notes' && request.method() === 'POST') { const body = request.postDataJSON() notes = [{ id: 91, content: body.content, type: body.type, visibility: body.visibility, is_pinned: false, author: { id: 11, name: 'کارشناس تیم' }, edited_at: null, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), capabilities: { edit: true, delete: true, pin: false } }] return route.fulfill({ status: 201, json: { data: notes[0] } }) } if (url.pathname === '/api/calls/51/notes') return route.fulfill({ json: { data: notes } }) if (url.pathname === '/api/tasks/999' || url.pathname === '/api/calls/999') { return route.fulfill({ status: 403, json: { message: 'Forbidden' } }) } if (url.pathname === '/api/tasks') return route.fulfill({ json: paginated([]) }) if (url.pathname === '/api/calls' && denyDirectAccess) return route.fulfill({ json: paginated([{ ...call, id: 999 }]) }) if (url.pathname === '/api/notifications/unread-count') return route.fulfill({ json: { data: 0 } }) return route.fulfill({ json: { data: {} } }) }) await page.goto('/calls') await page.getByText('رضا محمدی').click() await page.getByLabel('یادداشت جدید تماس').fill('تعهد به ارسال قرارداد') await page.getByRole('button', { name: 'ثبت یادداشت' }).click() await expect(page.getByText('تعهد به ارسال قرارداد')).toBeVisible() denyDirectAccess = true await page.goto('/tasks?task=999') await expect(page.getByRole('dialog')).toHaveCount(0) await page.goto('/calls') await page.getByText('رضا محمدی').click() await expect(page.getByRole('dialog')).toHaveCount(0) }) function task(overrides: Record) { return { id: 1, subject: 'کار', description: null, taskable_type: null, taskable_id: null, taskable: null, assigned_to: null, assignee: { id: 11, name: 'کارشناس تیم' }, assigned_by: 7, assigner: { id: 7, name: 'سرپرست تست' }, created_by: 7, creator: { id: 7, name: 'سرپرست تست' }, priority: 'normal', status: 'open', due_at: null, started_at: null, completed_at: null, reminder_at: null, parent_task_id: null, parent: null, estimated_minutes: null, visibility: 'team', version: 1, is_overdue: false, capabilities: { update: true, assign: true, transition: true, delete: true }, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), ...overrides, } } function paginated(items: Record[]) { return { data: items, meta: { current_page: 1, last_page: 1, per_page: 20, total: items.length, from: items.length ? 1 : 0, to: items.length } } } function user(role: 'agent' | 'supervisor', permissions: string[]) { return { id: role === 'agent' ? 11 : 7, name: role === 'agent' ? 'کارشناس تیم' : 'سرپرست تست', email: `${role}@example.test`, phone: null, voip_extension: null, avatar: null, is_active: true, last_login_at: null, roles: [role], permissions, team_id: 2, created_at: '', updated_at: '', } }