diff --git a/assignments/hackyourtemperature/.gitignore b/assignments/hackyourtemperature/.gitignore new file mode 100644 index 000000000..62c6d3435 --- /dev/null +++ b/assignments/hackyourtemperature/.gitignore @@ -0,0 +1 @@ +sources/keys.js \ No newline at end of file diff --git a/assignments/hackyourtemperature/__tests__/app.test.js b/assignments/hackyourtemperature/__tests__/app.test.js new file mode 100644 index 000000000..23504a815 --- /dev/null +++ b/assignments/hackyourtemperature/__tests__/app.test.js @@ -0,0 +1,44 @@ +import app from "../sources/app.js"; +import * as keys from "../sources/keys.js"; +import supertest from "supertest"; +import fetch from "node-fetch"; + +const request = supertest(app); + +describe("POST /weather", () => { + it("Checking for request body", (done) => { + request + .post("/weather") + .expect(400, { weatherText: "Request body is missing" }, done); + }); + + it("CityName should exist", (done) => { + request + .post("/weather") + .send({ City: "" }) + .expect(400, { weatherText: "City name is missing" }, done); + }); + + it("CityName should be a string", (done) => { + request + .post("/weather") + .send({ cityName: 5 }) + .expect(400, { weatherText: "City name should be a string" }, done); + }); + + it("Checking if the WeatherAPI is online", async () => { + const response = await fetch( + `https://api.openweathermap.org/data/2.5/weather?q=Arnhem,nl&appid=${keys.API_KEY}&units=metric` + ); + expect(response.status).toBe(200); + }); + + it("Checking if temperature is a number", async () => { + const response = await fetch( + `https://api.openweathermap.org/data/2.5/weather?q=Arnhem,nl&appid=${keys.API_KEY}&units=metric` + ); + const json = await response.json(); + const temp = json.main.temp; + expect(typeof temp).toBe("number"); + }); +}); 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..d0d1e9ff3 --- /dev/null +++ b/assignments/hackyourtemperature/package.json @@ -0,0 +1,25 @@ +{ + "name": "hackyourtemperature", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "test": "jest", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "module", + "dependencies": { + "express": "^5.1.0", + "express-handlebars": "^8.0.2", + "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..a033399f9 --- /dev/null +++ b/assignments/hackyourtemperature/server.js @@ -0,0 +1,7 @@ +import app from "./sources/app.js"; + +const PORT = 3000; + +app.listen(PORT, () => { + console.log(`Example app listening on port ${PORT}`); +}); diff --git a/assignments/hackyourtemperature/sources/app.js b/assignments/hackyourtemperature/sources/app.js new file mode 100644 index 000000000..b00f5f4f5 --- /dev/null +++ b/assignments/hackyourtemperature/sources/app.js @@ -0,0 +1,47 @@ +import express from "express"; +import fetch from "node-fetch"; +import * as keys from "./keys.js"; + +const app = express(); + +app.use(express.json()); + +app.get("/", (req, res) => { + res.send("hello from backend to frontend!"); +}); + +app.post("/weather", async (req, res) => { + try { + if (!req.body) { + throw { weatherText: "Request body is missing" }; + } + + const { cityName } = req.body; + + if (!cityName) { + throw { weatherText: "City name is missing" }; + } + + if (typeof cityName !== "string") { + throw { weatherText: "City name should be a string" }; + } + + const response = await fetch( + `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&APPID=${keys.API_KEY}&units=metric` + ); + + if (!response.ok) { + throw { weatherText: "City is not found!" }; + } + + const temp = await response.json(); + + res.status(200).json({ + weatherText: `The temperature in ${cityName} is ${temp.main.temp}℃`, + }); + } catch (error) { + res.status(400).json(error); + } +}); + +export default app;