Skip to content

Commit ffc176e

Browse files
committed
Small improvements
- Trim search query - obvious in hindsight. Does away with the need to set isSearching to false if the search query is falsy. - Rename test spec + add inline snapshot comparison that checks for the existence of forecast items.
1 parent 59e3402 commit ffc176e

File tree

2 files changed

+28
-18
lines changed

2 files changed

+28
-18
lines changed

src/__tests__/app.test.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import App from '../components/app';
1212

1313
describe('<App />', () => {
1414
beforeAll(() => jest.useFakeTimers());
15-
1615
afterAll(() => jest.clearAllTimers());
1716

1817
const history = createMemoryHistory();
@@ -24,7 +23,7 @@ describe('<App />', () => {
2423
</Router>,
2524
);
2625

27-
test('renders the app', async () => {
26+
test('fetches and renders the current weather and a five day forecast', async () => {
2827
renderApp();
2928

3029
await waitForLoadingToFinish();
@@ -36,15 +35,28 @@ describe('<App />', () => {
3635
expect(
3736
screen.getByPlaceholderText(/search for a location/i),
3837
).toBeInTheDocument();
39-
await screen.findByText(/eldoret, ke/i);
38+
39+
expect(screen.getByText(/eldoret, ke/i)).toBeInTheDocument();
4040
expect(screen.getByText(/broken clouds/i)).toBeInTheDocument();
4141
expect(screen.getByText(/feels like 18°/i)).toBeInTheDocument();
4242
expect(screen.getByText(/30m\/s winds/i)).toBeInTheDocument();
4343
expect(screen.getByText(/49% humidity/i)).toBeInTheDocument();
4444
expect(
4545
screen.getByText(/'Netflix and chill' weather. It's pleasant outside/i),
4646
).toBeInTheDocument();
47-
expect(screen.getAllByRole('list').length).toEqual(5);
47+
expect(screen.getAllByRole('listitem').length).toEqual(5);
48+
const forecast = screen.getAllByRole('listitem').map((listItem) => {
49+
return listItem.textContent;
50+
});
51+
expect(forecast).toMatchInlineSnapshot(`
52+
Array [
53+
"Saturday22° / 22°",
54+
"Sunday22° / 22°",
55+
"Monday22° / 22°",
56+
"Tuesday20° / 20°",
57+
"Wednesday21° / 21°",
58+
]
59+
`);
4860
expect(screen.getByText(/Open source by/i)).toBeInTheDocument();
4961
expect(screen.getByText(/Dennis Kigen/i)).toBeInTheDocument();
5062
expect(screen.getByText(/©2020 - now/i)).toBeInTheDocument();

src/components/app.js

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ function viewStateReducer(state, action) {
4141
const App = () => {
4242
const [location, setLocation] = React.useState('Eldoret');
4343
const [debouncedSearchTerm, setDebouncedSearchTerm] = React.useState('');
44-
const [isSearching, setIsSearching] = React.useState(false);
4544
const [units, setUnits] = React.useState('metric');
46-
const [state, dispatch] = React.useReducer(viewStateReducer, {
45+
const [viewState, dispatch] = React.useReducer(viewStateReducer, {
4746
status: 'started',
4847
error: null,
4948
forecast: [],
@@ -59,12 +58,11 @@ const App = () => {
5958
);
6059

6160
const handleLocationChange = (event) => {
62-
if (event.target.value) {
61+
const query = event.target.value.trim();
62+
if (query) {
6363
setIsSearching(true);
64-
} else {
65-
setIsSearching(false);
6664
}
67-
debounceSearch(event.target.value);
65+
debounceSearch(query);
6866
};
6967

7068
const handleUnitsChange = (newUnits) => {
@@ -75,7 +73,7 @@ const App = () => {
7573
if (debouncedSearchTerm) {
7674
setLocation(debouncedSearchTerm);
7775
}
78-
}, [debouncedSearchTerm, isSearching]);
76+
}, [debouncedSearchTerm,]);
7977

8078
React.useEffect(() => {
8179
async function getWeather() {
@@ -129,8 +127,8 @@ const App = () => {
129127
<NavBar />
130128
<Switch>
131129
<Route exact path="/">
132-
{state.status === 'started' ? <Loading /> : null}
133-
{state.status === 'rejected' ? (
130+
{viewState.status === 'started' ? <Loading /> : null}
131+
{viewState.status === 'rejected' ? (
134132
<div className="w-3/5 md:w-3/5 lg:w-1/2 m-auto">
135133
<div className="mx-auto sm:max-w-xl 2xl:max-w-2xl">
136134
<div
@@ -150,14 +148,14 @@ const App = () => {
150148
fillRule="evenodd"
151149
/>
152150
</svg>
153-
<span>{state.error.message}</span>
151+
<span>{viewState.error.message}</span>
154152
</div>
155153
</div>
156154
</div>
157155
</div>
158156
) : null}
159-
{(state.weather && Object.keys(state.weather).length) ||
160-
(state.forecast && Object.keys(state.forecast).length) ? (
157+
{(viewState.weather && Object.keys(viewState.weather).length) ||
158+
(viewState.forecast && Object.keys(viewState.forecast).length) ? (
161159
<main>
162160
<div className="mx-auto w-5/6 md:w-full 2xl:max-w-7xl xl:max-w-6xl">
163161
<Search
@@ -166,8 +164,8 @@ const App = () => {
166164
onLocationChange={handleLocationChange}
167165
/>
168166
<WeatherCard
169-
forecast={state.forecast}
170-
weather={state.weather}
167+
forecast={viewState.forecast}
168+
weather={viewState.weather}
171169
units={units}
172170
onUnitsChange={handleUnitsChange}
173171
/>

0 commit comments

Comments
 (0)