Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New #6

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,20 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ["@testing-library/jest-dom"],
collectCoverage: true,
coverageDirectory: "coverage",
coverageReporters: ["json", "lcov", "text", "clover"],
collectCoverageFrom: [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts",
"!src/index.tsx",
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"generator:dev": "nodemon server/generator.js",
"start": "craco start",
"build": "craco build",
"test": "jest",
"test": "jest --coverage",
"eject": "craco eject",
"format": "npx prettier --write .",
"lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
Expand Down
117 changes: 117 additions & 0 deletions src/components/custom/AuthStatus/AuthStatus.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import React from 'react';
import { render, screen, fireEvent, act } from '@testing-library/react';
import { MemoryRouter, Route, Routes, useNavigate } from 'react-router-dom';
import AuthStatus from '.';
import { useAuth } from '../../../contexts/AuthContext';
import { useTranslation } from 'react-i18next';

// Mock useAuth and useTranslation
jest.mock('../../../contexts/AuthContext', () => ({
useAuth: jest.fn(),
}));

jest.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key: string) => key, // Mock translation function to return the key
}),
}));

const mockNavigate = jest.fn();
const mockSignout = jest.fn();
const mockUseAuth = useAuth as jest.Mock;

// Mock useNavigate
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
}));

describe('AuthStatus', () => {
beforeEach(() => {
jest.clearAllMocks();
});

test('renders login button when user is not logged in and header is true', () => {
mockUseAuth.mockReturnValue({
user: null,
signout: mockSignout,
});

render(
<MemoryRouter>
<AuthStatus header />
</MemoryRouter>
);

expect(screen.getByTestId('login')).toBeInTheDocument();
});

test('renders login button and heading when user is not logged in and header is false', () => {
mockUseAuth.mockReturnValue({
user: null,
signout: mockSignout,
});

render(
<MemoryRouter>
<AuthStatus />
</MemoryRouter>
);

expect(screen.getByText('Gaana.com')).toBeInTheDocument();
expect(screen.getByTestId('login')).toBeInTheDocument();
});

test('renders logout button when user is logged in and header is true', () => {
mockUseAuth.mockReturnValue({
user: 'user',
signout: mockSignout,
});

render(
<MemoryRouter>
<AuthStatus header />
</MemoryRouter>
);

expect(screen.getByTestId('logout')).toBeInTheDocument();
});

test('renders link to /player when user is logged in and header is false', () => {
mockUseAuth.mockReturnValue({
user: 'user',
signout: mockSignout,
});

render(
<MemoryRouter>
<AuthStatus />
</MemoryRouter>
);

expect(screen.getByText('play_music')).toBeInTheDocument();
});

test('navigates to login page on login button click', () => {
mockUseAuth.mockReturnValue({
user: null,
signout: mockSignout,
});

render(
<MemoryRouter>
<AuthStatus header />
</MemoryRouter>
);

act(() => {
fireEvent.click(screen.getByTestId('login'));
});

expect(mockNavigate).toHaveBeenCalledWith('/login');
});




});
2 changes: 1 addition & 1 deletion src/components/custom/AuthStatus/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function AuthStatus({ header = false }: AuthStatusProps) {
<VStack.col>
<StyledFiller />
<h1>Gaana.com</h1>
<FormButton label={t('log_in')} type="button" variant="danger" onClick={handleLogin}/>
<FormButton label={t('log_in')} type="button" variant="danger" onClick={handleLogin} data-testid="login"/>

</VStack.col>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/custom/NoResult/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Paragraph } from '@/components/base/Typography';
import { Paragraph } from '../../../components/base/Typography';
import { BoomBox } from 'lucide-react';
import React from 'react';
import styled from 'styled-components';
Expand Down
4 changes: 2 additions & 2 deletions src/components/custom/ThemeToggler/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import styled from 'styled-components';
import { themes, useThemeContext } from '@/contexts/ThemeContext';
import { themes, useThemeContext } from '../../../contexts/ThemeContext';
import { Sun, Moon, Sparkles } from 'lucide-react';
import FormButton from '@/components/base/FormButton';
import FormButton from '../../../components/base/FormButton';

