Browse Source

Fixed by removing all unused files

pull/18/head
astria 3 months ago
parent
commit
35122820e8
  1. 0
      backend/app/middlewares/media.middleware.js
  2. 16
      backend/app/utils/wait-for-it.sh
  3. 14
      backend/freetube.sh
  4. 1
      backend/package.json
  5. 30
      backend/requests/channel.http
  6. 25
      backend/requests/comment.http
  7. 11
      backend/requests/medias.http
  8. 11
      backend/requests/playlist.http
  9. 5
      backend/requests/recommendation.http
  10. 17
      backend/requests/top-tags-videos.http
  11. 49
      backend/requests/user.http
  12. 33
      backend/requests/video.http
  13. 190
      backend/test/channel.test.js
  14. 175
      backend/test/comment.test.js
  15. 231
      backend/test/playlist.test.js
  16. 413
      backend/test/user.test.js
  17. 198
      backend/test/video.test.js
  18. 29
      backend/tools.js
  19. 6
      backend/vitest.config.js
  20. 7
      frontend/Docker.Development
  21. 12
      frontend/README.md
  22. 15
      frontend/rebuild.sh

0
backend/app/middlewares/media.middleware.js

16
backend/app/utils/wait-for-it.sh

@ -1,16 +0,0 @@
#!/bin/bash
hostport="$1"
shift
cmd="$@"
host="${hostport%%:*}"
port="${hostport##*:}"
while ! nc -z "$host" "$port"; do
echo "Waiting for $host:$port..."
sleep 1
done
echo "$host:$port is available. Running command: $cmd"
exec $cmd

14
backend/freetube.sh

