Skip to content

Commit

Permalink
Merge branch 'develop' into dependabot/npm_and_yarn/qs-6.5.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Naapperas authored Feb 9, 2023
2 parents 3410665 + 5f96cb4 commit ea716a6
Show file tree
Hide file tree
Showing 16 changed files with 255 additions and 41 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ jobs:
- name: Test
run: CI=true npm run test-ci

- name: Upload code coverage to Codecov
uses: codecov/codecov-action@v3

audit:

runs-on: ubuntu-latest
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
[![Build Preview](https://img.shields.io/badge/Build%20Preview-Develop-brightgreen.svg?style=for-the-badge)](https://develop--nijobs.netlify.com/)

![LGTM Grade](https://img.shields.io/lgtm/grade/javascript/g/NIAEFEUP/nijobs-fe.svg?style=for-the-badge)
[![GitHub license](https://img.shields.io/github/license/NIAEFEUP/nijobs-fe.svg?style=for-the-badge)](https://github.com/NIAEFEUP/nijobs-fe/blob/master/LICENSE)
[![Codecov](https://img.shields.io/codecov/c/gh/NIAEFEUP/nijobs-fe?style=for-the-badge&token=HZ9RUO0UWR)](https://app.codecov.io/gh/NIAEFEUP/nijobs-fe)

[![MVP Milestone](https://img.shields.io/github/milestones/progress-percent/NIAEFEUP/nijobs-fe/2?style=for-the-badge)](https://github.com/NIAEFEUP/nijobs-fe/milestone/2)
[![GitHub license](https://img.shields.io/github/license/NIAEFEUP/nijobs-fe.svg?style=for-the-badge)](https://github.com/NIAEFEUP/nijobs-fe/blob/master/LICENSE)

A platform for companies to advertise their job opportunities to the students

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@
"collectCoverage": true,
"coverageReporters": [
"text",
"html"
"html",
"json"
],
"coverageThreshold": {
"global": {
Expand Down
10 changes: 8 additions & 2 deletions src/components/HomePage/SearchArea/SearchArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import useOffersSearcher from "../SearchResultsArea/SearchResultsWidget/useOffer

import useSearchParams from "./useUrlSearchParams";

import { ensureArray } from "../../../utils";

export const AdvancedSearchControllerContext = React.createContext({});

export const AdvancedSearchController = ({
Expand Down Expand Up @@ -97,8 +99,8 @@ export const AdvancedSearchController = ({
]);

setJobType(queryParams.jobType);
setFields(queryParams.fields || []);
setTechs(queryParams.technologies || []);
setFields(ensureArray(queryParams.fields ?? []));
setTechs(ensureArray(queryParams.technologies ?? []));

setSearchValue(queryParams.searchValue);
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -175,6 +177,10 @@ export const SearchArea = ({ onSubmit, searchValue,
</form>
<SubmitSearchButton
onClick={submitForm}
searchHasUserInput={
(searchValue !== "" && searchValue !== undefined)
|| advancedOptionsActive
}
/>
</Paper>
</ContextProvider>
Expand Down
145 changes: 132 additions & 13 deletions src/components/HomePage/SearchArea/SearchArea.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import {
} from "../../../actions/searchOffersActions";
import { createTheme } from "@material-ui/core";
import { renderWithStoreAndTheme, screen, fireEvent, act } from "../../../test-utils";

import { MemoryRouter } from "react-router-dom";

import PropTypes from "prop-types";

import qs from "qs";
import { INITIAL_JOB_TYPE } from "../../../reducers/searchOffersReducer";

// eslint-disable-next-line react/prop-types
const RouteWrappedContent = ({ children, url = "/" }) => (
Expand All @@ -22,6 +24,47 @@ const RouteWrappedContent = ({ children, url = "/" }) => (
</MemoryRouter>
);

const SearchAreaWrapper = ({
searchValue = "", jobType = INITIAL_JOB_TYPE, jobDuration = [null, null], filterJobDuration = false,
showJobDurationSlider = false, fields = [], technologies = [], setShowJobDurationSlider = () => { },
setTechs = () => { }, setJobDuration = () => { }, setFields = () => { }, setJobType = () => { },
setSearchValue = () => { }, onSubmit = () => {},
}) => (
<SearchArea
searchValue={searchValue}
jobType={jobType}
jobDuration={jobDuration}
filterJobDuration={filterJobDuration}
fields={fields}
technologies={technologies}
showJobDurationSlider={showJobDurationSlider}
setShowJobDurationSlider={setShowJobDurationSlider}
setTechs={setTechs}
setJobDuration={setJobDuration}
setFields={setFields}
setJobType={setJobType}
setSearchValue={setSearchValue}
onSubmit={onSubmit}
/>
);

SearchAreaWrapper.propTypes = {
onSubmit: PropTypes.func,
searchValue: PropTypes.string.isRequired,
jobType: PropTypes.string,
setSearchValue: PropTypes.func.isRequired,
setJobDuration: PropTypes.func.isRequired,
setJobType: PropTypes.func.isRequired,
fields: PropTypes.array.isRequired,
technologies: PropTypes.array.isRequired,
showJobDurationSlider: PropTypes.bool.isRequired,
setFields: PropTypes.func.isRequired,
setTechs: PropTypes.func.isRequired,
setShowJobDurationSlider: PropTypes.func.isRequired,
jobDuration: PropTypes.number,
filterJobDuration: PropTypes.bool,
};

describe("SearchArea", () => {
let onSubmit;
const theme = createTheme();
Expand All @@ -34,16 +77,8 @@ describe("SearchArea", () => {
it("should render a Paper, a Form, a Search Bar, a Search Button and Advanced Options Button", () => {
renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchArea
<SearchAreaWrapper
onSubmit={onSubmit}
fields={[]}
technologies={[]}
setShowJobDurationSlider={() => { }}
setTechs={() => { }}
setJobDuration={() => { }}
setFields={() => { }}
setJobType={() => { }}
setSearchValue={() => { }}
/>
</RouteWrappedContent>,
{ initialState, theme }
Expand All @@ -55,6 +90,88 @@ describe("SearchArea", () => {
expect(screen.getByRole("button", { name: "Search" })).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Toggle Advanced Search" })).toBeInTheDocument();
});
it("should render a text='Show All' in the default state of searchArea", () => {
const searchArea = renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchAreaWrapper />
</RouteWrappedContent>,
{ initialState, theme }
);

expect(searchArea.getByRole("button", { name: "Search" })).toHaveTextContent("Show All");
});
it("should render a text='Search' when search bar value != ''", () => {
const searchArea = renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchAreaWrapper
searchValue={"somevalue"}
/>
</RouteWrappedContent>,
{ initialState, theme }
);

expect(searchArea.getByRole("button", { name: "Search" })).toHaveTextContent("Search");
});
it("should render a text='Show All' when search bar has undefined value", () => {
const searchArea = renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchAreaWrapper
searchValue={undefined}
/>
</RouteWrappedContent>,
{ initialState, theme }
);

expect(searchArea.getByRole("button", { name: "Search" })).toHaveTextContent("Show All");
});
it("should render a text='Search' when fields != []", () => {
const searchArea = renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchAreaWrapper
fields={["field1", "field2"]}
/>
</RouteWrappedContent>,
{ initialState, theme }
);

expect(searchArea.getByRole("button", { name: "Search" })).toHaveTextContent("Search");
});
it("should render a text='Search' when technologies != []", () => {
const searchArea = renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchAreaWrapper
technologies={["tech1", "tech2"]}
/>
</RouteWrappedContent>,
{ initialState, theme }
);

expect(searchArea.getByRole("button", { name: "Search" })).toHaveTextContent("Search");
});
it("should render a text='Search' when jobType != INITIAL_JOB_TYPE", () => {
const searchArea = renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchAreaWrapper
jobType={"JOB"}
/>
</RouteWrappedContent>,
{ initialState, theme }
);

expect(searchArea.getByRole("button", { name: "Search" })).toHaveTextContent("Search");
});
it("should render a text='Search' when showJobDurationSlider = true ", () => {
const searchArea = renderWithStoreAndTheme(
<RouteWrappedContent>
<SearchAreaWrapper
showJobDurationSlider={true}
/>
</RouteWrappedContent>,
{ initialState, theme }
);

expect(searchArea.getByRole("button", { name: "Search" })).toHaveTextContent("Search");
});
});

describe("interaction", () => {
Expand Down Expand Up @@ -124,15 +241,13 @@ describe("SearchArea", () => {

renderWithStoreAndTheme(
<RouteWrappedContent url={url}>
<SearchArea
<SearchAreaWrapper
onSubmit={onSubmit}
setSearchValue={setSearchValue}
setJobType={setJobType}
setJobDuration={setJobDuration}
setShowJobDurationSlider={setShowJobDurationSlider}
fields={[]}
setFields={setFields}
technologies={[]}
setTechs={setTechs}
/>
</RouteWrappedContent>,
Expand Down Expand Up @@ -193,6 +308,10 @@ describe("SearchArea", () => {
const filterJobDuration = false;
props.setShowJobDurationSlider(filterJobDuration);
expect(dispatch).toHaveBeenCalledWith(setShowJobDurationSlider(false));

dispatch.mockClear();
props.resetAdvancedSearchFields();
expect(dispatch).toHaveBeenCalled();
});
});
});
15 changes: 10 additions & 5 deletions src/components/HomePage/SearchArea/SubmitSearchButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,32 @@ import React from "react";
import PropTypes from "prop-types";

import { Fab } from "@material-ui/core";
import { Search } from "@material-ui/icons";

import useSearchAreaStyle from "./searchAreaStyle";

const ShowAdvancedOptionsButton = ({ onClick }) => {
const SubmitSearchButton = ({ onClick, searchHasUserInput }) => {
const classes = useSearchAreaStyle();
return (
<div className={classes.submitSearchButtonWrapper}>
<Fab
color="primary"
aria-label="Search"
variant="extended"
onClick={onClick}
>
<Search />
<span>
{searchHasUserInput
? "Search"
: "Show All"}
</span>
</Fab>
</div>
);
};

ShowAdvancedOptionsButton.propTypes = {
SubmitSearchButton.propTypes = {
onClick: PropTypes.func.isRequired,
searchHasUserInput: PropTypes.bool.isRequired,
};

export default ShowAdvancedOptionsButton;
export default SubmitSearchButton;
4 changes: 0 additions & 4 deletions src/components/HomePage/SearchArea/SubmitSearchButton.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { Search } from "@material-ui/icons";
import { Fab } from "@material-ui/core";
import SubmitSearchButton from "./SubmitSearchButton";

Expand All @@ -11,9 +10,6 @@ describe("SubmitSearchButton", () => {
.find(Fab).exists()
).toBe(true);
});
it("should render 'search' icon", () => {
expect(shallow(<SubmitSearchButton />).find(Search).exists()).toBe(true);
});
});

describe("interaction", () => {
Expand Down
21 changes: 17 additions & 4 deletions src/components/HomePage/SearchArea/useUrlSearchParams.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useLocation, useHistory } from "react-router-dom";

import { throttle } from "lodash";

import { ensureArray } from "../../../utils";

const HISTORY_REPLACE_THROTTLE_DELAY_MS = 350;

/**
Expand Down Expand Up @@ -55,6 +57,7 @@ export default ({
const actualSetJobType = useCallback(({ target: { value: jobType } }) => {
changeURLFilters(location, queryParams, { jobType });

/* istanbul ignore else */
if (setJobType)
setJobType(jobType);

Expand All @@ -66,6 +69,7 @@ export default ({

changeURLFilters(location, queryParams, { jobMinDuration, jobMaxDuration });

/* istanbul ignore else */
if (setJobDuration)
setJobDuration(unused, duration);

Expand All @@ -75,33 +79,41 @@ export default ({
if (!showJobDurationSlider)
changeURLFilters(location, queryParams, { jobMinDuration: null, jobMaxDuration: null });

/* istanbul ignore else */
if (setShowJobDurationSlider)
setShowJobDurationSlider(showJobDurationSlider);

}, [changeURLFilters, location, queryParams, setShowJobDurationSlider]);

const actualSetFields = useCallback((fields) => {

changeURLFilters(location, queryParams, { fields });
const sanitizedFields = ensureArray(fields);

changeURLFilters(location, queryParams, { fields: sanitizedFields });

/* istanbul ignore else */
if (setFields)
setFields(fields);
setFields(sanitizedFields);

}, [changeURLFilters, location, queryParams, setFields]);

const actualSetTechs = useCallback((technologies) => {

changeURLFilters(location, queryParams, { technologies });
const sanitizedTechnologies = ensureArray(technologies);

changeURLFilters(location, queryParams, { technologies: sanitizedTechnologies });

/* istanbul ignore else */
if (setTechs)
setTechs(technologies);
setTechs(sanitizedTechnologies);

}, [changeURLFilters, location, queryParams, setTechs]);

const actualSetSearchValue = useCallback((searchValue) => {

changeURLFilters(location, queryParams, { searchValue });

/* istanbul ignore else */
if (setSearchValue)
setSearchValue(searchValue);

Expand All @@ -110,6 +122,7 @@ export default ({
const actualResetAdvancedSearchFields = useCallback(() => {
clearURLFilters(location);

/* istanbul ignore else */
if (resetAdvancedSearchFields)
resetAdvancedSearchFields();

Expand Down
Loading

0 comments on commit ea716a6

Please sign in to comment.