|
|
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'; |
|
|
|
|
|
|
|
|
jest.mock('../../services/postService'); |
|
|
|
|
|
describe('KeywordTrendAnalyzer', () => { |
|
|
beforeEach(() => { |
|
|
jest.clearAllMocks(); |
|
|
}); |
|
|
|
|
|
test('renders the component with initial elements', () => { |
|
|
render(<KeywordTrendAnalyzer />); |
|
|
|
|
|
|
|
|
expect(screen.getByText('Keyword Trend Analysis')).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
expect(screen.getByPlaceholderText('Enter keyword to analyze')).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
expect(screen.getByText('Analyze')).toBeInTheDocument(); |
|
|
}); |
|
|
|
|
|
test('shows error when analyzing empty keyword', async () => { |
|
|
render(<KeywordTrendAnalyzer />); |
|
|
|
|
|
|
|
|
const analyzeButton = screen.getByText('Analyze'); |
|
|
fireEvent.click(analyzeButton); |
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
expect(screen.getByText('Please enter a keyword')).toBeInTheDocument(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
test('calls postService with correct keyword when analyzing', async () => { |
|
|
|
|
|
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(<KeywordTrendAnalyzer />); |
|
|
|
|
|
|
|
|
const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); |
|
|
fireEvent.change(keywordInput, { target: { value: 'technology' } }); |
|
|
|
|
|
|
|
|
const analyzeButton = screen.getByText('Analyze'); |
|
|
fireEvent.click(analyzeButton); |
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
expect(postService.analyzeKeywordTrend).toHaveBeenCalledWith('technology'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
test('displays analysis results when successful', async () => { |
|
|
|
|
|
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(<KeywordTrendAnalyzer />); |
|
|
|
|
|
|
|
|
const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); |
|
|
fireEvent.change(keywordInput, { target: { value: 'technology' } }); |
|
|
|
|
|
|
|
|
const analyzeButton = screen.getByText('Analyze'); |
|
|
fireEvent.click(analyzeButton); |
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
expect(screen.getByText('Keyword Frequency Trends for "technology"')).toBeInTheDocument(); |
|
|
}); |
|
|
|
|
|
|
|
|
expect(screen.getByTestId('recharts-responsive-container')).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
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 () => { |
|
|
|
|
|
postService.analyzeKeywordTrend.mockRejectedValue(new Error('Analysis failed')); |
|
|
|
|
|
render(<KeywordTrendAnalyzer />); |
|
|
|
|
|
|
|
|
const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); |
|
|
fireEvent.change(keywordInput, { target: { value: 'technology' } }); |
|
|
|
|
|
|
|
|
const analyzeButton = screen.getByText('Analyze'); |
|
|
fireEvent.click(analyzeButton); |
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
expect(screen.getByText('Failed to analyze keyword. Please try again.')).toBeInTheDocument(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
test('shows loading state during analysis', async () => { |
|
|
|
|
|
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(<KeywordTrendAnalyzer />); |
|
|
|
|
|
|
|
|
const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); |
|
|
fireEvent.change(keywordInput, { target: { value: 'technology' } }); |
|
|
|
|
|
|
|
|
const analyzeButton = screen.getByText('Analyze'); |
|
|
fireEvent.click(analyzeButton); |
|
|
|
|
|
|
|
|
expect(analyzeButton).toHaveTextContent('Analyzing...'); |
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
expect(analyzeButton).toHaveTextContent('Analyze'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
test('disables analyze button during loading', async () => { |
|
|
|
|
|
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(<KeywordTrendAnalyzer />); |
|
|
|
|
|
|
|
|
const keywordInput = screen.getByPlaceholderText('Enter keyword to analyze'); |
|
|
fireEvent.change(keywordInput, { target: { value: 'technology' } }); |
|
|
|
|
|
|
|
|
const analyzeButton = screen.getByText('Analyze'); |
|
|
fireEvent.click(analyzeButton); |
|
|
|
|
|
|
|
|
expect(analyzeButton).toBeDisabled(); |
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
expect(analyzeButton).not.toBeDisabled(); |
|
|
}); |
|
|
}); |
|
|
}); |