const ButtonContainer = styled.div`
display: flex;
Expand Down
9 changes: 3 additions & 6 deletions src/components/custom/TranslationButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import FormButton from '../../base/FormButton';

import FormButton from '../../../components/base/FormButton';
const TranslationButton: React.FC = () => {
const { i18n } = useTranslation();

const changeLanguage = (language: string) => {
i18n.changeLanguage(language);
setShowLanguages(false);
setShowLanguages(false);
};

const [showLanguages, setShowLanguages] = useState(false);

return (
<div>
<FormButton label="Select Language" onClick={() => setShowLanguages(!showLanguages)} />

{showLanguages && (
<div style={{ display: 'flex', justifyContent: 'space-around', marginTop: '10px' }}>
<FormButton label="English" onClick={() => changeLanguage('en')} />
Expand All @@ -26,5 +24,4 @@ const TranslationButton: React.FC = () => {
</div>
);
};

export default TranslationButton;
export default TranslationButton;
30 changes: 0 additions & 30 deletions src/components/custom/TranslationContainer/index.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/containers/PlayerContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useDispatch, useSelector } from 'react-redux';
import { nextSong, previousSong, togglePlaying } from '@/store/songs/SongSlice';
import PlayerView from '@/views/PlayerView';
import { nextSong, previousSong, togglePlaying } from '../../store/songs/SongSlice';
import PlayerView from '../../views/PlayerView';

const PlayerContainer = () => {
const dispatch = useDispatch();
Expand Down
4 changes: 2 additions & 2 deletions src/containers/PlaylistContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '@/store/store';
import PlaylistView from '@/views/PlaylistView';
import { RootState } from '../../store/store';
import PlaylistView from '../../views/PlaylistView';


const PlaylistContainer: React.FC = () => {
Expand Down
4 changes: 2 additions & 2 deletions src/contexts/ThemeContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getTheme, storeTheme } from '@/lib/common';
import { darkTheme, dreamTheme, lightTheme } from '@/styles/globalStyles';
import { getTheme, storeTheme } from '../lib/common';
import { darkTheme, dreamTheme, lightTheme } from '../styles/globalStyles';
import React, { createContext, useState, useContext, useMemo, useEffect } from 'react';
import { ThemeProvider as SCThemeProvider } from 'styled-components';

Expand Down
2 changes: 1 addition & 1 deletion src/lib/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ i18n
interpolation: {
escapeValue: false,
},
supportedLngs: ['en', 'fr', 'es', 'de', 'it', 'zh', 'ja'],
supportedLngs: ['en','fr', 'es', 'de', 'it', 'zh', 'ja'],
});
export { fakeAuthProvider , i18n};
93 changes: 93 additions & 0 deletions src/pages/HomePage/HomePage.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// HomePage.test.tsx

import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import HomePage from '.';
import songReducer from '../../store/songs/SongSlice';
import { useSongs } from './helper';
import { DEFAULT_SEARCH } from '../../lib/constants';
import { useTranslation } from 'react-i18next';
import store from '../../store/store';


jest.mock('./helper', () => ({
useSongs: jest.fn(),
}));


jest.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key: string) => key,
}),
}));


jest.mock('../../components/base/Loader', () => () => <div>Loader</div>);
jest.mock('../../components/custom/NoResult', () => () => <div>NoResult</div>);
jest.mock('../../containers/SongContainer', () => () => <div>SongContainer</div>);

const mockStore = configureStore({
reducer: {
songs: songReducer,
},
});

describe('HomePage', () => {
beforeEach(() => {
(useSongs as jest.Mock).mockReturnValue({
fetchNextPage: jest.fn(),
hasNextPage: false,
songs: [],
status: 'loading',
error: null,
});
});



it('should render the NoResult component when no songs are available', async () => {
(useSongs as jest.Mock).mockReturnValue({
fetchNextPage: jest.fn(),
hasNextPage: false,
songs: [],
status: 'success',
error: null,
});

render(
<Provider store={mockStore}>
<HomePage />
</Provider>
);

expect(await screen.findByText('NoResult')).toBeInTheDocument();
});

it('should render the SongContainer component when there are songs available', async () => {
(useSongs as jest.Mock).mockReturnValue({
fetchNextPage: jest.fn(),
hasNextPage: false,
songs: [{ id: '1', text: 'Test Song', liked: false }],
status: 'success',
error: null,
});

render(
<Provider store={mockStore}>
<HomePage />
</Provider>
);

expect(await screen.findByText('SongContainer')).toBeInTheDocument();
});


});






16 changes: 8 additions & 8 deletions src/pages/HomePage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React, { useRef } from 'react';
import { useDispatch } from 'react-redux';
import { Col, Container, Row ,Button} from 'react-bootstrap';
import FormInput from '@/components/base/FormInput';
import FormInput from '../../components/base/FormInput';
import { useSongs } from './helper';
import { useDebouncedCallback } from 'use-debounce';
import SongContainer from '@/containers/SongContainer';
import { setSongs } from '@/store/songs/SongSlice';
import { filterUndefined } from '@/lib/utils/sanitize';
import { DEFAULT_SEARCH } from '@/lib/constants';
import PlayerContainer from '@/containers/PlayerContainer';
import Loader from '@/components/base/Loader';
import SongContainer from '../../containers/SongContainer';
import { setSongs } from '../../store/songs/SongSlice';
import { filterUndefined } from '../../lib/utils/sanitize';
import { DEFAULT_SEARCH } from '../../lib/constants';
import PlayerContainer from '../../containers/PlayerContainer';
import Loader from '../../components/base/Loader';
import styled from 'styled-components';
import NoResult from '@/components/custom/NoResult';
import NoResult from '../../components/custom/NoResult';
import { useTranslation } from 'react-i18next';
import { useState,useEffect } from 'react';
import { Navigate } from 'react-router-dom';
Expand Down
Loading