import type { AppContextValue } from '@/context/app-context' import { fireEvent, render, screen } from '@testing-library/react' import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from '@/app/components/base/ui/dropdown-menu' import { Plan } from '@/app/components/billing/type' import { useAppContext } from '@/context/app-context' import { baseProviderContextValue, useProviderContext } from '@/context/provider-context' import Support from './support' const { mockZendeskKey } = vi.hoisted(() => ({ mockZendeskKey: { value: 'test-key' }, })) const { mockSupportEmailKey } = vi.hoisted(() => ({ mockSupportEmailKey: { value: '' }, })) vi.mock('@/context/app-context', async (importOriginal) => { const actual = await importOriginal() return { ...actual, useAppContext: vi.fn(), } }) vi.mock('@/context/provider-context', async (importOriginal) => { const actual = await importOriginal() return { ...actual, useProviderContext: vi.fn(), } }) vi.mock('@/config', async (importOriginal) => { const actual = await importOriginal() return { ...actual, IS_CE_EDITION: false, get ZENDESK_WIDGET_KEY() { return mockZendeskKey.value || '' }, get SUPPORT_EMAIL_ADDRESS() { return mockSupportEmailKey.value || '' }, } }) describe('Support', () => { const mockCloseAccountDropdown = vi.fn() const baseAppContextValue: AppContextValue = { userProfile: { id: '1', name: 'Test User', email: 'test@example.com', avatar: '', avatar_url: '', is_password_set: false, }, mutateUserProfile: vi.fn(), currentWorkspace: { id: '1', name: 'Workspace', plan: '', status: '', created_at: 0, role: 'owner', providers: [], trial_credits: 0, trial_credits_used: 0, next_credit_reset_date: 0, }, isCurrentWorkspaceManager: true, isCurrentWorkspaceOwner: true, isCurrentWorkspaceEditor: true, isCurrentWorkspaceDatasetOperator: false, mutateCurrentWorkspace: vi.fn(), langGeniusVersionInfo: { current_env: 'testing', current_version: '0.6.0', latest_version: '0.6.0', release_date: '', release_notes: '', version: '0.6.0', can_auto_update: false, }, useSelector: vi.fn(), isLoadingCurrentWorkspace: false, isValidatingCurrentWorkspace: false, } beforeEach(() => { vi.clearAllMocks() window.zE = vi.fn() mockZendeskKey.value = 'test-key' mockSupportEmailKey.value = '' vi.mocked(useAppContext).mockReturnValue(baseAppContextValue) vi.mocked(useProviderContext).mockReturnValue({ ...baseProviderContextValue, plan: { ...baseProviderContextValue.plan, type: Plan.professional, }, }) }) const renderSupport = () => { return render( { }}> open , ) } describe('Rendering', () => { it('should render support menu trigger', () => { // Act renderSupport() // Assert expect(screen.getByText('common.userProfile.support')).toBeInTheDocument() }) it('should show forum and community links when opened', () => { // Act renderSupport() fireEvent.click(screen.getByText('common.userProfile.support')) // Assert expect(screen.getByText('common.userProfile.forum')).toBeInTheDocument() expect(screen.getByText('common.userProfile.community')).toBeInTheDocument() }) }) describe('Dedicated Channels', () => { it('should show "Contact Us" when ZENDESK_WIDGET_KEY is present', () => { // Act renderSupport() fireEvent.click(screen.getByText('common.userProfile.support')) // Assert expect(screen.getByText('common.userProfile.contactUs')).toBeInTheDocument() }) it('should hide dedicated support channels for Sandbox plan', () => { // Arrange vi.mocked(useProviderContext).mockReturnValue({ ...baseProviderContextValue, plan: { ...baseProviderContextValue.plan, type: Plan.sandbox, }, }) // Act renderSupport() fireEvent.click(screen.getByText('common.userProfile.support')) // Assert expect(screen.queryByText('common.userProfile.contactUs')).not.toBeInTheDocument() expect(screen.queryByText('common.userProfile.emailSupport')).not.toBeInTheDocument() }) it('should show "Email Support" when ZENDESK_WIDGET_KEY is absent', () => { // Arrange mockZendeskKey.value = '' // Act renderSupport() fireEvent.click(screen.getByText('common.userProfile.support')) // Assert expect(screen.getByText('common.userProfile.emailSupport')).toBeInTheDocument() expect(screen.queryByText('common.userProfile.contactUs')).not.toBeInTheDocument() }) // Optional chain null guard: ZENDESK_WIDGET_KEY is null it('should show Email Support when ZENDESK_WIDGET_KEY is null', () => { // Arrange mockZendeskKey.value = null as unknown as string // Act renderSupport() fireEvent.click(screen.getByText('common.userProfile.support')) // Assert expect(screen.getByText('common.userProfile.emailSupport')).toBeInTheDocument() expect(screen.queryByText('common.userProfile.contactUs')).not.toBeInTheDocument() }) }) describe('Interactions and Links', () => { it('should call toggleZendeskWindow and closeAccountDropdown when "Contact Us" is clicked', () => { // Act renderSupport() fireEvent.click(screen.getByText('common.userProfile.support')) fireEvent.click(screen.getByText('common.userProfile.contactUs')) // Assert expect(window.zE).toHaveBeenCalledWith('messenger', 'open') expect(mockCloseAccountDropdown).toHaveBeenCalled() }) it('should have correct forum and community links', () => { // Act renderSupport() fireEvent.click(screen.getByText('common.userProfile.support')) // Assert const forumLink = screen.getByText('common.userProfile.forum').closest('a') const communityLink = screen.getByText('common.userProfile.community').closest('a') expect(forumLink).toHaveAttribute('href', 'https://forum.dify.ai/') expect(communityLink).toHaveAttribute('href', 'https://discord.gg/5AEfbxcd9k') }) }) })