Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into BE/test/need
Browse files Browse the repository at this point in the history
  • Loading branch information
azizamankenova committed Oct 31, 2023
2 parents d839d01 + 1fd2b4b commit 263f82f
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from http import HTTPStatus

from fastapi import APIRouter, HTTPException, Response, Depends
from Models.need_model import Need, QuantityUpdate
from Models.need_model import Need, QuantityUpdate,UrgencyUpdate
import Services.need_service as need_service

import Services.authentication_service as authentication_service
Expand Down Expand Up @@ -120,3 +120,25 @@ def get_unsupplied_quantity(need_id: str, response: Response):
err_json = create_json_for_error("Need unsupplied quantity get error", str(err))
response.status_code = HTTPStatus.NOT_FOUND
return json.loads(err_json)

@router.put("/{need_id}/urgency")
def set_urgency(need_id: str, urgency_data: UrgencyUpdate, response: Response, current_user: str = Depends(authentication_service.get_current_username)):
try:
need_service.set_urgency(need_id, urgency_data.urgency)
response.status_code = HTTPStatus.OK
return {"message": f"Urgency of need {need_id} is set to {urgency_data.urgency}"}
except ValueError as err:
err_json = create_json_for_error("Need urgency set update error", str(err))
response.status_code = HTTPStatus.NOT_FOUND
return json.loads(err_json)

@router.get("/{need_id}/urgency")
def get_urgency(need_id: str, response: Response):
try:
urgency = need_service.get_urgency(need_id)
response.status_code = HTTPStatus.OK
return {"Urgency": urgency}
except ValueError as err:
err_json = create_json_for_error("Need urgency get error", str(err))
response.status_code = HTTPStatus.NOT_FOUND
return json.loads(err_json)
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def general_user_optional_info(response, username:str = None) ->json:
json_result = create_json_for_error("Get user optional info faild", str(val_error))
return json.loads(json_result)

