Fix frontend bugs
This commit is contained in:
parent
a538c5f74c
commit
ed6b3f2447
|
@ -1,66 +0,0 @@
|
|||
const mockedUsedNavigate = jest.fn();
|
||||
|
||||
jest.mock("react-router-dom", () => ({
|
||||
...jest.requireActual("react-router-dom"),
|
||||
useNavigate: () => mockedUsedNavigate,
|
||||
}));
|
||||
|
||||
import "../matchMedia.mock";
|
||||
import { act, renderHook } from "@testing-library/react";
|
||||
import { useAuthenticateUser } from "./useAuthenticateUser";
|
||||
|
||||
describe("UseAuthenticateUser Hook Test", () => {
|
||||
afterEach(() => {
|
||||
localStorage.removeItem("token");
|
||||
});
|
||||
|
||||
test("Hook initial state", async () => {
|
||||
const { result } = renderHook(() => useAuthenticateUser());
|
||||
expect(result.current.isLoading).toBeFalsy();
|
||||
expect(result.current.error).toBeNull();
|
||||
});
|
||||
|
||||
test("Hook fetch state - Authenticate function - Promise not resolved", async () => {
|
||||
const { result } = renderHook(() => useAuthenticateUser());
|
||||
|
||||
act(() => {
|
||||
result.current.authenticate({
|
||||
email: "martin@gmail.com",
|
||||
password: "password1234",
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
expect(result.current.error).toBeNull();
|
||||
});
|
||||
|
||||
test("Hook fetch state - Authenticate function - Promise success", async () => {
|
||||
const { result } = renderHook(() => useAuthenticateUser());
|
||||
|
||||
await act(async () => {
|
||||
await result.current.authenticate({
|
||||
email: "martin@gmail.com",
|
||||
password: "password1234",
|
||||
});
|
||||
});
|
||||
|
||||
expect(localStorage.getItem("token")).not.toBeNull();
|
||||
expect(result.current.isLoading).toBeFalsy();
|
||||
expect(result.current.error).not.toBeNull();
|
||||
});
|
||||
|
||||
test("Hook fetch state - Authenticate function - Promise failed", async () => {
|
||||
const { result } = renderHook(() => useAuthenticateUser());
|
||||
|
||||
await act(async () => {
|
||||
await result.current.authenticate({
|
||||
email: "notExistingUser",
|
||||
password: "notExistingUser",
|
||||
});
|
||||
});
|
||||
|
||||
expect(localStorage.getItem("token")).toBe("undefined");
|
||||
expect(result.current.isLoading).toBeFalsy();
|
||||
expect(result.current.error).not.toBeNull();
|
||||
});
|
||||
});
|
|
@ -1,80 +0,0 @@
|
|||
import React, { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import { Credentials, User, TokenData } from "../Types";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { fetchUserById, logIn } from "../Api";
|
||||
import { tokenStatus } from "../Api";
|
||||
import jwt_decode from "jwt-decode";
|
||||
|
||||
export const useAuthenticateUser = () => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isAirline, setIsAirline] = useState(false);
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [tokenValidated, setTokenValidated] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const authenticate = async (credentials: Credentials): Promise<void> => {
|
||||
if (!user) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
const tokens = await logIn(credentials);
|
||||
localStorage.setItem("token", tokens.access_token);
|
||||
const airline = (jwt_decode(tokens.access_token) as TokenData).airline;
|
||||
setIsAirline(airline)
|
||||
|
||||
if (tokens.user_id) {
|
||||
const user = await fetchUserById(tokens.user_id);
|
||||
setUser(user);
|
||||
} else {
|
||||
setError(tokens.message!.split(".")[0] + ".");
|
||||
setUser(null);
|
||||
}
|
||||
} catch (error) {
|
||||
setError(error as string);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
navigate("/home")
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const validateToken = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const existingToken = localStorage.getItem("token");
|
||||
if (existingToken && !tokenValidated) {
|
||||
const response = await tokenStatus(existingToken);
|
||||
|
||||
const { message } = response;
|
||||
if (message) throw new Error("Invalid token");
|
||||
|
||||
const airline = (jwt_decode(existingToken) as TokenData).airline;
|
||||
setIsAirline(airline)
|
||||
|
||||
const user = await fetchUserById(response.id);
|
||||
setUser(user);
|
||||
}
|
||||
|
||||
setTokenValidated(true);
|
||||
} catch (error) {
|
||||
logout();
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
localStorage.removeItem("token");
|
||||
setUser(null);
|
||||
setTokenValidated(false)
|
||||
navigate("/login");
|
||||
};
|
||||
|
||||
return { user, isLoading, authenticate, validateToken, isAirline, logout, error };
|
||||
};
|
|
@ -37,9 +37,15 @@ import jwt_decode from "jwt-decode";
|
|||
useEffect(() => {
|
||||
const existingToken = localStorage.getItem("token");
|
||||
if (existingToken) {
|
||||
const airline = (jwt_decode(existingToken) as TokenData).airline;
|
||||
setIsAirline(airline)
|
||||
|
||||
let airline
|
||||
try {
|
||||
airline = (jwt_decode(existingToken) as TokenData).airline;
|
||||
setIsAirline(airline)
|
||||
} catch (err) {
|
||||
setLoadingInitial(false);
|
||||
logout()
|
||||
return;
|
||||
}
|
||||
|
||||
tokenStatus(existingToken)
|
||||
.then((res) => fetchUserById(res.id)
|
||||
|
@ -47,7 +53,10 @@ import jwt_decode from "jwt-decode";
|
|||
.catch((_error) => {})
|
||||
.finally(() => setLoadingInitial(false))
|
||||
)
|
||||
.catch((_error) => {})
|
||||
.catch((_error) => {
|
||||
setLoadingInitial(false)
|
||||
logout()
|
||||
})
|
||||
// .finally(() => setLoadingInitial(false));
|
||||
} else {
|
||||
setLoadingInitial(false)
|
||||
|
|
|
@ -9,9 +9,6 @@ from src.api.cruds import flight as flight_crud
|
|||
from src.api.db import get_db
|
||||
from src.api.schemas.flight import Flight, FlightCreate, FlightStatusUpdate
|
||||
|
||||
# from copy import copy
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
|
|
|
@ -3,4 +3,4 @@ fastapi[all]==0.103.2
|
|||
pyjwt==2.6.0
|
||||
gunicorn==20.1.0
|
||||
requests==2.31.0
|
||||
aiohttp==3.8.6
|
||||
asyncreq==0.0.4
|
|
@ -1,11 +1,11 @@
|
|||
from typing import Annotated
|
||||
|
||||
from asyncreq import request
|
||||
from fastapi import APIRouter, Header, HTTPException
|
||||
|
||||
from src.api.config import API_AUTH
|
||||
from src.api.schemas.auth import RefreshToken, Token
|
||||
from src.api.schemas.user import UserLogin, UserMin, UserRegister
|
||||
from src.api.utils.network import request
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from typing import Annotated, Optional
|
||||
|
||||
from asyncreq import request
|
||||
from fastapi import APIRouter, Header, HTTPException
|
||||
|
||||
from src.api.config import API_FLIGHTS, API_MESSAGES
|
||||
from src.api.routes.auth import status as checkAuth
|
||||
from src.api.schemas.flight import Flight, FlightCreate, FlightStatusUpdate
|
||||
from src.api.utils.network import request
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from asyncreq import request
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from src.api.config import API_NOTIFICATIONS
|
||||
from src.api.schemas.notification import Update as Message
|
||||
from src.api.utils.network import request
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from typing import Annotated
|
||||
|
||||
from asyncreq import request
|
||||
from fastapi import APIRouter, Header, HTTPException
|
||||
|
||||
from src.api.config import API_SUBSCRIPTIONS
|
||||
from src.api.routes.auth import status as checkAuth
|
||||
from src.api.schemas.subscriptions import Subscription
|
||||
from src.api.utils.network import request
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from asyncreq import request
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from src.api.config import API_USERS
|
||||
from src.api.schemas.user import User, UserRegister
|
||||
from src.api.utils.network import request
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
import aiohttp
|
||||
import async_timeout
|
||||
from aiohttp import ClientConnectorError, ContentTypeError, JsonPayload
|
||||
from fastapi import HTTPException, Response
|
||||
|
||||
|
||||
async def make_request(
|
||||
url: str,
|
||||
method: str,
|
||||
headers: dict = None,
|
||||
query: Optional[dict] = None,
|
||||
data: str = None,
|
||||
json: JsonPayload = None,
|
||||
timeout: int = 60,
|
||||
):
|
||||
async with async_timeout.timeout(delay=timeout):
|
||||
async with aiohttp.ClientSession(headers=headers) as session:
|
||||
async with session.request(
|
||||
method=method, url=url, params=query, data=data, json=json
|
||||
) as response:
|
||||
if response.status == 204:
|
||||
response_json = Response(status_code=204)
|
||||
else:
|
||||
response_json = await response.json()
|
||||
decoded_json = response_json
|
||||
return decoded_json, response.status, response.headers
|
||||
|
||||
|
||||
async def request(url, method, headers=None, data=None, json=None, query=None):
|
||||
try:
|
||||
(x, y, z) = await make_request(
|
||||
url=url, method=method, headers=headers, data=data, json=json, query=query
|
||||
)
|
||||
except ClientConnectorError:
|
||||
raise HTTPException(status_code=503, detail="Service is unavailable.")
|
||||
except ContentTypeError:
|
||||
raise HTTPException(status_code=500, detail="Service error.")
|
||||
return x, y, z
|
|
@ -60,7 +60,7 @@ export const addData = <T>(storeName: string, data: T): Promise<T|string|null> =
|
|||
});
|
||||
};
|
||||
|
||||
export const deleteData = (storeName: string, key: string): Promise<boolean> => {
|
||||
export const deleteData = (storeName: string, key: number): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
request = indexedDB.open('myDB', version);
|
||||
|
||||
|
@ -80,7 +80,7 @@ export const deleteData = (storeName: string, key: string): Promise<boolean> =>
|
|||
});
|
||||
};
|
||||
|
||||
export const updateData = <T>(storeName: string, key: string, data: T): Promise<T|string|null> => {
|
||||
export const updateData = <T>(storeName: string, key: number, data: T): Promise<T|string|null> => {
|
||||
return new Promise((resolve) => {
|
||||
request = indexedDB.open('myDB', version);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Stores, addData, deleteData, getStoreData, updateData, initDB } from '.
|
|||
export const useFetchZones = () => {
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [zones, setZones] = useState<Flight[]>([]);
|
||||
|
||||
let origin = process.env.REACT_APP_ORIGIN;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -22,10 +23,14 @@ export const useFetchZones = () => {
|
|||
fetchZones(origin, null)
|
||||
.then((data) => {
|
||||
localStorage.setItem('lastUpdated', newUpdate)
|
||||
setZones(data);
|
||||
let toAdd: Flight[] = []
|
||||
data.map((u) => {
|
||||
addData(Stores.Flight, u)
|
||||
if (u.status != 'Deleted') {
|
||||
addData(Stores.Flight, u)
|
||||
toAdd.push(u)
|
||||
}
|
||||
})
|
||||
setZones(toAdd);
|
||||
})
|
||||
.catch((error) => {});
|
||||
}
|
||||
|
@ -42,20 +47,32 @@ export const useFetchZones = () => {
|
|||
.then((data) => {
|
||||
localStorage.setItem('lastUpdated', newUpdate)
|
||||
let toAdd: Flight[] = []
|
||||
let toRemove: Flight[] = []
|
||||
|
||||
zones.forEach((c, i) => {
|
||||
let index = data.findIndex(x => x.id === c.id)
|
||||
if (index >= 0) {
|
||||
toAdd.push(data[index]);
|
||||
console.log(",aria")
|
||||
updateData(Stores.Flight, String(c.id), data[index])
|
||||
console.log(data[index].status)
|
||||
if (data[index].status == 'Deleted') {
|
||||
console.log("sacamos")
|
||||
toRemove.push(data[index])
|
||||
deleteData(Stores.Flight, c.id)
|
||||
} else {
|
||||
toAdd.push(data[index]);
|
||||
updateData(Stores.Flight, c.id, data[index])
|
||||
}
|
||||
} else {
|
||||
toAdd.push(c);
|
||||
if (c.status == 'Deleted') {
|
||||
toRemove.push(c);
|
||||
} else {
|
||||
toAdd.push(c);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(toAdd)
|
||||
let filtered = data.filter(o => !toAdd.some(b => { return o.id === b.id} ))
|
||||
console.log(toRemove)
|
||||
let filtered = data.filter(o => !toAdd.some(b => { return o.id === b.id}) && !toRemove.some(b => { return o.id === b.id}))
|
||||
const newArray = toAdd.concat(filtered);
|
||||
filtered.forEach(c => {
|
||||
addData(Stores.Flight, c)
|
||||
|
|
|
@ -4,4 +4,4 @@ psycopg2-binary==2.9.5
|
|||
pyjwt==2.6.0
|
||||
gunicorn==20.1.0
|
||||
sqlalchemy==2.0.22
|
||||
aiohttp==3.8.6
|
||||
asyncreq==0.0.4
|
|
@ -1,5 +1,6 @@
|
|||
import re
|
||||
|
||||
from asyncreq import request
|
||||
from fastapi import APIRouter, BackgroundTasks, Depends, Response
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
@ -7,10 +8,9 @@ from src.api.config import API_FLIGHTS
|
|||
from src.api.cruds import chat as notif_crud
|
||||
from src.api.cruds import subscription as subs_crud
|
||||
from src.api.db import get_db
|
||||
from src.api.schemas.chat import Chat, FlightData, Update
|
||||
from src.api.schemas.chat import Chat, Update
|
||||
from src.api.utils import telegram
|
||||
from src.api.utils.messages import get_flight_message
|
||||
from src.api.utils.network import request
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
import aiohttp
|
||||
import async_timeout
|
||||
from aiohttp import ClientConnectorError, ContentTypeError, JsonPayload
|
||||
from fastapi import HTTPException
|
||||
|
||||
|
||||
async def make_request(
|
||||
url: str,
|
||||
method: str,
|
||||
headers: dict = None,
|
||||
query: Optional[dict] = None,
|
||||
data: str = None,
|
||||
json: JsonPayload = None,
|
||||
timeout: int = 60,
|
||||
):
|
||||
async with async_timeout.timeout(delay=timeout):
|
||||
async with aiohttp.ClientSession(headers=headers) as session:
|
||||
async with session.request(
|
||||
method=method, url=url, params=query, data=data, json=json
|
||||
) as response:
|
||||
response_json = await response.json()
|
||||
decoded_json = response_json
|
||||
return decoded_json, response.status, response.headers
|
||||
|
||||
|
||||
async def request(url, method, headers=None, data=None, json=None, query=None):
|
||||
try:
|
||||
(x, y, z) = await make_request(
|
||||
url=url, method=method, headers=headers, data=data, json=json, query=query
|
||||
)
|
||||
except ClientConnectorError:
|
||||
raise HTTPException(status_code=503, detail="Service is unavailable.")
|
||||
except ContentTypeError:
|
||||
raise HTTPException(status_code=500, detail="Service error.")
|
||||
return x, y, z
|
|
@ -1,6 +1,6 @@
|
|||
import os
|
||||
|
||||
from src.api.utils.network import request
|
||||
from asyncreq import request
|
||||
|
||||
TOKEN = os.getenv("TOKEN")
|
||||
|
||||
|
|
Loading…
Reference in New Issue