grafana/public/app/features/datasources/components/EditDataSourceActions.test.tsx

504 lines
18 KiB
TypeScript
Raw Normal View History

Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
import { render, screen, fireEvent } from '@testing-library/react';
import { PluginExtensionTypes, IconName } from '@grafana/data';
import { setPluginLinksHook, config, getDataSourceSrv } from '@grafana/runtime';
Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
import { contextSrv } from 'app/core/services/context_srv';
import { getMockDataSource } from '../mocks/dataSourcesMocks';
import { EditDataSourceActions } from './EditDataSourceActions';
// Mock dependencies
jest.mock('app/core/services/context_srv');
jest.mock('../utils', () => ({
constructDataSourceExploreUrl: jest.fn(
() => '/explore?left=%7B%22datasource%22:%22Test%20Prometheus%22,%22context%22:%22explore%22%7D'
),
}));
// Mock @grafana/runtime
jest.mock('@grafana/runtime', () => ({
...jest.requireActual('@grafana/runtime'),
config: {
featureToggles: {
favoriteDatasources: false,
},
},
getDataSourceSrv: jest.fn(),
useFavoriteDatasources: jest.fn(),
}));
Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
// Set default plugin links hook
setPluginLinksHook(() => ({ links: [], isLoading: false }));
// Mock contextSrv
const mockContextSrv = jest.mocked(contextSrv);
// Mock getDataSourceSrv and favorite hooks
const mockGetDataSourceSrv = jest.mocked(getDataSourceSrv);
const mockUseFavoriteDatasources = jest.mocked(require('@grafana/runtime').useFavoriteDatasources);
// Create mock datasource instance
const mockDataSourceInstance = {
uid: 'test-uid',
name: 'Test Prometheus',
type: 'prometheus',
meta: {
name: 'Prometheus',
builtIn: false,
},
};
// Mock favorite datasources hook return value
const mockFavoriteHook = {
enabled: true,
favoriteDatasources: [],
initialFavoriteDataSources: [],
isFavoriteDatasource: jest.fn(),
addFavoriteDatasource: jest.fn(),
removeFavoriteDatasource: jest.fn(),
};
Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
// Helper function to create mock plugin link extensions with all required properties
const createMockPluginLink = (
overrides: Partial<{
id: string;
path: string;
onClick: jest.Mock;
title: string;
description: string;
pluginId: string;
icon?: IconName;
}> = {}
) => ({
id: 'test-link',
type: PluginExtensionTypes.link as const,
title: 'Test Action',
description: 'Test action description',
pluginId: 'grafana-lokiexplore-app',
path: '/test-action',
onClick: jest.fn(),
...overrides,
});
const mockDataSource = getMockDataSource({
uid: 'test-uid',
type: 'prometheus',
name: 'Test Prometheus',
typeName: 'Prometheus',
});
// Mock useDataSource hook
jest.mock('../state/hooks', () => ({
useDataSource: (uid: string) => (uid === 'not-found' ? {} : mockDataSource),
Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
}));
describe('EditDataSourceActions', () => {
beforeEach(() => {
jest.clearAllMocks();
// Reset plugin links hook to default
setPluginLinksHook(() => ({ links: [], isLoading: false }));
// Default contextSrv mock - user has explore rights
mockContextSrv.hasAccessToExplore.mockReturnValue(true);
// Setup default mocks for favorite functionality
mockGetDataSourceSrv.mockReturnValue({
getInstanceSettings: jest.fn().mockReturnValue(mockDataSourceInstance),
get: jest.fn(),
getList: jest.fn(),
reload: jest.fn(),
registerRuntimeDataSource: jest.fn(),
});
// Reset favorite hook mocks
mockFavoriteHook.isFavoriteDatasource.mockReturnValue(false);
mockFavoriteHook.addFavoriteDatasource.mockClear();
mockFavoriteHook.removeFavoriteDatasource.mockClear();
// Default: feature toggle disabled, so no favorite hook
mockUseFavoriteDatasources.mockReturnValue({ ...mockFavoriteHook, enabled: false });
config.featureToggles.favoriteDatasources = false;
Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
});
describe('Core Actions', () => {
it('should render core Grafana actions when user has explore rights', async () => {
mockContextSrv.hasAccessToExplore.mockReturnValue(true);
render(<EditDataSourceActions uid="test-uid" />);
// Core actions should be rendered as separate buttons
expect(screen.getByText('Explore data')).toBeInTheDocument();
expect(screen.getByText('Build a dashboard')).toBeInTheDocument();
});
it('should not render explore action when user lacks explore rights', () => {
mockContextSrv.hasAccessToExplore.mockReturnValue(false);
render(<EditDataSourceActions uid="test-uid" />);
// Should render just the "Build a dashboard" button
expect(screen.getByText('Build a dashboard')).toBeInTheDocument();
// Should not render explore action
expect(screen.queryByText('Explore data')).not.toBeInTheDocument();
});
it('should have correct href for explore action when no extensions', () => {
// No extensions, so explore should be a direct link
setPluginLinksHook(() => ({ links: [], isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
const exploreLink = screen.getByText('Explore data').closest('a');
// The explore URL uses the datasource name, not uid, and includes context
expect(exploreLink).toHaveAttribute(
'href',
'/explore?left=%7B%22datasource%22:%22Test%20Prometheus%22,%22context%22:%22explore%22%7D'
);
});
it('should have correct href for explore action when extensions are present', () => {
// Extensions present, so explore should be a dropdown with "Open in Explore View"
const mockLinks = [
createMockPluginLink({
id: 'test-extension',
title: 'Test Extension',
pluginId: 'grafana-lokiexplore-app',
}),
];
setPluginLinksHook(() => ({ links: mockLinks, isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
// Click to open dropdown
const exploreButton = screen.getByText('Explore data');
fireEvent.click(exploreButton);
const exploreViewLink = screen.getByText('Open in Explore View').closest('a');
// The explore URL uses the datasource name, not uid, and includes context
expect(exploreViewLink).toHaveAttribute(
'href',
'/explore?left=%7B%22datasource%22:%22Test%20Prometheus%22,%22context%22:%22explore%22%7D'
);
});
it('should have correct href for build dashboard action', () => {
render(<EditDataSourceActions uid="test-uid" />);
const dashboardLink = screen.getByText('Build a dashboard').closest('a');
expect(dashboardLink).toHaveAttribute('href', 'dashboard/new-with-ds/test-uid');
});
});
describe('Plugin Extension Actions', () => {
it('should render plugin extension links from allowed plugins', () => {
const mockLinks = [
createMockPluginLink({
id: 'loki-explore',
title: 'Explore Logs',
pluginId: 'grafana-lokiexplore-app',
path: '/a/grafana-lokiexplore-app',
}),
createMockPluginLink({
id: 'traces-explore',
title: 'Explore Traces',
pluginId: 'grafana-exploretraces-app',
path: '/a/grafana-exploretraces-app',
}),
];
setPluginLinksHook(() => ({ links: mockLinks, isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
// Click the Explore data dropdown to open the menu
const exploreButton = screen.getByText('Explore data');
fireEvent.click(exploreButton);
// Should have "Open in Explore View" as first item
expect(screen.getByText('Open in Explore View')).toBeInTheDocument();
// Should have extension links
expect(screen.getByText('Explore Logs')).toBeInTheDocument();
expect(screen.getByText('Explore Traces')).toBeInTheDocument();
});
it('should filter out links from non-allowed plugins', () => {
const mockLinks = [
createMockPluginLink({
id: 'allowed-plugin',
title: 'Allowed Action',
pluginId: 'grafana-lokiexplore-app', // Allowed
}),
createMockPluginLink({
id: 'disallowed-plugin',
title: 'Disallowed Action',
pluginId: 'some-random-plugin', // Not allowed
}),
];
setPluginLinksHook(() => ({ links: mockLinks, isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
// Click the Explore data dropdown to open the menu
const exploreButton = screen.getByText('Explore data');
fireEvent.click(exploreButton);
expect(screen.getByText('Allowed Action')).toBeInTheDocument();
expect(screen.queryByText('Disallowed Action')).not.toBeInTheDocument();
});
it('should call usePluginLinks with correct parameters', () => {
// This test verifies the component calls usePluginLinks correctly
// We can't easily test the exact parameters without more complex mocking
// but we can verify the component renders without errors when links are provided
setPluginLinksHook(() => ({ links: [], isLoading: false }));
expect(() => {
render(<EditDataSourceActions uid="test-uid" />);
}).not.toThrow();
});
it('should handle plugin link onClick events', () => {
const mockOnClick = jest.fn();
const mockLinks = [
createMockPluginLink({
id: 'clickable-action',
title: 'Clickable Action',
onClick: mockOnClick,
pluginId: 'grafana-lokiexplore-app',
}),
];
setPluginLinksHook(() => ({ links: mockLinks, isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
// Click the Explore data dropdown to open the menu
const exploreButton = screen.getByText('Explore data');
fireEvent.click(exploreButton);
const actionButton = screen.getByText('Clickable Action');
fireEvent.click(actionButton);
expect(mockOnClick).toHaveBeenCalledTimes(1);
});
it('should render extension links with correct attributes', () => {
const mockLinks = [
createMockPluginLink({
id: 'test-action',
title: 'Test Action',
description: 'Test description',
path: '/test-path',
icon: 'external-link-alt',
Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
pluginId: 'grafana-lokiexplore-app',
}),
];
setPluginLinksHook(() => ({ links: mockLinks, isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
// Click the Explore data dropdown to open the menu
const exploreButton = screen.getByText('Explore data');
fireEvent.click(exploreButton);
const actionButton = screen.getByText('Test Action');
const linkElement = actionButton.closest('a');
expect(linkElement).toHaveAttribute('href', '/test-path');
// The description is passed as tooltip, which may not appear as a title attribute
// This is handled by the LinkButton component internally
});
it('should not render extensions when isLoading is true', () => {
const mockLinks = [
createMockPluginLink({
title: 'Should Not Appear',
pluginId: 'grafana-lokiexplore-app',
}),
];
setPluginLinksHook(() => ({ links: mockLinks, isLoading: true }));
render(<EditDataSourceActions uid="test-uid" />);
// When isLoading is true, Explore data should be a regular link, not a dropdown
const exploreElement = screen.getByText('Explore data');
const exploreLink = exploreElement.closest('a');
expect(exploreLink).toBeInTheDocument();
expect(screen.queryByText('Should Not Appear')).not.toBeInTheDocument();
// Core actions should still be there
expect(screen.getByText('Build a dashboard')).toBeInTheDocument();
expect(screen.getByText('Explore data')).toBeInTheDocument();
});
it('should handle empty extension links gracefully', () => {
setPluginLinksHook(() => ({ links: [], isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
// When there are no extension links, Explore data should be a regular link
const exploreElement = screen.getByText('Explore data');
const exploreLink = exploreElement.closest('a');
expect(exploreLink).toBeInTheDocument();
// Should render core actions without errors
expect(screen.getByText('Build a dashboard')).toBeInTheDocument();
expect(screen.getByText('Explore data')).toBeInTheDocument();
});
it('should render Explore dropdown when there are plugin links', () => {
const mockLinks = [
createMockPluginLink({
id: 'test-extension',
title: 'Test Extension',
pluginId: 'grafana-lokiexplore-app',
}),
];
setPluginLinksHook(() => ({ links: mockLinks, isLoading: false }));
render(<EditDataSourceActions uid="test-uid" />);
// When there are extension links, Explore data should be a dropdown button
const exploreElement = screen.getByText('Explore data');
const exploreButton = exploreElement.closest('button');
expect(exploreButton).toBeInTheDocument();
// Core actions should still be there
expect(screen.getByText('Build a dashboard')).toBeInTheDocument();
expect(screen.getByText('Explore data')).toBeInTheDocument();
});
});
describe('DataSource Not Found', () => {
it('should not render actions when data source is not found', () => {
render(<EditDataSourceActions uid="not-found" />);
expect(screen.queryByText('Explore data')).not.toBeInTheDocument();
expect(screen.queryByText('Build a dashboard')).not.toBeInTheDocument();
});
});
describe('Favorite Actions', () => {
it('should not render favorite button when feature toggle is disabled', () => {
config.featureToggles.favoriteDatasources = false;
mockUseFavoriteDatasources.mockReturnValue({ ...mockFavoriteHook, enabled: false });
render(<EditDataSourceActions uid="test-uid" />);
// Should not find any favorite button
expect(screen.queryByTestId('favorite-button')).not.toBeInTheDocument();
// Core actions should still be rendered
expect(screen.getByText('Explore data')).toBeInTheDocument();
expect(screen.getByText('Build a dashboard')).toBeInTheDocument();
});
it('should not render favorite button for built-in datasources', () => {
config.featureToggles.favoriteDatasources = true;
mockUseFavoriteDatasources.mockReturnValue(mockFavoriteHook);
// Mock built-in datasource
const builtInDataSource = { ...mockDataSourceInstance, meta: { ...mockDataSourceInstance.meta, builtIn: true } };
mockGetDataSourceSrv.mockReturnValue({
getInstanceSettings: jest.fn().mockReturnValue(builtInDataSource),
get: jest.fn(),
getList: jest.fn(),
reload: jest.fn(),
registerRuntimeDataSource: jest.fn(),
});
render(<EditDataSourceActions uid="test-uid" />);
// Should not find any favorite button for built-in datasources
expect(screen.queryByTestId('favorite-button')).not.toBeInTheDocument();
});
it('should render favorite button when feature toggle is enabled and datasource is not built-in', () => {
config.featureToggles.favoriteDatasources = true;
mockUseFavoriteDatasources.mockReturnValue(mockFavoriteHook);
mockFavoriteHook.isFavoriteDatasource.mockReturnValue(false);
render(<EditDataSourceActions uid="test-uid" />);
// Should find star icon for non-favorite datasource
const favoriteButton = screen.getByTestId('favorite-button');
expect(favoriteButton).toBeInTheDocument();
// Should have correct aria-label for non-favorite datasource
expect(favoriteButton).toHaveAttribute('aria-label', 'Add to favorites');
});
it('should show favorite icon when datasource is favorited', () => {
config.featureToggles.favoriteDatasources = true;
mockUseFavoriteDatasources.mockReturnValue(mockFavoriteHook);
mockFavoriteHook.isFavoriteDatasource.mockReturnValue(true);
render(<EditDataSourceActions uid="test-uid" />);
// Should find favorite button for favorited datasource
const favoriteButton = screen.getByTestId('favorite-button');
expect(favoriteButton).toBeInTheDocument();
// Should have correct aria-label for favorited datasource
expect(favoriteButton).toHaveAttribute('aria-label', 'Remove from favorites');
});
it('should add datasource to favorites when star button is clicked', () => {
config.featureToggles.favoriteDatasources = true;
mockUseFavoriteDatasources.mockReturnValue(mockFavoriteHook);
mockFavoriteHook.isFavoriteDatasource.mockReturnValue(false);
render(<EditDataSourceActions uid="test-uid" />);
const favoriteButton = screen.getByTestId('favorite-button');
fireEvent.click(favoriteButton);
expect(mockFavoriteHook.addFavoriteDatasource).toHaveBeenCalledTimes(1);
expect(mockFavoriteHook.addFavoriteDatasource).toHaveBeenCalledWith(mockDataSourceInstance);
expect(mockFavoriteHook.removeFavoriteDatasource).not.toHaveBeenCalled();
});
it('should remove datasource from favorites when favorite button is clicked', () => {
config.featureToggles.favoriteDatasources = true;
mockUseFavoriteDatasources.mockReturnValue(mockFavoriteHook);
mockFavoriteHook.isFavoriteDatasource.mockReturnValue(true);
render(<EditDataSourceActions uid="test-uid" />);
const favoriteButton = screen.getByTestId('favorite-button');
fireEvent.click(favoriteButton);
expect(mockFavoriteHook.removeFavoriteDatasource).toHaveBeenCalledTimes(1);
expect(mockFavoriteHook.removeFavoriteDatasource).toHaveBeenCalledWith(mockDataSourceInstance);
expect(mockFavoriteHook.addFavoriteDatasource).not.toHaveBeenCalled();
});
it('should call isFavoriteDatasource with correct uid', () => {
config.featureToggles.favoriteDatasources = true;
mockUseFavoriteDatasources.mockReturnValue(mockFavoriteHook);
mockFavoriteHook.isFavoriteDatasource.mockReturnValue(false);
render(<EditDataSourceActions uid="test-uid" />);
expect(mockFavoriteHook.isFavoriteDatasource).toHaveBeenCalledWith('test-uid');
});
it('should disable favorite button when isLoading is true', () => {
config.featureToggles.favoriteDatasources = true;
mockUseFavoriteDatasources.mockReturnValue({
...mockFavoriteHook,
isLoading: true,
});
mockFavoriteHook.isFavoriteDatasource.mockReturnValue(false);
render(<EditDataSourceActions uid="test-uid" />);
const favoriteButton = screen.getByTestId('favorite-button');
expect(favoriteButton).toBeDisabled();
});
});
Plugin Extensions: DataSource Configuration Components (#108350) * add the plan * feat: Add plugin extension points for DataSource configuration components - Add DataSourceConfigActions and DataSourceConfigStatus extension points - Add PluginExtensionDataSourceConfigActionsContext and PluginExtensionDataSourceConfigStatusContext types - Update EditDataSourceActions.tsx with plugin extension support and allowlist filtering - Update DataSourceTestingStatus.tsx with dual extension point support (new + backward compatible) - Create getDataSourceExtensionConfigs.tsx with example core extensions - Update getCoreExtensionConfigurations.ts to include datasource extensions - Implement grafana-owned plugin allowlist for security and quality control - Support context-aware extensions based on datasource type and testing status - Maintain backward compatibility with existing DataSourceConfigErrorStatus extension point - Add proper TypeScript types and export them in index.ts This enables grafana-owned plugins to provide contextual actions and status-specific integrations within the datasource configuration workflow while maintaining security through plugin filtering. * docs: Update specs.md with implementation status and lessons learned - Add comprehensive implementation status section with completed features - Document critical lessons learned during implementation: * Translation limitations in extension configurations * Plugin security through allowlist filtering * Extension registration timing constraints * TypeScript context type patterns - Update implementation checklist with actual completion status - Add detailed next steps and recommendations - Include plugin development guidelines (do's and don'ts) - Document architectural insights and patterns discovered - Transform specs from theoretical design to practical implementation guide This update serves as both historical record and developer guide for future plugin extension work in Grafana. * Add comprehensive tests for DataSource plugin extensions - Add EditDataSourceActions.test.tsx with 12 tests covering: * Core Grafana actions functionality and permissions * Plugin extension rendering and interaction * Plugin allowlist filtering and security * Context passing and URL generation - Add getDataSourceExtensionConfigs.test.tsx with 14 tests covering: * Core extension configurations for both extension points * Context filtering logic (datasource type, severity) * Error handling and graceful failures * Extension structure validation and type safety Total: 26 tests passing, providing comprehensive coverage of the DataSourceConfigActions and DataSourceConfigStatus extension points implemented in previous commits. * Update specs.md to reflect completed test implementation - Mark unit testing phase as complete (26 tests added) - Add comprehensive Test Implementation section documenting: * Test file details and coverage areas * Testing challenges and solutions discovered * Performance metrics and execution strategy * Command examples for running tests - Update Success Metrics with concrete testing validation - Update Next Steps to reflect testing completion - Document new test files in Files Modified section The plugin extensions implementation now has complete unit test coverage for both DataSourceConfigActions and DataSourceConfigStatus extension points with 26 passing tests. * rm specs file * lint * refactor: replace 'any' types with proper TypeScript types in datasource extension tests * tsc * prettier: fix * Fix datasource extension path format to resolve CI test failure The troubleshooting link extension was using an invalid path format '/docs/troubleshooting/datasources' which caused console.error during test execution. Updated to proper Grafana core extension path format '/a/grafana/docs/troubleshooting/datasources' to comply with plugin extension validation rules. * fix: DataSourceTestingStatus test failures - Fix incorrect data-testid expectations to use proper e2e selectors - Add contextSrv mock for hasAccessToExplore() dependency - Create proper plugin links mock handling different extension points - Update plugin link tests to use allowed plugin IDs - Fix test logic to match actual component behavior for status/error links - Add test coverage for non-allowed plugin filtering All 10 tests now pass successfully. * lint fix * refactor: replace any types with proper TypeScript types in DataSourceTestingStatus test - Replace any[] with PluginExtensionLink[] for statusLinks and errorLinks parameters - Replace any with UsePluginLinksOptions for setPluginLinksHook callback parameter - Add proper imports for PluginExtensionLink and UsePluginLinksOptions - Improve type safety and IntelliSense support in tests * rm brittle tests * DataSource: Replace individual buttons with dropdown menu in EditDataSourceActions - Convert LinkButton components to dropdown with Menu.Item components - Add conditional rendering: show simple button when only one action, dropdown when multiple - Use LinkButton for navigation and Button with dropdown icon for menu trigger - Replace Trans components with t() function calls for Menu.Item labels - Prevent PageHeader crowding when multiple plugin extensions are registered - Maintain all existing functionality and tracking calls * refactor: use configure() for dynamic datasource extension URLs - Replace onClick handler with configure() function for dynamic path generation - Use context to build monitoring tool URL with datasource UID - Follows extension system design patterns for declarative configuration - Removes manual window.open() in favor of automatic path handling * refactor: use DataSourceConfigErrorStatus extension point for troubleshooting guide Use the specific DataSourceConfigErrorStatus extension point instead of DataSourceConfigStatus with conditional logic in configure function. This simplifies the code by leveraging the right abstraction level. * extract i18n * lint:fix * Revert "lint:fix" This reverts commit 23cdb39672a289e251910983747e412f641bdc16. * lint:fix * fix: mock plugin extensions registry in variables utils test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. Solution: Mock the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * fix: mock plugin extensions registry in explore query test Fixes console.error calls during test execution caused by plugin extension registration failures. The test was failing on CI because the extensions registry was trying to register link extensions with invalid configurations during module import. This applies the same fix as the variables utils test - mocking the entire plugin extensions registry setup to prevent side effects from interfering with the test execution. * better fix * Fix EditDataSourceActions test by mocking utils and handling dropdown UI - Add missing mock for constructDataSourceExploreUrl from ../utils - Update tests to interact with dropdown menu structure instead of expecting direct text - Fix test logic to match component behavior: Actions dropdown when user has explore rights * lint:fix * refactor: extract duplicated allowedPluginIds to single source of truth - Add ALLOWED_DATASOURCE_EXTENSION_PLUGINS constant to constants.ts - Remove duplicate allowedPluginIds arrays from DataSourceTestingStatus and EditDataSourceActions - Update both components to import and use the shared constant - Improves maintainability and ensures consistency across datasource config components * refactor: update datasource extension link configurations - Change title and description for the metrics drilldown link to improve clarity - Update the path for the metrics drilldown link to reflect the new routing structure - Remove the troubleshooting guide link configuration to streamline the extension options * removing unused config * better dropdown * fix: update EditDataSourceActions tests to match component implementation - Fixed tests to expect core actions as separate buttons instead of dropdown - Updated plugin extension tests to use 'Extensions' dropdown instead of 'Actions' - Added test for Extensions dropdown visibility logic - All 12 tests now passing * lint:fix * remove extra check * Update ALLOWED_DATASOURCE_EXTENSION_PLUGINS documentation to clarify plugin contributions to datasource configuration pages * feat: Convert Explore data button to dropdown when extensions are available - When hasActions is empty: shows normal Explore data and Build dashboard buttons - When hasActions is not empty: converts Explore data to dropdown with angle-down icon - First dropdown item: 'Open in Explore View' - Following items: extension links - Build dashboard button remains unchanged - Maintains existing tracking functionality and internationalization * test: Update EditDataSourceActions tests for new dropdown implementation - Update tests to work with new Explore data dropdown that includes extensions - Replace references to 'Extensions' button with 'Explore data' dropdown - Add test for 'Open in Explore View' menu item in dropdown - Verify correct behavior when extensions are present vs absent - All 13 tests now passing * test: Add comprehensive test coverage for dropdown explore functionality - Add test to verify explore action href when extensions are present - Ensure both dropdown and direct link behaviors are tested - Complete test coverage for new dropdown implementation * translation * compass icon for the explore item * feat: refactor AlertSuccessMessage to accept extension links as props - Move extension links from inline definition to props for better reusability - Add proper TypeScript support for PluginExtensionLink types - Improve component architecture by separating concerns - Add extensionLinks styling to getStyles function for consistency - Support both real extension links and custom link rendering in success messages This improves the component's flexibility while maintaining type safety. * lint:fix
2025-08-07 23:19:10 +08:00
});