fix profile-aware session history actions (#1011)
This commit is contained in:
@@ -15,6 +15,7 @@ vi.mock('@/router', () => ({
|
||||
import { getApiKey, setApiKey, clearApiKey, hasApiKey, getStoredUserRole, isStoredSuperAdmin, request } from '../../packages/client/src/api/client'
|
||||
import { getDownloadUrl } from '../../packages/client/src/api/hermes/download'
|
||||
import { uploadFiles } from '../../packages/client/src/api/hermes/files'
|
||||
import { batchDeleteSessions } from '../../packages/client/src/api/hermes/sessions'
|
||||
import router from '@/router'
|
||||
|
||||
function fakeJwt(payload: Record<string, unknown>) {
|
||||
@@ -202,4 +203,32 @@ describe('API Client', () => {
|
||||
expect(options.body).toBeInstanceOf(FormData)
|
||||
})
|
||||
})
|
||||
|
||||
describe('sessions API', () => {
|
||||
it('sends profile-qualified targets for batch deletes', async () => {
|
||||
localStorage.setItem('hermes_active_profile_name', 'research')
|
||||
mockFetch.mockResolvedValue({
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: () => Promise.resolve({ deleted: 2, failed: 0, errors: [] }),
|
||||
})
|
||||
|
||||
await batchDeleteSessions([
|
||||
{ id: 'session-default', profile: 'default' },
|
||||
{ id: 'session-travel', profile: 'travel' },
|
||||
])
|
||||
|
||||
const [url, options] = mockFetch.mock.calls[0]
|
||||
expect(url).toBe('/api/hermes/sessions/batch-delete')
|
||||
expect(options.method).toBe('POST')
|
||||
expect(options.headers['X-Hermes-Profile']).toBeUndefined()
|
||||
expect(JSON.parse(options.body)).toEqual({
|
||||
ids: ['session-default', 'session-travel'],
|
||||
sessions: [
|
||||
{ id: 'session-default', profile: 'default' },
|
||||
{ id: 'session-travel', profile: 'travel' },
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -601,6 +601,42 @@ describe('session conversations controller', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('batch deletes sessions from their requested profiles', async () => {
|
||||
listUserProfilesMock.mockReturnValue([{ profile_name: 'default' }, { profile_name: 'travel' }])
|
||||
getSessionMock.mockImplementation((id: string) => ({
|
||||
id,
|
||||
profile: id === 'travel-session' ? 'travel' : 'default',
|
||||
}))
|
||||
getExactSessionDetailFromDbWithProfileMock.mockResolvedValue({ id: 'matched', messages: [] })
|
||||
deleteHermesSessionForProfileMock.mockResolvedValue(true)
|
||||
localDeleteSessionMock.mockReturnValue(true)
|
||||
|
||||
const mod = await import('../../packages/server/src/controllers/hermes/sessions')
|
||||
const ctx: any = {
|
||||
request: {
|
||||
body: {
|
||||
sessions: [
|
||||
{ id: 'default-session', profile: 'default' },
|
||||
{ id: 'travel-session', profile: 'travel' },
|
||||
],
|
||||
},
|
||||
},
|
||||
state: {
|
||||
user: { id: 1, role: 'admin' },
|
||||
},
|
||||
body: null,
|
||||
}
|
||||
await mod.batchRemove(ctx)
|
||||
|
||||
expect(getExactSessionDetailFromDbWithProfileMock).toHaveBeenCalledWith('default-session', 'default')
|
||||
expect(getExactSessionDetailFromDbWithProfileMock).toHaveBeenCalledWith('travel-session', 'travel')
|
||||
expect(deleteHermesSessionForProfileMock).toHaveBeenCalledWith('default-session', 'default')
|
||||
expect(deleteHermesSessionForProfileMock).toHaveBeenCalledWith('travel-session', 'travel')
|
||||
expect(localDeleteSessionMock).toHaveBeenCalledWith('default-session')
|
||||
expect(localDeleteSessionMock).toHaveBeenCalledWith('travel-session')
|
||||
expect(ctx.body).toMatchObject({ ok: true, deleted: 2, failed: 0, hermesDeleted: 2 })
|
||||
})
|
||||
|
||||
describe('exportSession', () => {
|
||||
it('returns session as JSON download with correct headers (full mode)', async () => {
|
||||
const sessionData = { id: 'abc-123', title: 'Test Session', messages: [{ id: 1, role: 'user', content: 'hello' }] }
|
||||
|
||||
Reference in New Issue
Block a user