@router.get("/get-user-optional-info", responses={
@router.get("/user-optional-infos", responses={
status.HTTP_200_OK: {"model": UserOptionalInfos},
status.HTTP_404_NOT_FOUND: {"model": Error},
status.HTTP_401_UNAUTHORIZED: {"model": Error}
Expand All @@ -36,7 +36,7 @@ async def get_all_user_optional_info(response: Response, username: str = Depends
return general_user_optional_info(response=response)


@router.post("/set-user-optional-info", responses={
@router.post("/user-optional-infos/add-user-optional-info", responses={
status.HTTP_200_OK: {"model": UserOptionalInfo},
status.HTTP_404_NOT_FOUND: {"model": Error},
status.HTTP_401_UNAUTHORIZED: {"model": Error}
Expand All @@ -54,7 +54,7 @@ async def set_user_optional_info(user_optional_info: UserOptionalInfo, response:
return json.loads(json_result)


@router.post("/reset-user-optional-info", )
@router.post("/delete-user-optional-info-item", )
async def set_user_optional_info(reset_field: str, response: Response, username: str = Depends(authentication_service.get_current_username)):
try:
user_profile_service.reset_user_optional_info(username, reset_field)
Expand Down
3 changes: 3 additions & 0 deletions Disaster-Response-Platform/backend/Models/need_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ class Need(BaseModel):

class QuantityUpdate(BaseModel):
quantity: int

class UrgencyUpdate(BaseModel):
urgency: int
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from pydantic import BaseModel, Field
from typing import Dict, Any, List
from enum import Enum

class ProfileInfoApi(BaseModel):
base_url:str = "/api/profiles"
prefix:str = Field(default=None)
#route_path:str = Field(default=None)
name:str = Field(default=None)

15 changes: 14 additions & 1 deletion Disaster-Response-Platform/backend/Services/need_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,17 @@ def get_unsupplied_quantity(need_id: str) -> int:
if need_data:
return need_data["unsuppliedQuantity"]
else:
raise ValueError(f"Need id {need_id} not found")
raise ValueError(f"Need id {need_id} not found")

def set_urgency(need_id: str, urgency: int) -> bool:
result = needs_collection.update_one({"_id": ObjectId(need_id)}, {"$set": {"urgency": urgency}})
if result.matched_count == 0:
raise ValueError(f"Need id {need_id} not found")
return True

def get_urgency(need_id: str) -> int:
need_data = needs_collection.find_one({"_id": ObjectId(need_id)})
if need_data:
return need_data["urgency"]
else:
raise ValueError(f"Need id {need_id} not found")
159 changes: 159 additions & 0 deletions Disaster-Response-Platform/backend/Tests/test_user_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import datetime
import json
from fastapi.testclient import TestClient
from main import app
from Models.user_model import *
from Models.testing_profile_models import ProfileInfoApi
from Models.user_profile_model import *
from http import HTTPStatus
from Database.mongo import MongoDB
client = TestClient(app)

TEST_USER = "testi"
TEST_PASS = "tesTi2023!"

GLOBAL_TOKEN = ""
user_to_create:CreateUserRequest = CreateUserRequest(username = TEST_USER, first_name="Mahir", last_name = "Testeden",
phone_number = "05325325353", is_email_verified = False, private_account = False,
password = TEST_PASS, email = "testi@boun.edu.tr")
correct_login_request :LoginUserRequest = LoginUserRequest(username_or_email_or_phone = TEST_USER, password = TEST_PASS)
incorrect_login_request :LoginUserRequest = LoginUserRequest(username_or_email_or_phone = TEST_USER, password = "INCORRECT")

language_to_add:UserLanguage = UserLanguage(username=TEST_USER, language="Zulu", language_level="native")
language_to_update:UserLanguage = UserLanguage(username=TEST_USER, language="Zulu", language_level="beginner")
language_to_delete:UserLanguage = UserLanguage(username=TEST_USER, language="Zulu", language_level=None)


profession_to_add:UserProfession = UserProfession(username = TEST_USER, profession = "Truck Driver", profession_level= "certified pro")
skill_to_add:UserSkill = UserSkill(username=TEST_USER, skill_definition="Truck Driver", skill_level="skilled")
socialmedia_link_to_add = UserSocialMediaLink(username=TEST_USER, platform_name="X",
profile_URL="https://twitter.com/testici")
user_optionalinfo_to_add = UserOptionalInfo(username=TEST_USER,
date_of_birth=datetime.datetime.strptime("1990-10-12", "%Y-%m-%d"), nationality="TC",
identity_number="139090909090", education="orta",
ealth_condition="Hepimizi gömer", blood_type="B Rh+",
Address="O cadde bu sokak Kadıköy/İstanbul")

def clean_db_for_test():
profile_languages = MongoDB.get_collection('user_languages')
profile_optional_infos = MongoDB.get_collection('user_optional_infos')
profile_professions = MongoDB.get_collection('user_professions')
profile_skills = MongoDB.get_collection('user_skills')
profile_socialmedias = MongoDB.get_collection('user_socialmedias')
userDb = MongoDB.get_collection('authenticated_user')

query = {"username": TEST_USER}

profile_languages.delete_one(query)
profile_optional_infos.delete_one(query)
profile_professions.delete_one(query)
profile_skills.delete_one(query)
profile_socialmedias.delete_one(query)
userDb.delete_one(query)
return

def prepare_for_test():
global GLOBAL_TOKEN
clean_db_for_test()
create_user()
token = do_login()
GLOBAL_TOKEN = token

def create_user():
response = client.post("/api/users/signup", json=dict(user_to_create))
assert response.status_code == HTTPStatus.CREATED


def do_login():
response = client.post("/api/users/login", json=dict(correct_login_request))

assert response.status_code == HTTPStatus.OK

token = response.json()["access_token"]

assert token is not None
return token

def create_profile_info_subitems(profile_sub_info: ProfileInfoApi, jsonParam):
url = profile_sub_info.base_url + "/" + profile_sub_info.prefix +"/add-" + profile_sub_info.name
response = client.post(url,
json = dict(jsonParam),
headers={"Authorization": f"Bearer {GLOBAL_TOKEN}"})

assert response.status_code == HTTPStatus.OK

return response.json()

def test_create_language():
prepare_for_test()
command = ProfileInfoApi( prefix = "languages", name = "language")
create_profile_info_subitems(command, language_to_add)

def test_create_skills():
prepare_for_test()
command = ProfileInfoApi(prefix="skills", name="skill")
create_profile_info_subitems(command, skill_to_add)

def test_create_socialmedia_links():
prepare_for_test()
command = ProfileInfoApi(prefix="socialmedia-links", name="socialmedia-link")
create_profile_info_subitems(command, socialmedia_link_to_add)

def test_create_professions():
prepare_for_test()
command = ProfileInfoApi(prefix="professions", name="profession")
create_profile_info_subitems(command, profession_to_add)

def test_create_optionalinfos():
prepare_for_test()
command = ProfileInfoApi(prefix="user-optional-infos", name="user-optional-info")
res = user_optionalinfo_to_add.json()
res_j = json.loads(res)
create_profile_info_subitems(command, res_j)

def test_create_get_languages():
test_create_language()
command = ProfileInfoApi(prefix="languages", name="language")
response_json = create_get_profile_info_subitems(command)
assert dict(language_to_add) == dict(response_json["user_languages"][0])

def test_create_get_skills():
test_create_skills()
command = ProfileInfoApi(prefix="skills", name="skill")
response_json = create_get_profile_info_subitems(command)
assert dict(skill_to_add) == dict(response_json["user_skills"][0])

def test_create_get_professions():
test_create_professions()
command = ProfileInfoApi(prefix="professions", name="profession")
response_json = create_get_profile_info_subitems(command)
assert dict(profession_to_add) == dict(response_json["user_professions"][0])

def test_create_get_socialmedia_links():
test_create_socialmedia_links()
command = ProfileInfoApi(prefix="socialmedia-links", name="socialmedia-link")
response_json = create_get_profile_info_subitems(command)
assert dict(socialmedia_link_to_add) == dict(response_json["user_socialmedia_links"][0])

def test_create_get_optionalinfos():
test_create_optionalinfos()
command = ProfileInfoApi(prefix="user-optional-infos", name="user-optional-info")
response_json = create_get_profile_info_subitems(command)
res = user_optionalinfo_to_add.json()
res_j = json.loads(res)
if (response_json["user_optional_infos"][0]["date_of_birth"] is not None):
response_json["user_optional_infos"][0]["date_of_birth"] = (
datetime.datetime.strptime(response_json["user_optional_infos"][0]["date_of_birth"], "%Y-%m-%d %H:%M:%S"))
response_json["user_optional_infos"][0]["date_of_birth"] = response_json["user_optional_infos"][0]["date_of_birth"].strftime("%Y-%m-%d")
assert dict(res_j) == dict(response_json["user_optional_infos"][0])

def create_get_profile_info_subitems(profile_sub_info: ProfileInfoApi):
url = profile_sub_info.base_url + "/" + profile_sub_info.prefix
response = client.get(url,
headers={"Authorization": f"Bearer {GLOBAL_TOKEN}"})

assert response.status_code == HTTPStatus.OK

#assert dict(language_to_add) == dict(response.json()["user_languages"][0])

return response.json()
28 changes: 21 additions & 7 deletions Disaster-Response-Platform/frontend/components/NavigationBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Button, useDisclosure } from '@nextui-org/react'
import AddResourceForm from "./AddResource";
import useUser from "@/lib/useUser";
import { useRouter } from "next/router";
import fetchJson from "@/lib/fetchJson";


export default function NavigationBar() {
Expand All @@ -28,11 +29,6 @@ export default function NavigationBar() {
<FaMapMarkedAlt size={30} />
</Link>
</nav>
<nav className="p-4 h-14 text-center hover:-translate-y-1 duration-300" >
<Link href={`search`}>
<BsSearch size={25} />
</Link>
</nav>
</div>
<div className={styles.rightbar}>
<nav>
Expand All @@ -44,19 +40,37 @@ export default function NavigationBar() {
<AddResourceForm onOpenChange={onOpenChange} isOpen={isOpen} />
{user?.isLoggedIn === false && <nav>
<Link href={`register`}>
<Button variant="solid" color="primary" >Sign up</Button>
<Button variant="solid" color="primary" >Kayıt ol</Button>
</Link>
</nav>}
{user?.isLoggedIn === false && <nav>
<Link href={`login`}>
<Button variant="solid" color='primary' >Sign in</Button>
<Button variant="solid" color='primary' >Giriş yap</Button>
</Link>
</nav>}
{user?.isLoggedIn === true && <nav className="p-4 h-14 text-center hover:-translate-y-1 duration-300">
<Link href={`/profile`}>
<CgProfile size={30} />
</Link>
</nav>}
{user?.isLoggedIn === true && <nav >
<Button variant="solid" color='default'>

<a
href="/api/logout"
onClick={async (e) => {
e.preventDefault();
mutateUser(
await fetchJson("/api/logout", { method: "POST" }),
false,
);
router.push("/");
}}
>
Çıkış yap
</a>
</Button>
</nav>}
<nav>
<Button color="primary" className={styles.button}>
Acil Durum
Expand Down
16 changes: 7 additions & 9 deletions Disaster-Response-Platform/frontend/pages/api/logout.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
// pages/api/logout.ts

import sessionConfig from "@/lib/sessionConfig";
import { withIronSessionApiRoute } from "iron-session/next";

export default withIronSessionApiRoute(
function logoutRoute(req, res) {
req.session.destroy();
res.send({ ok: true });
},
sessionConfig
);

export default withIronSessionApiRoute(logoutRoute, sessionConfig);

async function logoutRoute(req, res) {
req.session.destroy();
res.json({ isLoggedIn: false, login: "" });
}
16 changes: 9 additions & 7 deletions Disaster-Response-Platform/frontend/pages/login/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,28 @@ export default function login() {
}
}
const fields = [
{ type: "text", name: "username_or_email_or_phone", required: true, label: "username, email or phone", },
{ type: "password", name: "password", required: true, label: "Password" },
{ type: "text", name: "username_or_email_or_phone", required: true, label: "telefon numarası, email ya da kullanıcı adı", placeholder: "telefon numarası, email ya da kullanıcı adı" },
{ type: "password", name: "password", required: true, label: "Şifre" , placeholder: "strong12345"},

]
return <form className="rounded-xl bg-gray-400 p-4 w-8/12" onSubmit={handleSubmit(onSubmit)} >

return <form className="rounded-xl bg-gray-200 p-6 w-8/12 center" onSubmit={handleSubmit(onSubmit)} >
<h1 className='text-6xl font-normal leading-normal mt-0 mb-2 text-center text-emerald-800'> Giriş yap</h1>
{fields.map(field => {
return <>
<Input type={field.type}
{...register(field.name, { required: field.required })}
style={{ border: 'none' }}
label={field.label}
labelPlacement={'outside'}
variant={'bordered'}
variant={'faded'}
className='mb-2'
placeholder={field.placeholder}
isRequired
/>
<div className="error" >{errors[field.name]?.message}</div>
<div className="text-center" >{errors[field.name]?.message}</div>
</>
})}
<Button disabled={isSubmitting} type='submit'>
<Button disabled={isSubmitting} type='submit' className='m-3 ml-0'>
{isSubmitting ? 'Loading' : "Submit"}
</Button>
</form>;
Expand Down
Loading

0 comments on commit 263f82f

Please sign in to comment.