v1.12.29 접속자 요약과 회원 작성 이력 및 댓글 표시 정리
This commit is contained in:
@@ -401,6 +401,33 @@ test('CSP 수집은 IP 해시 기준 분당 요청 상한을 적용한다', asyn
|
||||
expect(Number(limitedResponse.headers()['retry-after'])).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
test('실시간 접속 요약은 표시 제한 밖의 활성 탭까지 집계하고 만료 탭을 제외한다', async ({ request: anonymousApi }) => {
|
||||
expect((await anonymousApi.get('/admin/api/analytics/realtime')).status()).toBe(401)
|
||||
try {
|
||||
await database`
|
||||
INSERT INTO analytics_active_sessions (session_hash, path, ip_address)
|
||||
SELECT 'realtime-api-test-' || value, '/post/shared', '198.51.100.' || value
|
||||
FROM generate_series(1, 21) AS value
|
||||
`
|
||||
await database`
|
||||
INSERT INTO analytics_active_sessions (session_hash, path, ip_address, last_seen_at)
|
||||
VALUES
|
||||
('realtime-api-test-extra-1', '/post/shared', '198.51.100.1', now()),
|
||||
('realtime-api-test-extra-2', '/post/another', '198.51.100.1', now()),
|
||||
('realtime-api-test-expired', '/post/expired', '198.51.100.99', now() - interval '2 minutes')
|
||||
`
|
||||
const response = await adminApi.get('/admin/api/analytics/realtime?limit=20')
|
||||
expect(response.status()).toBe(200)
|
||||
const result = await response.json()
|
||||
expect(result.summary).toMatchObject({ onlineNow: 21, anonymousNow: 21, loggedInNow: 0, openPageCount: 23 })
|
||||
expect(result.sessions).toHaveLength(20)
|
||||
expect(result.sessions.find((session) => session.ipAddress === '198.51.100.1')).toMatchObject({ pageCount: 3 })
|
||||
expect(result.sessions.some((session) => session.ipAddress === '198.51.100.99')).toBe(false)
|
||||
} finally {
|
||||
await database`DELETE FROM analytics_active_sessions WHERE session_hash LIKE 'realtime-api-test-%'`
|
||||
}
|
||||
})
|
||||
|
||||
test('미디어 카탈로그 reconcile과 DB 목록 계약 및 fallback을 유지한다', async () => {
|
||||
const uploadRoot = process.env.SORI_TEST_UPLOAD_ROOT
|
||||
const mediaDirectory = join(uploadRoot, 'posts', 'catalog-api-test')
|
||||
|
||||
@@ -33,10 +33,10 @@ test('멤버 통합 작성 이력의 종류 필터·검색·페이지와 대시
|
||||
await expect(list.locator('.admin-member-activity__post').first()).toHaveAttribute('href', '/post/comments-ui-test#comments')
|
||||
await list.getByRole('button', { name: '다음 페이지' }).click()
|
||||
await expect(items).toHaveCount(2)
|
||||
await expect(list.locator('.admin-member-activity__kind')).toHaveText(['댓글', '게시글'])
|
||||
await expect(list.getByRole('columnheader')).toHaveText(['게시글', '내용', '작성일'])
|
||||
await expect(list.locator('.admin-member-activity__body').last()).toHaveText('본문')
|
||||
await list.getByLabel('작성 종류').selectOption('comment')
|
||||
await expect(items).toHaveCount(10)
|
||||
await expect(list.locator('.admin-member-activity__kind').first()).toHaveText('댓글')
|
||||
await list.getByRole('button', { name: '다음 페이지' }).click()
|
||||
await expect(items).toHaveCount(1)
|
||||
await list.getByLabel('작성한 글 검색').fill('화면 댓글 0')
|
||||
@@ -48,7 +48,6 @@ test('멤버 통합 작성 이력의 종류 필터·검색·페이지와 대시
|
||||
await list.getByLabel('작성한 글 검색').fill('')
|
||||
await list.getByRole('button', { name: '검색', exact: true }).click()
|
||||
await expect(items).toHaveCount(1)
|
||||
await expect(list.locator('.admin-member-activity__kind')).toHaveText('게시글')
|
||||
await expect(list.locator('.admin-member-activity__body')).toHaveText('본문')
|
||||
await list.getByLabel('작성 종류').selectOption('all')
|
||||
await expect(items).toHaveCount(10)
|
||||
@@ -59,6 +58,11 @@ test('멤버 통합 작성 이력의 종류 필터·검색·페이지와 대시
|
||||
await page.goto('/admin')
|
||||
await expect(page.locator('.admin-comment-list__item')).toHaveCount(5)
|
||||
await expect(page.locator('.admin-comment-list__body').first()).toHaveText('화면 댓글 10')
|
||||
const recentComment = page.locator('.admin-comment-list__item').first()
|
||||
expect(await recentComment.locator(':scope > *').evaluateAll((elements) => elements.map((element) => element.className.split(' ')[0]))).toEqual([
|
||||
'admin-comment-list__post', 'admin-comment-list__body', 'admin-comment-list__author', 'admin-comment-list__time'
|
||||
])
|
||||
await expect(recentComment.locator('.admin-comment-list__author')).toHaveAttribute('href', `/admin/members/${admin.userId}`)
|
||||
await expect(page.locator('.admin-dashboard__csp')).toHaveCount(0)
|
||||
const recentBox = await page.locator('.admin-comment-list').boundingBox()
|
||||
expect(recentBox.height).toBeLessThan(250)
|
||||
|
||||
@@ -24,16 +24,25 @@ test('대시보드 숫자·섹션 순서와 한 줄 접속자 페이지 목록
|
||||
...[2, 3, 4].map((index) => ({ key: String(index), path: `/post/page-${index}`, postTitle: `열린 페이지 ${index}`, lastSeenAt: `2026-10-21T0${index}:00:00Z` }))
|
||||
]
|
||||
}
|
||||
await page.route('**/admin/api/analytics/realtime?*', (route) => route.fulfill({ json: { summary: { onlineNow: 1234 }, sessions: [session] } }))
|
||||
const singlePageSession = {
|
||||
activeKey: 'single-page-visitor', isLoggedIn: false, ipAddress: '198.51.100.2', durationSeconds: 60, pageCount: 1,
|
||||
pages: [{ key: 'single', path: '/post/single', postTitle: '한 페이지만 보는 방문자' }]
|
||||
}
|
||||
await page.route('**/admin/api/analytics/realtime?*', (route) => route.fulfill({ json: { summary: { onlineNow: 1234, openPageCount: 12345 }, sessions: [session, singlePageSession] } }))
|
||||
await page.getByRole('link', { name: '대시보드', exact: true }).click()
|
||||
await expect(page.locator('.admin-dashboard__summary')).toContainText('10,413')
|
||||
await expect(page.locator('.admin-dashboard__summary')).toContainText('1,234')
|
||||
await expect(page.locator('.admin-dashboard__traffic-total')).toContainText('12,345')
|
||||
const sections = await page.locator('.admin-dashboard__body > section').evaluateAll((elements) => elements.map((element) => element.className))
|
||||
expect(sections.map((value) => value.match(/admin-dashboard__(summary|adsense|charts|selected-detail|recent-comments|live)\b/)[1])).toEqual(['summary', 'adsense', 'charts', 'selected-detail', 'recent-comments', 'live'])
|
||||
const visitor = page.locator('.admin-dashboard__live-item')
|
||||
await expect(page.locator('.admin-dashboard__live-count')).toHaveText('전체 1,234명 중 2명 표시 · 열린 화면 12,345개')
|
||||
const visitor = page.locator('.admin-dashboard__live-item').first()
|
||||
await expect(visitor).toContainText('가장 최근 페이지')
|
||||
await expect(visitor).toContainText('외 4개')
|
||||
await expect(visitor.locator('.admin-realtime-pages__extra')).toHaveCSS('color', 'rgb(37, 99, 235)')
|
||||
await expect(visitor.locator('.admin-realtime-pages__extra-number')).toHaveText('4')
|
||||
await expect(visitor.locator('.admin-realtime-pages__extra-number')).toHaveCSS('font-weight', '700')
|
||||
await expect(visitor.locator('.admin-dashboard__live-duration')).toHaveAttribute('title', /백그라운드 시간을 포함하며 최대 30분/)
|
||||
expect((await visitor.boundingBox()).height).toBeLessThan(45)
|
||||
const trigger = visitor.getByRole('button', { name: '열린 페이지 목록', exact: true })
|
||||
await trigger.hover()
|
||||
@@ -49,4 +58,10 @@ test('대시보드 숫자·섹션 순서와 한 줄 접속자 페이지 목록
|
||||
await expect(popover).toBeVisible()
|
||||
await popover.getByRole('button', { name: '열린 페이지 목록 닫기' }).click()
|
||||
await expect(popover).toHaveCount(0)
|
||||
const singleVisitor = page.locator('.admin-dashboard__live-item').last()
|
||||
await singleVisitor.locator('.admin-realtime-pages__single').hover()
|
||||
await expect(singleVisitor.getByRole('button', { name: '열린 페이지 목록', exact: true })).toHaveCount(0)
|
||||
await expect(singleVisitor.locator('.admin-realtime-pages__extra')).toHaveCount(0)
|
||||
await expect(singleVisitor.getByRole('link', { name: '한 페이지만 보는 방문자' })).toHaveAttribute('href', '/post/single')
|
||||
await expect(popover).toHaveCount(0)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user