Skip to content

Glib-w2-NodeJS #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
37 changes: 37 additions & 0 deletions assignments/hackyourtemperature/__tests__/app.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { app } from "../app.js";
import supertest from "supertest";

const request = supertest(app);

describe("POST /weather", () => {
it("should return weather if cityName is provided", async () => {
const cityName = "Amsterdam";

const response = await request
.post("/weather")
.send({ cityName });

expect(response.status).toBe(200);
expect(response.body.weatherText).toContain("Temperature in Amsterdam");
});

it("should return error if cityName isn't provided", async () => {
const response = await request
.post("/weather")
.send({});

expect(response.status).toBe(400);
expect(response.body.error).toBe("cityName is required");
});

it("should return error if city is not found", async () => {
const cityName = "Balaboobooboo";

const response = await request
.post("/weather")
.send({ cityName });

expect(response.status).toBe(200);
expect(response.body.weatherText).toBe("City not found!");
Comment on lines +30 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in such a case don't you think that a 404 Not found as a good fit?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your test expects a 200 status code when a city is not found, but logically, it should return 404 (Not Found) instead.

Fix: update it to return res.status(404).json({ error: "City not found!" })
instead of:
res.json({ weatherText: "City not found!" }).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use .toMatchObject() Instead of .toBe() for JSON Comparisons.

Update it to: expect(response.body).toMatchObject({ error: "cityName is required" });

});
});
27 changes: 27 additions & 0 deletions assignments/hackyourtemperature/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import express from 'express';
import { keys } from './sources/keys.js';

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

app.get('/', (req, res) => {
res.send('Hello from backend to frontend!');
});

app.post('/weather', async (req, res) => {
const { cityName } = req.body;

if (!cityName) return res.status(400).json({ error: "cityName is required" });

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 (data.cod !== 200) return res.json({ weatherText: 'City not found!' });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a good idea to check for the response.ok and it's not always a check for a 200, not everything comes as okay or not, thus you might wanna change the returned status code to be a good match to the response type. but for basic use and learning purposes only you might just wanna keep it meaningful to the message sent.

have you thought of 404?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Check for 404, not 200 in the if condition.
  2. data.main.temp might be undefined if the API request fails or returns an unexpected response.
    Calling Math.floor(undefined) will result in NaN, which is not user-friendly.
  3. You're catching errors but not logging them, which makes debugging harder.

console.error(error); // Logs the error in the console
res.status(500).json({ error: 'Server-side error.' });


const temperature = Math.floor(data.main.temp);
res.json({ weatherText: `Temperature in ${cityName} is ${temperature}°C` });
} catch (error) {
res.status(500).json({ error: 'Server-side error.' });
}
});
13 changes: 13 additions & 0 deletions assignments/hackyourtemperature/babel.config.cjs
Original file line number Diff line number Diff line change
@@ -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",
},
},
],
],
};
8 changes: 8 additions & 0 deletions assignments/hackyourtemperature/jest.config.js
Original file line number Diff line number Diff line change
@@ -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: [],
};
25 changes: 25 additions & 0 deletions assignments/hackyourtemperature/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "hackyourtemperature",
"version": "1.0.0",
"main": "server.js",
"type": "module",
"scripts": {
"test": "jest",
"start": "nodemon server.js"
},
Comment on lines +6 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it.

"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.21.2",
"express-handlebars": "^8.0.1"
},
"devDependencies": {
"@babel/preset-env": "^7.26.9",
"babel-jest": "^29.7.0",
"jest": "^29.7.0",
"nodemon": "^3.1.9",
"supertest": "^7.0.0"
},
"description": ""
}
5 changes: 5 additions & 0 deletions assignments/hackyourtemperature/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { app } from './app.js';

const PORT = 3000;

app.listen(PORT, () => console.log(`Server is running on port ${PORT}...`));
3 changes: 3 additions & 0 deletions assignments/hackyourtemperature/sources/keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const keys = {
API_KEY: 'afc0f7157bda937505e237c68802afa5'
}
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the easy way as requested by the homework description, have you thought of a bit safer more reliable way? maybe you wanna lookup dotenv?

Copy link

@saadkhaleeq610 saadkhaleeq610 Mar 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exposing an API key in your source code is a security risk 🚨

Anyone can steal and misuse it.

The best practice is to hide the API key.

npm install dotenv

Move API key to a .env file (create this in your project root):

and write in it:

API_KEY=afc0f7157bda937505e237c68802afa5

then you can import the dotenv to securely import that api key. Something like this below.

import dotenv from 'dotenv';
dotenv.config();

export const keys = {
  API_KEY: process.env.API_KEY
};