mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-14 23:20:19 +08:00
Align admin user usage timing samples
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
|
||||||
const { getMock, cachedRequestMock, dedupedRequestMock, buildCacheKeyMock } = vi.hoisted(() => ({
|
const { getMock, cachedRequestMock, dedupedRequestMock, buildCacheKeyMock } = vi.hoisted(() => ({
|
||||||
getMock: vi.fn(),
|
getMock: vi.fn(),
|
||||||
@@ -29,6 +29,10 @@ describe('usageApi contract alignment', () => {
|
|||||||
buildCacheKeyMock.mockClear()
|
buildCacheKeyMock.mockClear()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.restoreAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
it('loads current-user usage records from the Rust usage endpoint and normalizes pagination', async () => {
|
it('loads current-user usage records from the Rust usage endpoint and normalizes pagination', async () => {
|
||||||
getMock.mockResolvedValueOnce({
|
getMock.mockResolvedValueOnce({
|
||||||
data: {
|
data: {
|
||||||
@@ -115,6 +119,53 @@ describe('usageApi contract alignment', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('captures admin user usage server timing when the records request resolves', async () => {
|
||||||
|
let now = 1_000
|
||||||
|
vi.spyOn(Date, 'now').mockImplementation(() => now)
|
||||||
|
|
||||||
|
let resolveStats: ((value: unknown) => void) | null = null
|
||||||
|
getMock.mockImplementation((url: string) => {
|
||||||
|
if (url === '/api/admin/usage/stats') {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
resolveStats = resolve
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (url === '/api/admin/usage/records') {
|
||||||
|
return Promise.resolve({
|
||||||
|
data: {
|
||||||
|
server_now_unix_ms: 10_050,
|
||||||
|
records: [{ id: 'record-3' }],
|
||||||
|
total: 1,
|
||||||
|
limit: 25,
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`unexpected url: ${url}`))
|
||||||
|
})
|
||||||
|
|
||||||
|
const resultPromise = usageApi.getUserUsage('user-123', { page: 1, page_size: 25 })
|
||||||
|
now = 1_100
|
||||||
|
await Promise.resolve()
|
||||||
|
now = 20_000
|
||||||
|
resolveStats?.({
|
||||||
|
data: {
|
||||||
|
total_requests: 1,
|
||||||
|
total_tokens: 10,
|
||||||
|
total_cost: 0.1,
|
||||||
|
avg_response_time: 500,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await resultPromise
|
||||||
|
|
||||||
|
expect(result.server_timing).toEqual({
|
||||||
|
server_now_unix_ms: 10_050,
|
||||||
|
client_send_unix_ms: 1_000,
|
||||||
|
client_receive_unix_ms: 1_100,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('uses an extended timeout and cache bypass option for admin analytics', async () => {
|
it('uses an extended timeout and cache bypass option for admin analytics', async () => {
|
||||||
getMock
|
getMock
|
||||||
.mockResolvedValueOnce({
|
.mockResolvedValueOnce({
|
||||||
|
|||||||
@@ -458,17 +458,21 @@ export const usageApi = {
|
|||||||
}> {
|
}> {
|
||||||
const statsParams = buildAdminUsageStatsParams(userId, filters)
|
const statsParams = buildAdminUsageStatsParams(userId, filters)
|
||||||
const { params: recordParams } = buildAdminUsageRecordParams(userId, filters)
|
const { params: recordParams } = buildAdminUsageRecordParams(userId, filters)
|
||||||
const clientSendUnixMs = beginServerTimingSample()
|
const statsRequest = apiClient.get<UsageStats>('/api/admin/usage/stats', { params: statsParams })
|
||||||
|
const recordsClientSendUnixMs = beginServerTimingSample()
|
||||||
|
const recordsRequest = apiClient
|
||||||
|
.get<UsageListResponse>('/api/admin/usage/records', { params: recordParams })
|
||||||
|
.then(response => withServerTiming(response.data, recordsClientSendUnixMs))
|
||||||
|
|
||||||
const [statsResponse, recordsResponse] = await Promise.all([
|
const [statsResponse, recordsResponse] = await Promise.all([
|
||||||
apiClient.get<UsageStats>('/api/admin/usage/stats', { params: statsParams }),
|
statsRequest,
|
||||||
apiClient.get<UsageListResponse>('/api/admin/usage/records', { params: recordParams }),
|
recordsRequest,
|
||||||
])
|
])
|
||||||
const recordsPayload = withServerTiming(recordsResponse.data, clientSendUnixMs)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
records: assertUsageRecords(recordsPayload.records),
|
records: assertUsageRecords(recordsResponse.records),
|
||||||
stats: statsResponse.data,
|
stats: statsResponse.data,
|
||||||
...(recordsPayload.server_timing ? { server_timing: recordsPayload.server_timing } : {}),
|
...(recordsResponse.server_timing ? { server_timing: recordsResponse.server_timing } : {}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user