diff --git a/backend/.gitattributes b/backend/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/backend/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..517ab17 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,62 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +HELP.md + +target/ + +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +.conseilsGemini diff --git a/backend/.mvn/wrapper/maven-wrapper.properties b/backend/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..d58dfb7 --- /dev/null +++ b/backend/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..cdffe02 --- /dev/null +++ b/backend/README.md @@ -0,0 +1,16 @@ +# Réécriture du projet Simpleat + +## Historique +L'application Simpleat fût présentée comme projet "Fil Rouge" lors de ma formation de développeur Web et Web mobile en 2022 à l'école Simplon de Montreuil. +A l'origine écrite en Angular 13 et Java 11 et développée par 4 étudiants débutants, elle est aujourd'hui obsolète. En temps que développeur historique je m'attaque donc à sa réécriture. +Merci à Thomas Cardon, Paul-Emmanuel Ribardière et Romain Verger pour cette belle aventure. + +## Stack technique +* Java 21 et Sprinboot 3 pour le backend +* Angular 20 avec des composants standalone pour le frontend +* MariaDB pour la base de données +* Le projet est hébergé dans un dépot Gitea (Forgejo !) chez Zaclys + +## Futur +Après le developpement le projet devrait être auto-hébergé via un container Docker dans mon Raspberry Pi. + diff --git a/backend/mvnw b/backend/mvnw new file mode 100755 index 0000000..19529dd --- /dev/null +++ b/backend/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/backend/mvnw.cmd b/backend/mvnw.cmd new file mode 100644 index 0000000..249bdf3 --- /dev/null +++ b/backend/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/backend/pom.xml b/backend/pom.xml new file mode 100644 index 0000000..648d3fc --- /dev/null +++ b/backend/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.5 + + + fr.vincentRamiere + MangerAutourDeSimplonBack + 0.0.1-SNAPSHOT + MangerAutourDeSimplonBack + Réécriture de Simpleat + + + + + + + + + + + + + + + 21 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + io.jsonwebtoken + jjwt + 0.12.6 + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + com.mysql + mysql-connector-j + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + org.projectlombok + lombok + 1.18.38 + provided + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + + + + diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/MangerAutourDeSimplonBackApplication.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/MangerAutourDeSimplonBackApplication.java new file mode 100644 index 0000000..4cde0bc --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/MangerAutourDeSimplonBackApplication.java @@ -0,0 +1,13 @@ +package fr.vincent.ramiere.mangerautourdesimplonback; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MangerAutourDeSimplonBackApplication { + + public static void main(String[] args) { + SpringApplication.run(MangerAutourDeSimplonBackApplication.class, args); + } + +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/config/SecurityConfig.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/config/SecurityConfig.java new file mode 100644 index 0000000..b15fb10 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/config/SecurityConfig.java @@ -0,0 +1,42 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.config; + +import fr.vincent.ramiere.mangerautourdesimplonback.service.JpaUserDetailsService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity +public class SecurityConfig { + + private final JpaUserDetailsService jpaUserDetailsService; + + public SecurityConfig(JpaUserDetailsService jpaUserDetailsService) { + this.jpaUserDetailsService = jpaUserDetailsService; + } + + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + return http + .csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/api/v1/restaurants/**").permitAll() + .requestMatchers("/api/v1/personnes/**").permitAll() + .anyRequest().authenticated()) + .userDetailsService(jpaUserDetailsService) + .httpBasic(Customizer.withDefaults()) + .build(); + } + + @Bean + PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceController.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceController.java new file mode 100644 index 0000000..b9ddc17 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceController.java @@ -0,0 +1,64 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.controller; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Preference; +import fr.vincent.ramiere.mangerautourdesimplonback.service.PreferenceService; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * Controleur REST pour la gestion des préférences des utilisateurs. + */ +@RestController +@RequestMapping("/api/v1/preferences") +@AllArgsConstructor +public class PreferenceController { + + private final PreferenceService preferenceService; + + /** + * DTO pour recevoir les données de préférence. + */ + @Data + static class PreferenceRequest { + private Integer personneId; + private Integer restaurantId; + private Integer note; + private Boolean favori; + } + + /** + * Endpoint pour récupérer toutes les préférences d'un utilisateur. + * + * @param personneId L'ID de l'utilisateur. + * @return une ResponseEntity contenant la liste des préférences et le statut + * HTTP OK. + */ + @GetMapping("/user/{personneId}") + public ResponseEntity> getPreferencesByPersonneId(@PathVariable Integer personneId) { + List preferences = preferenceService.getPreferencesByPersonneId(personneId); + return ResponseEntity.ok(preferences); + } + + /** + * Endpoint pour créer ou mettre à jour une préférence (note et/ou favori). + * + * @param request Le corps de la requête contenant les détails de la préférence. + * @return une ResponseEntity contenant la préférence sauvegardée (OK) ou + * NOT_FOUND si l'utilisateur ou le restaurant n'existe pas. + */ + @PutMapping + public ResponseEntity saveOrUpdatePreference(@RequestBody PreferenceRequest request) { + return preferenceService.saveOrUpdatePreference( + request.getPersonneId(), + request.getRestaurantId(), + request.getNote(), + request.getFavori()) + .map(ResponseEntity::ok) + .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND)); + } +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/RestaurantController.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/RestaurantController.java new file mode 100644 index 0000000..2ec6436 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/RestaurantController.java @@ -0,0 +1,91 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.controller; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; +import fr.vincent.ramiere.mangerautourdesimplonback.service.RestaurantService; + +import java.util.List; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.AllArgsConstructor; + +/** + * Controleur REST pour la gestion des restaurants. + * Expose les endpoints de l'API pour les opérations CRUD. + */ +@RestController +@RequestMapping("/api/v1/restaurants") +@AllArgsConstructor +public class RestaurantController { + private final RestaurantService restaurantService; + + /** + * Endpoint pour récupérer la liste de tous les restaurants. + * @return une ResponseEntity contenant la liste des restaurants et le statut HTTP OK. + */ + @GetMapping + public ResponseEntity> getAllRestaurants() { + List restaurants = restaurantService.getAllRestaurants(); + return new ResponseEntity<>(restaurants, HttpStatus.OK); + } + + /** + * Endpoint pour récupérer un restaurant par son identifiant. + * @param id L'identifiant du restaurant. + * @return une ResponseEntity contenant le restaurant s'il est trouvé (OK), sinon NOT_FOUND. + */ + @GetMapping("/{id}") + public ResponseEntity getRestaurantById(@PathVariable Integer id) { + return restaurantService.getRestaurantById(id) + .map(restaurant -> new ResponseEntity<>(restaurant, HttpStatus.OK)) + .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND)); + } + + /** + * Endpoint pour créer un nouveau restaurant. + * @param restaurant Le restaurant à créer. + * @return une ResponseEntity contenant le restaurant créé et le statut CREATED. + */ + @PostMapping + public ResponseEntity createRestaurant(@RequestBody Restaurant restaurant) { + Restaurant savedRestaurant = restaurantService.saveRestaurant(restaurant); + return new ResponseEntity<>(savedRestaurant, HttpStatus.CREATED); + } + + /** + * Endpoint pour mettre à jour un restaurant existant. + * @param id L'identifiant du restaurant à mettre à jour. + * @param restaurantDetails Les nouvelles données du restaurant. + * @return une ResponseEntity contenant le restaurant mis à jour (OK), sinon NOT_FOUND. + */ + @PutMapping("/{id}") + public ResponseEntity updateRestaurant(@PathVariable Integer id, @RequestBody Restaurant restaurantDetails) { + return restaurantService.updateRestaurant(id, restaurantDetails) + .map(updateRestaurant -> new ResponseEntity<>(updateRestaurant, HttpStatus.OK)) + .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND)); + } + + /** + * Endpoint pour supprimer un restaurant. + * @param id L'identifiant du restaurant à supprimer. + * @return une ResponseEntity avec le statut NO_CONTENT si la suppression réussit, + * ou NOT_FOUND si le restaurant n'existe pas. + */ + @DeleteMapping("/{id}") + public ResponseEntity deleteRestaurant(@PathVariable Integer id) { + if (restaurantService.getRestaurantById(id).isPresent()) { + restaurantService.deleteRestaurant(id); + return ResponseEntity.noContent().build(); + } + return ResponseEntity.notFound().build(); + } +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/EnumRole.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/EnumRole.java new file mode 100644 index 0000000..96f9aa4 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/EnumRole.java @@ -0,0 +1,24 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import org.springframework.security.core.GrantedAuthority; + +/** + * Énumération des rôles possibles pour un utilisateur dans le système. + * Implémente GrantedAuthority pour l'intégration avec Spring Security. + */ +public enum EnumRole implements GrantedAuthority { + /** + * Rôle standard avec des droits de lecture et d'interaction de base. + */ + ROLE_READER, + /** + * Rôle administrateur avec des droits étendus sur l'application. + */ + ROLE_ADMIN; + + @Override + public String getAuthority() { + return name(); + } + +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Personne.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Personne.java new file mode 100644 index 0000000..fe71b60 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Personne.java @@ -0,0 +1,76 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Entité représentant un utilisateur de l'application. + */ +@Entity +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Personne implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Identifiant unique de la personne, généré automatiquement. + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id_personne") + private int id; + + /** + * Nom de famille de l'utilisateur. + */ + @Column(nullable = false) + private String nom; + + /** + * Prénom de l'utilisateur. + */ + @Column(nullable = false) + private String prenom; + + /** + * Adresse e-mail de l'utilisateur, utilisée comme identifiant de connexion. + */ + @Column(nullable = false) + private String email; + + /** + * Mot de passe de l'utilisateur, stocké sous forme de hachage sécurisé. + */ + @Column(nullable = false) + private String password; + + /** + * Collection des préférences (notes, favoris) de cet utilisateur pour les restaurants. + * La suppression d'une personne entraîne la suppression de ses préférences. + */ + @OneToMany(mappedBy = "preferencePK.personne", cascade = CascadeType.REMOVE) + //@JsonIgnore + @Builder.Default + private Collection preference = new ArrayList<>(); + + /** + * Liste des rôles attribués à l'utilisateur (ex: ROLE_ADMIN, ROLE_READER). + * Chargée immédiatement avec l'entité (EAGER). + */ + @ElementCollection(fetch = FetchType.EAGER) + @Enumerated(EnumType.STRING) + @Builder.Default + private List roleList = new ArrayList<>(); + +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Preference.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Preference.java new file mode 100644 index 0000000..4d95c9f --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Preference.java @@ -0,0 +1,54 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import java.io.Serializable; + +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Entité représentant les préférences d'un utilisateur (Personne) pour un restaurant (Restaurant). + * Utilise une clé primaire composite {@link PreferencePK}. + */ +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class Preference implements Serializable { + private static final long serialVersionUID = 1L; + + + /** + * Clé primaire composite, contenant les références vers Personne et Restaurant. + */ + @EmbeddedId + private PreferencePK preferencePK; + + /** + * Note (de 1 à 5) attribuée par l'utilisateur au restaurant. Peut être nulle si non noté. + */ + @Column // Par défaut, nullable = true pour Integer + private Integer note; + + /** + * Indique si le restaurant est marqué comme favori par l'utilisateur. + */ + @Column(name = "favori") + private Boolean favori; + + /** + * Constructeur partiel pour initialiser avec la clé primaire. + * Ce constructeur est conservé car @AllArgsConstructor ne couvre pas ce cas spécifique + * si vous souhaitez initialiser uniquement avec la clé. + * Si @AllArgsConstructor suffit, vous pouvez supprimer celui-ci. + */ + public Preference(PreferencePK preferencePK){ + this.preferencePK = preferencePK; + } +} \ No newline at end of file diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePK.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePK.java new file mode 100644 index 0000000..205afb3 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePK.java @@ -0,0 +1,47 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import jakarta.persistence.Embeddable; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Classe représentant la clé primaire composite pour l'entité {@link Preference}. + * Elle est composée d'une référence à une {@link Personne} et à un {@link Restaurant}. + * Cette classe doit implémenter {@link Serializable} et redéfinir {@code equals()} et {@code hashCode()}. + */ +@Embeddable +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode +public class PreferencePK implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * La personne associée à cette préférence. Fait partie de la clé composite. + */ + @ManyToOne + @JoinColumn(name = "personne_id_personne") + @JsonBackReference("personne-preferencepk") + private Personne personne; + + /** + * Le restaurant associé à cette préférence. Fait partie de la clé composite. + */ + @ManyToOne + @JoinColumn(name="restau_id_restau") + @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) + private Restaurant restau; +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Restaurant.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Restaurant.java new file mode 100644 index 0000000..58d95eb --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/Restaurant.java @@ -0,0 +1,115 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.*; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; + +/** + * Entité représentant un restaurant dans l'application. + */ +@Entity +@Table(name = "restaurant") +@Getter +@Setter +@ToString(exclude = {"typerestaus", "preference"}) +@EqualsAndHashCode(exclude = {"typerestaus", "preference"}) +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Restaurant implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Identifiant unique du restaurant, généré automatiquement. + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id_restau") + private int id; + + /** + * Nom commercial du restaurant. + */ + @Column(nullable = false) + private String nom; + + /** + * Adresse postale complète du restaurant. + */ + @Column(nullable = false) + private String adresse; + + /** + * Numéro de téléphone du restaurant. + */ + @Column + private String telephone; + + /** + * Indique si le restaurant propose la vente à emporter. + */ + @Column(name = "a_emporter") + private Boolean aEmporter; + + /** + * Indique si le restaurant propose de consommer sur place. + */ + @Column(name = "sur_place") + private Boolean surPlace; + + /** + * Indication du niveau de prix (ex: 1 pour €, 2 pour €€, 3 pour €€€). + */ + @Column + private Integer prix; + + /** + * Indique si le restaurant est accessible aux Personnes à Mobilité Réduite. + */ + @Column(name = "accespmr") + private Boolean accesPMR; + + /** + * Coordonnée de latitude pour la géolocalisation. + */ + @Column(nullable = false) + private String latitude; + + /** + * Coordonnée de longitude pour la géolocalisation. + */ + @Column(nullable = false) + private String longitude; + + /** + * URL du site web du restaurant. + */ + @Column + private String website; + + /** + * Collection des types de cuisine proposés par le restaurant (ex: Italien, Français). + */ + @ManyToMany + @JoinTable( + name = "type_restau", + joinColumns = @JoinColumn(name = "id_restau", referencedColumnName = "id_restau"), + inverseJoinColumns = @JoinColumn(name = "id_type", referencedColumnName = "id_type") + ) + @Builder.Default + private Collection typerestaus = new ArrayList<>(); + + /** + * Collection des préférences des utilisateurs associées à ce restaurant. + * La suppression d'un restaurant entraîne la suppression des préférences associées. + */ + @OneToMany(mappedBy = "preferencePK.restau", cascade = CascadeType.REMOVE) + @JsonIgnore + @Builder.Default + private Collection preference = new ArrayList<>(); +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/TypeRestau.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/TypeRestau.java new file mode 100644 index 0000000..2e11726 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/models/TypeRestau.java @@ -0,0 +1,45 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.*; +import lombok.*; + +import java.util.ArrayList; +import java.io.Serializable; +import java.util.List; + +/** + * Entité représentant un type de cuisine (ex: "Italien", "Japonais"). + */ +@Entity +@Table(name = "type") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class TypeRestau implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Identifiant unique du type de cuisine, généré automatiquement. + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id_type") + private int id; + + /** + * Nom du type de cuisine (ex: "Pizza", "Français"). + */ + @Column(nullable = false) + private String libelle; + + /** + * Liste des restaurants associés à ce type de cuisine. + */ + @ManyToMany(mappedBy = "typerestaus") + @JsonBackReference("restaurants") + @Builder.Default + private List restaurants = new ArrayList<>(); +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/PersonneRepository.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/PersonneRepository.java new file mode 100644 index 0000000..b874bf9 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/PersonneRepository.java @@ -0,0 +1,12 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.repository; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Personne; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface PersonneRepository extends JpaRepository { + Optional findByEmail(String email); +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/PreferenceRepository.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/PreferenceRepository.java new file mode 100644 index 0000000..75d08fc --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/PreferenceRepository.java @@ -0,0 +1,17 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.repository; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Preference; +import fr.vincent.ramiere.mangerautourdesimplonback.models.PreferencePK; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * Repository pour l'entité Preference. + * Fournit les méthodes pour les opérations CRUD sur les préférences. + */ +@Repository +public interface PreferenceRepository extends JpaRepository { + List findByPreferencePK_Personne_Id(Integer personneId); +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/RestaurantRepository.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/RestaurantRepository.java new file mode 100644 index 0000000..784d470 --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/repository/RestaurantRepository.java @@ -0,0 +1,16 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; + +/** + * Dépot pour l'entité Restaurant. + * Fournit les méthodes pour les opérations CRUD. + */ + +@Repository +public interface RestaurantRepository extends JpaRepository{ + +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/JpaUserDetailsService.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/JpaUserDetailsService.java new file mode 100644 index 0000000..ec70c2a --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/JpaUserDetailsService.java @@ -0,0 +1,29 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.service; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Personne; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.PersonneRepository; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +public class JpaUserDetailsService implements UserDetailsService { + + private final PersonneRepository personneRepository; + + public JpaUserDetailsService(PersonneRepository personneRepository) { + this.personneRepository = personneRepository; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Personne personne = personneRepository.findByEmail(username) + .orElseThrow(() -> new UsernameNotFoundException("Aucun utilisateur trouvé avec l'email: " + username)); + + return new org.springframework.security.core.userdetails.User( + personne.getEmail(), + personne.getPassword(), + personne.getRoleList()); + } +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/PreferenceService.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/PreferenceService.java new file mode 100644 index 0000000..843b9de --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/PreferenceService.java @@ -0,0 +1,71 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.service; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Personne; +import fr.vincent.ramiere.mangerautourdesimplonback.models.Preference; +import fr.vincent.ramiere.mangerautourdesimplonback.models.PreferencePK; +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.PersonneRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.PreferenceRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.RestaurantRepository; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + +/** + * Service pour la gestion des préférences des utilisateurs. + */ +@Service +@AllArgsConstructor +public class PreferenceService { + + private final PreferenceRepository preferenceRepository; + private final PersonneRepository personneRepository; + private final RestaurantRepository restaurantRepository; + + /** + * Récupère toutes les préférences pour un utilisateur donné. + * + * @param personneId L'ID de l'utilisateur. + * @return Une liste de préférences. + */ + public List getPreferencesByPersonneId(Integer personneId) { + return preferenceRepository.findByPreferencePK_Personne_Id(personneId); + } + + /** + * Crée ou met à jour une préférence pour un utilisateur et un restaurant. + * + * @param personneId L'ID de l'utilisateur. + * @param restaurantId L'ID du restaurant. + * @param note La note attribuée (peut être null). + * @param favori Le statut de favori (peut être null). + * @return Un Optional contenant la préférence sauvegardée, ou un Optional vide + * si l'utilisateur ou le restaurant n'existe pas. + */ + @Transactional + public Optional saveOrUpdatePreference(Integer personneId, Integer restaurantId, Integer note, + Boolean favori) { + Optional personneOpt = personneRepository.findById(personneId); + Optional restaurantOpt = restaurantRepository.findById(restaurantId); + + if (personneOpt.isEmpty() || restaurantOpt.isEmpty()) { + return Optional.empty(); + } + + Personne personne = personneOpt.get(); + Restaurant restaurant = restaurantOpt.get(); + + PreferencePK preferencePK = new PreferencePK(personne, restaurant); + + Preference preference = preferenceRepository.findById(preferencePK) + .orElse(new Preference(preferencePK)); + + preference.setNote(note); + preference.setFavori(favori); + + return Optional.of(preferenceRepository.save(preference)); + } +} diff --git a/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/RestaurantService.java b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/RestaurantService.java new file mode 100644 index 0000000..c6e9aaf --- /dev/null +++ b/backend/src/main/java/fr/vincent/ramiere/mangerautourdesimplonback/service/RestaurantService.java @@ -0,0 +1,78 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.service; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.RestaurantRepository; + +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import lombok.AllArgsConstructor; + +/** + * Service pour la gestion des restaurants. + * Contient la logique métier liée aux opérations sur les restaurants. + */ +@Service +@AllArgsConstructor +public class RestaurantService { + private final RestaurantRepository restaurantRepository; + + /** + * Récupère tous les restaurants. + * @return une liste de tous les restaurants. + */ + public List getAllRestaurants() { + return restaurantRepository.findAll(); + } + + /** + * Récupère un restaurant par son identifiant. + * @param id L'identifiant du restaurant. + * @return un Optional contenant le restaurant s'il est trouvé, sinon un Optional vide. + */ + public Optional getRestaurantById(Integer id) { + return restaurantRepository.findById(id); + } + + /** + * Enregistre un nouveau restaurant. + * @param restaurant Le restaurant à enregistrer. + * @return le restaurant enregistré + */ + public Restaurant saveRestaurant(Restaurant restaurant) { + return restaurantRepository.save(restaurant); + } + + /** + * Met à jour un restaurant existant. + * @param id L'identifiant du restaurant à mettre à jour. + * @param restaurantDetails Les nouvelles informations du restaurant. + * @return le restaurant mis à jour. + */ + public Optional updateRestaurant(Integer id, Restaurant restaurantDetails) { + return restaurantRepository.findById(id) + .map(existingRestaurant -> { + existingRestaurant.setNom(restaurantDetails.getNom()); + existingRestaurant.setAdresse(restaurantDetails.getAdresse()); + existingRestaurant.setTelephone(restaurantDetails.getTelephone()); + existingRestaurant.setAccesPMR(restaurantDetails.getAccesPMR()); + existingRestaurant.setAEmporter(restaurantDetails.getAEmporter()); + existingRestaurant.setSurPlace(restaurantDetails.getSurPlace()); + existingRestaurant.setPrix(restaurantDetails.getPrix()); + existingRestaurant.setLatitude(restaurantDetails.getLatitude()); + existingRestaurant.setLongitude(restaurantDetails.getLongitude()); + existingRestaurant.setWebsite(restaurantDetails.getWebsite()); + return restaurantRepository.save(existingRestaurant); + }); + } + + /** + * Supprime un restaurant par son identifiant. + * @param id L'identifiant du restaurant à supprimer. + */ + public void deleteRestaurant(Integer id) { + restaurantRepository.deleteById(id); + } +} diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties new file mode 100644 index 0000000..10b44fa --- /dev/null +++ b/backend/src/main/resources/application.properties @@ -0,0 +1,26 @@ +spring.application.name=MangerAutourDeSimplonBack + +# =============================== +# base de données MySQL +# =============================== +spring.datasource.url=jdbc:mysql://localhost:3306/simpleat?useSSL=false&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=CET +spring.datasource.username=milane +spring.datasource.password=bbLouis1+Noe2 +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +# log +#logging.level.root=INFO +#logging.file=d:/data/log-hibernate-jpa.log +#logging.level.org.springframework.jdbc.core.JdbcTemplate=debug +# =============================== +# JPA / HIBERNATE +# =============================== +spring.jpa.show-sql=true +# spring.jpa.hibernate.ddl-auto=update +# spring.jpa.hibernate.ddl-auto=none +# spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect +# =============================== +# Permet d'exécuter le data.sql +# =============================== +# spring.sql.init.mode=always +# spring.jpa.defer-datasource-initialization=true +# server.port=8081 \ No newline at end of file diff --git a/backend/src/main/resources/data.sql b/backend/src/main/resources/data.sql new file mode 100644 index 0000000..233989d --- /dev/null +++ b/backend/src/main/resources/data.sql @@ -0,0 +1,150 @@ +insert into personne (nom, prenom, email, password) values ('Cardon', 'Thomas', 'thomas.cardon@gmail.com', '$2a$10$724bLjLyGOEKTBbHy.s3C.ETc.HuBnhEoCOuoO7.Ts7kyPbz6hkme'); +insert into personne (nom, prenom, email, password) values ('Ramiere', 'Vincent', 'vincent.ramiere@gmail.com', '$2a$10$x6.VyO9PCMXSPsi5/m/Hze9xOP.IUdYbaye7cNFc.PfyuRuVLbG7e'); +insert into personne (nom, prenom, email, password) values ('Verger', 'Romain', 'romain.verger@gmail.com', '$2a$10$oe/h0ZDpi6xFmTj8CvDMDe13hoEGv0DhHziY7GUatbb9ETcRw/8RG'); +insert into personne (nom, prenom, email, password) values ('Ribardiere', 'Paul-Emmanuel', 'paul.ribardiere@gmail.com', '$2a$10$ArSe7TSUapTs9oGE8824fOv4PM6NJwu7mzcg72cSmHy0.ds585Oke'); +insert into personne (nom, prenom, email, password) values ('Noris', 'William', 'william.noris@gmail.com', '$2a$10$6UbvPYBR2Ql09M1kgK0.HuoX3X1gxScmaOxI242EB2U7cXiylX3z.'); +insert into personne (nom, prenom, email, password) values ('Harmand', 'Isabelle', 'isabelle.harmand@gmail.com', '$2a$10$at1EZABxNN32M5pCttV36OvzbUWx1myGisa36i3..vveO6j0Lk2Da'); +insert into personne (nom, prenom, email, password) values ('Bajard', 'Blandine', 'blandine.bajard@gmail.com', '$2a$10$koeHn0Wg54MTc7iDb9hbsujy/Opfrhhu0uuhhBNA00rMXLeMpSl.m'); +insert into personne (nom, prenom, email, password) values ('El Hiri', 'Sana', 'sana.el-hiri@gmail.com', '$2a$10$jBBk1RQrl5XOeSQYz3xdJ.Xl8hBIu/x3mqHpYyL10m6KjwfDsWGEW'); +insert into personne (nom, prenom, email, password) values ('Lucas', 'Cecile', 'cecile.lucas@gmail.com', '$2a$10$HAUg8vlmtvS/YphJzWAPfuGJdLd/3SeSZ48JVvybK6Wh/AY3QirGG'); +insert into personne (nom, prenom, email, password) values ('Kerkeb', 'Mohamed', 'mohamed.kerkeb@gmail.com', '$2a$10$BpWZMlDLKXA2qGMo9t6cxeS6G/6mvjdsdN4nIUOAjE2sr/0sJNiCW'); +insert into personne (nom, prenom, email, password) values ('Rinquin', 'Aline', 'aline.rinquin@gmail.com', '$2a$10$FJKDTcipj/8PKos7AcCnZ.HHAmdDh6EjknpUWPLDcVfSXWPcHZI5O'); +insert into personne (nom, prenom, email, password) values ('Keddar', 'Noreddine', 'noredinne.keddar@gmail.com', '$2a$10$5iowOIUv72hFVsT9B8K.nerA3YTPAyyUiqOAwKR55ZZcpiHT96LhG'); +insert into personne (nom, prenom, email, password) values ('Tomczyk', 'Julian', 'julian.tomczyk@gmail.com', '$2a$10$vJ89S5CXjtO01NsYrwfLyudU/p2Cz1QNDm1dGUkfKD60Z23HLZM2.'); +insert into personne (nom, prenom, email, password) values ('Mjid', 'Hedi', 'hedi.mjid@gmail.com', '$10$vJ89S5CXjtO01NsYrwfLyudU/p2Cz1QNDm1dGUkfKD60Z23HLZM2.'); +insert into personne (nom, prenom, email, password) values ('BIDEN', 'Joe', 'joe@biden.fr', '$2a$10$NNfAnATNZf/MzIjrUFi5K.xqWizxv1Hil4/PyRAabKWK5DxsLPE6.'); + +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (1,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (2,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (3,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (4,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (5,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (6,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (7,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (8,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (9,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (10,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (11,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (12,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (13,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (14,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (15,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (15,'ROLE_READER'); + + +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,1,'Le Jardin de Montreuil','1 Rue du Sergent Godefroy, 93100 Montreuil','01 41 63 92 66','http://www.lejardindemontreuil.fr/','48.853391599999995','2.4347358'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,0,'La CaVe','45 Rue de Paris, 93100 Montreuil','01 42 87 09 48','http://www.lacaveestrestaurant.com/','48.8576152','2.4342148999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,0,1,1,'Villa 9 Trois','71 Rue Hoche, 93100 Montreuil','01 48 58 17 37','http://www.villa9trois.com/','48.8638352','2.4331966'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'L''Amourette','54 Rue Robespierre, 93100 Montreuil','01 48 59 99 94','http://www.lamourette.fr/','48.853121599999994','2.4234494'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Maison Montreuil','31 Rue du Capitaine Dreyfus, 93100 Montreuil','09 87 18 18 81','https://www.lamaisonmontreuil.com/','48.859359700000006','2.4399254999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'le poulet en feu','63 Rue Danton, 93100 Montreuil','09 87 51 10 90','https://www.pouletenfeu.fr/','48.8653553','2.4514297'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,1,'Les Tonneaux','62 Rue Robespierre, 93100 Montreuil','01 48 58 95 01',NULL,'48.85205','2.4238472'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Les Pianos','26 Rue Robespierre, 93100 Montreuil','09 63 53 85 17','https://www.facebook.com/lespianosmontreuilofficiel/','48.854841799999996','2.4230319'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,1,'M I M','113 Rue Marceau, 93100 Montreuil','01 43 63 31 13',NULL,'48.849849999999996','2.4265312999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'Le Gévaudan','1 Bd Rouget de Lisle, 93100 Montreuil','01 42 87 42 83',NULL,'48.8617445','2.4412374'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Restaurant Filippo','6 Bd Chanzy, 93100 Montreuil','01 48 18 08 16',NULL,'48.8583964','2.4349743'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,0,1,1,'Le Mange Disc','50 Rue de Romainville, 93100 Montreuil','09 83 54 60 27','https://m.facebook.com/Le-Mange-Disc-102557926519195/?locale2=fr_FR','48.8658457','2.4466363'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,NULL,'Restaurant El Kahina','227 Rue de Paris, 93100 Montreuil','01 48 70 95 46',NULL,'48.8550124','2.4195686'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (NULL,1,1,1,'La Baraka','262 Rue de Paris, 93100 Montreuil','01 42 87 19 27','http://www.labarakamontreuil.fr/?lang=fr','48.8549268','2.4177603999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Bottega Della Pizza','34 Bd Rouget de Lisle, 93100 Montreuil','01 43 63 04 35','http://www.labottegadellapizza.fr/','48.860204200000005','2.4387626'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,NULL,'Restaurant de la Paix','11 Rue Armand Carrel, 93100 Montreuil','01 73 55 21 72',NULL,'48.853764','2.4177003999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Fontaine Bar Restaurant','47 Rue Armand Carrel, 93100 Montreuil','01 48 70 08 84','https://www.facebook.com/pages/la-fontaine-de-montreuil-Restaurant/213852528659590?fref=ts','48.8512132','2.4183881'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,1,1,NULL,'La Cantine Arkose Montreuil','33 Rue du Progrès, 93100 Montreuil','01 49 88 45 07','https://lacantine.arkose.com/montreuil/','48.8516335','2.419278'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,1,1,NULL,'Kashmir Café.','14 Rue du Capitaine Dreyfus, 93100 Montreuil','01 43 63 33 86','http://www.kashmircafe.fr/','48.8582843','2.4378471999999998'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'W Lounge','37 Rue de Valmy, 93100 Montreuil','01 48 37 61 17','http://wlounge-montreuil.com/?utm_source=gmb&utm_medium=referral','48.8507208','2.4187186'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'L''Oasis','171 Rue de Paris, 93100 Montreuil','01 48 70 70 52','https://loasis-montreuil.fr/fr','48.855555599999995','2.4230556'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Obrigado','8 Av. de la Prte de Montreuil, 75020 Paris','09 84 58 24 21','http://obrigado.paris/','48.8534995','2.4118692'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Le Xanthos','30 Rue du Capitaine Dreyfus, 93100 Montreuil','01 55 86 26 77',NULL,'48.858785','2.4388468999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Thé Vert','43 Rue du Capitaine Dreyfus, 93100 Montreuil','01 42 87 79 57','http://www.thevertenligne.fr/','48.8596741','2.4405049'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Gramophone','1 Rue Pépin, 93100 Montreuil','01 49 88 74 56','http://www.restaurantlegramophone.com/','48.8641275','2.4449753'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,NULL,'La Grosse Mignonne','56 Rue Carnot, 93100 Montreuil','01 42 87 54 51','https://www.facebook.com/LaGrosseMignonne','48.855322','2.4413144'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,NULL,'La Galetiere','126 Rue de Paris, 93100 Montreuil','01 42 87 47 32','http://lagaletiere.eatbu.com/','48.8563999','2.4263293'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,1,1,1,'Le Mamaju','36 Rue de Lagny, 93100 Montreuil','01 83 74 02 26','https://mamaju-restaurant-montreuil.eatbu.com/','48.8490247','2.4265491'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'Le Pizzo','15 Rue du Capitaine Dreyfus, 93100 Montreuil','09 88 46 71 29',NULL,'48.8588721','2.4385882999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'L''Olivier','211 Rue de Paris, 93100 Montreuil','06 47 82 43 41',NULL,'48.855081','2.4203481'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Louise','27 Rue du Capitaine Dreyfus, 93100 Montreuil','06 75 32 56 81','https://instagram.com/cafelouisemontreuil?utm_medium=copy_link','48.859237','2.4394462'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'Ô Bar Lié','16 Rue de la République, 93100 Montreuil','01 48 58 71 95','http://www.obarlie.com/','48.8531155','2.4209562'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,NULL,'Gabycook','27 Rue du Progrès, 93100 Montreuil',NULL,NULL,'48.851772999999994','2.4202114'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'L''ALEMBERT','268 Rue de Paris, 93100 Montreuil','01 42 87 29 61','http://www.lalembert.fr/','48.8549126','2.4174881999999998'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'Gujarat','35 Bd Paul Vaillant Couturier, 93100 Montreuil','01 48 58 77 16','http://restaurantgujarat.fr/','48.865111','2.443053'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'L''effiloché Montreuil','5 Rue du Centenaire, 93100 Montreuil',NULL,NULL,'48.8579636','2.4270348'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'Famille-CMC','6 Av. Pasteur, 93100 Montreuil',NULL,NULL,'48.862999300000006','2.441328'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'O''Villagio','28 Rue du Capitaine Dreyfus, 93100 Montreuil','01 57 42 63 82','https://ovillaggio93.wixsite.com/o-villaggio','48.858722','2.4386695'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Brasserie des Laitières','38 Rue de Lagny, 93100 Montreuil','01 48 51 50 70','https://le-bl.metro.biz/','48.8490399','2.4262376999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'LE HAVANE','248 Rue de Paris, 93100 Montreuil','01 48 57 17 23',NULL,'48.855091599999994','2.4187965'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Chez Carla','6 Rue Claude Bernard, 93100 Montreuil','01 48 18 00 53','http://www.chezcarla.fr/','48.8699343','2.4507599'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'2 Bd Chanzy, 93100 Montreuil','48.85847716355682','2.4358987134859515','Le Sultan',1,1,'0148180475',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'19 Av. de la Résistance, 93100 Montreuil','48.85945630168561','2.436446504305728','Monoprix',1,0,'0141720580','monoprix.fr'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,' 20, Avenue De La Resistance','48.859572881535506','2.43723868323233','Fournil du Perche',1,0,'',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'Place Jacques Duclot','48.85763987017326','2.4357752878301313','Street Wok',1,0,'',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'18 Bd Rouget de Lisle, 93100 Montreuil','48.86127664908431','2.440266447738863','La Casa',2,1,'0187004594','www.lacasa-pizza.fr/'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'31 Rue Franklin, 93100 Montreuil','48.86373425237411','2.444081609130601','New Kyoto',2,1,'0142877365','https://newkyoto93.fr/'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'86 Bd Henri Barbusse, 93100 Montreuil','48.868535950518506','2.4415787173758625','Cosa C E Da Mangiare',2,1,'0148510777',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'8 Av. Walwein, 93100 Montreuil','48.86227215595597','2.443526611143298','Bamboo & Sum',2,1,'0987366393',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'78 Av. de la Résistance, 93100 Montreuil','48.86260826926845','2.4370469579964404','O Bon Coin',1,1,'0953523586',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'14 Rue du Capitaine Dreyfus, 93100 Montreuil','48.85828992238344','2.437848545198565','Kashmir Café',2,1,'0143633386','http://www.kashmircafe.fr/'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'45 Bd Paul Vaillant Couturier, 93100 Montreuil','48.86615467929139','2.4442899980905284','Le Marrakech',3,1,'0148589402',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'7 Bd Rouget de Lisle, 93100 Montreuil','48.86133951184523','2.4407883330629856','BOLKIRI',2,1,'0184671708','http://bolkiri.fr/'); + + + +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (2, 9, 1, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (3, 1, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 9, 3, true); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (4, 6, 2, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (5, 5, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 10, 1, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (5, 3, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 7, 1, true); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (4, 2, 1, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 3, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (3, 10, 4, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (3, 3, 4, true); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (2, 3, 3, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (2, 8, 3, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (5, 15, 3, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (8, 15, 3, false); + +insert into type (id_type, libelle) values (1, 'Kebab'); +insert into type (id_type, libelle) values (2, 'Supermarché'); +insert into type (id_type, libelle) values (3, 'Boulangerie'); +insert into type (id_type, libelle) values (4, 'Thaï'); +insert into type (id_type, libelle) values (5, 'Français'); +insert into type (id_type, libelle) values (6, 'Pizza'); +insert into type (id_type, libelle) values (7, 'Brasserie'); +insert into type (id_type, libelle) values (8, 'Americain'); +insert into type (id_type, libelle) values (9, 'Japonais'); +insert into type (id_type, libelle) values (11, 'Italien'); +insert into type (id_type, libelle) values (13, 'Chinois'); +insert into type (id_type, libelle) values (15, 'Hamburger'); +insert into type (id_type, libelle) values (16, 'Indien'); +insert into type (id_type, libelle) values (17, 'Marocain'); +insert into type (id_type, libelle) values (20, 'Vietnamien'); +insert into type (id_type, libelle) values (21, 'Bistrot'); +insert into type (id_type, libelle) values (22, 'Poulet'); + +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (1,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (2,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (3,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (4,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (5,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (6,8); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (6,22); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (7,7); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (8,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (9,21); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (10,7); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (42,1); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (43,2); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (44,3); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (45,4); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (46,6); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (47,9); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (48,11); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (49,13); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (50,15); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (51,16); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (52,17); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (53,20); + + diff --git a/backend/src/main/resources/script-simpleat.sql b/backend/src/main/resources/script-simpleat.sql new file mode 100644 index 0000000..86a47cb --- /dev/null +++ b/backend/src/main/resources/script-simpleat.sql @@ -0,0 +1,230 @@ +DROP SCHEMA IF EXISTS `simpleat`; + +CREATE SCHEMA IF NOT EXISTS `simpleat` DEFAULT CHARACTER SET utf8mb4 ; +USE `simpleat` ; + +CREATE TABLE IF NOT EXISTS `simpleat`.`personne` ( + `id_personne` INT NOT NULL AUTO_INCREMENT, + `email` VARCHAR(255) NOT NULL, + `nom` VARCHAR(255) NOT NULL, + `password` VARCHAR(255) NOT NULL, + `prenom` VARCHAR(255) NOT NULL, + PRIMARY KEY (`id_personne`) +); + +CREATE TABLE IF NOT EXISTS `simpleat`.`personne_role_list` ( + `personne_id_personne` INT NOT NULL, + `role_list` VARCHAR(255) NULL DEFAULT NULL, + INDEX (`personne_id_personne`), + FOREIGN KEY (`personne_id_personne`) + REFERENCES `simpleat`.`personne` (`id_personne`) +); + +CREATE TABLE IF NOT EXISTS `simpleat`.`restaurant` ( + `id_restau` INT NOT NULL AUTO_INCREMENT, + `a_emporter` BOOLEAN NULL DEFAULT NULL, + `accespmr` BOOLEAN NULL DEFAULT NULL, + `adresse` VARCHAR(255) NOT NULL, + `latitude` VARCHAR(255) NOT NULL, + `longitude` VARCHAR(255) NOT NULL, + `nom` VARCHAR(255) NOT NULL, + `prix` INT NULL DEFAULT NULL, + `sur_place` BOOLEAN NULL DEFAULT NULL, + `telephone` VARCHAR(255) NULL DEFAULT NULL, + `website` VARCHAR(255) NULL DEFAULT NULL, + PRIMARY KEY (`id_restau`) +); + +CREATE TABLE IF NOT EXISTS `simpleat`.`preference` ( + `favori` BOOLEAN NULL DEFAULT NULL, + `note` INT NULL DEFAULT NULL, + `restau_id_restau` INT NOT NULL, + `personne_id_personne` INT NOT NULL, + PRIMARY KEY (`personne_id_personne`, `restau_id_restau`), + INDEX (`restau_id_restau`), + INDEX (`personne_id_personne`), + FOREIGN KEY (`restau_id_restau`) + REFERENCES `simpleat`.`restaurant` (`id_restau`), + FOREIGN KEY (`personne_id_personne`) + REFERENCES `simpleat`.`personne` (`id_personne`) +); + +CREATE TABLE IF NOT EXISTS `simpleat`.`reservation` ( + `date_resa` DATETIME NOT NULL, + `nb_personne` INT NOT NULL, + `id_restau` INT NOT NULL, + `id_personne` INT NOT NULL, + PRIMARY KEY (`date_resa`, `id_personne`, `id_restau`), + INDEX (`id_restau`), + INDEX (`id_personne`), + FOREIGN KEY (`id_restau`) + REFERENCES `simpleat`.`restaurant` (`id_restau`), + FOREIGN KEY (`id_personne`) + REFERENCES `simpleat`.`personne` (`id_personne`) +); + +CREATE TABLE IF NOT EXISTS `simpleat`.`type` ( + `id_type` INT NOT NULL AUTO_INCREMENT, + `libelle` VARCHAR(255) NOT NULL, + PRIMARY KEY (`id_type`) +); + +CREATE TABLE IF NOT EXISTS `simpleat`.`type_restau` ( + `id_restau` INT NOT NULL, + `id_type` INT NOT NULL, + INDEX (`id_type`) , + INDEX (`id_restau` ) , + FOREIGN KEY (`id_type`) + REFERENCES `simpleat`.`type` (`id_type`), + FOREIGN KEY (`id_restau`) + REFERENCES `simpleat`.`restaurant` (`id_restau`) +); + +insert into personne (nom, prenom, email, password) values ('Cardon', 'Thomas', 'thomas.cardon@gmail.com', '$2a$10$724bLjLyGOEKTBbHy.s3C.ETc.HuBnhEoCOuoO7.Ts7kyPbz6hkme'); +insert into personne (nom, prenom, email, password) values ('Ramiere', 'Vincent', 'vincent.ramiere@gmail.com', '$2a$10$x6.VyO9PCMXSPsi5/m/Hze9xOP.IUdYbaye7cNFc.PfyuRuVLbG7e'); +insert into personne (nom, prenom, email, password) values ('Verger', 'Romain', 'romain.verger@gmail.com', '$2a$10$oe/h0ZDpi6xFmTj8CvDMDe13hoEGv0DhHziY7GUatbb9ETcRw/8RG'); +insert into personne (nom, prenom, email, password) values ('Ribardiere', 'Paul-Emmanuel', 'paul.ribardiere@gmail.com', '$2a$10$ArSe7TSUapTs9oGE8824fOv4PM6NJwu7mzcg72cSmHy0.ds585Oke'); +insert into personne (nom, prenom, email, password) values ('Noris', 'William', 'william.noris@gmail.com', '$2a$10$6UbvPYBR2Ql09M1kgK0.HuoX3X1gxScmaOxI242EB2U7cXiylX3z.'); +insert into personne (nom, prenom, email, password) values ('Harmand', 'Isabelle', 'isabelle.harmand@gmail.com', '$2a$10$at1EZABxNN32M5pCttV36OvzbUWx1myGisa36i3..vveO6j0Lk2Da'); +insert into personne (nom, prenom, email, password) values ('Bajard', 'Blandine', 'blandine.bajard@gmail.com', '$2a$10$koeHn0Wg54MTc7iDb9hbsujy/Opfrhhu0uuhhBNA00rMXLeMpSl.m'); +insert into personne (nom, prenom, email, password) values ('El Hiri', 'Sana', 'sana.el-hiri@gmail.com', '$2a$10$jBBk1RQrl5XOeSQYz3xdJ.Xl8hBIu/x3mqHpYyL10m6KjwfDsWGEW'); +insert into personne (nom, prenom, email, password) values ('Lucas', 'Cecile', 'cecile.lucas@gmail.com', '$2a$10$HAUg8vlmtvS/YphJzWAPfuGJdLd/3SeSZ48JVvybK6Wh/AY3QirGG'); +insert into personne (nom, prenom, email, password) values ('Kerkeb', 'Mohamed', 'mohamed.kerkeb@gmail.com', '$2a$10$BpWZMlDLKXA2qGMo9t6cxeS6G/6mvjdsdN4nIUOAjE2sr/0sJNiCW'); +insert into personne (nom, prenom, email, password) values ('Rinquin', 'Aline', 'aline.rinquin@gmail.com', '$2a$10$FJKDTcipj/8PKos7AcCnZ.HHAmdDh6EjknpUWPLDcVfSXWPcHZI5O'); +insert into personne (nom, prenom, email, password) values ('Keddar', 'Noreddine', 'noredinne.keddar@gmail.com', '$2a$10$5iowOIUv72hFVsT9B8K.nerA3YTPAyyUiqOAwKR55ZZcpiHT96LhG'); +insert into personne (nom, prenom, email, password) values ('Tomczyk', 'Julian', 'julian.tomczyk@gmail.com', '$2a$10$vJ89S5CXjtO01NsYrwfLyudU/p2Cz1QNDm1dGUkfKD60Z23HLZM2.'); +insert into personne (nom, prenom, email, password) values ('Mjid', 'Hedi', 'hedi.mjid@gmail.com', '$10$vJ89S5CXjtO01NsYrwfLyudU/p2Cz1QNDm1dGUkfKD60Z23HLZM2.'); +insert into personne (nom, prenom, email, password) values ('BIDEN', 'Joe', 'joe@biden.fr', '$2a$10$NNfAnATNZf/MzIjrUFi5K.xqWizxv1Hil4/PyRAabKWK5DxsLPE6.'); + +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (1,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (2,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (3,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (4,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (5,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (6,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (7,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (8,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (9,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (10,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (11,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (12,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (13,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (14,'ROLE_READER'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (15,'ROLE_ADMIN'); +INSERT INTO `personne_role_list` (`personne_id_personne`,`role_list`) VALUES (15,'ROLE_READER'); + + +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,1,'Le Jardin de Montreuil','1 Rue du Sergent Godefroy, 93100 Montreuil','01 41 63 92 66','http://www.lejardindemontreuil.fr/','48.853391599999995','2.4347358'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,0,'La CaVe','45 Rue de Paris, 93100 Montreuil','01 42 87 09 48','http://www.lacaveestrestaurant.com/','48.8576152','2.4342148999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,0,1,1,'Villa 9 Trois','71 Rue Hoche, 93100 Montreuil','01 48 58 17 37','http://www.villa9trois.com/','48.8638352','2.4331966'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'L''Amourette','54 Rue Robespierre, 93100 Montreuil','01 48 59 99 94','http://www.lamourette.fr/','48.853121599999994','2.4234494'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Maison Montreuil','31 Rue du Capitaine Dreyfus, 93100 Montreuil','09 87 18 18 81','https://www.lamaisonmontreuil.com/','48.859359700000006','2.4399254999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'le poulet en feu','63 Rue Danton, 93100 Montreuil','09 87 51 10 90','https://www.pouletenfeu.fr/','48.8653553','2.4514297'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,1,'Les Tonneaux','62 Rue Robespierre, 93100 Montreuil','01 48 58 95 01',NULL,'48.85205','2.4238472'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Les Pianos','26 Rue Robespierre, 93100 Montreuil','09 63 53 85 17','https://www.facebook.com/lespianosmontreuilofficiel/','48.854841799999996','2.4230319'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,1,'M I M','113 Rue Marceau, 93100 Montreuil','01 43 63 31 13',NULL,'48.849849999999996','2.4265312999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'Le Gévaudan','1 Bd Rouget de Lisle, 93100 Montreuil','01 42 87 42 83',NULL,'48.8617445','2.4412374'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Restaurant Filippo','6 Bd Chanzy, 93100 Montreuil','01 48 18 08 16',NULL,'48.8583964','2.4349743'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,0,1,1,'Le Mange Disc','50 Rue de Romainville, 93100 Montreuil','09 83 54 60 27','https://m.facebook.com/Le-Mange-Disc-102557926519195/?locale2=fr_FR','48.8658457','2.4466363'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,NULL,'Restaurant El Kahina','227 Rue de Paris, 93100 Montreuil','01 48 70 95 46',NULL,'48.8550124','2.4195686'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (NULL,1,1,1,'La Baraka','262 Rue de Paris, 93100 Montreuil','01 42 87 19 27','http://www.labarakamontreuil.fr/?lang=fr','48.8549268','2.4177603999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Bottega Della Pizza','34 Bd Rouget de Lisle, 93100 Montreuil','01 43 63 04 35','http://www.labottegadellapizza.fr/','48.860204200000005','2.4387626'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,NULL,'Restaurant de la Paix','11 Rue Armand Carrel, 93100 Montreuil','01 73 55 21 72',NULL,'48.853764','2.4177003999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Fontaine Bar Restaurant','47 Rue Armand Carrel, 93100 Montreuil','01 48 70 08 84','https://www.facebook.com/pages/la-fontaine-de-montreuil-Restaurant/213852528659590?fref=ts','48.8512132','2.4183881'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,1,1,NULL,'La Cantine Arkose Montreuil','33 Rue du Progrès, 93100 Montreuil','01 49 88 45 07','https://lacantine.arkose.com/montreuil/','48.8516335','2.419278'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,1,1,NULL,'Kashmir Café.','14 Rue du Capitaine Dreyfus, 93100 Montreuil','01 43 63 33 86','http://www.kashmircafe.fr/','48.8582843','2.4378471999999998'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'W Lounge','37 Rue de Valmy, 93100 Montreuil','01 48 37 61 17','http://wlounge-montreuil.com/?utm_source=gmb&utm_medium=referral','48.8507208','2.4187186'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'L''Oasis','171 Rue de Paris, 93100 Montreuil','01 48 70 70 52','https://loasis-montreuil.fr/fr','48.855555599999995','2.4230556'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Obrigado','8 Av. de la Prte de Montreuil, 75020 Paris','09 84 58 24 21','http://obrigado.paris/','48.8534995','2.4118692'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Le Xanthos','30 Rue du Capitaine Dreyfus, 93100 Montreuil','01 55 86 26 77',NULL,'48.858785','2.4388468999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Thé Vert','43 Rue du Capitaine Dreyfus, 93100 Montreuil','01 42 87 79 57','http://www.thevertenligne.fr/','48.8596741','2.4405049'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Gramophone','1 Rue Pépin, 93100 Montreuil','01 49 88 74 56','http://www.restaurantlegramophone.com/','48.8641275','2.4449753'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,0,1,NULL,'La Grosse Mignonne','56 Rue Carnot, 93100 Montreuil','01 42 87 54 51','https://www.facebook.com/LaGrosseMignonne','48.855322','2.4413144'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,NULL,'La Galetiere','126 Rue de Paris, 93100 Montreuil','01 42 87 47 32','http://lagaletiere.eatbu.com/','48.8563999','2.4263293'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (3,1,1,1,'Le Mamaju','36 Rue de Lagny, 93100 Montreuil','01 83 74 02 26','https://mamaju-restaurant-montreuil.eatbu.com/','48.8490247','2.4265491'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'Le Pizzo','15 Rue du Capitaine Dreyfus, 93100 Montreuil','09 88 46 71 29',NULL,'48.8588721','2.4385882999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'L''Olivier','211 Rue de Paris, 93100 Montreuil','06 47 82 43 41',NULL,'48.855081','2.4203481'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Louise','27 Rue du Capitaine Dreyfus, 93100 Montreuil','06 75 32 56 81','https://instagram.com/cafelouisemontreuil?utm_medium=copy_link','48.859237','2.4394462'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'Ô Bar Lié','16 Rue de la République, 93100 Montreuil','01 48 58 71 95','http://www.obarlie.com/','48.8531155','2.4209562'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,NULL,'Gabycook','27 Rue du Progrès, 93100 Montreuil',NULL,NULL,'48.851772999999994','2.4202114'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'L''ALEMBERT','268 Rue de Paris, 93100 Montreuil','01 42 87 29 61','http://www.lalembert.fr/','48.8549126','2.4174881999999998'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'Gujarat','35 Bd Paul Vaillant Couturier, 93100 Montreuil','01 48 58 77 16','http://restaurantgujarat.fr/','48.865111','2.443053'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'L''effiloché Montreuil','5 Rue du Centenaire, 93100 Montreuil',NULL,NULL,'48.8579636','2.4270348'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'Famille-CMC','6 Av. Pasteur, 93100 Montreuil',NULL,NULL,'48.862999300000006','2.441328'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,NULL,'O''Villagio','28 Rue du Capitaine Dreyfus, 93100 Montreuil','01 57 42 63 82','https://ovillaggio93.wixsite.com/o-villaggio','48.858722','2.4386695'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'La Brasserie des Laitières','38 Rue de Lagny, 93100 Montreuil','01 48 51 50 70','https://le-bl.metro.biz/','48.8490399','2.4262376999999997'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (1,1,1,1,'LE HAVANE','248 Rue de Paris, 93100 Montreuil','01 48 57 17 23',NULL,'48.855091599999994','2.4187965'); +INSERT INTO restaurant(prix,a_emporter,sur_place,accespmr,nom,adresse,telephone,website,latitude,longitude) VALUES (2,1,1,1,'Chez Carla','6 Rue Claude Bernard, 93100 Montreuil','01 48 18 00 53','http://www.chezcarla.fr/','48.8699343','2.4507599'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'2 Bd Chanzy, 93100 Montreuil','48.85847716355682','2.4358987134859515','Le Sultan',1,1,'0148180475',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'19 Av. de la Résistance, 93100 Montreuil','48.85945630168561','2.436446504305728','Monoprix',1,0,'0141720580','monoprix.fr'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,' 20, Avenue De La Resistance','48.859572881535506','2.43723868323233','Fournil du Perche',1,0,'',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'Place Jacques Duclot','48.85763987017326','2.4357752878301313','Street Wok',1,0,'',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'18 Bd Rouget de Lisle, 93100 Montreuil','48.86127664908431','2.440266447738863','La Casa',2,1,'0187004594','www.lacasa-pizza.fr/'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'31 Rue Franklin, 93100 Montreuil','48.86373425237411','2.444081609130601','New Kyoto',2,1,'0142877365','https://newkyoto93.fr/'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'86 Bd Henri Barbusse, 93100 Montreuil','48.868535950518506','2.4415787173758625','Cosa C E Da Mangiare',2,1,'0148510777',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,1,'8 Av. Walwein, 93100 Montreuil','48.86227215595597','2.443526611143298','Bamboo & Sum',2,1,'0987366393',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'78 Av. de la Résistance, 93100 Montreuil','48.86260826926845','2.4370469579964404','O Bon Coin',1,1,'0953523586',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'14 Rue du Capitaine Dreyfus, 93100 Montreuil','48.85828992238344','2.437848545198565','Kashmir Café',2,1,'0143633386','http://www.kashmircafe.fr/'); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'45 Bd Paul Vaillant Couturier, 93100 Montreuil','48.86615467929139','2.4442899980905284','Le Marrakech',3,1,'0148589402',''); +INSERT INTO restaurant (`a_emporter`,`accespmr`,`adresse`,`latitude`,`longitude`,`nom`,`prix`,`sur_place`,`telephone`,`website`) VALUES (1,NULL,'7 Bd Rouget de Lisle, 93100 Montreuil','48.86133951184523','2.4407883330629856','BOLKIRI',2,1,'0184671708','http://bolkiri.fr/'); + + + +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (2, 9, 1, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (3, 1, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 9, 3, true); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (4, 6, 2, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (5, 5, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 10, 1, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (5, 3, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 7, 1, true); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (4, 2, 1, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (1, 3, 5, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (3, 10, 4, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (3, 3, 4, true); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (2, 3, 3, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (2, 8, 3, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (5, 15, 3, false); +insert into preference (restau_id_restau, personne_id_personne, note, favori) values (8, 15, 3, false); + +insert into type (id_type, libelle) values (1, 'Kebab'); +insert into type (id_type, libelle) values (2, 'Supermarché'); +insert into type (id_type, libelle) values (3, 'Boulangerie'); +insert into type (id_type, libelle) values (4, 'Thaï'); +insert into type (id_type, libelle) values (5, 'Français'); +insert into type (id_type, libelle) values (6, 'Pizza'); +insert into type (id_type, libelle) values (7, 'Brasserie'); +insert into type (id_type, libelle) values (8, 'Americain'); +insert into type (id_type, libelle) values (9, 'Japonais'); +insert into type (id_type, libelle) values (11, 'Italien'); +insert into type (id_type, libelle) values (13, 'Chinois'); +insert into type (id_type, libelle) values (15, 'Hamburger'); +insert into type (id_type, libelle) values (16, 'Indien'); +insert into type (id_type, libelle) values (17, 'Marocain'); +insert into type (id_type, libelle) values (20, 'Vietnamien'); +insert into type (id_type, libelle) values (21, 'Bistrot'); +insert into type (id_type, libelle) values (22, 'Poulet'); + +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (1,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (2,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (3,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (4,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (5,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (6,8); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (6,22); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (7,7); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (8,5); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (9,21); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (10,7); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (42,1); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (43,2); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (44,3); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (45,4); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (46,6); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (47,9); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (48,11); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (49,13); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (50,15); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (51,16); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (52,17); +INSERT INTO type_restau (`id_restau`,`id_type`) VALUES (53,20); diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/MangerAutourDeSimplonBackApplicationTests.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/MangerAutourDeSimplonBackApplicationTests.java new file mode 100644 index 0000000..c8a4b6e --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/MangerAutourDeSimplonBackApplicationTests.java @@ -0,0 +1,14 @@ +package fr.vincent.ramiere.mangerautourdesimplonback; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class MangerAutourDeSimplonBackApplicationTests { + + @Test + void contextLoads() { + // Ce test garantit que le contexte de l'application Spring peut démarrer avec + // succès. + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceControllerTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceControllerTest.java new file mode 100644 index 0000000..de56c65 --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/PreferenceControllerTest.java @@ -0,0 +1,72 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.controller; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Preference; +import fr.vincent.ramiere.mangerautourdesimplonback.service.PreferenceService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import java.util.Collections; +import java.util.Optional; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +class PreferenceControllerTest { + + private PreferenceService preferenceService; + private MockMvc mockMvc; + + @BeforeEach + void setup() { + preferenceService = Mockito.mock(PreferenceService.class); + PreferenceController controller = new PreferenceController(preferenceService); + mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); + } + + @Test + void getPreferencesByPersonneId_shouldReturnOkAndCallService() throws Exception { + when(preferenceService.getPreferencesByPersonneId(42)).thenReturn(Collections.emptyList()); + + mockMvc.perform(get("/api/v1/preferences/user/42")) + .andExpect(status().isOk()); + + verify(preferenceService, times(1)).getPreferencesByPersonneId(42); + } + + @Test + void saveOrUpdatePreference_shouldReturnNotFound_whenServiceReturnsEmpty() throws Exception { + when(preferenceService.saveOrUpdatePreference(1, 2, 5, true)) + .thenReturn(Optional.empty()); + + String json = "{\"personneId\":1,\"restaurantId\":2,\"note\":5,\"favori\":true}"; + + mockMvc.perform(put("/api/v1/preferences") + .contentType(MediaType.APPLICATION_JSON) + .content(json)) + .andExpect(status().isNotFound()); + + verify(preferenceService, times(1)).saveOrUpdatePreference(1, 2, 5, true); + } + + @Test + void saveOrUpdatePreference_shouldReturnOk_whenServiceReturnsPreference() throws Exception { + Preference prefMock = Mockito.mock(Preference.class); + when(preferenceService.saveOrUpdatePreference(7, 8, 3, false)) + .thenReturn(Optional.of(prefMock)); + + String json = "{\"personneId\":7,\"restaurantId\":8,\"note\":3,\"favori\":false}"; + + mockMvc.perform(put("/api/v1/preferences") + .contentType(MediaType.APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()); + + verify(preferenceService, times(1)).saveOrUpdatePreference(7, 8, 3, false); + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/RestaurantControllerTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/RestaurantControllerTest.java new file mode 100644 index 0000000..dfec961 --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/controller/RestaurantControllerTest.java @@ -0,0 +1,120 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.controller; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; +import fr.vincent.ramiere.mangerautourdesimplonback.service.RestaurantService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class RestaurantControllerTest { + + @Mock + private RestaurantService restaurantService; + + @InjectMocks + private RestaurantController restaurantController; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void getAllRestaurants_shouldReturnListOfRestaurants() { + Restaurant r1 = new Restaurant(); + Restaurant r2 = new Restaurant(); + List restaurants = Arrays.asList(r1, r2); + + when(restaurantService.getAllRestaurants()).thenReturn(restaurants); + + ResponseEntity> response = restaurantController.getAllRestaurants(); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(restaurants, response.getBody()); + } + + @Test + void getRestaurantById_found_shouldReturnRestaurant() { + Restaurant restaurant = new Restaurant(); + when(restaurantService.getRestaurantById(1)).thenReturn(Optional.of(restaurant)); + + ResponseEntity response = restaurantController.getRestaurantById(1); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(restaurant, response.getBody()); + } + + @Test + void getRestaurantById_notFound_shouldReturnNotFound() { + when(restaurantService.getRestaurantById(1)).thenReturn(Optional.empty()); + + ResponseEntity response = restaurantController.getRestaurantById(1); + + assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); + assertNull(response.getBody()); + } + + @Test + void createRestaurant_shouldReturnCreatedRestaurant() { + Restaurant restaurant = new Restaurant(); + Restaurant savedRestaurant = new Restaurant(); + when(restaurantService.saveRestaurant(restaurant)).thenReturn(savedRestaurant); + + ResponseEntity response = restaurantController.createRestaurant(restaurant); + + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertEquals(savedRestaurant, response.getBody()); + } + + @Test + void updateRestaurant_found_shouldReturnUpdatedRestaurant() { + Restaurant details = new Restaurant(); + Restaurant updated = new Restaurant(); + when(restaurantService.updateRestaurant(eq(1), any(Restaurant.class))).thenReturn(Optional.of(updated)); + + ResponseEntity response = restaurantController.updateRestaurant(1, details); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(updated, response.getBody()); + } + + @Test + void updateRestaurant_notFound_shouldReturnNotFound() { + Restaurant details = new Restaurant(); + when(restaurantService.updateRestaurant(eq(1), any(Restaurant.class))).thenReturn(Optional.empty()); + + ResponseEntity response = restaurantController.updateRestaurant(1, details); + + assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); + assertNull(response.getBody()); + } + + @Test + void deleteRestaurant_found_shouldReturnNoContent() { + when(restaurantService.getRestaurantById(1)).thenReturn(Optional.of(new Restaurant())); + + ResponseEntity response = restaurantController.deleteRestaurant(1); + + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + verify(restaurantService, times(1)).deleteRestaurant(1); + } + + @Test + void deleteRestaurant_notFound_shouldReturnNotFound() { + when(restaurantService.getRestaurantById(1)).thenReturn(Optional.empty()); + + ResponseEntity response = restaurantController.deleteRestaurant(1); + + assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); + verify(restaurantService, never()).deleteRestaurant(anyInt()); + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PersonneTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PersonneTest.java new file mode 100644 index 0000000..06a821a --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PersonneTest.java @@ -0,0 +1,16 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class PersonneTest { + @Test + void testBuilder() { + Personne p = Personne.builder().nom("Test").prenom("Test").email("t@t.fr").password("1234").build(); + assertEquals("Test", p.getNom()); + assertEquals("Test", p.getPrenom()); + assertEquals("t@t.fr", p.getEmail()); + assertEquals("1234", p.getPassword()); + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePKTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePKTest.java new file mode 100644 index 0000000..0c83749 --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferencePKTest.java @@ -0,0 +1,48 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +class PreferencePKTest { + + @Test + void noArgsConstructor_settersAndGetters_handleNulls() { + PreferencePK pk = new PreferencePK(); + // initially null + assertNull(pk.getPersonne()); + assertNull(pk.getRestau()); + + // set to null explicitly and verify + pk.setPersonne(null); + pk.setRestau(null); + assertNull(pk.getPersonne()); + assertNull(pk.getRestau()); + } + + @Test + void equals_and_hashCode_withBothFieldsNull_areEqual() { + PreferencePK a = new PreferencePK(); + PreferencePK b = new PreferencePK(); + + // Both have null personne and restau -> should be equal and have same hashCode + assertEquals(a, b); + assertEquals(b, a); + assertEquals(a.hashCode(), b.hashCode()); + + // reflexive + assertEquals(a, a); + } + + @Test + void equals_withSameReference_isTrue_and_hashCodeStable() { + PreferencePK original = new PreferencePK(); + PreferencePK sameRef = original; + + assertEquals(original, sameRef); + assertEquals(original.hashCode(), sameRef.hashCode()); + + int firstHash = original.hashCode(); + int secondHash = original.hashCode(); + assertEquals(firstHash, secondHash, "hashCode should be stable across invocations"); + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferenceTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferenceTest.java new file mode 100644 index 0000000..dc8d2e1 --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/PreferenceTest.java @@ -0,0 +1,65 @@ + +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import org.junit.jupiter.api.Test; +import java.io.*; +import static org.junit.jupiter.api.Assertions.*; + +class PreferenceTest { + + @Test + void defaultConstructor_and_setters_getters() { + Preference p = new Preference(); + assertNull(p.getPreferencePK()); + assertNull(p.getNote()); + assertNull(p.getFavori()); + + p.setNote(5); + p.setFavori(Boolean.TRUE); + + assertEquals(5, p.getNote()); + assertTrue(p.getFavori()); + } + + @Test + void allArgsConstructor_setsFieldsInOrder() { + // AllArgsConstructor order is (PreferencePK preferencePK, Integer note, Boolean + // favori) + Preference p = new Preference(null, 3, Boolean.FALSE); + + assertNull(p.getPreferencePK()); + assertEquals(3, p.getNote()); + assertFalse(p.getFavori()); + } + + @Test + void singleArgConstructor_setsOnlyPreferencePK() { + Preference p = new Preference((PreferencePK) null); + + assertNull(p.getPreferencePK()); + // other fields remain null when not provided + assertNull(p.getNote()); + assertNull(p.getFavori()); + } + + @Test + void implementsSerializable_and_canBeSerialized() throws Exception { + Preference original = new Preference(null, 4, Boolean.TRUE); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(original); + } + + byte[] bytes = bos.toByteArray(); + try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) { + Object obj = ois.readObject(); + assertTrue(obj instanceof Preference); + Preference deserialized = (Preference) obj; + + assertEquals(original.getPreferencePK(), deserialized.getPreferencePK()); + assertEquals(original.getNote(), deserialized.getNote()); + assertEquals(original.getFavori(), deserialized.getFavori()); + } + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/RestaurantTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/RestaurantTest.java new file mode 100644 index 0000000..fb96825 --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/models/RestaurantTest.java @@ -0,0 +1,26 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.models; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class RestaurantTest { + @Test + void testBuilder() { + Restaurant r = Restaurant.builder().nom("Test").adresse("Adresse Test").telephone("0123456789").accesPMR(true) + .aEmporter(true) + .surPlace(false).prix(10).latitude("1.0").longitude("2.0").website("site-test.com").build(); + assertEquals("Test", r.getNom()); + assertEquals("Adresse Test", r.getAdresse()); + assertEquals("0123456789", r.getTelephone()); + assertTrue(r.getAccesPMR()); + assertTrue(r.getAEmporter()); + assertFalse(r.getSurPlace()); + assertEquals(10, r.getPrix()); + assertEquals("1.0", r.getLatitude()); + assertEquals("2.0", r.getLongitude()); + assertEquals("site-test.com", r.getWebsite()); + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/PreferenceServiceTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/PreferenceServiceTest.java new file mode 100644 index 0000000..dc05244 --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/PreferenceServiceTest.java @@ -0,0 +1,116 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.services; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Personne; +import fr.vincent.ramiere.mangerautourdesimplonback.models.Preference; +import fr.vincent.ramiere.mangerautourdesimplonback.models.PreferencePK; +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.PersonneRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.PreferenceRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.RestaurantRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.service.PreferenceService; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import java.util.List; +import java.util.Optional; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** + * Unit tests for PreferenceService. + */ +@ExtendWith(MockitoExtension.class) +class PreferenceServiceTest { + + @Mock + private PreferenceRepository preferenceRepository; + + @Mock + private PersonneRepository personneRepository; + + @Mock + private RestaurantRepository restaurantRepository; + + @InjectMocks + private PreferenceService preferenceService; + + @Test + void getPreferencesByPersonneId_returnsListFromRepository() { + Personne p = mock(Personne.class); + Restaurant r = mock(Restaurant.class); + Preference pref = new Preference(new PreferencePK(p, r)); + List expected = List.of(pref); + + when(preferenceRepository.findByPreferencePK_Personne_Id(1)).thenReturn(expected); + + List result = preferenceService.getPreferencesByPersonneId(1); + + assertSame(expected, result); + verify(preferenceRepository, times(1)).findByPreferencePK_Personne_Id(1); + } + + @Test + void saveOrUpdatePreference_whenPersonMissing_returnsEmpty() { + when(personneRepository.findById(1)).thenReturn(Optional.empty()); + // restaurant repo may or may not be called; service checks person first + Optional result = preferenceService.saveOrUpdatePreference(1, 2, 5, true); + + assertTrue(result.isEmpty()); + verify(personneRepository, times(1)).findById(1); + verifyNoInteractions(preferenceRepository); + } + + @Test + void saveOrUpdatePreference_createsNewPreference_andSavesIt() { + Personne personne = new Personne(); + Restaurant restaurant = new Restaurant(); + + when(personneRepository.findById(10)).thenReturn(Optional.of(personne)); + when(restaurantRepository.findById(20)).thenReturn(Optional.of(restaurant)); + when(preferenceRepository.findById(any(PreferencePK.class))).thenReturn(Optional.empty()); + when(preferenceRepository.save(any(Preference.class))).thenAnswer(invocation -> invocation.getArgument(0)); + + Optional result = preferenceService.saveOrUpdatePreference(10, 20, 4, Boolean.TRUE); + + assertTrue(result.isPresent()); + Preference saved = result.get(); + // assume typical getter names getNote/getFavori exist on Preference + assertEquals(4, saved.getNote()); + assertEquals(Boolean.TRUE, saved.getFavori()); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class); + verify(preferenceRepository, times(1)).save(captor.capture()); + Preference captured = captor.getValue(); + assertEquals(4, captured.getNote()); + assertEquals(Boolean.TRUE, captured.getFavori()); + } + + @Test + void saveOrUpdatePreference_updatesExistingPreference_andSavesIt() { + Personne personne = new Personne(); + Restaurant restaurant = new Restaurant(); + PreferencePK pk = new PreferencePK(personne, restaurant); + Preference existing = new Preference(pk); + existing.setNote(1); + existing.setFavori(false); + + when(personneRepository.findById(7)).thenReturn(Optional.of(personne)); + when(restaurantRepository.findById(8)).thenReturn(Optional.of(restaurant)); + when(preferenceRepository.findById(any(PreferencePK.class))).thenReturn(Optional.of(existing)); + when(preferenceRepository.save(any(Preference.class))).thenAnswer(invocation -> invocation.getArgument(0)); + + Optional result = preferenceService.saveOrUpdatePreference(7, 8, 10, Boolean.TRUE); + + assertTrue(result.isPresent()); + Preference updated = result.get(); + assertSame(existing, updated); + assertEquals(10, updated.getNote()); + assertEquals(Boolean.TRUE, updated.getFavori()); + + verify(preferenceRepository, times(1)).save(existing); + } +} diff --git a/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/RestaurantServiceTest.java b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/RestaurantServiceTest.java new file mode 100644 index 0000000..85dd820 --- /dev/null +++ b/backend/src/test/java/fr/vincent/ramiere/mangerautourdesimplonback/services/RestaurantServiceTest.java @@ -0,0 +1,131 @@ +package fr.vincent.ramiere.mangerautourdesimplonback.services; + +import fr.vincent.ramiere.mangerautourdesimplonback.models.Restaurant; +import fr.vincent.ramiere.mangerautourdesimplonback.repository.RestaurantRepository; +import fr.vincent.ramiere.mangerautourdesimplonback.service.RestaurantService; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.*; + +class RestaurantServiceTest { + @Mock + private RestaurantRepository restaurantRepository; + @InjectMocks + private RestaurantService restaurantService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testGetAllRestaurants() { + Restaurant r1 = new Restaurant(); + Restaurant r2 = new Restaurant(); + when(restaurantRepository.findAll()).thenReturn(Arrays.asList(r1, r2)); + + List result = restaurantService.getAllRestaurants(); + + assertEquals(2, result.size()); + verify(restaurantRepository).findAll(); + } + + @Test + void testGetRestaurantById_Found() { + Restaurant r = new Restaurant(); + r.setNom("Test"); + when(restaurantRepository.findById(1)).thenReturn(Optional.of(r)); + + Optional result = restaurantService.getRestaurantById(1); + + assertTrue(result.isPresent()); + assertEquals("Test", result.get().getNom()); + verify(restaurantRepository).findById(1); + } + + @Test + void testGetRestaurantById_NotFound() { + when(restaurantRepository.findById(2)).thenReturn(Optional.empty()); + + Optional result = restaurantService.getRestaurantById(2); + + assertFalse(result.isPresent()); + verify(restaurantRepository).findById(2); + } + + @Test + void testSaveRestaurant() { + Restaurant r = new Restaurant(); + r.setNom("SaveTest"); + when(restaurantRepository.save(r)).thenReturn(r); + + Restaurant result = restaurantService.saveRestaurant(r); + + assertEquals("SaveTest", result.getNom()); + verify(restaurantRepository).save(r); + } + + @Test + void testUpdateRestaurant_Found() { + Restaurant existing = new Restaurant(); + existing.setNom("Old"); + Restaurant details = new Restaurant(); + details.setNom("New"); + details.setAdresse("Adresse"); + details.setTelephone("123"); + details.setAccesPMR(true); + details.setAEmporter(true); + details.setSurPlace(false); + details.setPrix(10); + details.setLatitude("1.0"); + details.setLongitude("2.0"); + details.setWebsite("site"); + + when(restaurantRepository.findById(1)).thenReturn(Optional.of(existing)); + when(restaurantRepository.save(any(Restaurant.class))).thenAnswer(invocation -> invocation.getArgument(0)); + + Optional result = restaurantService.updateRestaurant(1, details); + + assertTrue(result.isPresent()); + Restaurant updatedRestaurant = result.get(); + assertEquals("New", updatedRestaurant.getNom()); + assertEquals("Adresse", updatedRestaurant.getAdresse()); + assertEquals("123", updatedRestaurant.getTelephone()); + assertTrue(updatedRestaurant.getAccesPMR()); + assertTrue(updatedRestaurant.getAEmporter()); + assertFalse(updatedRestaurant.getSurPlace()); + assertEquals(10, updatedRestaurant.getPrix()); + assertEquals("1.0", updatedRestaurant.getLatitude()); + assertEquals("2.0", updatedRestaurant.getLongitude()); + assertEquals("site", updatedRestaurant.getWebsite()); + verify(restaurantRepository).findById(1); + verify(restaurantRepository).save(existing); + } + + @Test + void testUpdateRestaurant_NotFound() { + Restaurant details = new Restaurant(); + when(restaurantRepository.findById(99)).thenReturn(Optional.empty()); + + Optional result = restaurantService.updateRestaurant(99, details); + + assertFalse(result.isPresent()); + verify(restaurantRepository).findById(99); + verify(restaurantRepository, never()).save(any()); + } + + @Test + void testDeleteRestaurant() { + restaurantService.deleteRestaurant(5); + verify(restaurantRepository).deleteById(5); + } +}