mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
Signed-off-by: linghaoSu <linghao.su@daocloud.io>
This commit is contained in:
committed by
github-actions[bot]
parent
61267982ab
commit
0ccc00e1d8
137
ui/src/app/applications/components/resource-icon.test.tsx
Normal file
137
ui/src/app/applications/components/resource-icon.test.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
import * as React from 'react';
|
||||
import * as renderer from 'react-test-renderer';
|
||||
import {ResourceIcon} from './resource-icon';
|
||||
|
||||
// Mock the resourceIcons and resourceCustomizations
|
||||
jest.mock('./resources', () => ({
|
||||
resourceIcons: new Map([
|
||||
['Ingress', 'ing'],
|
||||
['ConfigMap', 'cm'],
|
||||
['Deployment', 'deploy'],
|
||||
['Service', 'svc']
|
||||
])
|
||||
}));
|
||||
|
||||
jest.mock('./resource-customizations', () => ({
|
||||
resourceIconGroups: {
|
||||
'*.crossplane.io': true,
|
||||
'*.fluxcd.io': true,
|
||||
'cert-manager.io': true
|
||||
}
|
||||
}));
|
||||
|
||||
describe('ResourceIcon', () => {
|
||||
describe('kind-based icons (no group)', () => {
|
||||
it('should show kind-based icon for ConfigMap without group', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='' kind='ConfigMap' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
expect(imgs[0].props.src).toBe('assets/images/resources/cm.svg');
|
||||
});
|
||||
|
||||
it('should show kind-based icon for Deployment without group', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='' kind='Deployment' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
expect(imgs[0].props.src).toBe('assets/images/resources/deploy.svg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('group-based icons (with matching group)', () => {
|
||||
it('should show group-based icon for exact group match', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='cert-manager.io' kind='Certificate' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
expect(imgs[0].props.src).toBe('assets/images/resources/cert-manager.io/icon.svg');
|
||||
});
|
||||
|
||||
it('should show group-based icon for wildcard group match (crossplane)', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='pkg.crossplane.io' kind='Provider' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
// Wildcard '*' should be replaced with '_' in the path
|
||||
expect(imgs[0].props.src).toBe('assets/images/resources/_.crossplane.io/icon.svg');
|
||||
|
||||
const complexTestRenderer = renderer.create(<ResourceIcon group='identify.provider.crossplane.io' kind='Provider' />);
|
||||
const complexTestInstance = complexTestRenderer.root;
|
||||
const complexImgs = complexTestInstance.findAllByType('img');
|
||||
expect(complexImgs.length).toBeGreaterThan(0);
|
||||
// Wildcard '*' should be replaced with '_' in the path
|
||||
expect(complexImgs[0].props.src).toBe('assets/images/resources/_.crossplane.io/icon.svg');
|
||||
});
|
||||
|
||||
it('should show group-based icon for wildcard group match (fluxcd)', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='source.fluxcd.io' kind='GitRepository' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
expect(imgs[0].props.src).toBe('assets/images/resources/_.fluxcd.io/icon.svg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fallback to kind-based icons (with non-matching group) - THIS IS THE BUG FIX', () => {
|
||||
it('should fallback to kind-based icon for Ingress with networking.k8s.io group', () => {
|
||||
// This is the main bug fix test case
|
||||
// Ingress has group 'networking.k8s.io' which is NOT in resourceCustomizations
|
||||
// But Ingress IS in resourceIcons, so it should still show the icon
|
||||
const testRenderer = renderer.create(<ResourceIcon group='networking.k8s.io' kind='Ingress' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
expect(imgs[0].props.src).toBe('assets/images/resources/ing.svg');
|
||||
});
|
||||
|
||||
it('should fallback to kind-based icon for Service with core group', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='' kind='Service' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
expect(imgs[0].props.src).toBe('assets/images/resources/svc.svg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fallback to initials (no matching group or kind)', () => {
|
||||
it('should show initials for unknown resource with unknown group', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='unknown.example.io' kind='UnknownResource' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBe(0);
|
||||
// Should show initials "UR" (uppercase letters from UnknownResource)
|
||||
const spans = testInstance.findAllByType('span');
|
||||
const textSpan = spans.find(s => s.children.includes('UR'));
|
||||
expect(textSpan).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show initials for MyCustomKind', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='' kind='MyCustomKind' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBe(0);
|
||||
// Should show initials "MCK"
|
||||
const spans = testInstance.findAllByType('span');
|
||||
const textSpan = spans.find(s => s.children.includes('MCK'));
|
||||
expect(textSpan).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('special cases', () => {
|
||||
it('should show node icon for kind=node', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='' kind='node' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const imgs = testInstance.findAllByType('img');
|
||||
expect(imgs.length).toBeGreaterThan(0);
|
||||
expect(imgs[0].props.src).toBe('assets/images/infrastructure_components/node.svg');
|
||||
});
|
||||
|
||||
it('should show application icon for kind=Application', () => {
|
||||
const testRenderer = renderer.create(<ResourceIcon group='' kind='Application' />);
|
||||
const testInstance = testRenderer.root;
|
||||
const icons = testInstance.findAll(node => node.type === 'i' && typeof node.props.className === 'string' && node.props.className.includes('argo-icon-application'));
|
||||
expect(icons.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,17 +10,18 @@ export const ResourceIcon = ({group, kind, customStyle}: {group: string; kind: s
|
||||
if (kind === 'Application') {
|
||||
return <i title={kind} className={`icon argo-icon-application`} style={customStyle} />;
|
||||
}
|
||||
if (!group) {
|
||||
const i = resourceIcons.get(kind);
|
||||
if (i !== undefined) {
|
||||
return <img src={'assets/images/resources/' + i + '.svg'} alt={kind} style={{padding: '2px', width: '40px', height: '32px', ...customStyle}} />;
|
||||
}
|
||||
} else {
|
||||
// First, check for group-based custom icons
|
||||
if (group) {
|
||||
const matchedGroup = matchGroupToResource(group);
|
||||
if (matchedGroup) {
|
||||
return <img src={`assets/images/resources/${matchedGroup}/icon.svg`} alt={kind} style={{paddingBottom: '2px', width: '40px', height: '32px', ...customStyle}} />;
|
||||
}
|
||||
}
|
||||
// Fallback to kind-based icons (works for both empty group and non-matching groups)
|
||||
const i = resourceIcons.get(kind);
|
||||
if (i !== undefined) {
|
||||
return <img src={'assets/images/resources/' + i + '.svg'} alt={kind} style={{padding: '2px', width: '40px', height: '32px', ...customStyle}} />;
|
||||
}
|
||||
const initials = kind.replace(/[a-z]/g, '');
|
||||
const n = initials.length;
|
||||
const style: React.CSSProperties = {
|
||||
|
||||
Reference in New Issue
Block a user