@ -1,14 +0,0 @@
#!/usr/bin/env bash
# Script pour exécuter Node.js avec les paramètres passés en ligne de commande
# Récupérer tous les paramètres passés au script
PARAMS="$@"
# Vérifier si des paramètres ont été fournis
if [ $# -eq 0 ]; then
echo "Aucun paramètre fourni."
else
echo "Exécution de Node.js avec les paramètres: $PARAMS"
node /app/tools.js $PARAMS
fi

1
backend/package.json

@ -5,7 +5,6 @@
"type": "module",
"scripts": {
"dev": "nodemon .",
"test": "vitest",
"start": "node server.js"
},
"keywords": [],

30
backend/requests/channel.http

@ -1,30 +0,0 @@
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhc3RyaWEiLCJpYXQiOjE3NTMwNDAxMTh9.GNGee4BYCL-wO3I8FtXXJIc-xsLMfuOoUlBhHjQJcWo
### CREATE CHANNEL
POST http://localhost:8000/api/channels
Authorization: Bearer {{token}}
Content-Type: application/json
{
"name": "Arcanas",
"description": "kljsdfjklsdfjkl",
"owner": 1
}
### GET CHANNEL BY ID
GET http://localhost:8000/api/channels/20
Authorization: Bearer {{token}}
### GET ALL CHANNEL
GET http://localhost:8000/api/channels/
Authorization: Bearer {{token}}
### UPDATE CHANNEL
PUT http://localhost:8000/api/channels/2
Authorization: Bearer {{token}}
Content-Type: application/json
{
"name": "Salut cest cool",
"description": "hjqdfshjklsdqfhjkl"
}

25
backend/requests/comment.http

@ -1,25 +0,0 @@
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidXNlcm5hbWUiOiJhc3RyaWEiLCJpYXQiOjE3NTI5NDQxMDF9.dbGCL8qqqLR3e7Ngns-xPfZAvp0WQzAbjaEHjDVg1HI
### POST COMMENT
POST http://127.0.0.1:8000/api/comments/
Content-Type: application/json
Authorization: Bearer {{token}}
{
"content": "Lorem",
"video": 3
}
### GET COMMENT FROM VIDEO ID
GET http://127.0.0.1:8000/api/comments/video/astria
Authorization: Bearer {{token}}
### POST COMMENT
PUT http://127.0.0.1:8000/api/comments/1
Content-Type: application/json
Authorization: Bearer {{token}}
{
"content": "fsd",
"video": 14
}

11
backend/requests/medias.http

@ -1,11 +0,0 @@
### GET PROFILE PICTURE (through nginx)
GET http://localhost/api/media/profile/sacha.jpg
### GET PROFILE PICTURE (direct backend - for testing)
GET http://localhost:8000/api/media/profile/sacha.jpg
### GET THUMBNAIL (through nginx)
GET http://localhost/api/media/thumbnail/E90B982DE9C5112C.jpg
### GET THUMBNAIL (direct backend - for testing)
GET http://localhost:8000/api/media/thumbnail/E90B982DE9C5112C.jpg

11
backend/requests/playlist.http

@ -1,11 +0,0 @@
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhc3RyaWEiLCJpYXQiOjE3NTMwNDAxMTh9.GNGee4BYCL-wO3I8FtXXJIc-xsLMfuOoUlBhHjQJcWo
### ADD PLAYLIST
POST http://localhost/api/playlists
Authorization: Bearer {{token}}
Content-Type: application/json
{
"name": "A regarder plus tard",
"owner": 1
}

5
backend/requests/recommendation.http

@ -1,5 +0,0 @@
### GET NON-AUTHENTICATED RECOMMENDATIONS
GET http://localhost:8000/api/recommendations/
### GET TRENDING VIDS
GET http://localhost:8000/api/recommendations/trending/

17
backend/requests/top-tags-videos.http

@ -1,17 +0,0 @@
### Get all videos from the three most watched tags
GET http://127.0.0.1:8000/api/videos/top-tags/videos
### Alternative localhost URL
GET http://localhost:8000/api/videos/top-tags/videos
### With frontend URL (if using nginx proxy)
GET http://localhost/api/videos/top-tags/videos
###
# This endpoint returns:
# - topTags: The 3 most used tags with their usage count
# - videos: All public videos that have any of these top 3 tags
# - totalVideos: Count of videos returned
#
# Videos are ordered by popularity score (calculated from views, likes, comments)
# and then by release date (newest first)

49
backend/requests/user.http

@ -1,49 +0,0 @@
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhc3RyaWEiLCJpYXQiOjE3NTMwNDAxMTh9.GNGee4BYCL-wO3I8FtXXJIc-xsLMfuOoUlBhHjQJcWo
### CREATE USER
POST http://localhost:8000/api/users/
Content-Type: application/json
{
"email": "sacha@gmail.com",
"username": "astria",
"password": "Test_974",
"picture": "null"
}
### LOGIN USER
POST http://localhost:8000/api/users/login
Content-Type: application/json
{
"username": "astria",
"password": "Test1234!"
}
### GET USER BY ID
GET http://localhost:8000/api/users/astria
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhc3RyaWEiLCJpYXQiOjE3NTE3NDYxMzJ9.i0MPfB7IJbMGNnaktV0OlxoCRs6ujKtVmSmlxLa2eNY
### GET USER BY USERNAME
GET http://localhost:8000/api/users/username/astria
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywidXNlcm5hbWUiOiJhc3RyaWEiLCJpYXQiOjE3NTE3NDYxMzJ9.i0MPfB7IJbMGNnaktV0OlxoCRs6ujKtVmSmlxLa2eNY
### UPDATE USER
PUT http://localhost:8000/api/users/5
Authorization: Bearer {{token}}
Content-Type: application/json
{
"email": "test@test.com",
"username": "test",
"password": "Rwqfsfasxc_974",
"picture": "null"
}
### DELETE USER
DELETE http://localhost:8000/api/users/4
Authorization: Bearer {{token}}
### GET HISTORY
GET http://localhost:8000/api/users/1/history/
Authorization: Bearer {{token}}

33
backend/requests/video.http

@ -1,33 +0,0 @@
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhc3RyaWEiLCJpYXQiOjE3NTMzODAyNjB9._rUcieo3acJp6tjQao7V3UQz0_ngHuB2z36_fG_fIX8
### UPDATE VIDEO
PUT http://127.0.0.1:8000/api/videos/3
Content-Type: application/json
Authorization: Bearer {{token}}
{
"title": " I built a REDSTONE FACTORY in Minecraft Create Mod! [#28] ",
"description": "I've been struggling for Redstone, so it's time we make a Crete Mod 6 redstone farm! This does mean we need to also make a cobble generator, netherwart farm and blaze farm to reach our goals, all in one new victorian-era-steampunky-type-brick buiilding.",
"visibility": "public"
}
### TOGGLE LIKE
GET http://127.0.0.1:8000/api/videos/14/like
Authorization: Bearer {{token}}
### ADD TAGS
PUT http://127.0.0.1:8000/api/videos/3/tags
Content-Type: application/json
Authorization: Bearer {{token}}
{
"tags": [
"Minecraft",
"Create Mod",
"Redstone"
],
"channel": 1
}
###
GET http://localhost/api/search?q=minecraft&type=videos&offset=0&limit=10

190
backend/test/channel.test.js

@ -1,190 +0,0 @@
import vitest, {describe} from "vitest";
import app from "../server.js";
import request from "supertest";
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwidXNlcm5hbWUiOiJ0ZXN0IiwiaWF0IjoxNzUxNzk2MjM2fQ.XmaVA_NQcpW7fxRtDWOinMyQXPaFixpp3ib_mzo6M6c"
describe("CREATE CHANNEL", async function() {
it("Should return 401 if token isn't valid", async function() {
const channel = {
"name": "Astria",
"description": "A channel already exists",
"owner": 5
}
const req = await request(app).post("/api/channels/").send(channel);
expect(req.statusCode).toBe(401);
})
it("Should return 400 if owner is not number", async function() {
const channel = {
"name": "Machin",
"description": "kljsdfjklsdfjkl",
"owner": "astria"
}
const req = await request(app).post("/api/channels/").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if owner don't exist", async function() {
const channel = {
"name": "Machin",
"description": "kljsdfjklsdfjkl",
"owner": 55
}
const req = await request(app).post("/api/channels/").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user isn't owner of owner", async function() {
const channel = {
"name": "Machin",
"description": "kljsdfjklsdfjkl",
"owner": 3
}
const req = await request(app).post("/api/channels/").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(403);
})
it("Should return 400 if channel name already exists", async function() {
const channel = {
"name": "Sacha",
"description": "A channel already exists",
"owner": 5
}
const req = await request(app).post("/api/channels/").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
it("Should return 400 if channel name is empty", async function() {
const channel = {
"description": "A channel already exists",
"owner": 5
}
const req = await request(app).post("/api/channels/").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
it("Should return 400 if owner is empty", async function() {
const channel = {
"name": "Astria",
"description": "A channel already exists",
}
const req = await request(app).post("/api/channels/").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
})
describe("GET CHANNEL BY ID", async function() {
it("Should return 401 if token is not valid", async function() {
const req = await request(app).get("/api/channels/2").send();
expect(req.statusCode).toBe(401);
})
it("Should return 400 if id is not number", async function() {
const req = await request(app).get("/api/channels/sacha").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if channel does not exist", async function() {
const req = await request(app).get("/api/channels/200").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(404);
})
it("Should return 200 if OK", async function() {
const req = await request(app).get("/api/channels/2").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(200);
})
})
describe("GET ALL CHANNELS", async function() {
it("Should be 401 if token is not valid", async function() {
const req = await request(app).get("/api/channels/").send();
expect(req.statusCode).toBe(401);
})
it("Should return 200 if OK", async function() {
const req = await request(app).get("/api/channels/").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(200);
})
})
describe("UPDATE CHANNEL", async function() {
it("Should be 401 if token is not valid", async function() {
const channel = {
"name": "Machin",
"description": "kljsdfjklsdfjkl",
}
const req = await request(app).put("/api/channels/2").send(channel);
expect(req.statusCode).toBe(401);
})
it("Should return 400 if name is empty", async function() {
const channel = {
"name": null,
"description": "A channel already exists",
}
const req = await request(app).put("/api/channels/2").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if channel does not exist", async function() {
const channel = {
"name": "Machin",
"description": "kljsdfjklsdfjkl",
}
const req = await request(app).put("/api/channels/404").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the channel", async function() {
const channel = {
"name": "Machin",
"description": "kljsdfjklsdfjkl",
}
const req = await request(app).put("/api/channels/3").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(403);
})
it("Should return 400 if channel name is changed but already used", async function() {
const channel = {
"name": "Astria",
"description": "kljsdfjklsdfjkl",
}
const req = await request(app).put("/api/channels/2").send(channel).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
})
describe("DELETE CHANNEL", async function() {
it("Should be 401 if token is not valid", async function() {
const req = await request(app).del("/api/channels/2").send();
expect(req.statusCode).toBe(401);
})
it("Should return 400 if id is not number", async function() {
const req = await request(app).del("/api/channels/astria").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if channel does not exist", async function() {
const req = await request(app).del("/api/channels/404").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the channel", async function() {
const req = await request(app).del("/api/channels/3").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(403);
})
})
describe("TOGGLE SUBSCRIPTION", async function() {
it("Should return 401 if token is not valid", async function() {
const req = await request(app).post("/api/channels/2/subscribe").send();
expect(req.statusCode).toBe(401);
})
it("Should return 400 if id is not number", async function() {
const req = await request(app).post("/api/channels/sacha/subscribe").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if channel does not exist", async function() {
const req = await request(app).post("/api/channels/404/subscribe").send().set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(404);
})
it("Should return 200 if OK", async function() {
const body = {
"userId": 5
}
const req = await request(app).post("/api/channels/2/subscribe").send(body).set("Authorization", "Bearer " + token);
expect(req.statusCode).toBe(200);
})
})

175
backend/test/comment.test.js

@ -1,175 +0,0 @@
import app from "../server.js";
import request from "supertest";
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwidXNlcm5hbWUiOiJ0ZXN0IiwiaWF0IjoxNzUxNzk2MjM2fQ.XmaVA_NQcpW7fxRtDWOinMyQXPaFixpp3ib_mzo6M6c"
const videoId = 14
const commentId = 1
describe("POST COMMENT", async function() {
it("Should return 401 if token is missing", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"video": videoId
}
const req = await request(app).post("/api/comments/").send(comment);
expect(req.status).toBe(401);
})
it("Should return 400 if video is missing", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
}
const req = await request(app).post("/api/comments/").send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(400);
})
it("Should return 400 if content is missing", async function() {
const comment = {
'video': videoId
}
const req = await request(app).post("/api/comments/").send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(400);
})
it("Should return 400 if video is not number", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"video": "lorem"
}
const req = await request(app).post("/api/comments/").send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(400);
})
it("Should return 404 if video doesn't exist", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"author": 5,
"video": 404
}
const req = await request(app).post("/api/comments/").send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(404);
})
})
describe("GET COMMENTS FROM VIDEO ID", async function() {
it("Should return 401 if token is missing", async function() {
const req = await request(app).get("/api/comments/video/" + videoId).send();
expect(req.status).toBe(401);
})
it("Should return 404 if video doesn't exist", async function() {
const req = await request(app).get("/api/comments/video/404").send().set("Authorization", "Bearer " + token)
expect(req.status).toBe(404);
})
it("Should return 200 if OK", async function() {
const req = await request(app).get("/api/comments/video/" + videoId).send().set("Authorization", "Bearer " + token)
expect(req.status).toBe(200);
})
})
describe("GET COMMENT BY ID", async function() {
it("Should return 401 if token is missing", async function() {
const req = await request(app).get("/api/comments/1").send()
expect(req.status).toBe(401);
})
it("Should return 400 if id is not number", async function() {
const req = await request(app).get("/api/comments/sacha").send().set("Authorization", "Bearer " + token)
expect(req.status).toBe(400);
})
it("Should return 404 if comment doesn't exist", async function() {
const req = await request(app).get("/api/comments/404").send().set("Authorization", "Bearer " + token)
expect(req.status).toBe(404);
})
it("Should return 200 if OK", async function() {
const req = await request(app).get("/api/comments/1").send().set("Authorization", "Bearer " + token)
expect(req.status).toBe(200);
})
})
describe("UPDATE COMMENT", async function() {
it("Should return 401 if token is missing", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"video": videoId
}
const req = await request(app).put("/api/comments/" + commentId).send(comment);
expect(req.status).toBe(401);
})
it("Should return 400 if video is missing", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
}
const req = await request(app).put("/api/comments/" + commentId).send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(400);
})
it("Should return 400 if content is missing", async function() {
const comment = {
'video': videoId
}
const req = await request(app).put("/api/comments/" + commentId).send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(400);
})
it("Should return 400 if video is not number", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"video": "lorem"
}
const req = await request(app).put("/api/comments/" + commentId).send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(400);
})
it("Should return 403 if user is not the author", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"video": videoId
}
const req = await request(app).put("/api/comments/2").send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(403);
})
it("Should return 404 if comment doesn't exist", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"video": videoId
}
const req = await request(app).put("/api/comments/12").send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(404);
})
it("Should return 404 if video doesn't exist", async function() {
const comment = {
"content": "Lorem ipsum dolor sit amet",
"author": 5,
"video": 404
}
const req = await request(app).put("/api/comments/" + commentId).send(comment).set("Authorization", "Bearer " + token);
expect(req.status).toBe(404);
})
})
describe("DELETE COMMENT", async function() {
it("Should return 401 if token is missing", async function() {
const req = await request(app).del("/api/comments/" + commentId).send();
expect(req.status).toBe(401);
})
it("Should return 403 if user is not the author", async function() {
const req = await request(app).del("/api/comments/2").send();
expect(req.status).toBe(401);
})
it("Should return 404 if comment doesn't exist", async function() {
const req = await request(app).del("/api/comments/404" + commentId).send().set("Authorization", "Bearer " + token);
expect(req.status).toBe(404);
})
})

