Skip to content

Commit ada1b2d

Browse files
committed
test(webui): lock T1 fix against the changed-tool data shape
Reproduces the reported case (a sole 'changed' tool with pending_approval=1): clicking the Pending Approval stat now lists that row instead of an empty table, and the awaiting filter matches both pending and changed. Refs MCP-998
1 parent 4179da0 commit ada1b2d

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { describe, it, expect, beforeEach, vi } from 'vitest'
2+
import { mount, flushPromises } from '@vue/test-utils'
3+
import { createPinia, setActivePinia } from 'pinia'
4+
import Tools from '@/views/Tools.vue'
5+
import api from '@/services/api'
6+
7+
// T1 (v0.36.0 feedback): the "Pending Approval" stat counts tools that are
8+
// pending OR changed, but the Approval=Pending filter matched only "pending",
9+
// so an instance whose sole awaiting tool was "changed" (a rug-pull) showed a
10+
// non-zero stat with an EMPTY table. This reproduces that exact data shape —
11+
// one approved tool + one CHANGED tool, pending_approval = 1 — and locks the
12+
// fix: clicking the stat applies an "awaiting" filter that surfaces the row.
13+
14+
vi.mock('@/services/api', () => ({
15+
default: { getGlobalTools: vi.fn(), setToolEnabled: vi.fn() },
16+
}))
17+
18+
const globalStubs = { CollapsibleHintsPanel: { template: '<div />' } }
19+
20+
function mountView() {
21+
return mount(Tools, { global: { plugins: [createPinia()], stubs: globalStubs } })
22+
}
23+
24+
describe('Tools — Pending Approval count matches the filtered table', () => {
25+
beforeEach(() => {
26+
setActivePinia(createPinia())
27+
;(api.getGlobalTools as any).mockResolvedValue({
28+
success: true,
29+
data: {
30+
stats: { total: 2, enabled: 2, disabled: 0, pending_approval: 1 },
31+
tools: [
32+
{ name: 'hf_doc_search', server_name: 'hugginface', approval_status: 'changed', enabled: true, description: 'changed tool' },
33+
{ name: 'list_repos', server_name: 'github', approval_status: 'approved', enabled: true, description: 'ok' },
34+
],
35+
},
36+
})
37+
})
38+
39+
it('shows the changed tool (not an empty table) when the Pending Approval stat is clicked', async () => {
40+
const wrapper = mountView()
41+
await flushPromises()
42+
43+
// Stat reflects the changed tool.
44+
expect(wrapper.find('[data-test="stat-pending"] .stat-value').text().trim()).toBe('1')
45+
46+
// Before the fix this produced "No matching tools"; now it lists the changed row.
47+
await wrapper.find('[data-test="stat-pending"]').trigger('click')
48+
await flushPromises()
49+
50+
const rows = wrapper.findAll('[data-test="tool-row"]')
51+
expect(rows.length).toBe(1)
52+
expect(rows[0].text()).toContain('hf_doc_search')
53+
})
54+
55+
it('the Awaiting-approval filter matches both pending and changed', async () => {
56+
;(api.getGlobalTools as any).mockResolvedValue({
57+
success: true,
58+
data: {
59+
stats: { total: 3, enabled: 3, disabled: 0, pending_approval: 2 },
60+
tools: [
61+
{ name: 'new_tool', server_name: 's', approval_status: 'pending', enabled: true, description: '' },
62+
{ name: 'rugpull', server_name: 's', approval_status: 'changed', enabled: true, description: '' },
63+
{ name: 'fine', server_name: 's', approval_status: 'approved', enabled: true, description: '' },
64+
],
65+
},
66+
})
67+
const wrapper = mountView()
68+
await flushPromises()
69+
await wrapper.find('[data-test="stat-pending"]').trigger('click')
70+
await flushPromises()
71+
const rows = wrapper.findAll('[data-test="tool-row"]')
72+
expect(rows.length).toBe(2) // pending + changed, not approved
73+
const text = rows.map(r => r.text()).join(' ')
74+
expect(text).toContain('new_tool')
75+
expect(text).toContain('rugpull')
76+
expect(text).not.toContain('fine')
77+
})
78+
})

0 commit comments

Comments
 (0)