/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import '@testing-library/jest-dom'; import { render, fireEvent } from '@testing-library/react'; import { SupersetTheme, ThemeProvider } from '@superset-ui/core'; // CRITICAL: Don't import from the mocked path - import directly to avoid global mocks import AsyncIcon from '../../../src/components/Icons/AsyncIcon'; // Mock only the SVG import to prevent dynamic import issues jest.mock( '!!@svgr/webpack!../../../src/assets/images/icons/slack.svg', () => { const MockSlackSVG = (props: any) => ( ); return { default: MockSlackSVG }; }, { virtual: true }, ); // Basic theme for testing const mockTheme: SupersetTheme = { fontSize: 16, sizeUnit: 4, } as SupersetTheme; describe('AsyncIcon Integration Tests (Real Component)', () => { it('should have data-test and aria-label attributes with real component', () => { const { container } = render( , ); // Don't wait for SVG since it's mocked - just check the span wrapper const spanElement = container.querySelector('span'); // Test the ACTUAL component behavior (not the mock) expect(spanElement).toHaveAttribute('aria-label', 'slack'); expect(spanElement).toHaveAttribute('role', 'img'); expect(spanElement).toHaveAttribute('data-test', 'slack'); }); it('should always have aria-label and data-test for testing', () => { const { container } = render( , ); const spanElement = container.querySelector('span'); // The critical requirement: we MUST have these attributes for accessibility and testing expect(spanElement).toHaveAttribute('aria-label'); expect(spanElement).toHaveAttribute('data-test'); // The values should be consistent const ariaLabel = spanElement?.getAttribute('aria-label'); const dataTest = spanElement?.getAttribute('data-test'); expect(ariaLabel).toBe('slack'); expect(dataTest).toBe('slack'); }); it('should set role to button when onClick is provided in real component', () => { const onClick = jest.fn(); const { container } = render( , ); const spanElement = container.querySelector('span'); expect(spanElement).toHaveAttribute('role', 'button'); expect(spanElement).toHaveAttribute('aria-label', 'slack'); expect(spanElement).toHaveAttribute('data-test', 'slack'); // Verify onClick handler actually works fireEvent.click(spanElement!); expect(onClick).toHaveBeenCalledTimes(1); }); it('should handle complex fileName patterns like BaseIcon', () => { const { container } = render( , ); const spanElement = container.querySelector('span'); // Should follow BaseIcon's genAriaLabel logic: // fileName="slack_notification" -> name="slack-notification" -> "slack-notification" (not just "slack") expect(spanElement).toHaveAttribute('aria-label', 'slack-notification'); expect(spanElement).toHaveAttribute('data-test', 'slack-notification'); }); });