Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
147 lines
4.7 KiB
TypeScript
147 lines
4.7 KiB
TypeScript
import { expect, test } from '@playwright/test'
|
|
|
|
import { authenticateAs } from '@/e2e/fixtures/session'
|
|
|
|
const conversationId = 'oversight-conversation-1'
|
|
const apiEnvelope = (data: unknown) => ({ success: true, data })
|
|
|
|
const participants = [
|
|
{
|
|
userId: 'user-1',
|
|
mobile: '09121234567',
|
|
firstName: 'سارا',
|
|
lastName: 'احمدی',
|
|
avatarUrl: null,
|
|
gender: 'female',
|
|
status: 'active',
|
|
joinedAt: '2026-08-01T10:00:00.000Z',
|
|
},
|
|
{
|
|
userId: 'user-2',
|
|
mobile: '09351234567',
|
|
firstName: 'امیر',
|
|
lastName: 'رضایی',
|
|
avatarUrl: null,
|
|
gender: 'male',
|
|
status: 'active',
|
|
joinedAt: '2026-08-01T10:01:00.000Z',
|
|
},
|
|
]
|
|
|
|
test.beforeEach(async ({ context, page }) => {
|
|
await authenticateAs(context, page, 'admin')
|
|
await page.route('**/api/v1/**', (route) =>
|
|
route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(apiEnvelope({ items: [], response: { page: 1, totalPages: 1 } })),
|
|
})
|
|
)
|
|
})
|
|
|
|
test('renders the admin thread like consumer chat while remaining strictly read-only', async ({ page }) => {
|
|
const oversightMethods: string[] = []
|
|
|
|
await page.route(`**/api/v1/admin/conversations/${conversationId}`, (route) => {
|
|
oversightMethods.push(route.request().method())
|
|
|
|
return route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(
|
|
apiEnvelope({
|
|
id: conversationId,
|
|
type: 'direct',
|
|
eventId: null,
|
|
eventTitle: null,
|
|
participantPreview: participants,
|
|
memberCount: 2,
|
|
preview: 'پاسخ کاربر دوم',
|
|
closesAt: null,
|
|
lastMessageAt: '2026-08-01T12:02:00.000Z',
|
|
createdAt: '2026-08-01T10:00:00.000Z',
|
|
})
|
|
),
|
|
})
|
|
})
|
|
await page.route(`**/api/v1/admin/conversations/${conversationId}/participants**`, (route) => {
|
|
oversightMethods.push(route.request().method())
|
|
|
|
return route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(
|
|
apiEnvelope({
|
|
items: participants,
|
|
response: { page: 1, pageSize: 100, totalItemsCount: 2, totalPages: 1 },
|
|
})
|
|
),
|
|
})
|
|
})
|
|
await page.route(`**/api/v1/admin/conversations/${conversationId}/messages**`, (route) => {
|
|
oversightMethods.push(route.request().method())
|
|
|
|
return route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(
|
|
apiEnvelope({
|
|
items: [
|
|
{
|
|
id: 'message-1',
|
|
conversationId,
|
|
senderId: 'user-1',
|
|
senderMobile: '09121234567',
|
|
senderFirstName: 'سارا',
|
|
senderLastName: 'احمدی',
|
|
senderAvatarUrl: null,
|
|
senderGender: 'female',
|
|
body: 'پیام کاربر اول',
|
|
imageUrl: null,
|
|
createdAt: '2026-08-01T12:00:00.000Z',
|
|
},
|
|
{
|
|
id: 'message-2',
|
|
conversationId,
|
|
senderId: 'user-2',
|
|
senderMobile: '09351234567',
|
|
senderFirstName: 'امیر',
|
|
senderLastName: 'رضایی',
|
|
senderAvatarUrl: null,
|
|
senderGender: 'male',
|
|
body: 'پاسخ کاربر دوم',
|
|
imageUrl: null,
|
|
createdAt: '2026-08-01T12:02:00.000Z',
|
|
},
|
|
],
|
|
response: {
|
|
olderCursor: null,
|
|
newerCursor: null,
|
|
hasMoreBefore: false,
|
|
hasMoreAfter: false,
|
|
},
|
|
})
|
|
),
|
|
})
|
|
})
|
|
|
|
await page.goto(`/chat-oversight/${conversationId}`)
|
|
|
|
await expect(page.getByText('حالت نظارت — فقط خواندنی')).toBeVisible()
|
|
await expect(page.getByText('گفتگوی خصوصی', { exact: true })).toBeVisible()
|
|
await expect(page.getByText('پیام کاربر اول')).toBeVisible()
|
|
await expect(page.getByText('پاسخ کاربر دوم')).toBeVisible()
|
|
const primaryBubble = page.locator('.justify-start').filter({ hasText: 'پیام کاربر اول' })
|
|
const secondaryBubble = page.locator('.justify-end').filter({ hasText: 'پاسخ کاربر دوم' })
|
|
|
|
await expect(primaryBubble).toBeVisible()
|
|
await expect(primaryBubble.getByText('سارا احمدی')).toBeVisible()
|
|
await expect(secondaryBubble).toBeVisible()
|
|
await expect(secondaryBubble.getByText('امیر رضایی')).toBeVisible()
|
|
|
|
await expect(page.getByPlaceholder('پیام خود را بنویسید...')).toHaveCount(0)
|
|
await expect(page.getByRole('button', { name: 'ارسال' })).toHaveCount(0)
|
|
expect(oversightMethods).toHaveLength(3)
|
|
expect(oversightMethods.every((method) => method === 'GET')).toBe(true)
|
|
})
|