mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-06-22 21:08:12 +08:00
refactor(curriculum): mock fetch in Build a Weather App (#59549)
This commit is contained in:
parent
26ab080ada
commit
ccdd205a15
@ -88,6 +88,38 @@ You will use a weather API. The output data has the following format:
|
||||
|
||||
NOTE: The tests will take time to complete. As long as you see `// running tests` in the console, they are being executed.
|
||||
|
||||
# --before-all--
|
||||
|
||||
```js
|
||||
window.fetch = (url) => {
|
||||
const city = url.split('/').pop();
|
||||
const cityMap = {
|
||||
'new york': {"coord":{"lon":-74.0059,"lat":40.7127},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"https://cdn.freecodecamp.org/weather-icons/04d.png"}],"base":"stations","main":{"temp":14.33,"feels_like":13.2,"temp_min":13.21,"temp_max":15.54,"pressure":1008,"humidity":53,"sea_level":1008,"grnd_level":1007},"visibility":10000,"wind":{"speed":3.6,"deg":40},"clouds":{"all":100},"dt":1732123426,"sys":{"type":1,"id":4610,"country":"US","sunrise":1732103363,"sunset":1732138471},"timezone":-18000,"id":5128581,"name":"New York","cod":200},
|
||||
"los angeles": {"coord":{"lon":-118.2437,"lat":34.0522},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"https://cdn.freecodecamp.org/weather-icons/01d.png"}],"base":"stations","main":{"temp":17.24,"feels_like":15.88,"temp_min":14.84,"temp_max":19.62,"pressure":1023,"humidity":33,"sea_level":1023,"grnd_level":1003},"visibility":10000,"wind":{"speed":2.57,"deg":70},"clouds":{"all":0},"dt":1732123664,"sys":{"type":2,"id":2075946,"country":"US","sunrise":1732113063,"sunset":1732150008},"timezone":-28800,"id":5368361,"name":"Los Angeles","cod":200},
|
||||
chicago: {"coord":{"lon":-87.6298,"lat":41.8781},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"https://cdn.freecodecamp.org/weather-icons/03d.png"}],"base":"stations","main":{"temp":8.91,"feels_like":4.91,"temp_min":7.86,"temp_max":9.44,"pressure":1009,"humidity":50,"sea_level":1009,"grnd_level":987},"visibility":10000,"wind":{"speed":9.39,"deg":285,"gust":12.52},"clouds":{"all":40},"dt":1732123645,"sys":{"type":2,"id":2010190,"country":"US","sunrise":1732106817,"sunset":1732141557},"timezone":-21600,"id":4887398,"name":"Chicago","cod":200},
|
||||
london: {"coord":{"lon":-0.1278,"lat":51.5074},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"https://cdn.freecodecamp.org/weather-icons/01n.png"}],"base":"stations","main":{"temp":2.62,"feels_like":0.84,"temp_min":1.72,"temp_max":3.49,"pressure":1010,"humidity":81,"sea_level":1010,"grnd_level":1005},"visibility":10000,"wind":{"speed":1.79,"deg":285,"gust":3.13},"clouds":{"all":1},"dt":1732123462,"sys":{"type":2,"id":2075535,"country":"GB","sunrise":1732087658,"sunset":1732118707},"timezone":0,"id":2643743,"name":"London","cod":200},
|
||||
tokyo: {"coord":{"lon":139.6917,"lat":35.6895},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"https://cdn.freecodecamp.org/weather-icons/10n.png"}],"base":"stations","main":{"temp":8.71,"feels_like":5.38,"temp_min":8.08,"temp_max":9.81,"pressure":1015,"humidity":92,"sea_level":1015,"grnd_level":1014},"visibility":7000,"wind":{"speed":6.69,"deg":330},"rain":{"1h":2.05},"clouds":{"all":75},"dt":1732123711,"sys":{"type":2,"id":268395,"country":"JP","sunrise":1732137787,"sunset":1732174284},"timezone":32400,"id":1850144,"name":"Tokyo","cod":200},
|
||||
|
||||
};
|
||||
return Promise.resolve({
|
||||
ok: city !== 'paris',
|
||||
json: () => Promise.resolve( cityMap[city]
|
||||
)}
|
||||
);
|
||||
}
|
||||
// function that construct an object with the id-value pairs that we expect in the page from an object
|
||||
const helper = wobj => ({
|
||||
'weather-icon': wobj.weather[0].icon,
|
||||
'main-temperature': wobj.main.temp || 'N/A',
|
||||
'feels-like': wobj.main.feels_like || 'N/A',
|
||||
humidity: wobj.main.humidity || 'N/A',
|
||||
wind: wobj.wind.speed || 'N/A',
|
||||
'wind-gust': wobj.wind.gust || 'N/A',
|
||||
'weather-main': wobj.weather[0].main || 'N/A',
|
||||
location: wobj.name || 'N/A'
|
||||
});
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `button` element with an `id` of `get-forecast`.
|
||||
@ -132,7 +164,7 @@ You should have an `img` element with the id `weather-icon` for displaying the w
|
||||
async () => {
|
||||
document.querySelector('select').value = 'chicago';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('img#weather-icon'));
|
||||
};
|
||||
```
|
||||
@ -143,7 +175,7 @@ You should have an element with the id `main-temperature` for displaying the mai
|
||||
async () => {
|
||||
document.querySelector('select').value = 'london';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('#main-temperature'));
|
||||
};
|
||||
```
|
||||
@ -154,7 +186,7 @@ You should have an element with the id `feels-like` for displaying what the temp
|
||||
async () => {
|
||||
document.querySelector('select').value = 'london';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('#feels-like'));
|
||||
};
|
||||
```
|
||||
@ -165,7 +197,7 @@ You should have an element with the id `humidity` for displaying the amount of h
|
||||
async () => {
|
||||
document.querySelector('select').value = 'london';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('#humidity'));
|
||||
};
|
||||
```
|
||||
@ -176,7 +208,7 @@ You should have an element with the id `wind` element for displaying the wind sp
|
||||
async () => {
|
||||
document.querySelector('select').value = 'new york';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('#wind'));
|
||||
};
|
||||
```
|
||||
@ -187,7 +219,7 @@ You should have an element with the id `wind-gust` element for displaying the wi
|
||||
async () => {
|
||||
document.querySelector('select').value = 'new york';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('#wind-gust'));
|
||||
};
|
||||
```
|
||||
@ -198,7 +230,7 @@ You should have an element with the id `weather-main` element for displaying the
|
||||
async () => {
|
||||
document.querySelector('select').value = 'new york';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('#weather-main'));
|
||||
};
|
||||
```
|
||||
@ -209,7 +241,7 @@ You should have an element with the id `location` element for displaying the cur
|
||||
async () => {
|
||||
document.querySelector('select').value = 'new york';
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.exists(document.querySelector('#location'));
|
||||
};
|
||||
```
|
||||
@ -269,17 +301,6 @@ When New York is selected the `showWeather` function should display the data fro
|
||||
```js
|
||||
async () => {
|
||||
try {
|
||||
// function that construct an object with the id-value pairs that we expect in the page from an object
|
||||
const helper = wobj => ({
|
||||
'weather-icon': wobj.weather[0].icon,
|
||||
'main-temperature': wobj.main.temp || 'N/A',
|
||||
'feels-like': wobj.main.feels_like || 'N/A',
|
||||
humidity: wobj.main.humidity || 'N/A',
|
||||
wind: wobj.wind.speed || 'N/A',
|
||||
'wind-gust': wobj.wind.gust || 'N/A',
|
||||
'weather-main': wobj.weather[0].main || 'N/A',
|
||||
location: wobj.name || 'N/A'
|
||||
});
|
||||
const city = 'new york';
|
||||
document.querySelector('select').value = city;
|
||||
document.querySelector('#get-forecast').click();
|
||||
@ -289,8 +310,6 @@ async () => {
|
||||
`https://weather-proxy.freecodecamp.rocks/api/city/${city}`
|
||||
).then(data => data.json());
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
|
||||
// construct the object from the data from the API
|
||||
const extractedData = helper(body);
|
||||
|
||||
@ -319,17 +338,6 @@ When Chicago is selected the `showWeather` function should display the data from
|
||||
```js
|
||||
async () => {
|
||||
try {
|
||||
// function that construct an object with the id-value pairs that we expect in the page from an object
|
||||
const helper = wobj => ({
|
||||
'weather-icon': wobj.weather[0].icon,
|
||||
'main-temperature': wobj.main.temp || 'N/A',
|
||||
'feels-like': wobj.main.feels_like || 'N/A',
|
||||
humidity: wobj.main.humidity || 'N/A',
|
||||
wind: wobj.wind.speed || 'N/A',
|
||||
'wind-gust': wobj.wind.gust || 'N/A',
|
||||
'weather-main': wobj.weather[0].main || 'N/A',
|
||||
location: wobj.name || 'N/A'
|
||||
});
|
||||
const city = 'chicago';
|
||||
document.querySelector('select').value = city;
|
||||
document.querySelector('#get-forecast').click();
|
||||
@ -339,8 +347,6 @@ async () => {
|
||||
`https://weather-proxy.freecodecamp.rocks/api/city/${city}`
|
||||
).then(data => data.json());
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
|
||||
// construct the object from the data from the API
|
||||
const extractedData = helper(body);
|
||||
|
||||
@ -369,17 +375,6 @@ When London is selected the `showWeather` function should display the data from
|
||||
```js
|
||||
async () => {
|
||||
try {
|
||||
// function that construct an object with the id-value pairs that we expect in the page from an object
|
||||
const helper = wobj => ({
|
||||
'weather-icon': wobj.weather[0].icon,
|
||||
'main-temperature': wobj.main.temp || 'N/A',
|
||||
'feels-like': wobj.main.feels_like || 'N/A',
|
||||
humidity: wobj.main.humidity || 'N/A',
|
||||
wind: wobj.wind.speed || 'N/A',
|
||||
'wind-gust': wobj.wind.gust || 'N/A',
|
||||
'weather-main': wobj.weather[0].main || 'N/A',
|
||||
location: wobj.name || 'N/A'
|
||||
});
|
||||
const city = 'london';
|
||||
document.querySelector('select').value = city;
|
||||
document.querySelector('#get-forecast').click();
|
||||
@ -389,8 +384,6 @@ async () => {
|
||||
`https://weather-proxy.freecodecamp.rocks/api/city/${city}`
|
||||
).then(data => data.json());
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
|
||||
// construct the object from the data from the API
|
||||
const extractedData = helper(body);
|
||||
|
||||
@ -419,17 +412,6 @@ When Tokyo is selected the `showWeather` function should display the data from t
|
||||
```js
|
||||
async () => {
|
||||
try {
|
||||
// function that construct an object with the id-value pairs that we expect in the page from an object
|
||||
const helper = wobj => ({
|
||||
'weather-icon': wobj.weather[0].icon,
|
||||
'main-temperature': wobj.main.temp || 'N/A',
|
||||
'feels-like': wobj.main.feels_like || 'N/A',
|
||||
humidity: wobj.main.humidity || 'N/A',
|
||||
wind: wobj.wind.speed || 'N/A',
|
||||
'wind-gust': wobj.wind.gust || 'N/A',
|
||||
'weather-main': wobj.weather[0].main || 'N/A',
|
||||
location: wobj.name || 'N/A'
|
||||
});
|
||||
const city = 'tokyo';
|
||||
document.querySelector('select').value = city;
|
||||
document.querySelector('#get-forecast').click();
|
||||
@ -439,8 +421,6 @@ async () => {
|
||||
`https://weather-proxy.freecodecamp.rocks/api/city/${city}`
|
||||
).then(data => data.json());
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
|
||||
// construct the object from the data from the API
|
||||
const extractedData = helper(body);
|
||||
|
||||
@ -469,17 +449,6 @@ When Los Angeles is selected the `showWeather` function should display the data
|
||||
```js
|
||||
async () => {
|
||||
try {
|
||||
// function that construct an object with the id-value pairs that we expect in the page from an object
|
||||
const helper = wobj => ({
|
||||
'weather-icon': wobj.weather[0].icon,
|
||||
'main-temperature': wobj.main.temp || 'N/A',
|
||||
'feels-like': wobj.main.feels_like || 'N/A',
|
||||
humidity: wobj.main.humidity || 'N/A',
|
||||
wind: wobj.wind.speed || 'N/A',
|
||||
'wind-gust': wobj.wind.gust || 'N/A',
|
||||
'weather-main': wobj.weather[0].main || 'N/A',
|
||||
location: wobj.name || 'N/A'
|
||||
});
|
||||
const city = 'los angeles';
|
||||
document.querySelector('select').value = city;
|
||||
document.querySelector('#get-forecast').click();
|
||||
@ -489,8 +458,6 @@ async () => {
|
||||
`https://weather-proxy.freecodecamp.rocks/api/city/${city}`
|
||||
).then(data => data.json());
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
|
||||
// construct the object from the data from the API
|
||||
const extractedData = helper(body);
|
||||
|
||||
@ -559,7 +526,7 @@ async () => {
|
||||
const city = 'paris';
|
||||
document.querySelector('select').value = city;
|
||||
document.querySelector('#get-forecast').click();
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
assert.include(testArr[0], 'Something went wrong, please try again later');
|
||||
assert.lengthOf(testArr, 1);
|
||||
} finally {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user