Skip to content

Commit

Permalink
Merge pull request #25 from Pushkarm029/tests
Browse files Browse the repository at this point in the history
[DRAFT] Frontend Tests implemented using JEST
  • Loading branch information
Pushkarm029 authored Oct 21, 2023
2 parents d158a2f + 187141f commit 45df0b8
Show file tree
Hide file tree
Showing 9 changed files with 3,771 additions and 4,488 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Run Test
name: Running React Frontend Tests

on:
push:
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ Full Stack Application Will be ***Deployed soon***.
```shell
$ npm run deploy
```
7. cd into backend folder
7. To Run Tests on Frontend Locally
```shell
$ npm run test
```
8. cd into backend folder
```shell
cd ../backend
```
8. install the required dependencies for backend
9. install the required dependencies for backend
```shell
go get -u ./...
```
9. Start the server on :8080
10. Start the server on :8080
```shell
go run main.go
```
Expand Down
2 changes: 1 addition & 1 deletion frontend/Dockerfile.frontend
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ WORKDIR /app/frontend
COPY ./package.json ./
COPY ./package-lock.json ./
EXPOSE $PORT
RUN npm ci
RUN npm i
COPY ./ ./
CMD [ "npm", "start"]

Expand Down
8,010 changes: 3,645 additions & 4,365 deletions frontend/package-lock.json

Large diffs are not rendered by default.

