import Page from '@/views/goauto/client-keys/index.vue' import { createClientKey, editClientKey, listClientKeys, clientKeyModules } from '@/api/goauto/client-keys' jest.mock('@/api/goauto/client-keys', () => ({ createClientKey: jest.fn(), editClientKey: jest.fn(), disableClientKey: jest.fn(), listClientKeys: jest.fn(), clientKeyModules: jest.fn() })) jest.mock('element-plus', () => ({ ElMessage: { success: jest.fn(), error: jest.fn(), warning: jest.fn() }, ElMessageBox: { confirm: jest.fn() }})) function vm() { const value = { ...Page.data(), $store: { getters: { roles: ['admin'] }}} for (const [name, fn] of Object.entries(Page.methods)) value[name] = fn.bind(value) for (const [name, fn] of Object.entries(Page.computed)) Object.defineProperty(value, name, { get: fn.bind(value) }) return value } const row = () => ({ id: 12, version: 2, name: 'Tool', prefix: 'masked', enabled: true, grants: [{ module: 'pdd_products', write: false, actions: [] }] }) beforeEach(() => { jest.clearAllMocks(); listClientKeys.mockResolvedValue({ data: { items: [], total: 0 }}); clientKeyModules.mockResolvedValue({ data: [] }) }) test('edit prefill and cancel never change the existing row or create a key', () => { const p = vm(); const original = row(); p.openEditor(original) expect(p.changed).toBe(false) p.grants.pdd_products.write = true; expect(p.changed).toBe(true) p.closeEditor() expect(original.grants[0].write).toBe(false) expect(editClientKey).not.toHaveBeenCalled(); expect(createClientKey).not.toHaveBeenCalled() }) test('module group selection defaults read-only and removing a module removes actions', () => { const p = vm(); p.selectGroup({ modules: [{ key: 'one' }, { key: 'two' }] }, true) expect(p.grants.one).toEqual({ module: 'one', write: false, actions: [] }) p.grants.one.actions.push('delete'); p.selectModule('one', false); p.selectModule('one', true) expect(p.grants.one.actions).toEqual([]) }) test('edit saves same ID with version, does not issue a new key', async() => { const p = vm(); p.openEditor(row()); p.grants.pdd_products.write = true editClientKey.mockResolvedValue({ data: {}}); await p.save() expect(editClientKey).toHaveBeenCalledWith(12, { version: 2, grants: [{ module: 'pdd_products', write: true, actions: [] }] }) expect(createClientKey).not.toHaveBeenCalled(); expect(p.secret).toBe(''); expect(p.editorOpen).toBe(false) }) test('failure preserves changes and conflict prevents blind retry', async() => { const p = vm(); p.openEditor(row()); p.grants.pdd_products.write = true editClientKey.mockRejectedValue({ response: { status: 409, data: { message: 'conflict' }}}) await p.save(); expect(p.editorOpen).toBe(true); expect(p.grants.pdd_products.write).toBe(true); expect(p.conflicted).toBe(true) await p.save(); expect(editClientKey).toHaveBeenCalledTimes(1) }) test('disabled keys are read-only and no modules cannot be saved', async() => { const p = vm(); p.openEditor({ ...row(), enabled: false }); expect(p.editorOpen).toBe(false) p.openEditor({ ...row(), enabled: false }, true); expect(p.readonly).toBe(true) p.openEditor(row()); p.selectModule('pdd_products', false); await p.save(); expect(editClientKey).not.toHaveBeenCalled() }) test('secret is cleared when dialog or cached view closes', () => { const p = vm(); p.secret = 'DEMO_NOT_A_VALID_SECRET'; p.clearSecret(); expect(p.secret).toBe('') p.secret = 'DEMO_NOT_A_VALID_SECRET'; p.secretOpen = true; Page.deactivated.call(p); expect(p.secret).toBe(''); expect(p.secretOpen).toBe(false) }) test('ordinary users do not load or open management', async() => { const p = vm(); p.$store.getters.roles = ['purchaser']; await p.load(); p.openEditor(); expect(listClientKeys).not.toHaveBeenCalled(); expect(p.editorOpen).toBe(false) }) test('late creation response after navigation does not retain a secret', async() => { const p = vm(); p.name = 'test'; p.selectModule('pdd_products', true) let resolve createClientKey.mockImplementation(() => new Promise(done => { resolve = done })) const pending = p.save(); Page.deactivated.call(p) resolve({ data: { secret: 'DEMO_ONLY_NOT_A_VALID_SECRET' }}); await pending expect(p.secret).toBe(''); expect(p.secretOpen).toBe(false) })