import React from 'react'; import { render, screen, waitFor, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom'; import KeywordTrendAnalyzer from '../KeywordTrendAnalyzer'; import postService from '../../services/postService'; // Mock the postService jest.mock('../../services/postService'); describe('KeywordTrendAnalyzer', () => { beforeEach(() => { jest.clearAllMocks(); }); test('renders the component with initial elements', () => { render(); // Check if the main heading is present expect(screen.getByText('Keyword Trend Analysis')).toBeInTheDocument(); // Check if the input field is present expect(screen.getByPlaceholderText('Enter keyword to analyze')).toBeInTheDocument(); // Check if the analyze button is present expect(screen.getByText('Analyze')).toBeInTheDocument(); }); test('shows error when analyzing empty keyword', async () => { render(); // Click the analyze button without entering a keyword const analyzeButton = screen.getByText('Analyze'); fireEvent.click(analyzeButton); // Wait for the error message to appear await waitFor(() => { expect(screen.getByText('Please enter a keyword')).toBeInTheDocument(); }); }); test('calls postService with correct keyword when analyzing', async () => { // Mock the analyzeKeywordTrend method to return sample data const mockAnalysisData = [ { date: '2024-01-01', daily: 5, weekly: 25, monthly: 100 }, { date: '2024-01-08', daily: 7, weekly: 30, monthly: 110 } ]; postService.analyzeKeywordTrend.mockResolvedValue({ data: { success: true, keyword: 'technology', date_range: 'monthly', analysis: mockAnalysisData } }); render(); // Enter a keyword in the input field const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); fireEvent.change(keywordInput, { target: { value: 'technology' } }); // Click the analyze button const analyzeButton = screen.getByText('Analyze'); fireEvent.click(analyzeButton); // Wait for the analysis to complete await waitFor(() => { expect(postService.analyzeKeywordTrend).toHaveBeenCalledWith('technology'); }); }); test('displays analysis results when successful', async () => { // Mock the analyzeKeywordTrend method to return sample data const mockAnalysisData = [ { date: '2024-01-01', daily: 5, weekly: 25, monthly: 100 }, { date: '2024-01-08', daily: 7, weekly: 30, monthly: 110 } ]; postService.analyzeKeywordTrend.mockResolvedValue({ data: { success: true, keyword: 'technology', date_range: 'monthly', analysis: mockAnalysisData } }); render(); // Enter a keyword in the input field const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); fireEvent.change(keywordInput, { target: { value: 'technology' } }); // Click the analyze button const analyzeButton = screen.getByText('Analyze'); fireEvent.click(analyzeButton); // Wait for the results to be displayed await waitFor(() => { expect(screen.getByText('Keyword Frequency Trends for "technology"')).toBeInTheDocument(); }); // Check if the chart container is present expect(screen.getByTestId('recharts-responsive-container')).toBeInTheDocument(); // Check if the average stats are displayed expect(screen.getByText('Daily Average')).toBeInTheDocument(); expect(screen.getByText('Weekly Average')).toBeInTheDocument(); expect(screen.getByText('Monthly Average')).toBeInTheDocument(); }); test('shows error message when analysis fails', async () => { // Mock the analyzeKeywordTrend method to throw an error postService.analyzeKeywordTrend.mockRejectedValue(new Error('Analysis failed')); render(); // Enter a keyword in the input field const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); fireEvent.change(keywordInput, { target: { value: 'technology' } }); // Click the analyze button const analyzeButton = screen.getByText('Analyze'); fireEvent.click(analyzeButton); // Wait for the error message to appear await waitFor(() => { expect(screen.getByText('Failed to analyze keyword. Please try again.')).toBeInTheDocument(); }); }); test('shows loading state during analysis', async () => { // Create a promise that doesn't resolve immediately to simulate loading const mockPromise = new Promise((resolve) => { setTimeout(() => resolve({ data: { success: true, keyword: 'technology', date_range: 'monthly', analysis: [{ date: '2024-01-01', daily: 5, weekly: 25, monthly: 100 }] } }), 100); }); postService.analyzeKeywordTrend.mockReturnValue(mockPromise); render(); // Enter a keyword in the input field const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); fireEvent.change(keywordInput, { target: { value: 'technology' } }); // Click the analyze button const analyzeButton = screen.getByText('Analyze'); fireEvent.click(analyzeButton); // Check if the button text changes to 'Analyzing...' expect(analyzeButton).toHaveTextContent('Analyzing...'); // Wait for the analysis to complete await waitFor(() => { expect(analyzeButton).toHaveTextContent('Analyze'); }); }); test('disables analyze button during loading', async () => { // Create a promise that doesn't resolve immediately to simulate loading const mockPromise = new Promise((resolve) => { setTimeout(() => resolve({ data: { success: true, keyword: 'technology', date_range: 'monthly', analysis: [{ date: '2024-01-01', daily: 5, weekly: 25, monthly: 100 }] } }), 100); }); postService.analyzeKeywordTrend.mockReturnValue(mockPromise); render(); // Enter a keyword in the input field const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); fireEvent.change(keywordInput, { target: { value: 'technology' } }); // Click the analyze button const analyzeButton = screen.getByText('Analyze'); fireEvent.click(analyzeButton); // Check if the button is disabled expect(analyzeButton).toBeDisabled(); // Wait for the analysis to complete await waitFor(() => { expect(analyzeButton).not.toBeDisabled(); }); }); });