agent-exec transport ce569400d5a47d09bea58e39b89b8843/8043305a983f
This commit is contained in:
+1
-1
@@ -817,7 +817,7 @@ export const store = {
|
||||
}
|
||||
// U4/R5:已保存页面从权威快照重载(刷新/断线恢复;事件流只做增量投影)。
|
||||
// surfaceList 返回扁平 SurfaceMeta,不可写入 surfaces;必须经 surfaceGet 水合为 Snapshot。
|
||||
api.projectSurfaces(state.currentProjectId ?? '').then(list => { if (state.currentConvId === convId && conversationEpoch === epoch) set({ projectSurfaces: list ?? [] }) }).catch(() => {})
|
||||
if (state.currentProjectId) api.projectSurfaces(state.currentProjectId).then(list => { if (state.currentConvId === convId && conversationEpoch === epoch) set({ projectSurfaces: list ?? [] }) }).catch(() => {})
|
||||
api.surfaceList(convId).then(async list => {
|
||||
if (state.currentConvId !== convId || conversationEpoch !== epoch) return
|
||||
const metas = list ?? []
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// ps-frontend-no-project-surfaces-r2:openConversation 在 state.currentProjectId 为空时
|
||||
// 不再触发 /api/projects/<id>/surfaces 请求(避免被移除项目成员打开历史会话时的 404 噪音)。
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { api } from '../src/api'
|
||||
import { store } from '../src/store'
|
||||
import type { Conversation, Message, SurfaceMeta } from '../src/contracts'
|
||||
|
||||
function detail(id: string) {
|
||||
return {
|
||||
conversation: { id, projectId: '', title: id, createdAt: '', updatedAt: '' } as Conversation,
|
||||
messages: [] as Message[], runs: [], activeHitl: [], lastSeq: 0, resumeSeq: 0,
|
||||
}
|
||||
}
|
||||
class FakeEventSource {
|
||||
onopen = null
|
||||
onerror = null
|
||||
onmessage = null
|
||||
addEventListener() {}
|
||||
close() {}
|
||||
}
|
||||
|
||||
let projectSurfacesSpy: ReturnType<typeof vi.spyOn>
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.stubGlobal('EventSource', FakeEventSource)
|
||||
vi.spyOn(api, 'conversationDetail').mockImplementation(async id => detail(id))
|
||||
vi.spyOn(api, 'getPlan').mockResolvedValue(null)
|
||||
vi.spyOn(api, 'getTodos').mockResolvedValue(null)
|
||||
vi.spyOn(api, 'listCards').mockResolvedValue([])
|
||||
vi.spyOn(api, 'listTasks').mockResolvedValue([])
|
||||
vi.spyOn(api, 'listArtifacts').mockResolvedValue([])
|
||||
vi.spyOn(api, 'surfaceList').mockResolvedValue([])
|
||||
projectSurfacesSpy = vi.spyOn(api, 'projectSurfaces').mockResolvedValue([])
|
||||
vi.spyOn(api, 'listProjectCards').mockResolvedValue([])
|
||||
// 还原至 currentProjectId = null 的干净投影,避免别的套件残留影响本次断言。
|
||||
store.resetIdentity()
|
||||
})
|
||||
afterEach(() => { vi.useRealTimers(); vi.restoreAllMocks(); vi.unstubAllGlobals() })
|
||||
|
||||
describe('openConversation projectSurfaces gating', () => {
|
||||
it('skips the /api/projects/.../surfaces request and keeps projectSurfaces empty when no project is current', async () => {
|
||||
expect(store.getState().currentProjectId).toBeNull()
|
||||
await store.openConversation('cnv_no_project')
|
||||
// 让微任务(包含 surfaceList/Stream 等链)落定,但不改变当前结论。
|
||||
await new Promise(r => setTimeout(r, 0))
|
||||
expect(projectSurfacesSpy).not.toHaveBeenCalled()
|
||||
expect(store.getState().projectSurfaces).toEqual([])
|
||||
expect(store.getState().currentProjectId).toBeNull()
|
||||
})
|
||||
|
||||
it('still requests /api/projects/<id>/surfaces when a project is current', async () => {
|
||||
const metas: SurfaceMeta[] = [{ surfaceId: 'surf_1', title: '页面一', pluginId: 'plg_1', revision: 1, updatedAt: '2026-10-12T00:00:00Z' }]
|
||||
projectSurfacesSpy.mockResolvedValueOnce(metas)
|
||||
await store.openProject('prj_with_surfaces')
|
||||
expect(store.getState().currentProjectId).toBe('prj_with_surfaces')
|
||||
projectSurfacesSpy.mockClear()
|
||||
await store.openConversation('cnv_with_project')
|
||||
expect(projectSurfacesSpy).toHaveBeenCalledTimes(1)
|
||||
expect(projectSurfacesSpy.mock.calls[0][0]).toBe('prj_with_surfaces')
|
||||
// 微任务处理完 .then 后,projectSurfaces 投影被填进服务端的元数据列表。
|
||||
await new Promise(r => setTimeout(r, 0))
|
||||
expect(store.getState().projectSurfaces).toEqual(metas)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user