$
This commit is contained in:
parent
873dd8c458
commit
3cf55ab609
@ -1,19 +0,0 @@
|
||||
// src/__ tests __/App.test.tsx
|
||||
|
||||
import { expect, test } from "vitest";
|
||||
import { render } from "@testing-library/react";
|
||||
import App from "../src/App.jsx";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
|
||||
test("demo", () => {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
|
||||
test("Renders the main page", () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>,
|
||||
);
|
||||
expect(true).toBeTruthy();
|
||||
});
|
@ -1,53 +0,0 @@
|
||||
import { describe, it, expect, beforeEach, vi, afterEach } from "vitest";
|
||||
import { render, fireEvent, screen, cleanup } from "@testing-library/react";
|
||||
import { Login } from "../../../src/pages/index.js";
|
||||
import { AuthenticationContext } from "../../../src/contexts/index.js";
|
||||
|
||||
describe("Login Component", () => {
|
||||
let loginFunction;
|
||||
|
||||
beforeEach(() => {
|
||||
loginFunction = vi.fn(); // Mock login function
|
||||
render(
|
||||
<AuthenticationContext.Provider value={{ login: loginFunction }}>
|
||||
<Login />
|
||||
</AuthenticationContext.Provider>,
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it("renders without errors", () => {
|
||||
expect(screen.getByText("Login page")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("allows entering a username and password", () => {
|
||||
fireEvent.change(screen.getByPlaceholderText("username"), {
|
||||
target: { value: "testuser" },
|
||||
});
|
||||
fireEvent.change(screen.getByPlaceholderText("password"), {
|
||||
target: { value: "Password123!!@" },
|
||||
});
|
||||
|
||||
expect(screen.getByPlaceholderText("username").value).toBe("testuser");
|
||||
expect(screen.getByPlaceholderText("password").value).toBe(
|
||||
"Password123!!@",
|
||||
);
|
||||
});
|
||||
|
||||
it("handles submit event", async () => {
|
||||
fireEvent.change(screen.getByPlaceholderText("username"), {
|
||||
target: { value: "testuser" },
|
||||
});
|
||||
fireEvent.change(screen.getByPlaceholderText("password"), {
|
||||
target: { value: "Password123!!@" },
|
||||
});
|
||||
fireEvent.click(screen.getByText("submit"));
|
||||
|
||||
expect(loginFunction).toHaveBeenCalledWith("testuser", "Password123!!@");
|
||||
});
|
||||
|
||||
//TODO add more tests please :)
|
||||
});
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "projet-but3",
|
||||
"name": "2024-dev-but3",
|
||||
"description": "Gestionnaire de depense portant le nom de : T'as cru j'etais riche ? (TCJR abrege).",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@ -42,7 +43,6 @@
|
||||
"husky": "^9.0.6",
|
||||
"lint-staged": "^15.2.0",
|
||||
"prettier": "^3.2.4",
|
||||
"vite": "^5.0.8",
|
||||
"vitest": "^1.2.2"
|
||||
"vite": "^5.0.8"
|
||||
}
|
||||
}
|
@ -31,6 +31,8 @@ export default defineConfig({
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
|
||||
outputDir: "./tests/traces",
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
|
316
pnpm-lock.yaml
generated
316
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@ export default function NavBar() {
|
||||
{user ? (
|
||||
<div className="leaf-into">
|
||||
<li className="leaf">
|
||||
<Link to="profile">Profile</Link>
|
||||
<Link to="profile">Profil</Link>
|
||||
</li>
|
||||
|
||||
<button className="leaf-btn" onClick={onLogout}>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import LoaderSpace from "../components/LoaderSpace/LoaderSpace";
|
||||
import {
|
||||
createUser as registerApi,
|
||||
isLoggedIn,
|
||||
@ -17,7 +17,7 @@ const initState = {
|
||||
export const AuthenticationContext = React.createContext({
|
||||
...initState,
|
||||
login: async () => {},
|
||||
register: () => {},
|
||||
register: async () => {},
|
||||
logout: async () => {},
|
||||
});
|
||||
|
||||
@ -90,7 +90,7 @@ export const AuthenticationProvider = ({ children }) => {
|
||||
}, [location]);
|
||||
|
||||
if (isLoading) {
|
||||
return <p>Loading...</p>;
|
||||
return <LoaderSpace isVisible={true} isCenterLoader={true} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -15,7 +15,7 @@
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
color: $red;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
@ -3,13 +3,13 @@ import { useAuth } from "../../hooks";
|
||||
import { useEffect } from "react";
|
||||
import "./authanticated.scss";
|
||||
import "../../components/StylizedBtn/StylizedBtn.scss";
|
||||
import passwordCheck from "../../services/password";
|
||||
|
||||
export const Login = () => {
|
||||
const { login } = useAuth();
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
document.title = "Connexion";
|
||||
@ -17,18 +17,13 @@ export const Login = () => {
|
||||
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const response = await login(username, password);
|
||||
|
||||
if (response && !response.success) {
|
||||
setError(response.error);
|
||||
}
|
||||
await login(username, password);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<form className="form" onSubmit={onSubmit}>
|
||||
<h3 className="title">Connexion</h3>
|
||||
{error && <p>{error}</p>}
|
||||
|
||||
<input
|
||||
type="text"
|
||||
|
@ -1,14 +1,13 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import "../../components/StylizedBtn/StylizedBtn.scss";
|
||||
import { useAuth } from "../../hooks";
|
||||
import passwordCheck from "../../services/password";
|
||||
|
||||
export const Register = () => {
|
||||
const { register } = useAuth();
|
||||
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmation, setConfirmation] = useState("");
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = "Inscription";
|
||||
@ -17,19 +16,13 @@ export const Register = () => {
|
||||
const onSubmit = async (e) => {
|
||||
try {
|
||||
e.preventDefault();
|
||||
const response = await register(username, password, confirmation);
|
||||
|
||||
if (!response) {
|
||||
setError(
|
||||
"Assurez vous que le mot de passe contient au moins 8 caracteres dont une majuscule, un symbole special et au minimum un chiffre.",
|
||||
);
|
||||
}
|
||||
|
||||
if (response && !response.success) {
|
||||
setError(
|
||||
if (!passwordCheck(password, confirmation)) {
|
||||
alert(
|
||||
"Assurez vous que le mot de passe contient au moins 8 caracteres dont une majuscule, un symbole special et au minimum un chiffre.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
await register(username, password, confirmation);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
@ -40,8 +33,6 @@ export const Register = () => {
|
||||
<form className="form" onSubmit={onSubmit}>
|
||||
<h3 className="title">Inscription</h3>
|
||||
|
||||
{error ? <div className="error">{error}</div> : null}
|
||||
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
|
@ -26,7 +26,6 @@ export const Home = () => {
|
||||
setupRoomsStats(res.rooms);
|
||||
setupGlobalStat({ years: res.years, global: res.global });
|
||||
} catch (err) {
|
||||
window.location.href = "/login";
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ export default function Profile() {
|
||||
const [isInAfterImport, setIsInAfterImport] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = `Profile`;
|
||||
document.title = `Profil de ${user.user.username}`;
|
||||
});
|
||||
|
||||
const handleHelpIE = () => {
|
||||
|
@ -6,8 +6,10 @@ import AddBtn from "../../components/AddBtn/AddBtn";
|
||||
import { createItem, deleteItem, updateItem } from "../../api/";
|
||||
import StylizedBtn from "../../components/StylizedBtn/StylizedBtn";
|
||||
import LoaderSpace from "../../components/LoaderSpace/LoaderSpace";
|
||||
import { useAuth } from "../../hooks";
|
||||
|
||||
export default function Room() {
|
||||
const { _user } = useAuth();
|
||||
const { id } = useParams();
|
||||
const [data, setData] = useState({});
|
||||
const [isInForm, setInForm] = useState(false);
|
||||
@ -55,10 +57,17 @@ export default function Room() {
|
||||
setIsInFormUpdate(!isInFormUpdate);
|
||||
};
|
||||
|
||||
const handleDelete = (id) => {
|
||||
deleteItem(id).then((_) => {
|
||||
const handleDelete = (item) => {
|
||||
const confirmation = prompt(
|
||||
`Etes-vous sur de vouloir supprimer ${item.brand} ${item.model} ? (oui ou non)`,
|
||||
"oui",
|
||||
);
|
||||
|
||||
if (!confirmation || confirmation.toLocaleLowerCase() !== "oui") return;
|
||||
|
||||
deleteItem(item._id).then((_) => {
|
||||
const cpy = [...data.items];
|
||||
const filtered = cpy.filter((e) => e._id !== id);
|
||||
const filtered = cpy.filter((e) => e._id !== item._id);
|
||||
setData({ ...data, items: filtered });
|
||||
});
|
||||
};
|
||||
@ -127,7 +136,11 @@ export default function Room() {
|
||||
<div id="item-actions-container">
|
||||
<button
|
||||
onClick={() => {
|
||||
handleDelete(e._id);
|
||||
handleDelete({
|
||||
_id: e._id,
|
||||
brand: e.brand,
|
||||
model: e.model,
|
||||
});
|
||||
}}
|
||||
id="item-delete-btn"
|
||||
>
|
||||
@ -240,28 +253,28 @@ export default function Room() {
|
||||
handleFormUpdateDataChange(e, "brand");
|
||||
}}
|
||||
type="text"
|
||||
placeholder={formUpdateData.brand}
|
||||
placeholder={`(Marque) ${formUpdateData.brand}`}
|
||||
/>
|
||||
<input
|
||||
onChange={(e) => {
|
||||
handleFormUpdateDataChange(e, "model");
|
||||
}}
|
||||
type="text"
|
||||
placeholder={formUpdateData.model}
|
||||
placeholder={`(Modele) ${formUpdateData.model}`}
|
||||
/>
|
||||
<input
|
||||
onChange={(e) => {
|
||||
handleFormUpdateDataChange(e, "description");
|
||||
}}
|
||||
type="text"
|
||||
placeholder={formUpdateData.description}
|
||||
placeholder={`(Description) ${formUpdateData.description}`}
|
||||
/>
|
||||
<input
|
||||
onChange={(e) => {
|
||||
handleFormUpdateDataChange(e, "price");
|
||||
}}
|
||||
type="number"
|
||||
placeholder={formUpdateData.price}
|
||||
placeholder={`(Prix) ${formUpdateData.price}`}
|
||||
/>
|
||||
<input
|
||||
onChange={(e) => {
|
||||
@ -277,7 +290,7 @@ export default function Room() {
|
||||
handleFormUpdateDataChange(e, "link");
|
||||
}}
|
||||
type="text"
|
||||
placeholder={formUpdateData.link}
|
||||
placeholder={`(Lien) ${formUpdateData.link}`}
|
||||
/>
|
||||
|
||||
<div id="actions">
|
||||
|
@ -11,7 +11,6 @@
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
filter: blur(30px);
|
||||
background: $primary;
|
||||
z-index: 99;
|
||||
}
|
||||
@ -41,16 +40,16 @@
|
||||
|
||||
#item-actions-container {
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
|
||||
#item-update-btn {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50px;
|
||||
border: none;
|
||||
border-bottom-left-radius: $my_border_rad;
|
||||
|
||||
&:hover {
|
||||
background-color: $orange;
|
||||
@ -61,8 +60,9 @@
|
||||
#item-delete-btn {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50px;
|
||||
font-size: 1em;
|
||||
border: none;
|
||||
border-top-right-radius: $my_border_rad;
|
||||
|
||||
&:hover {
|
||||
background: $red;
|
||||
|
@ -4,11 +4,14 @@ import { createRoom, getRooms, deleteRoom } from "../../api";
|
||||
import { Link } from "react-router-dom";
|
||||
import LoaderSpace from "../../components/LoaderSpace/LoaderSpace";
|
||||
import AddBtn from "./../../components/AddBtn/AddBtn";
|
||||
import { useAuth } from "../../hooks";
|
||||
|
||||
export default function Rooms() {
|
||||
const { _user } = useAuth();
|
||||
const [rooms, setRooms] = useState(null);
|
||||
const [isLoad, setIsLoad] = useState(true);
|
||||
const [isErr, setIsErr] = useState(false);
|
||||
const [splicedRooms, setSplicedRooms] = useState(null);
|
||||
|
||||
const onClickCreate = () => {
|
||||
const name = prompt("Nom de la piece ?");
|
||||
@ -21,6 +24,22 @@ export default function Rooms() {
|
||||
});
|
||||
};
|
||||
|
||||
const configureRooms = (data) => {
|
||||
const splicer = (rms, datasPerPage) => {
|
||||
const partitions = [];
|
||||
let index = 0;
|
||||
|
||||
while (index < rms.length) {
|
||||
partitions.push(rms.slice(index, index + datasPerPage));
|
||||
index += datasPerPage;
|
||||
}
|
||||
|
||||
return partitions;
|
||||
};
|
||||
|
||||
console.log(splicer(data, 8));
|
||||
};
|
||||
|
||||
const onClickDelete = (id, name) => {
|
||||
const confirmation = prompt(
|
||||
`Etes-vous sur de vouloir supprimer ${name} ? (oui ou non)`,
|
||||
@ -45,6 +64,7 @@ export default function Rooms() {
|
||||
}
|
||||
|
||||
setRooms(res);
|
||||
configureRooms(res);
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
@ -9,6 +9,7 @@ export const Router = () => (
|
||||
<Routes>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="home" element={<Home />} />
|
||||
<Route path="stats" element={<Home />} />
|
||||
<Route path="login" element={<Login />} />
|
||||
<Route path="register" element={<Register />} />
|
||||
<Route path="rooms/" element={<Rooms />} />
|
||||
|
0
src/tests/services/password.test.js
Normal file
0
src/tests/services/password.test.js
Normal file
Binary file not shown.
Binary file not shown.
@ -5,10 +5,5 @@ export default defineConfig({
|
||||
server: {
|
||||
port: 3001,
|
||||
},
|
||||
test: {
|
||||
include: ["__tests__/**/*.test.{js,jsx}"],
|
||||
environment: "happy-dom",
|
||||
},
|
||||
|
||||
plugins: [react()],
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user