diff --git a/frontend/src/components/HeaderRightSection/HeaderRightSection.tsx b/frontend/src/components/HeaderRightSection/HeaderRightSection.tsx
index 19b00391bd7e..846079843447 100644
--- a/frontend/src/components/HeaderRightSection/HeaderRightSection.tsx
+++ b/frontend/src/components/HeaderRightSection/HeaderRightSection.tsx
@@ -2,6 +2,7 @@ import './HeaderRightSection.styles.scss';
import { Button, Popover } from 'antd';
import logEvent from 'api/common/logEvent';
+import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
import { Globe, Inbox, SquarePen } from 'lucide-react';
import { useCallback, useState } from 'react';
import { useLocation } from 'react-router-dom';
@@ -20,13 +21,15 @@ function HeaderRightSection({
enableAnnouncements,
enableShare,
enableFeedback,
-}: HeaderRightSectionProps): JSX.Element {
+}: HeaderRightSectionProps): JSX.Element | null {
const location = useLocation();
const [openFeedbackModal, setOpenFeedbackModal] = useState(false);
const [openShareURLModal, setOpenShareURLModal] = useState(false);
const [openAnnouncementsModal, setOpenAnnouncementsModal] = useState(false);
+ const { isCloudUser, isEnterpriseSelfHostedUser } = useGetTenantLicense();
+
const handleOpenFeedbackModal = useCallback((): void => {
logEvent('Feedback: Clicked', {
page: location.pathname,
@@ -63,9 +66,11 @@ function HeaderRightSection({
setOpenShareURLModal(open);
};
+ const isLicenseEnabled = isEnterpriseSelfHostedUser || isCloudUser;
+
return (
- {enableFeedback && (
+ {enableFeedback && isLicenseEnabled && (
({
),
}));
+jest.mock('hooks/useGetTenantLicense', () => ({
+ useGetTenantLicense: jest.fn(),
+}));
+
const mockLogEvent = logEvent as jest.Mock;
const mockUseLocation = useLocation as jest.Mock;
+const mockUseGetTenantLicense = useGetTenantLicense as jest.Mock;
const defaultProps = {
enableAnnouncements: true,
@@ -61,6 +67,13 @@ describe('HeaderRightSection', () => {
beforeEach(() => {
jest.clearAllMocks();
mockUseLocation.mockReturnValue(mockLocation);
+ // Default to licensed user (Enterprise or Cloud)
+ mockUseGetTenantLicense.mockReturnValue({
+ isCloudUser: true,
+ isEnterpriseSelfHostedUser: false,
+ isCommunityUser: false,
+ isCommunityEnterpriseUser: false,
+ });
});
it('should render all buttons when all features are enabled', () => {
@@ -189,4 +202,84 @@ describe('HeaderRightSection', () => {
expect(screen.getByTestId('feedback-modal')).toBeInTheDocument();
expect(screen.queryByTestId('share-modal')).not.toBeInTheDocument();
});
+
+ it('should show feedback button for Cloud users when feedback is enabled', () => {
+ mockUseGetTenantLicense.mockReturnValue({
+ isCloudUser: true,
+ isEnterpriseSelfHostedUser: false,
+ isCommunityUser: false,
+ isCommunityEnterpriseUser: false,
+ });
+
+ render();
+
+ const feedbackButton = document.querySelector('.lucide-square-pen');
+ expect(feedbackButton).toBeInTheDocument();
+ });
+
+ it('should show feedback button for Enterprise self-hosted users when feedback is enabled', () => {
+ mockUseGetTenantLicense.mockReturnValue({
+ isCloudUser: false,
+ isEnterpriseSelfHostedUser: true,
+ isCommunityUser: false,
+ isCommunityEnterpriseUser: false,
+ });
+
+ render();
+
+ const feedbackButton = document.querySelector('.lucide-square-pen');
+ expect(feedbackButton).toBeInTheDocument();
+ });
+
+ it('should hide feedback button for Community users even when feedback is enabled', () => {
+ mockUseGetTenantLicense.mockReturnValue({
+ isCloudUser: false,
+ isEnterpriseSelfHostedUser: false,
+ isCommunityUser: true,
+ isCommunityEnterpriseUser: false,
+ });
+
+ render();
+
+ const feedbackButton = document.querySelector('.lucide-square-pen');
+ expect(feedbackButton).not.toBeInTheDocument();
+ });
+
+ it('should hide feedback button for Community Enterprise users even when feedback is enabled', () => {
+ mockUseGetTenantLicense.mockReturnValue({
+ isCloudUser: false,
+ isEnterpriseSelfHostedUser: false,
+ isCommunityUser: false,
+ isCommunityEnterpriseUser: true,
+ });
+
+ render();
+
+ const feedbackButton = document.querySelector('.lucide-square-pen');
+ expect(feedbackButton).not.toBeInTheDocument();
+ });
+
+ it('should render correct number of buttons when feedback is hidden due to license', () => {
+ mockUseGetTenantLicense.mockReturnValue({
+ isCloudUser: false,
+ isEnterpriseSelfHostedUser: false,
+ isCommunityUser: true,
+ isCommunityEnterpriseUser: false,
+ });
+
+ render();
+
+ // Should have 2 buttons (announcements + share) instead of 3
+ const buttons = screen.getAllByRole('button');
+ expect(buttons).toHaveLength(2);
+
+ // Verify which buttons are present
+ expect(screen.getByRole('button', { name: /share/i })).toBeInTheDocument();
+ const inboxIcon = document.querySelector('.lucide-inbox');
+ expect(inboxIcon).toBeInTheDocument();
+
+ // Verify feedback button is not present
+ const feedbackIcon = document.querySelector('.lucide-square-pen');
+ expect(feedbackIcon).not.toBeInTheDocument();
+ });
});
diff --git a/frontend/src/components/RouteTab/RouteTab.test.tsx b/frontend/src/components/RouteTab/RouteTab.test.tsx
index af20927e2ace..f645bc2eeb50 100644
--- a/frontend/src/components/RouteTab/RouteTab.test.tsx
+++ b/frontend/src/components/RouteTab/RouteTab.test.tsx
@@ -1,6 +1,6 @@
-import { fireEvent, render, screen } from '@testing-library/react';
import { createMemoryHistory } from 'history';
import { Router } from 'react-router-dom';
+import { fireEvent, render, screen } from 'tests/test-utils';
import RouteTab from './index';
import { RouteTabProps } from './types';