Skip to content

Commit

Permalink
feat: add test component
Browse files Browse the repository at this point in the history
  • Loading branch information
sahsisunny committed Nov 7, 2023
1 parent 540c546 commit b862085
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 11 deletions.
41 changes: 41 additions & 0 deletions __tests__/components/Toast.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import Toast from '../../src/components/Toast';

describe('Toast', () => {
const onDismiss = jest.fn();

test('should render the toast component', () => {
const { container } = render(
<Toast message="This is a toast message" isVisible={true} timeToShow={5000} onDismiss={onDismiss} />
);

expect(container).toMatchSnapshot();
});

test('should render the toast component with the message', () => {
render(<Toast message="This is a toast message" isVisible={true} timeToShow={5000} onDismiss={onDismiss} />);

expect(screen.getByText('This is a toast message')).toBeInTheDocument();
});

test('should not render the toast component', () => {
const { container } = render(
<Toast message="This is a toast message" isVisible={false} timeToShow={5000} onDismiss={onDismiss} />
);

expect(container).toMatchSnapshot();
});

test('should not call onDismiss function when the timeToShow is not completed', () => {
render(<Toast message="This is a toast message" isVisible={true} timeToShow={5000} onDismiss={onDismiss} />);

expect(onDismiss).not.toHaveBeenCalled();
});

test('should call onDismiss function when the timeToShow is completed', async () => {
render(<Toast message="This is a toast message" isVisible={true} timeToShow={0} onDismiss={onDismiss} />);

await waitFor(() => expect(onDismiss).toHaveBeenCalled());
});
});
10 changes: 0 additions & 10 deletions __tests__/hello.test.tsx

This file was deleted.

26 changes: 26 additions & 0 deletions __tests__/pages/dashboard.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Dashboard from '../../src/pages/dashboard';
import { render, screen, fireEvent } from '@testing-library/react';

describe('Dashboard Component', () => {
test('renders the Dashboard component', () => {
render(<Dashboard />);
const urlInput = screen.getByPlaceholderText('🔗 Enter the URL');
const generateButton = screen.getByText('Generate');
const copyButton = screen.getByTestId('copy-button');

expect(urlInput).toBeInTheDocument();
expect(generateButton).toBeInTheDocument();
expect(copyButton).toBeInTheDocument();
});

test('generates a short URL when clicking the Generate button', () => {
render(<Dashboard />);
const generateButton = screen.getByText('Generate');
const shortUrlInput = screen.getByPlaceholderText('Copy the URL');

fireEvent.click(generateButton);
const shortUrlValue = shortUrlInput.value;

expect(shortUrlValue).toMatch(/^https:\/\/rds\.li\/[a-zA-Z0-9]+$/);
});
});
30 changes: 30 additions & 0 deletions src/components/Toast/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useEffect } from 'react';

interface ToastProps {
message: string;
isVisible: boolean;
timeToShow: number;
onDismiss: () => void;
}

const Toast: React.FC<ToastProps> = ({ message, isVisible, timeToShow, onDismiss }) => {
useEffect(() => {
if (isVisible) {
const timer = setTimeout(() => {
onDismiss();
}, timeToShow);

return () => {
clearTimeout(timer);
};
}
}, [isVisible, timeToShow, onDismiss]);

return isVisible ? (
<div className="fixed bottom-10 left-1/2 transform -translate-x-1/2 bg-gray-900 text-white px-4 py-2 rounded-lg border-2 border-cyan-100">
{message}
</div>
) : null;
};

export default Toast;
21 changes: 20 additions & 1 deletion src/pages/dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import Button from '@/components/Button';
import InputBox from '@/components/InputBox';
import Layout from '@/components/Layout';
import Toast from '@/components/Toast';
import { randomString } from '@/utils/constants';
import { useState } from 'react';
import CopyIcon from '../../../public/assets/icons/copy';

const Dashboard = () => {
const [url, getUrl] = useState<string>('');
const [shortUrl, setUrl] = useState<string>('');
const [toastMessage, setToastMessage] = useState<string>('');
const [showToast, setShowToast] = useState(false);

const handleUniqueUrl = () => {
setUrl(`https://rds.li/${randomString}`);
};

const handleCopyUrl = () => {
shortUrl ? setToastMessage('Copied to clipboard') : setToastMessage('No URL to copy');
navigator.clipboard.writeText(shortUrl);
setShowToast(true);
};

return (
<Layout title="Home | URL Shortener">
<div className="w-screen">
Expand Down Expand Up @@ -47,13 +57,22 @@ const Dashboard = () => {
<Button
type="button"
className="bg-gray-200 rounded-r-2xl p-4 hover:bg-gray-400"
onClick={() => navigator.clipboard.writeText(shortUrl)}
testId="copy-button"
onClick={handleCopyUrl}
>
<CopyIcon />
</Button>
</div>
</div>
</div>
{showToast && (
<Toast
message={toastMessage}
isVisible={showToast}
timeToShow={3000}
onDismiss={() => setShowToast(false)}
/>
)}
</div>
</Layout>
);
Expand Down

0 comments on commit b862085

Please sign in to comment.