diff --git a/assignments/hackyourtemperature/__tests__/app.test.js b/assignments/hackyourtemperature/__tests__/app.test.js new file mode 100644 index 000000000..bfd01cb65 --- /dev/null +++ b/assignments/hackyourtemperature/__tests__/app.test.js @@ -0,0 +1,41 @@ +import app from "../app.js"; +import supertest from "supertest"; + +const request = supertest(app); + +describe("get /", () => { + it(`it should return status code 200 and "Hello from backend to frontend!"`, (done) => { + request.get('/') + .expect(200, 'Hello from backend to frontend!', done) + }); + });`` + + + describe("POST /weather", () => { + it('should return status code 400 and "Missing name of city" if no cityName', (done) => { + request.post('/weather') + .send({ cityName: "" }) + .expect(400, `{"error":"Missing name of city"}`, done) + }); + + it('should return status code 200 and contain "City: Amsterdam" and "temperature"', (done) => { + request.post('/weather') + .send({ cityName: "Amsterdam" }) + .expect(200) + .expect(res => { + if (!res.text.includes("City: Amsterdam")) { + throw new Error('Response does not include "City: Amsterdam"'); + } + if (!res.text.toLowerCase().includes("temperature")) { + throw new Error('Response does not include "temperature"'); + } + }) + .end(done); + }); + + it('should return status code 400 and "weatherText": "Error: city not found" if typing error', (done) => { + request.post('/weather') + .send({ cityName: "Amesterdam" }) + .expect(400, `{"weatherText":"Error: city not found"}`, done) + }); + }); \ No newline at end of file diff --git a/assignments/hackyourtemperature/app.js b/assignments/hackyourtemperature/app.js new file mode 100644 index 000000000..f9d549130 --- /dev/null +++ b/assignments/hackyourtemperature/app.js @@ -0,0 +1,42 @@ +import express from "express"; +import fetch from "node-fetch"; +import keys from "./sources/keys.js"; + +const app = express(); + +app.use(express.json()); + +app.get('/', (req, res) => { + res.status(200).send("Hello from backend to frontend!"); +}); + +app.post('/weather', async (req, res) => { + const cityName = req.body.cityName; + const responseText = { weatherText: "" } + + if (!cityName) { + return res.status(400).json({ error: "Missing name of city" }); + } + + try { + const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=${keys.API_KEY}&units=metric`); + const data = await response.json(); + + if (!response.ok) { + const {message} = data; + + throw new Error(message); + }; + + const {name, main} = data; + responseText.weatherText = `City: ${name}, temperature: ${main.temp.toFixed(1)}°C`; + res.status(200).send(responseText); + + } catch (error) { + responseText.weatherText = `${error}`; + res.status(400).send(responseText); + } + +}); + +export default app; \ No newline at end of file diff --git a/assignments/hackyourtemperature/babel.config.cjs b/assignments/hackyourtemperature/babel.config.cjs new file mode 100644 index 000000000..fbb629af6 --- /dev/null +++ b/assignments/hackyourtemperature/babel.config.cjs @@ -0,0 +1,13 @@ +module.exports = { + presets: [ + [ + // This is a configuration, here we are telling babel what configuration to use + "@babel/preset-env", + { + targets: { + node: "current", + }, + }, + ], + ], +}; diff --git a/assignments/hackyourtemperature/jest.config.js b/assignments/hackyourtemperature/jest.config.js new file mode 100644 index 000000000..19ba9649e --- /dev/null +++ b/assignments/hackyourtemperature/jest.config.js @@ -0,0 +1,8 @@ +export default { + // Tells jest that any file that has 2 .'s in it and ends with either js or jsx should be run through the babel-jest transformer + transform: { + "^.+\\.jsx?$": "babel-jest", + }, + // By default our `node_modules` folder is ignored by jest, this tells jest to transform those as well + transformIgnorePatterns: [], +}; diff --git a/assignments/hackyourtemperature/package.json b/assignments/hackyourtemperature/package.json new file mode 100644 index 000000000..c5ccfabc4 --- /dev/null +++ b/assignments/hackyourtemperature/package.json @@ -0,0 +1,24 @@ +{ + "name": "hackyourtemperature", + "version": "1.0.0", + "main": "server.js", + "scripts": { + "test": "jest", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "module", + "description": "", + "dependencies": { + "express": "^5.1.0", + "node-fetch": "^3.3.2" + }, + "devDependencies": { + "@babel/preset-env": "^7.27.1", + "babel-jest": "^29.7.0", + "jest": "^29.7.0", + "supertest": "^7.1.0" + } +} diff --git a/assignments/hackyourtemperature/server.js b/assignments/hackyourtemperature/server.js new file mode 100644 index 000000000..957db1951 --- /dev/null +++ b/assignments/hackyourtemperature/server.js @@ -0,0 +1,5 @@ +import app from './app.js'; + +const port = process.env.PORT || 3000; + +app.listen(port, () => console.log(`Listening on port ${port}`)); \ No newline at end of file diff --git a/assignments/hackyourtemperature/sources/keys.js b/assignments/hackyourtemperature/sources/keys.js new file mode 100644 index 000000000..89d33d049 --- /dev/null +++ b/assignments/hackyourtemperature/sources/keys.js @@ -0,0 +1,5 @@ +const keys = { + API_KEY: +} + +export default keys;