diff --git a/.gitignore b/.gitignore index b6b402ed9..339aed723 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ yarn-error.log *.bkp week3/prep-exercise/server-demo/ + +.env diff --git a/assignments/hackyourtemperature/app.js b/assignments/hackyourtemperature/app.js new file mode 100644 index 000000000..ed71b234b --- /dev/null +++ b/assignments/hackyourtemperature/app.js @@ -0,0 +1,49 @@ +// Import necessary modules +import express from 'express'; +import fetch from 'node-fetch'; +import keys from './sources/keys.js'; + +// Initialize Express app +const app = express(); + +// Middleware to parse JSON request bodies +app.use(express.json()); + +// Define a simple GET route +app.get('/', async (req, res) => { + res.send("Hello from backend to frontend") +}); + +// Post route to fetch weather data +app.post('/weather', async (req, res) => { + // Extract city name from request body + const { cityName } = req.body; + + // Validate the request + if (!cityName) { + return res.status(400).json({ weatherText: "City name is required" }); + } + try { + // Fetch weather data from OpenWeatherMap API using provided city name and API key + 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 (data.cod !== 200) { + return res.status(404).json({ weatherText: "City is not found" }); + } + + // return fetched weather data + res.json({ + temperature: data.main.temp, + weatherText: `The temperature in ${data.name} is ${data.main.temp}°C` + + }); + + } catch (error) { + res.status(500).json({ weatherText: "Server error" }); + } +}); +export default app; \ No newline at end of file diff --git a/assignments/hackyourtemperature/app.test.js b/assignments/hackyourtemperature/app.test.js new file mode 100644 index 000000000..a0a06400c --- /dev/null +++ b/assignments/hackyourtemperature/app.test.js @@ -0,0 +1,36 @@ +// Import required modules for testing +import request from "supertest"; +import app from "./app.js"; + +// Define test suite for POST /weather route +describe("POST /weather" , () => { + it("should return weather data for a valid city", async () => { + const response = await request(app) + .post('/weather') + .send({ cityName: "London" }); + + expect(response.status).toBe(200); + expect(response.body).toHaveProperty("temperature"); + expect(response.body.temperature).toBeGreaterThan(-50); + expect(response.body.temperature).toBeLessThan(60); + }); + + it("should return an error for an invalid city", async () => { + const response = await request(app) + .post('/weather') + .send({ cityName: "InvalidCity" }); + + expect(response.status).toBe(404); + expect(response.body).toHaveProperty("weatherText", "City is not found"); + }); + + it("should return an error for an empty city", async () => { + const response = await request(app) + .post('/weather') + .send({ cityName: "" }); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty("weatherText", "City name is required"); + }); +}); + diff --git a/assignments/config-files/babel.config.cjs b/assignments/hackyourtemperature/babel.config.cjs similarity index 100% rename from assignments/config-files/babel.config.cjs rename to assignments/hackyourtemperature/babel.config.cjs diff --git a/assignments/config-files/jest.config.js b/assignments/hackyourtemperature/jest.config.js similarity index 100% rename from assignments/config-files/jest.config.js rename to assignments/hackyourtemperature/jest.config.js diff --git a/assignments/hackyourtemperature/package.json b/assignments/hackyourtemperature/package.json new file mode 100644 index 000000000..a82ad588e --- /dev/null +++ b/assignments/hackyourtemperature/package.json @@ -0,0 +1,32 @@ +{ + "name": "hackyourtemperature", + "version": "1.0.0", + "main": "server.js", + "scripts": { + "test": "jest", + "start": "node server.js" + }, + "keywords": [], + "type": "module", + "author": "ahmadi.samira6761@gmail.com", + "license": "ISC", + "dependencies": { + "dotenv": "^16.4.7", + "express": "^4.21.2", + "express-handlebars": "^8.0.1", + "node-fetch": "^2.7.0" + }, + "devDependencies": { + "@babel/core": "^7.26.9", + "@babel/preset-env": "^7.26.9", + "babel-jest": "^29.7.0", + "cross-env": "^7.0.3", + "jest": "^29.7.0", + "supertest": "^7.0.0", + "ts-jest": "^29.2.6" + }, + "directories": { + "test": "tests" + }, + "description": "" +} diff --git a/assignments/hackyourtemperature/server.js b/assignments/hackyourtemperature/server.js new file mode 100644 index 000000000..eeef154bf --- /dev/null +++ b/assignments/hackyourtemperature/server.js @@ -0,0 +1,8 @@ +import app from './app.js'; + +const PORT = 3000; + +// Start the server on the specified port +app.listen(PORT, () => { + console.log(`Server is runnig 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..e5aa7611c --- /dev/null +++ b/assignments/hackyourtemperature/sources/keys.js @@ -0,0 +1,7 @@ +import dotenv from "dotenv"; +dotenv.config(); + +export default { + BASE_URL:process.env.BASE_URL, + API_KEY:process.env.API_KEY, +};