Skip to content
14 changes: 12 additions & 2 deletions src/features/authentication/hooks/useEmailValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,21 @@ const getFriendlyErrorMessage = (backendMessage: string): string => {
const message = backendMessage.toLowerCase();

if (message.includes('email must be an email')) {
return 'Please enter a valid email';
return 'Please enter a valid email.';
}
if (message.includes('email has already been taken')) {
return 'Email has already been taken.';
}
if (message.includes('invalid email format')) {
return 'Invalid email format.';
}
if (message.includes('email is required')) {
return 'Email is required.';
}
// Add more mappings as needed

// Default fallback for other validation errors
return 'Please enter a valid email';
return 'An unknown error occurred. Please check your email.';
};

export function useEmailValidation({
Expand Down
1 change: 0 additions & 1 deletion src/features/explore/components/SearchTweets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export default function SearchTweets() {
hasNextPage,
} = useExploreSearchFeed();

console.log(data);
const pages = data?.pages.flat();

const renderTweets = pages?.map((group, i) => (
Expand Down
1 change: 0 additions & 1 deletion src/features/explore/components/Trendings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { useRouter } from 'next/navigation';
export default function Trendings() {
const { data, error, isError, isLoading } = useTrendingFeed();
const router = useRouter();
console.log(data?.metadata.HashtagsCount);
const renderTrends = data?.data.trending.map((trend, ind) => (
<Trend
data-testid={`explore-feed-trend-${trend.tag}`}
Expand Down
1 change: 0 additions & 1 deletion src/features/explore/components/TweetsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default function TweetsList() {
const { data, error, isError, isLoading } = useExplorePosts();
const router = useRouter();

console.log(data);
if (isLoading)
return (
<div
Expand Down
5 changes: 2 additions & 3 deletions src/features/explore/hooks/exploreQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,12 @@ export const EXPLORE_QUERY_KEYS = {
export const useExploreSearchFeed = () => {
const selectedTab = useSelectedSearchTab();
const search = useSearch();
console.log(search.length);
const searchDate = useSearchDate();
const isHash =
search.trimStart().startsWith('#') &&
!search.trimStart().includes(' ') &&
!search.trimStart().slice(1).includes('#');
const type = isHash ? 'hashtag' : 'searchQuery';
console.log(isHash);
const queryKey:
| ReturnType<typeof EXPLORE_QUERY_KEYS.EXPLORE_FEED_SEARCH_TOP>
| ReturnType<typeof EXPLORE_QUERY_KEYS.EXPLORE_FEED_SEARCH_LATEST> =
Expand Down Expand Up @@ -107,7 +105,6 @@ export const useTrendingFeed = () => {
const selectedTab = useSelectedTab();
const path = usePathname();
const valid = path?.startsWith('/explore');
console.log(path, valid);
let queryKey;
let limit;
switch (selectedTab) {
Expand All @@ -132,9 +129,11 @@ export const useTrendingFeed = () => {
case FOR_YOU_TAB:
queryKey = EXPLORE_QUERY_KEYS.EXPLORE_TRENDS_FOR_YOU;
limit = 5;
break;
default:
queryKey = EXPLORE_QUERY_KEYS.EXPLORE_TRENDS_FOR_YOU;
limit = 5;
break;
}

return useQuery<
Expand Down
2 changes: 0 additions & 2 deletions src/features/explore/services/exploreApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ async function handleResponse<T>(response: Response): Promise<T> {
throw new ApiError(errorMessage, statusCode);
}
const data = await response.json();
console.log(data);
return data;
}
export const exploreApi = {
Expand Down Expand Up @@ -149,7 +148,6 @@ export const exploreApi = {
limit: `${limit}`,
sortBy: `latest`,
});
console.log(tab);
const response = await fetch(
`${API_CONFIG.BASE_URL}${EXPLORE_ENDPOINTS.EXPLORE_FEED_INTEREST}?` +
params,
Expand Down
145 changes: 145 additions & 0 deletions src/features/explore/tests/Explore.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import React from 'react';

// Mock the store
vi.mock('../store/useExploreStore', () => ({
useSelectedTab: vi.fn(() => 'personalized'),
}));

// Mock the hooks
vi.mock('../hooks/exploreQueries', () => ({
useTrendingFeed: vi.fn(() => ({
data: {
data: { trending: [{ tag: '#test', totalPosts: 100 }] },
metadata: { HashtagsCount: 1, category: 'general' },
},
error: null,
isError: false,
isLoading: false,
})),
useExplorePosts: vi.fn(() => ({
data: {
data: {
Technology: [
{
userId: 1,
postId: 1,
date: '2024-01-01',
text: 'Test tweet',
},
],
},
},
error: null,
isError: false,
isLoading: false,
})),
}));

// Mock next/navigation
vi.mock('next/navigation', () => ({
useRouter: () => ({ push: vi.fn() }),
usePathname: () => '/explore',
}));

vi.mock('@/components/generic/Loader', () => ({
default: () => <div data-testid="loader">Loading...</div>,
}));

vi.mock('../constants/tabs', () => ({
FOR_YOU_TAB: 'personalized',
TRENDING_TAB: 'general',
TOP_TAB: 'top',
NEWS_TAB: 'news',
SPORTS_TAB: 'sports',
ENTERTAINMENT_TAB: 'entertainment',
}));

vi.mock('@/features/tweets/components/Tweet', () => ({
default: ({ data }: { data: { text: string } }) => (
<div data-testid="tweet-component">{data.text}</div>
),
}));

vi.mock('@/components/ui/home/Icon', () => ({
default: () => <div data-testid="icon">Icon</div>,
}));

import Explore from '../components/Explore';
import { useSelectedTab } from '../store/useExploreStore';
import { useTrendingFeed } from '../hooks/exploreQueries';

describe('Explore', () => {
beforeEach(() => {
vi.clearAllMocks();
vi.mocked(useSelectedTab).mockReturnValue('personalized');
vi.mocked(useTrendingFeed).mockReturnValue({
data: {
data: { trending: [{ tag: '#test', totalPosts: 100 }] },
metadata: { HashtagsCount: 1, category: 'general' },
},
error: null,
isError: false,
isLoading: false,
} as ReturnType<typeof useTrendingFeed>);
});

it('should render ForYou content when FOR_YOU_TAB is selected', async () => {
vi.mocked(useSelectedTab).mockReturnValue('personalized');
render(<Explore />);
// ForYou renders TweetsList and Trendings
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
expect(
screen.getByTestId('explore-feed-render-tweet-list')
).toBeInTheDocument();
});

it('should render Trendings content when a different tab is selected', async () => {
vi.mocked(useSelectedTab).mockReturnValue('general');
render(<Explore />);
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
});

it('should render component without crashing', () => {
const { container } = render(<Explore />);
expect(container).toBeTruthy();
});

it('should render Trendings when TRENDING_TAB is selected', async () => {
vi.mocked(useSelectedTab).mockReturnValue('general');
render(<Explore />);
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
});

it('should render Trendings when NEWS_TAB is selected', async () => {
vi.mocked(useSelectedTab).mockReturnValue('news');
render(<Explore />);
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
});

it('should render Trendings when SPORTS_TAB is selected', async () => {
vi.mocked(useSelectedTab).mockReturnValue('sports');
render(<Explore />);
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
});

it('should render Trendings when ENTERTAINMENT_TAB is selected', async () => {
vi.mocked(useSelectedTab).mockReturnValue('entertainment');
render(<Explore />);
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
});
});
107 changes: 107 additions & 0 deletions src/features/explore/tests/ForYou.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import React from 'react';

// Mock the hooks
vi.mock('../hooks/exploreQueries', () => ({
useTrendingFeed: vi.fn(() => ({
data: {
data: { trending: [{ tag: '#test', totalPosts: 100 }] },
metadata: { HashtagsCount: 1, category: 'general' },
},
error: null,
isError: false,
isLoading: false,
})),
useExplorePosts: vi.fn(() => ({
data: {
data: {
Technology: [
{
userId: 1,
postId: 1,
date: '2024-01-01',
text: 'Test tweet',
},
],
},
},
error: null,
isError: false,
isLoading: false,
})),
}));

// Mock next/navigation
vi.mock('next/navigation', () => ({
useRouter: () => ({ push: vi.fn() }),
usePathname: () => '/explore',
}));

vi.mock('../constants/tabs', () => ({
FOR_YOU_TAB: 'personalized',
TRENDING_TAB: 'general',
TOP_TAB: 'top',
NEWS_TAB: 'news',
SPORTS_TAB: 'sports',
ENTERTAINMENT_TAB: 'entertainment',
}));

vi.mock('../store/useExploreStore', () => ({
useSelectedTab: vi.fn(() => 'personalized'),
}));

vi.mock('@/features/tweets/components/Tweet', () => ({
default: ({ data }: { data: { text: string } }) => (
<div data-testid="tweet-component">{data.text}</div>
),
}));

vi.mock('@/components/ui/home/Icon', () => ({
default: () => <div data-testid="icon">Icon</div>,
}));

import ForYou from '../components/ForYou';

describe('ForYou', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('should render the ForYou component', () => {
render(<ForYou />);
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
expect(
screen.getByTestId('explore-feed-render-tweet-list')
).toBeInTheDocument();
});

it('should render Trendings content', () => {
render(<ForYou />);
expect(
screen.getByTestId('explore-feed-render-trending-list')
).toBeInTheDocument();
});

it('should render TweetsList content', () => {
render(<ForYou />);
expect(
screen.getByTestId('explore-feed-render-tweet-list')
).toBeInTheDocument();
});

it('should have correct flex container structure', () => {
const { container } = render(<ForYou />);
const flexContainer = container.querySelector('.flex.flex-col.flex-1');
expect(flexContainer).toBeInTheDocument();
});

it('should render both sections in order', () => {
const { container } = render(<ForYou />);
const children = container.firstChild?.childNodes;
expect(children).toHaveLength(2);
});
});
Loading