From a6824db622e2c5456ec0a2ed4e254116c69ac03b Mon Sep 17 00:00:00 2001
From: Amlan Kumar Nandy <45410599+amlannandy@users.noreply.github.com>
Date: Wed, 23 Apr 2025 17:42:09 +0700
Subject: [PATCH] fix: metric details something went wrong message (#7686)
---
.../api/metricsExplorer/getMetricDetails.ts | 2 +-
.../MetricDetails/MetricDetails.tsx | 10 +-
.../__tests__/MetricDetails.test.tsx | 175 ++++++++++++++++++
3 files changed, 184 insertions(+), 3 deletions(-)
create mode 100644 frontend/src/container/MetricsExplorer/MetricDetails/__tests__/MetricDetails.test.tsx
diff --git a/frontend/src/api/metricsExplorer/getMetricDetails.ts b/frontend/src/api/metricsExplorer/getMetricDetails.ts
index 06ab7e62bb..74bde3e671 100644
--- a/frontend/src/api/metricsExplorer/getMetricDetails.ts
+++ b/frontend/src/api/metricsExplorer/getMetricDetails.ts
@@ -15,7 +15,7 @@ export interface MetricDetails {
timeSeriesTotal: number;
timeSeriesActive: number;
lastReceived: string;
- attributes: MetricDetailsAttribute[];
+ attributes: MetricDetailsAttribute[] | null;
metadata?: {
metric_type: MetricType;
description: string;
diff --git a/frontend/src/container/MetricsExplorer/MetricDetails/MetricDetails.tsx b/frontend/src/container/MetricsExplorer/MetricDetails/MetricDetails.tsx
index 0d0a640b20..2781ce5870 100644
--- a/frontend/src/container/MetricsExplorer/MetricDetails/MetricDetails.tsx
+++ b/frontend/src/container/MetricsExplorer/MetricDetails/MetricDetails.tsx
@@ -130,7 +130,11 @@ function MetricDetails({
destroyOnClose
closeIcon={}
>
- {isMetricDetailsLoading && }
+ {isMetricDetailsLoading && (
+
+
+
+ )}
{isMetricDetailsError && !isMetricDetailsLoading && (
)}
@@ -171,7 +175,9 @@ function MetricDetails({
metadata={metric.metadata}
refetchMetricDetails={refetchMetricDetails}
/>
-
+ {metric.attributes && (
+
+ )}
)}
diff --git a/frontend/src/container/MetricsExplorer/MetricDetails/__tests__/MetricDetails.test.tsx b/frontend/src/container/MetricsExplorer/MetricDetails/__tests__/MetricDetails.test.tsx
new file mode 100644
index 0000000000..5eb7e867ea
--- /dev/null
+++ b/frontend/src/container/MetricsExplorer/MetricDetails/__tests__/MetricDetails.test.tsx
@@ -0,0 +1,175 @@
+import { render, screen } from '@testing-library/react';
+import { MetricDetails } from 'api/metricsExplorer/getMetricDetails';
+import { MetricType } from 'api/metricsExplorer/getMetricsList';
+import ROUTES from 'constants/routes';
+import * as useGetMetricDetails from 'hooks/metricsExplorer/useGetMetricDetails';
+import * as useUpdateMetricMetadata from 'hooks/metricsExplorer/useUpdateMetricMetadata';
+
+import MetricDetailsView from '../MetricDetails';
+
+const mockMetricName = 'test-metric';
+const mockMetricDescription = 'description for a test metric';
+const mockMetricData: MetricDetails = {
+ name: mockMetricName,
+ description: mockMetricDescription,
+ unit: 'count',
+ attributes: [
+ {
+ key: 'test-attribute',
+ value: ['test-value'],
+ valueCount: 1,
+ },
+ ],
+ alerts: [],
+ dashboards: [],
+ metadata: {
+ metric_type: MetricType.SUM,
+ description: mockMetricDescription,
+ unit: 'count',
+ },
+ type: '',
+ timeseries: 0,
+ samples: 0,
+ timeSeriesTotal: 0,
+ timeSeriesActive: 0,
+ lastReceived: '',
+};
+const mockOpenInspectModal = jest.fn();
+const mockOnClose = jest.fn();
+
+const mockUseGetMetricDetailsData = {
+ data: {
+ payload: {
+ data: mockMetricData,
+ },
+ },
+ isLoading: false,
+ isFetching: false,
+ isError: false,
+ error: null,
+ refetch: jest.fn(),
+};
+
+jest
+ .spyOn(useGetMetricDetails, 'useGetMetricDetails')
+ .mockReturnValue(mockUseGetMetricDetailsData as any);
+
+jest.spyOn(useUpdateMetricMetadata, 'useUpdateMetricMetadata').mockReturnValue({
+ mutate: jest.fn(),
+ isLoading: false,
+ isError: false,
+ error: null,
+} as any);
+
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useLocation: (): { pathname: string } => ({
+ pathname: `${ROUTES.METRICS_EXPLORER}`,
+ }),
+}));
+jest.mock('hooks/useSafeNavigate', () => ({
+ useSafeNavigate: (): any => ({
+ safeNavigate: jest.fn(),
+ }),
+}));
+
+describe('MetricDetails', () => {
+ it('renders metric details correctly', () => {
+ render(
+ ,
+ );
+
+ expect(screen.getByText(mockMetricName)).toBeInTheDocument();
+ expect(screen.getByText(mockMetricDescription)).toBeInTheDocument();
+ expect(screen.getByText(`${mockMetricData.unit}`)).toBeInTheDocument();
+ });
+
+ it('should render error state when metric details are not found', () => {
+ jest.spyOn(useGetMetricDetails, 'useGetMetricDetails').mockReturnValue({
+ ...mockUseGetMetricDetailsData,
+ isError: true,
+ error: {
+ message: 'Error fetching metric details',
+ },
+ } as any);
+
+ render(
+ ,
+ );
+
+ expect(screen.getByText('Error fetching metric details')).toBeInTheDocument();
+ });
+
+ it('should render loading state when metric details are loading', () => {
+ jest.spyOn(useGetMetricDetails, 'useGetMetricDetails').mockReturnValue({
+ ...mockUseGetMetricDetailsData,
+ isLoading: true,
+ } as any);
+
+ render(
+ ,
+ );
+
+ expect(screen.getByTestId('metric-details-skeleton')).toBeInTheDocument();
+ });
+
+ it('should render all attributes section', () => {
+ jest
+ .spyOn(useGetMetricDetails, 'useGetMetricDetails')
+ .mockReturnValue(mockUseGetMetricDetailsData as any);
+ render(
+ ,
+ );
+
+ expect(screen.getByText('All Attributes')).toBeInTheDocument();
+ });
+
+ it('should not render all attributes section when relevant data is not present', () => {
+ jest.spyOn(useGetMetricDetails, 'useGetMetricDetails').mockReturnValue({
+ ...mockUseGetMetricDetailsData,
+ data: {
+ payload: {
+ data: {
+ ...mockMetricData,
+ attributes: null,
+ },
+ },
+ },
+ } as any);
+ render(
+ ,
+ );
+
+ expect(screen.queryByText('All Attributes')).not.toBeInTheDocument();
+ });
+});