9 changes: 2 additions & 7 deletions frontend/src/__tests__/explore.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
import fetchMock from 'fetch-mock';
import Explore from '../explore/App'; // Import your Explore component
import Explore from '../explore/App';
jest.setTimeout(20000)
const fakeData = [
{
Expand Down Expand Up @@ -317,13 +317,8 @@ describe('Explore', () => {
});

render(<Explore />);

// Use querySelector to get all img elements
const imgElements = document.querySelectorAll('.exploreImages img');

// Wait for the "Loading Bro......" text to be removed
await waitForElementToBeRemoved(() => screen.getByText('Loading Bro......'), { timeout: 10000 }); // Wait for up to 10 seconds

await waitForElementToBeRemoved(() => screen.getByText('Loading Bro......'), { timeout: 10000 });
imgElements.forEach((img, index) => {
expect(img).toHaveAttribute('src', fakeData[index].userPosts[0].image_link);
});
Expand Down
75 changes: 0 additions & 75 deletions frontend/src/__tests__/home.test.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,4 @@
import '@testing-library/jest-dom'
// import * as React from 'react'
// import {render, fireEvent, screen} from '@testing-library/react'
// import Login from '../components/auth/LoginAccountForm'

// jest.mock('../firebase')

// // const fakeUserResponse = {token: 'fake_user_token'}
// // const server = setupServer(
// // rest.post('/api/login', (req, res, ctx) => {
// // return res(ctx.json(fakeUserResponse))
// // }),
// // )
test('login test', () => {
expect(true).toBe(true);
})



// // beforeAll(() => server.listen())
// // afterEach(() => {
// // server.resetHandlers()
// // // window.localStorage.removeItem('token')
// // })
// // afterAll(() => server.close())


// const username = 'demo';
// const password = 'demo1234';

// test('Login Test', async () => {
// render(<Login />)
// // fireEvent.change(screen.getByLabelText(/username/i), {
// // target: {value: 'chuck'},
// // })
// // fireEvent.change(screen.getByLabelText(/password/i), {
// // target: {value: 'norris'},
// // })
// const emailField = getByTestId('email');
// const passField = getByTestId('password');
// fireEvent.change(emailField, { target: { value: 'Hello, Jest!' } });
// fireEvent.change(passField, { target: { value: 'Hello, Jest!' } });

// expect(emailField.value).toBe('Hello, Jest!');
// expect(passField.value).toBe('Hello, Jest!');


// // fireEvent.click(screen.getByText(/submit/i))
// // const alert = await screen.findByRole('alert')
// // expect(alert).toHaveTextContent(/congrats/i)
// // expect(window.localStorage.getItem('token')).toEqual(fakeUserResponse.token)
// })

// // test('handles server exceptions', async () => {
// // // mock the server error response for this test suite only.
// // server.use(
// // rest.post('/api/login', (req, res, ctx) => {
// // return res(ctx.status(500), ctx.json({message: 'Internal server error'}))
// // }),
// // )

// // render(<Login />)

// // // fill out the form
// // fireEvent.change(screen.getByLabelText(/username/i), {
// // target: {value: 'chuck'},
// // })
// // fireEvent.change(screen.getByLabelText(/password/i), {
// // target: {value: 'norris'},
// // })

// // fireEvent.click(screen.getByText(/submit/i))

// // // wait for the error message
// // const alert = await screen.findByRole('alert')

// // expect(alert).toHaveTextContent(/internal server error/i)
// // expect(window.localStorage.getItem('token')).toBeNull()
// // })
68 changes: 68 additions & 0 deletions frontend/src/__tests__/search.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import { render, screen, fireEvent, waitForElementToBeRemoved } from '@testing-library/react';
import SearchPage from '../overlay/search/App';
import { BrowserRouter } from 'react-router-dom';
import fetchMock from 'fetch-mock';
jest.setTimeout(20000)

const mockAPIdata = [[
"kd",
"0",
"KD",
"https://images.unsplash.com/photo-1691860305089-9a2566296202?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=385&q=80",
"kd@gmail.com"
],
[
"test",
"10001",
"testingname",
"https://images.unsplash.com/photo-1682314170732-2de75372c338?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHx0b3BpYy1mZWVkfDExOHx4SHhZVE1ITGdPY3x8ZW58MHx8fHw%3D&auto=format&fit=crop&w=500&q=60",
"test@insta.in"
]
]

test('renders the SearchPage component', () => {
render(<SearchPage />, { wrapper: BrowserRouter });
});

test('displays "No search results yet." with no input', () => {
const { getByText } = render(<SearchPage />, { wrapper: BrowserRouter });
const noResultsMessage = getByText('No search results yet.');
expect(noResultsMessage).toBeInTheDocument();
});

test('displays search results for a valid input', async () => {
fetchMock.mock('/api/search/users', () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
status: 200,
body: mockAPIdata,
});
}, 5000);
});
});
const { getByTestId, getByPlaceholderText, getByText } = render(<SearchPage />, { wrapper: BrowserRouter });
const searchInput = getByPlaceholderText('Type to search...');
fireEvent.change(searchInput, { target: { value: 'kd' } });
await waitForElementToBeRemoved(() => screen.getByText("kd is currently not available on this platform"), { timeout: 10000 });
const searchResults = getByTestId("search-results");
expect(searchResults).toBeInTheDocument();
});

test('displays a "not available" message when there are no results', () => {
const { getByTestId, getByPlaceholderText, getByText } = render(<SearchPage />, { wrapper: BrowserRouter });
const searchInput = getByPlaceholderText('Type to search...');
fireEvent.change(searchInput, { target: { value: 'NonExistentUser' } });
const notAvailableMessage = getByText('NonExistentUser is currently not available on this platform');
expect(notAvailableMessage).toBeInTheDocument();
});

