fix(esmole): truncate all tool responses; guard normalizes leading slash
This commit is contained in:
1 parent
ab5416f443
commit
dd6ca2deff
10 files changed
+94
-16
No files matched your search
@@ -45,6 +45,11 @@ describe('assertReadAllowed', () => {
|
||||
it('ignores a trailing slash', () => {
|
||||
expect(() => assertReadAllowed('POST', '/idx/_search/')).not.toThrow()
|
||||
})
|
||||
it('treats a missing leading slash like the slashed path', () => {
|
||||
expect(() => assertReadAllowed('POST', '_search')).not.toThrow()
|
||||
expect(() => assertReadAllowed('POST', 'idx/_search')).not.toThrow()
|
||||
expect(() => assertReadAllowed('POST', 'idx/_doc')).toThrow(EsGuardError)
|
||||
})
|
||||
it('rejects an unknown method', () => {
|
||||
expect(() => assertReadAllowed('PATCH', '/idx/_search')).toThrow(EsGuardError)
|
||||
})
|
||||
|
||||
@@ -28,4 +28,26 @@ describe('runGetMapping', () => {
|
||||
expect(out.body).toEqual({ error: 'not_found' })
|
||||
expect(out.fields).toBeUndefined()
|
||||
})
|
||||
it('truncates an over-budget flattened-fields response', async () => {
|
||||
const properties: Record<string, { type: string }> = {}
|
||||
for (let i = 0; i < 50; i++) {
|
||||
properties['field_with_a_long_name_' + i] = { type: 'keyword' }
|
||||
}
|
||||
const out = await runGetMapping(
|
||||
managed(200, { idx: { mappings: { properties } } }),
|
||||
'idx',
|
||||
false,
|
||||
100
|
||||
)
|
||||
expect(out.truncated).toBe(true)
|
||||
})
|
||||
it('truncates an over-budget raw response', async () => {
|
||||
const big: Record<string, string> = {}
|
||||
for (let i = 0; i < 50; i++) {
|
||||
big['key_with_a_fairly_long_name_' + i] = 'some value here ' + i
|
||||
}
|
||||
const out = await runGetMapping(managed(200, big), 'idx', true, 100)
|
||||
expect(out.truncated).toBe(true)
|
||||
expect(out.fields).toBeUndefined()
|
||||
})
|
||||
})
|
||||
@@ -149,4 +149,42 @@ describe('registerEsTools', () => {
|
||||
expect(calls[0].path).toBe('/_cluster/health')
|
||||
expect(isCallToolResult(res)).toBe(true)
|
||||
})
|
||||
|
||||
it('es_list_indices truncates an over-budget body', async () => {
|
||||
const big = Array.from({ length: 8000 }, (_, i) => ({
|
||||
index: 'index_with_a_fairly_long_name_' + i,
|
||||
health: 'green'
|
||||
}))
|
||||
const calls: RequestCall[] = []
|
||||
const { handlers, server } = fakeServer()
|
||||
registerEsTools(server, fakeManager(calls, big))
|
||||
const handler = handlers.get('es_list_indices')
|
||||
if (handler === undefined) {
|
||||
throw new Error('es_list_indices not registered')
|
||||
}
|
||||
const res = await handler({ connection: 'c', pattern: '*' })
|
||||
expect(isCallToolResult(res)).toBe(true)
|
||||
const payload = JSON.parse((res.content as Array<{ text: string }>)[0].text)
|
||||
expect(payload.truncated).toBe(true)
|
||||
expect(payload.body._truncated).toBe(true)
|
||||
})
|
||||
|
||||
it('es_cluster_health truncates an over-budget body', async () => {
|
||||
const big: Record<string, string> = {}
|
||||
for (let i = 0; i < 8000; i++) {
|
||||
big['node_with_a_fairly_long_name_' + i] = 'some descriptive value ' + i
|
||||
}
|
||||
const calls: RequestCall[] = []
|
||||
const { handlers, server } = fakeServer()
|
||||
registerEsTools(server, fakeManager(calls, big))
|
||||
const handler = handlers.get('es_cluster_health')
|
||||
if (handler === undefined) {
|
||||
throw new Error('es_cluster_health not registered')
|
||||
}
|
||||
const res = await handler({ connection: 'c' })
|
||||
expect(isCallToolResult(res)).toBe(true)
|
||||
const payload = JSON.parse((res.content as Array<{ text: string }>)[0].text)
|
||||
expect(payload.truncated).toBe(true)
|
||||
expect(payload.body._truncated).toBe(true)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user