From e8865c9ea5f243114dead90c9750d284b8a83e21 Mon Sep 17 00:00:00 2001 From: Nadav Erell Date: Wed, 7 Oct 2026 07:51:27 +0300 Subject: [PATCH 1/2] Link explicit Pod priority and runtime classes with cluster scope --- .../renderers/PodClassReferences.test.tsx | 22 +++++++++++++++++++ .../resources/renderers/PodRenderer.tsx | 6 +++++ 2 files changed, 28 insertions(+) create mode 100644 packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx diff --git a/packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx b/packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx new file mode 100644 index 0000000000..84db930cb6 --- /dev/null +++ b/packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx @@ -0,0 +1,22 @@ +// @vitest-environment jsdom +import { act } from 'react' +import { createRoot } from 'react-dom/client' +import { renderToStaticMarkup } from 'react-dom/server' +import { expect, it, vi } from 'vitest' +import { PodRenderer } from './PodRenderer' + +const data = { metadata: {name:'worker',namespace:'app'}, spec:{containers:[],priority:1000,priorityClassName:'urgent',runtimeClassName:'sandbox'},status:{phase:'Pending'} } + +it('navigates explicit scheduling class names with their canonical API groups and cluster scope', async()=>{ + const onNavigate=vi.fn();const node=document.createElement('div');document.body.append(node);const root=createRoot(node) + try{ + await act(async()=>{root.render({}} copied={null} onNavigate={onNavigate}/>)}) + for(const [name,kind,group] of [['urgent','priorityclasses','scheduling.k8s.io'],['sandbox','runtimeclasses','node.k8s.io']]){ + const button=Array.from(node.querySelectorAll('button')).find(b=>b.textContent===name);expect(button).toBeDefined();await act(async()=>{button!.click()});expect(onNavigate).toHaveBeenLastCalledWith({kind,group,namespace:'',name}) + } + }finally{await act(async()=>{root.unmount()});node.remove()} +}) +it('does not infer a class reference from numeric priority or absent class fields',()=>{ + const html=renderToStaticMarkup({}} copied={null}/>) + expect(html).not.toContain('Priority Class');expect(html).not.toContain('Runtime Class') +}) diff --git a/packages/k8s-ui/src/components/resources/renderers/PodRenderer.tsx b/packages/k8s-ui/src/components/resources/renderers/PodRenderer.tsx index 60aaa31928..884b6a6689 100644 --- a/packages/k8s-ui/src/components/resources/renderers/PodRenderer.tsx +++ b/packages/k8s-ui/src/components/resources/renderers/PodRenderer.tsx @@ -453,6 +453,12 @@ export function PodRenderer({ : undefined } copyable onCopy={onCopy} copied={copied} /> + {data.spec?.priorityClassName && + } />} + {data.spec?.runtimeClassName && + } />} Date: Wed, 7 Oct 2026 12:09:24 +0300 Subject: [PATCH 2/2] Rewrite Pod class reference test in renderer-test style --- .../renderers/PodClassReferences.test.tsx | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx b/packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx index 84db930cb6..9ef8143ea5 100644 --- a/packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx +++ b/packages/k8s-ui/src/components/resources/renderers/PodClassReferences.test.tsx @@ -2,21 +2,41 @@ import { act } from 'react' import { createRoot } from 'react-dom/client' import { renderToStaticMarkup } from 'react-dom/server' -import { expect, it, vi } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import { PodRenderer } from './PodRenderer' -const data = { metadata: {name:'worker',namespace:'app'}, spec:{containers:[],priority:1000,priorityClassName:'urgent',runtimeClassName:'sandbox'},status:{phase:'Pending'} } +const data = { + metadata: { name: 'worker', namespace: 'app' }, + spec: { containers: [], priority: 1000, priorityClassName: 'urgent', runtimeClassName: 'sandbox' }, + status: { phase: 'Pending' }, +} -it('navigates explicit scheduling class names with their canonical API groups and cluster scope', async()=>{ - const onNavigate=vi.fn();const node=document.createElement('div');document.body.append(node);const root=createRoot(node) - try{ - await act(async()=>{root.render({}} copied={null} onNavigate={onNavigate}/>)}) - for(const [name,kind,group] of [['urgent','priorityclasses','scheduling.k8s.io'],['sandbox','runtimeclasses','node.k8s.io']]){ - const button=Array.from(node.querySelectorAll('button')).find(b=>b.textContent===name);expect(button).toBeDefined();await act(async()=>{button!.click()});expect(onNavigate).toHaveBeenLastCalledWith({kind,group,namespace:'',name}) - } - }finally{await act(async()=>{root.unmount()});node.remove()} -}) -it('does not infer a class reference from numeric priority or absent class fields',()=>{ - const html=renderToStaticMarkup({}} copied={null}/>) - expect(html).not.toContain('Priority Class');expect(html).not.toContain('Runtime Class') +describe('PodRenderer class references', () => { + it('links explicit class names with their API groups and cluster scope', async () => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }) + const container = document.createElement('div') + const root = createRoot(container) + const onNavigate = vi.fn() + try { + await act(async () => root.render( {}} copied={null} onNavigate={onNavigate} />)) + for (const [name, kind, group] of [ + ['urgent', 'priorityclasses', 'scheduling.k8s.io'], + ['sandbox', 'runtimeclasses', 'node.k8s.io'], + ]) { + const button = [...container.querySelectorAll('button')].find(button => button.textContent === name) + expect(button).toBeDefined() + await act(async () => button!.click()) + expect(onNavigate).toHaveBeenLastCalledWith({ kind, group, namespace: '', name }) + } + } finally { + await act(async () => root.unmount()) + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: false }) + } + }) + + it('does not infer a class from numeric priority alone', () => { + const html = renderToStaticMarkup( {}} copied={null} />) + expect(html).not.toContain('Priority Class') + expect(html).not.toContain('Runtime Class') + }) })