test('navigates to the profile page when a search result is clicked', async () => {
const { getByTestId, getByPlaceholderText } = render(<SearchPage />, { wrapper: BrowserRouter });
const searchInput = getByPlaceholderText('Type to search...');
fireEvent.change(searchInput, { target: { value: 'kd' } });
await waitForElementToBeRemoved(() => screen.getByText("kd is currently not available on this platform"), { timeout: 10000 });
const searchResult = getByTestId("search-box-result");
fireEvent.click(searchResult);
});
49 changes: 30 additions & 19 deletions frontend/src/overlay/search/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,32 @@ export default function SearchPage() {
const navigate = useNavigate();
const [searchQuery, setSearchQuery] = useState("");
const [filteredResults, setFilteredResults] = useState([]);
const [userData, setUserData] = useState([]); // Initialize as an empty array
const [userData, setUserData] = useState([]);

useEffect(() => {
const abortController = new AbortController();
const signal = abortController.signal;
fetch(`/api/search/users`, {
headers: {
Accept: 'application/json',
Accept: "application/json",
},
signal, // Pass the signal to the fetch request
signal,
})
.then(response => response.json())
.then(data => {
console.log('API Response Data:', data);
.then((response) => response.json())
.then((data) => {
setUserData(data);
})
.catch(error => {
console.error('Error fetching images links:', error);
.catch((error) => {
console.error("Error fetching user data:", error);
setUserData([]);
});

return () => {
abortController.abort(); // Cancel the fetch request when the component unmounts
abortController.abort();
};
}, []);

useEffect(() => {
// Filter the data based on the search query
const filteredData = userData.filter((item) =>
item[0].toLowerCase().includes(searchQuery.toLowerCase())
);
Expand All @@ -43,9 +41,10 @@ export default function SearchPage() {
const handleSearchChange = (e) => {
setSearchQuery(e.target.value);
};

const handleNavigation = (targetEmail) => {
navigate(`/profile?prop=${targetEmail}`)
}
navigate(`/profile?prop=${targetEmail}`);
};

return (
<div className="searchOverlay">
Expand All @@ -57,32 +56,44 @@ export default function SearchPage() {
value={searchQuery}
onChange={handleSearchChange}
placeholder="Type to search..."
data-testid="search-input"
/>
{searchQuery.length > 0 ? (
filteredResults.length > 0 ? (
<div className="searchResults">
{filteredResults.map((result, index) => (
<div onClick={() => handleNavigation(result[4])} className="eachSearchResult" key={index}>
<img src={result[3]} />
<div
onClick={() => handleNavigation(result[4])}
className="eachSearchResult"
key={index}
data-testid="search-box-result"
>
<img src={result[3]} alt={`Result ${index}`} />
<div className="eachSearchResultLeft">
<div className="eachSearchResultTop">
<p><strong>{result[0]}</strong></p>
<p>
<strong>{result[0]}</strong>
</p>
</div>
<div className="eachSearchResultBottom">
<p className="eachSearchedUserName">{result[2]}</p>
<p className="eachSearchedFollowers">{result[1]} Followers</p>
<p className="eachSearchedUserName" data-testid="search-results">{result[2]}</p>
<p className="eachSearchedFollowers">
{result[1]} Followers
</p>
</div>
</div>
</div>
))}
</div>
) : (
<p><strong>{searchQuery}</strong> is currently not available on this platform</p>
<p>
{searchQuery} is currently not available on this platform
</p>
)
) : (
<p>No search results yet.</p>
)}
</div>
</div>
);
};
}
34 changes: 17 additions & 17 deletions frontend/src/setupProxy.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
// const { createProxyMiddleware } = require('http-proxy-middleware');

// module.exports = function (app) {
// const target = process.env.API_PROXY_TARGET || 'http://localhost:8080'; // Default to localhost:8080 if the env variable is not set

// app.use(
// '/api',
// createProxyMiddleware({
// target,
// changeOrigin: true,
// // secure: false,
// })
// );
// };

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
const target = process.env.API_PROXY_TARGET || 'http://localhost:8080'; // Default to localhost:8080 if the env variable is not set

app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8080',
target,
changeOrigin: true,
// secure: false,
})
);
};
};

// const { createProxyMiddleware } = require('http-proxy-middleware');

// module.exports = function (app) {
// app.use(
// '/api',
// createProxyMiddleware({
// target: 'http://localhost:8080',
// changeOrigin: true,
// })
// );
// };

0 comments on commit 45df0b8

Please sign in to comment.