231
backend/test/playlist.test.js

@ -1,231 +0,0 @@
import { describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../server.js';
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwidXNlcm5hbWUiOiJ0ZXN0IiwiaWF0IjoxNzUxODA5OTA3fQ.uCJFysaOiXC8qZKykWLi58WDcItKSkQPUIZ7kH-87Tg";
const playlistId = 1;
const playlistId2 = 3;
const videoId = 14;
const falseVideoId = 404;
const falseplaylistId = 404;
const userId = 5;
describe('CREATE PLAYLIST', () => {
it("Should return 401 if token is missing", async () => {
const playlist = {
"name": "Playlist Test",
}
const req = await request(app).post("/api/playlists").send(playlist);
expect(req.statusCode).toBe(401);
})
it("Should return 400 if name is missing", async () => {
const playlist = {}
const req = await request(app).post("/api/playlists").set("Authorization", `Bearer ${token}`).send(playlist);
expect(req.statusCode).toBe(400);
})
it("Should return 400 if name is not alphanumeric", async () => {
const playlist = {
"name": "Playlist Test !@#"
}
const req = await request(app).post("/api/playlists").set("Authorization", `Bearer ${token}`).send(playlist);
expect(req.statusCode).toBe(400);
})
it("Should return 200 if playlist is created", async () => {
const playlist = {
"name": "Playlist Test",
}
const req = await request(app).post("/api/playlists").set("Authorization", `Bearer ${token}`).send(playlist);
expect(req.statusCode).toBe(200);
})
});
describe('ADD VIDEO TO PLAYLIST', () => {
it("Should return 401 if token is missing", async () => {
const req = await request(app).post(`/api/playlists/${playlistId}`).send({ video: videoId });
expect(req.statusCode).toBe(401);
})
it("Should return 404 if playlist does not exist", async () => {
const req = await request(app).post(`/api/playlists/${falseplaylistId}`).set("Authorization", `Bearer ${token}`).send({ video: videoId });
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the playlist", async () => {
const req = await request(app).post(`/api/playlists/${playlistId2}`).set("Authorization", `Bearer ${token}`).send({ video: videoId });
expect(req.statusCode).toBe(403);
})
it("Should return 400 if video id is missing", async () => {
const req = await request(app).post(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`).send({});
expect(req.statusCode).toBe(400);
})
it("Should return 400 if video id is not numeric", async () => {
const req = await request(app).post(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`).send({ video: "test" });
expect(req.statusCode).toBe(400);
})
it("Should return 404 if video does not exist", async () => {
const req = await request(app).post(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`).send({ video: falseVideoId });
expect(req.statusCode).toBe(404);
})
it("Should return 200 if video is added to playlist", async () => {
const req = await request(app).post(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`).send({ video: videoId });
expect(req.statusCode).toBe(200);
})
});
describe('GET PLAYLIST BY USER', () => {
it("Should return 401 if token is missing", async () => {
const req = await request(app).get("/api/playlists/user/" + userId);
expect(req.statusCode).toBe(401);
})
it("Should return 400 if user id is not numeric", async () => {
const req = await request(app).get("/api/playlists/user/test").set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if user does not exist", async () => {
const req = await request(app).get("/api/playlists/user/404").set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the account", async () => {
const req = await request(app).get("/api/playlists/user/" + 6).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(403);
})
it("Should return 200 if playlists are found for user", async () => {
const req = await request(app).get("/api/playlists/user/" + 5).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(200);
})
});
describe('GET PLAYLIST BY ID', () => {
it("Should return 401 if token is missing", async ()=> {
const req = await request(app).get(`/api/playlists/${playlistId}`);
expect(req.statusCode).toBe(401);
})
it("Should return 400 if playlist id is not numeric", async () => {
const req = await request(app).get("/api/playlists/test").set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if playlist does not exist", async () => {
const req = await request(app).get(`/api/playlists/${falseplaylistId}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the playlist", async () => {
const req = await request(app).get(`/api/playlists/${playlistId2}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(403);
})
it("Should return 200 if playlist is found", async () => {
const req = await request(app).get(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(200);
})
})
describe("UPDATE PLAYLIST", () => {
it("Should return 401 if token is missing", async () => {
const req = await request(app).put(`/api/playlists/${playlistId}`).send({ name: "New Playlist Name" });
expect(req.statusCode).toBe(401);
})
it("Should return 400 if playlist id is not numeric", async () => {
const req = await request(app).put("/api/playlists/test").set("Authorization", `Bearer ${token}`).send({ name: "New Playlist Name" });
expect(req.statusCode).toBe(400);
})
it("Should return 404 if playlist does not exist", async () => {
const req = await request(app).put(`/api/playlists/${falseplaylistId}`).set("Authorization", `Bearer ${token}`).send({ name: "New Playlist Name" });
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the playlist", async () => {
const req = await request(app).put(`/api/playlists/${playlistId2}`).set("Authorization", `Bearer ${token}`).send({ name: "New Playlist Name" });
expect(req.statusCode).toBe(403);
})
it("Should return 400 if name is missing", async () => {
const req = await request(app).put(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`).send({});
expect(req.statusCode).toBe(400);
})
it("Should return 400 if name is not alphanumeric", async () => {
const req = await request(app).put(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`).send({ name: "New Playlist Name !@#" });
expect(req.statusCode).toBe(400);
})
it("Should return 200 if playlist is updated", async () => {
const req = await request(app).put(`/api/playlists/${playlistId}`).set("Authorization", `Bearer ${token}`).send({ name: "Updated Playlist Name" });
expect(req.statusCode).toBe(200);
})
})
describe("DELETE VIDEO FROM PLAYLIST", () => {
it("Should return 401 if token is missing", async () => {
const req = await request(app).delete(`/api/playlists/${playlistId}/video/${videoId}`);
expect(req.statusCode).toBe(401);
})
it("Should return 400 if playlist id is not numeric", async () => {
const req = await request(app).delete("/api/playlists/test/video/14").set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(400);
})
it("Should return 400 if video id is not numeric", async () => {
const req = await request(app).delete(`/api/playlists/${playlistId}/video/test`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if playlist does not exist", async () => {
const req = await request(app).delete(`/api/playlists/${falseplaylistId}/video/${videoId}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the playlist", async () => {
const req = await request(app).delete(`/api/playlists/${playlistId2}/video/${videoId}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(403);
})
it("Should return 404 if video is not in the playlist", async () => {
const req = await request(app).delete(`/api/playlists/${playlistId}/video/${falseVideoId}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(404);
})
it("Should return 200 if video is deleted from playlist", async () => {
const req = await request(app).delete(`/api/playlists/${playlistId}/video/${videoId}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(200);
})
})
describe("DELETE PLAYLIST", () => {
it("Should return 401 if token is missing", async () => {
const req = await request(app).delete(`/api/playlists/${playlistId}`);
expect(req.statusCode).toBe(401);
})
it("Should return 400 if playlist id is not numeric", async () => {
const req = await request(app).delete("/api/playlists/test").set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(400);
})
it("Should return 404 if playlist does not exist", async () => {
const req = await request(app).delete(`/api/playlists/${falseplaylistId}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(404);
})
it("Should return 403 if user is not the owner of the playlist", async () => {
const req = await request(app).delete(`/api/playlists/${playlistId2}`).set("Authorization", `Bearer ${token}`);
expect(req.statusCode).toBe(403);
})
})

413
backend/test/user.test.js

@ -1,413 +0,0 @@
import { describe, it, expect } from 'vitest';
import app from '../server.js';
import request from 'supertest';
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwidXNlcm5hbWUiOiJ0ZXN0IiwiaWF0IjoxNzUxNzk2MjM2fQ.XmaVA_NQcpW7fxRtDWOinMyQXPaFixpp3ib_mzo6M6c"
describe('USER REGISTER', () => {
it('should return 400 when password is too short', async () => {
const user = {
email: "sachaguerin@gmail.com",
username: "sachaguerin",
password: "Toor!9",
picture: "null"
};
const res = await request(app)
.post('/api/users')
.send(user);
expect(res.status).toBe(400);
});
it('should return 400 when password is too long', async () => {
const user = {
email: "sachaguerin",
username: "sachaguerin",
password: "Toor!95555555555555555555555555555555555555555555555555555555",
picture: "null"
}
const res = await request(app)
.post("/api/users")
.send(user);
expect(res.status).toBe(400);
});
it('should return 400 when password don\'t have capital letters', async () => {
const user = {
email: "sachaguerin",
username: "sachaguerin",
password: "toooooooooor_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
});
it('should return 400 when password don\'t have lowercase letters', async () => {
const user = {
email: "sachaguerin",
username: "sachaguerin",
password: "TOOOOOOOOOOOOOOOOOOOORRR_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
});
it('should return 400 when password don\'t have symbols', async () => {
const user = {
email: "sachaguerin",
username: "sachaguerin",
password: "Rwqfsfasxc974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
});
it("Should return 400 if email is invalid", async () => {
const user = {
email: "sachaguerin",
username: "sachaguerin",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if username isn't string", async () => {
const user = {
email: "sachaguerin",
username: 48,
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if email is already used", async () => {
const user = {
email: "sachaguerin.sg@gmail.com",
username: "sachaguerin",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if username is already used", async () => {
const user = {
email: "sachaguerin@gmail.com",
username: "astria",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if email isn't provided", async () => {
const user = {
username: "sachaguerin",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if username isn't provided", async () => {
const user = {
email: "sachaguerin@gmail.com",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if password isn't provided", async () => {
const user = {
email: "sachaguerin@gmail.com",
username: "sachaguerin",
picture: "null"
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if picture isn't provided", async () => {
const user = {
email: "sachaguerin@gmail.com",
username: "sachaguerin",
password: "Rwqfsfasxc_974",
}
const res = await request(app).post('/api/users').send(user);
expect(res.status).toBe(400);
})
});
describe('USER LOGIN', () => {
it('Should return 401 if account doesn\'t exist', async () => {
const user = {
username: "sachaguerin",
password: "Rwqfsfasxc__974",
}
const req = await request(app).post('/api/users/login').send(user);
expect(req.status).toBe(401);
})
it('Should return 401 if password is not valid', async () => {
const user = {
username: "astria",
password: "Rwqfsfasxc__974",
}
const req = await request(app).post('/api/users/login').send(user);
expect(req.status).toBe(401);
})
it("Should return 400 if username isn't provided", async () => {
const user = {
password: "Rwqfsfasxc_974",
}
const res = await request(app).post('/api/users/login').send(user);
expect(res.status).toBe(400);
})
it("Should return 400 if password isn't provided", async () => {
const user = {
username: "astria",
}
const res = await request(app).post('/api/users/login').send(user);
expect(res.status).toBe(400);
})
it("Should return 200 if OK", async () => {
const user = {
username: "astria",
password: "Rwqfsfasxc_974",
}
const res = await request(app).post('/api/users/login').send(user);
expect(res.status).toBe(200);
})
})
describe('GET USER BY ID', async () => {
it("Should return 401 if token is not valid", async () => {
const res = await request(app).get("/api/users/5").send();
expect(res.status).toBe(401);
})
it("Should return 404 if user doesn\'t exist", async () => {
const res = await request(app).get("/api/users/3333").send().set("Authorization", "Bearer " + token);
expect(res.status).toBe(404);
})
it("Should return 400 if id is not integer", async () => {
const res = await request(app).get("/api/users/sacha").send().set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
})
it("Should return 200 if OK", async () => {
const res = await request(app).get("/api/users/3").send().set("Authorization", "Bearer " + token);
expect(res.status).toBe(200);
})
})
describe('GET USER BY USERNAME', async () => {
it("Should return 401 if token is not valid", async () => {
const req = await request(app).get("/api/users/username/astria").send();
expect(req.status).toBe(401);
})
it("Should return 404 if user doesn\'t exist", async () => {
const req = await request(app).get("/api/users/username/congolexicomatision").send().set("Authorization", "Bearer " + token);
expect(req.status).toBe(404);
})
it("Should return 200 if OK", async () => {
const req = await request(app).get("/api/users/username/astria").send().set("Authorization", "Bearer " + token);
expect(req.status).toBe(200);
})
})
describe('UPDATE USER', () => {
it("Should return 401 if token is not valid", async () => {
const user = {
email: "sachaguerin@gmail.com",
username: "sacha",
password: "Rwqfsfasxc__974",
picture: "Sachaguerin",
}
const res = await request(app).put('/api/users/3').send(user);
expect(res.status).toBe(401);
})
it('should return 400 when password is too short', async () => {
const user = {
email: "test@test.com",
username: "test",
password: "Toor!9",
picture: "null"
};
const res = await request(app)
.put('/api/users/5')
.send(user)
.set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
});
it('should return 400 when password don\'t have capital letters', async () => {
const user = {
email: "test@test.com",
username: "test",
password: "toooooooooor_974",
picture: "null"
}
const res = await request(app).put('/api/users/5').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
});
it('should return 400 when password don\'t have lowercase letters', async () => {
const user = {
email: "test@test.com",
username: "test",
password: "TOOOOOOOOOOOOOOOOOOOORRR_974",
picture: "null"
}
const res = await request(app).put('/api/users/5').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
});
it('should return 400 when password don\'t have symbols', async () => {
const user = {
email: "test@test.com",
username: "test",
password: "Rwqfsfasxc974",
picture: "null"
}
const res = await request(app).put('/api/users/5').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
});
it("Should return 400 if email is invalid", async () => {
const user = {
email: "sachaguerin",
username: "test",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).put('/api/users/5').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
})
it("Should return 403 if the user is not the owner", async () => {
const user = {
email: "test@test.com",
username: "test",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).put('/api/users/3').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(403);
})
it("Should return 400 if mail change but already taken", async () => {
const user = {
email: "sachaguerin.sg@gmail.com",
username: "test",
picture: "null",
password: "Test_974"
}
const res = await request(app).put('/api/users/5').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
})
it("Should return 400 if username changed but already taken", async () => {
const user = {
email: "test@test.com",
username: "astria",
password: "Test_974",
picture: "null"
}
const res = await request(app).put('/api/users/5').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(400);
})
it("Should return 404 if user doesn't exist", async () => {
const user = {
email: "test@test.com",
username: "test",
password: "Rwqfsfasxc_974",
picture: "null"
}
const res = await request(app).put('/api/users/666').send(user).set("Authorization", "Bearer " + token);
expect(res.status).toBe(404);
})
})
describe ('DELETE USER', async function () {
it("Should return 401 if token is not valid", async () => {
const req = await request(app).del('/api/users/5').send();
expect(req.status).toBe(401);
})
it ("Should return 403 if user isn't the owner", async () => {
const req = await request(app).del('/api/users/4').send().set("Authorization", "Bearer " + token);
expect(req.status).toBe(403);
})
it("Should return 400 if id is empty", async () => {
const req = await request(app).del('/api/users').send().set("Authorization", "Bearer " + token);
expect(req.status).toBe(404);
})
it("Should return 400 if id isn't number", async () => {
const req = await request(app).del('/api/users/sacha').send().set("Authorization", "Bearer " + token);
expect(req.status).toBe(400);
})
it("Should return 404 if user doesn't exist", async () => {
const req = await request(app).del('/api/users/666').send().set("Authorization", "Bearer " + token);
expect(req.status).toBe(404);
})
})

198
backend/test/video.test.js

@ -1,198 +0,0 @@
import vitest from "vitest";
import app from "../server.js";
import request from "supertest";
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NSwidXNlcm5hbWUiOiJ0ZXN0IiwiaWF0IjoxNzUxNzk2MjM2fQ.XmaVA_NQcpW7fxRtDWOinMyQXPaFixpp3ib_mzo6M6c"
const videoId = 14
describe("GET BY ID", async () => {
it("Should return 401 if token is missing", async () => {
const req = await request(app).get("/api/videos/" + videoId).send()
expect(req.status).toBe(401)
})
it("Should return 400 if id is not number", async () => {
const req = await request(app).get("/api/videos/sacha").send().set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 404 if video does not exist", async () => {
const req = await request(app).get("/api/videos/404").send().set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(404)
})
it("Should return 200 if OK", async () => {
const req = await request(app).get("/api/videos/" + videoId).send().set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(200)
})
})
describe("GET BY CHANNEL", async () => {
it("Should return 401 if token is missing", async () => {
const req = await request(app).get("/api/videos/channel/2").send()
expect(req.status).toBe(401)
})
it("Should return 400 if channeld id is not number", async () => {
const req = await request(app).get("/api/videos/channel/astria").send().set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 404 if channel does not exist", async () => {
const req = await request(app).get("/api/videos/channel/404").send().set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(404)
})
it("Should return 200 if OK", async () => {
const req = await request(app).get("/api/videos/channel/2").send().set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(200)
})
})
describe("UPDATE VIDEO DATA", async () => {
it("Should return 401 if token is missing", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": "private",
"channel": 2
}
const req = await request(app).put(`/api/videos/` + videoId).send(video)
expect(req.status).toBe(401)
})
it("Should return 400 if id is not number", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": "private",
"channel": 2
}
const req = await request(app).put(`/api/videos/sacha`).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 400 if title is missing", async () => {
const video = {
"description": "video",
"visibility": "private",
"channel": 2
}
const req = await request(app).put(`/api/videos/` + videoId).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 400 if visibility is missing", async () => {
const video = {
"title": "video",
"description": "video",
"channel": 2
}
const req = await request(app).put('/api/videos/' + videoId).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 400 if visibility is not string", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": 400,
"channel": 2
}
const req = await request(app).put("/api/videos/" + videoId).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 400 if channel is missing", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": "private",
}
const req = await request(app).put("/api/videos/" + videoId).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 400 if channel is not number", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": "private",
"channel": "astria"
}
const req = await request(app).put("/api/videos/" + videoId).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 404 if video does not exist", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": "private",
"channel": 2
}
const req = await request(app).put("/api/videos/404").send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(404);
})
it("Should return 404 if channel does not exist", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": "private",
"channel": 404
}
const req = await request(app).put("/api/videos/" + videoId).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(404);
})
it("Should return 403 if user not the owner", async () => {
const video = {
"title": "video",
"description": "video",
"visibility": "private",
"channel": 3
}
const req = await request(app).put("/api/videos/" + videoId).send(video).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(403);
})
})
describe("UPDATE TAGS", async () => {
it("Should return 401 if token is missing", async () => {
const tags = {
"tags": ["tag1", "tag2"]
}
const req = await request(app).put(`/api/videos/` + videoId + "/tags").send(tags)
expect(req.status).toBe(401)
})
it("Should return 400 if id is not number", async () => {
const tags = {
"tags": ["tag1", "tag2"]
}
const req = await request(app).put(`/api/videos/sacha/tags`).send(tags).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 400 if tags is not array", async () => {
const tags = {
"tags": "tag1, tag2"
}
const req = await request(app).put(`/api/videos/` + videoId + "/tags").send(tags).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(400)
})
it("Should return 404 if video does not exist", async () => {
const tags = {
"tags": ["tag1", "tag2"]
}
const req = await request(app).put("/api/videos/404/tags").send(tags).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(404);
})
it("Should return 403 if user not the owner", async () => {
const tags = {
"tags": ["tag1", "tag2"],
"channel": 3
}
const req = await request(app).put("/api/videos/" + videoId + "/tags").send(tags).set("Authorization", `Bearer ${token}`);
expect(req.status).toBe(403);
})
})

29
backend/tools.js

@ -1,29 +0,0 @@
import pg from "pg";
if (process.argv[2] === "flush") {
flushDatabase();
}
async function flushDatabase() {
const client = new pg.Client({
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
host: process.env.DB_HOST,
database: process.env.DB_NAME,
port: 5432
});
try {
await client.connect();
await client.query('TRUNCATE TABLE users CASCADE');
} catch (err) {
console.error('Error flushing database:', err);
} finally {
await client.end();
}
}

6
backend/vitest.config.js

@ -1,6 +0,0 @@
export default {
test: {
globals: true,
environment: 'node',
},
};

7
frontend/Docker.Development

@ -1,7 +0,0 @@
# Build stage
FROM node:22-alpine3.20 as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .

12
frontend/README.md

@ -1,12 +0,0 @@
# React + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## Expanding the ESLint configuration
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.

15
frontend/rebuild.sh

@ -1,15 +0,0 @@
#!/bin/bash
echo "🧹 Nettoyage des caches..."
rm -rf dist
rm -rf node_modules/.vite
rm -rf node_modules/.cache
echo "📦 Build de l'application..."
npm run build
echo "🔄 Redémarrage du container frontend..."
cd ../
sudo docker-compose restart frontend
echo "✅ Build terminé et container redémarré !"
Loading…
Cancel
Save