Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assignments/hackyourtemperature_W2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
24 changes: 24 additions & 0 deletions assignments/hackyourtemperature_W2/__tests__/app.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import app from "../app.js";
import supertest from "supertest";

const request = supertest(app);

describe("POST /weather", () => {
it("should return 400 if cityName is missing", async () => {
const res = await request.post("/weather").send({});
expect(res.status).toBe(400);
expect(res.body.weatherText).toBe("cityName is required");
});

it("should return 404 if cityName is invalid", async () => {
const res = await request.post("/weather").send({ cityName: "InvalidCity123" });
expect(res.status).toBe(404);
expect(res.body.weatherText).toBe("City is not found!");
});

it("should return temperature if cityName is valid", async () => {
const res = await request.post("/weather").send({ cityName: "Amsterdam" });
expect(res.status).toBe(200);
expect(res.body.weatherText).toContain("The temperature in Amsterdam is");
});
});
43 changes: 43 additions & 0 deletions assignments/hackyourtemperature_W2/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import express from "express";
import keys from "./sources/keys.js";

const app = express();
app.use(express.json());

// Проверка работы сервера === test route
app.get("/", (req, res) => {
res.send("hello from backend to frontend!");
});

// Получение погоды по названию города === get weather by city name
app.post("/weather", async (req, res) => {
const cityName = req.body.cityName;

// Если город не указан === if city is not provided
if (!cityName) {
return res.status(400).json({ weatherText: "cityName is required" });
}

try {
// Запрос к OpenWeather API === request to OpenWeather API
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 city is not found
if (data.cod !== 200) {
return res.status(404).json({ weatherText: "City is not found!" });
}

// Отправка температуры пользователю === send temperature to user
const temperature = data.main.temp;
res.json({ weatherText: `The temperature in ${data.name} is ${temperature}°C` });
} catch (error) {
// Ошибка сервера === server error
res.status(500).json({ weatherText: "Server error!" });
}
});

// Экспорт для тестов и сервера === export for tests and server
export default app;
12 changes: 12 additions & 0 deletions assignments/hackyourtemperature_W2/babel.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
node: "current" // чтобы Jest понимал текущую версию Node === for Jest to understand the current Node version
}
}
]
]
};
27 changes: 27 additions & 0 deletions assignments/hackyourtemperature_W2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "hackyourtemperature_w2",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"scripts": {
"test": "jest",
"start": "node server.js",
"dev": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"dotenv": "^17.2.3",
"express": "^5.1.0",
"node-fetch": "^3.3.2"
},
"devDependencies": {
"@babel/preset-env": "^7.28.5",
"babel-jest": "^30.2.0",
"jest": "^30.2.0",
"nodemon": "^3.1.10",
"supertest": "^7.1.4"
}
}
4 changes: 4 additions & 0 deletions assignments/hackyourtemperature_W2/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import app from "./app.js";
// Start the server === don't add funktionality in this file
const PORT = 3000;
app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));
9 changes: 9 additions & 0 deletions assignments/hackyourtemperature_W2/sources/keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// sources/keys.js
import dotenv from "dotenv";
dotenv.config(); // Загружает переменные из .env === loads variables from .env

const keys = {
API_KEY: process.env.API_KEY || "" // fallback на пустую строку === fallback to empty string
};

export default keys;