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';