From e0927bb1a9726d298815e926ff3a000bc4d8f9e1 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 11:24:25 +0100 Subject: [PATCH 001/112] Start up repo --- .gitignore | 36 ++ .mvn/wrapper/maven-wrapper.jar | Bin 0 -> 62547 bytes .mvn/wrapper/maven-wrapper.properties | 2 + mvnw | 308 ++++++++++++++++++ mvnw.cmd | 205 ++++++++++++ pom.xml | 63 ++++ .../ironLibrary/IronLibraryApplication.java | 14 + src/main/resources/application.properties | 12 + .../IronLibraryApplicationTests.java | 13 + src/test/resources/application.properties | 13 + 10 files changed, 666 insertions(+) create mode 100644 .gitignore create mode 100644 .mvn/wrapper/maven-wrapper.jar create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100755 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml create mode 100644 src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java create mode 100644 src/main/resources/application.properties create mode 100644 src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java create mode 100644 src/test/resources/application.properties diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..690b83d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +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/ + +### Env +.env \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..cb28b0e37c7d206feb564310fdeec0927af4123a GIT binary patch literal 62547 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 A?*IS* literal 0 HcmV?d00001 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..5f0536eb --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/mvnw b/mvnw new file mode 100755 index 00000000..66df2854 --- /dev/null +++ b/mvnw @@ -0,0 +1,308 @@ +#!/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 +# +# https://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.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "\"$javaExecutable\"")" + fi + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + 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" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +fi + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 00000000..95ba6f54 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,205 @@ +@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 https://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.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..036a0d22 --- /dev/null +++ b/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.3 + + + com.ironhack + ironLibrary + 0.0.1-SNAPSHOT + ironLibrary + Demo project for Spring Boot + + 17 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.mysql + mysql-connector-j + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java new file mode 100644 index 00000000..2497e923 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -0,0 +1,14 @@ +package com.ironhack.ironLibrary; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class IronLibraryApplication { + + public static void main(String[] args) { + SpringApplication.run(IronLibraryApplication.class, args + ); + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..9481e873 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,12 @@ +spring.application.name=ironLibrary +spring.datasource.url=jdbc:mysql://localhost:3306/libary?createDatabaseIfNotExist=TRUE +spring.datasource.username=root +spring.datasource.password=40S4r3dder + +spring.jpa.properties.hibernate.hbm2ddl.auto=update +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect +##spring.jpa.hibernate.ddl-auto=validate + +spring.jpa.show-sql=true +spring.jpa.open-in-view=true diff --git a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java new file mode 100644 index 00000000..f997ff2d --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java @@ -0,0 +1,13 @@ +package com.ironhack.ironLibrary; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class IronLibraryApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 00000000..613e0441 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,13 @@ + +spring.application.name=ironLibrary +spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}_test?createDatabaseIfNotExist=TRUE +spring.datasource.username=${MYSQL_USERNAME} +spring.datasource.password=${MYSQL_PASSWORD} + +spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect +##spring.jpa.hibernate.ddl-auto=validate + +spring.jpa.show-sql=true +spring.jpa.open-in-view=true From 94436b49b8b4ad0c66922238e54ed6da20843d71 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 12:13:34 +0100 Subject: [PATCH 002/112] Create maven.yml --- .github/workflows/maven.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/maven.yml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 00000000..d00a0e20 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,35 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Java CI with Maven + +on: + pull_request: + branches: + - main + - develop + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build with Maven + run: mvn -B clean package --file pom.xml + + - name: Run unit tests + run : mvn test --file pom.xml From 8e0e6bfa90b9fc68390ff158cc6eefb20ff8ef07 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 12:32:40 +0100 Subject: [PATCH 003/112] chore: add jaCoCo, .env file setting --- pom.xml | 25 ++++++++++++++++++++++- src/main/resources/application.properties | 6 +++--- src/test/resources/application.properties | 1 - 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 036a0d22..4d645198 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,11 @@ org.springframework.boot spring-boot-starter-data-jpa - + + org.jacoco + jacoco-maven-plugin + 0.8.11 + com.mysql mysql-connector-j @@ -57,6 +61,25 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + prepare-agent + + + + report + test + + report + + + + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9481e873..53ff8fe5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,7 +1,7 @@ spring.application.name=ironLibrary -spring.datasource.url=jdbc:mysql://localhost:3306/libary?createDatabaseIfNotExist=TRUE -spring.datasource.username=root -spring.datasource.password=40S4r3dder +spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}?createDatabaseIfNotExist=TRUE +spring.datasource.username=${MYSQL_USERNAME} +spring.datasource.password=${MYSQL_PASSWORD} spring.jpa.properties.hibernate.hbm2ddl.auto=update spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 613e0441..df8acaee 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,4 +1,3 @@ - spring.application.name=ironLibrary spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}_test?createDatabaseIfNotExist=TRUE spring.datasource.username=${MYSQL_USERNAME} From 9006047287c5f542b9ca72257d2c84f92eff6640 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 15:27:08 +0100 Subject: [PATCH 004/112] chore: create validator class --- src/main/java/utils/Validator.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/java/utils/Validator.java diff --git a/src/main/java/utils/Validator.java b/src/main/java/utils/Validator.java new file mode 100644 index 00000000..2e67ffd1 --- /dev/null +++ b/src/main/java/utils/Validator.java @@ -0,0 +1,6 @@ +package utils; + +public class Validator { + + +} From 3bc6503b231812f3d60e014275ea56bfe74a43d6 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 15:33:49 +0100 Subject: [PATCH 005/112] refactor: Data Structure --- src/main/java/com/ironhack/ironLibrary/utils/Validator.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/Validator.java diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java new file mode 100644 index 00000000..a7069faa --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -0,0 +1,6 @@ +package com.ironhack.ironLibrary.utils; + +public class Validator { + + +} From 8c828edf46f484b26009a32585c629fff267a619 Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Sat, 16 Mar 2024 15:37:37 +0100 Subject: [PATCH 006/112] create author class --- src/main/java/com/ironhack/ironLibrary/model/Author.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/model/Author.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Author.java b/src/main/java/com/ironhack/ironLibrary/model/Author.java new file mode 100644 index 00000000..d1ec30b9 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/model/Author.java @@ -0,0 +1,7 @@ +package com.ironhack.ironLibrary.model; + +import lombok.Data; + +@Data +public class Author { +} From 9e480f1822f2d3dd28a751b56699be606907c8c8 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 15:38:16 +0100 Subject: [PATCH 007/112] Delete src/main/java/utils directory --- src/main/java/utils/Validator.java | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/main/java/utils/Validator.java diff --git a/src/main/java/utils/Validator.java b/src/main/java/utils/Validator.java deleted file mode 100644 index 2e67ffd1..00000000 --- a/src/main/java/utils/Validator.java +++ /dev/null @@ -1,6 +0,0 @@ -package utils; - -public class Validator { - - -} From 73d1028953be42301df1f4ad47e0e78bd0b11fc2 Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Sat, 16 Mar 2024 15:46:06 +0100 Subject: [PATCH 008/112] author class defined --- .../java/com/ironhack/ironLibrary/model/Author.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Author.java b/src/main/java/com/ironhack/ironLibrary/model/Author.java index d1ec30b9..caf86615 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Author.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Author.java @@ -1,7 +1,19 @@ package com.ironhack.ironLibrary.model; +import jakarta.persistence.*; +import lombok.AccessLevel; import lombok.Data; +import lombok.Setter; @Data +@Entity +@Table(name = "authors") public class Author { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Setter(AccessLevel.NONE) + private Integer authorId; + private String name; + private String email; + private Book authorBook; } From 480ef647b37104d075e154c569c21cae5abe992f Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 16 Mar 2024 15:47:06 +0100 Subject: [PATCH 009/112] basice student class, first itetation --- .../ironhack/ironLibrary/model/Student.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/model/Student.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Student.java b/src/main/java/com/ironhack/ironLibrary/model/Student.java new file mode 100644 index 00000000..b9fa260c --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/model/Student.java @@ -0,0 +1,23 @@ +package com.ironhack.ironLibrary.model; + +import jakarta.persistence.Entity; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Table(name = "student") +@Data +public class Student { + + @Setter(AccessLevel.NONE) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private String usn; + + private String name; + + public Student() { + + } + +} From 263d0a7b69c874c6429c541717cb36f61bec877b Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Sat, 16 Mar 2024 15:51:23 +0100 Subject: [PATCH 010/112] comment authorBook due to bugs --- src/main/java/com/ironhack/ironLibrary/model/Author.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Author.java b/src/main/java/com/ironhack/ironLibrary/model/Author.java index caf86615..b8c9a5d1 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Author.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Author.java @@ -15,5 +15,5 @@ public class Author { private Integer authorId; private String name; private String email; - private Book authorBook; + //private Book authorBook; } From ff2eba95df31446d936f8af722a92818c233e24c Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Sat, 16 Mar 2024 15:52:27 +0100 Subject: [PATCH 011/112] create Book class --- .../com/ironhack/ironLibrary/model/Book.java | 17 +++++++++++++++++ .../ironhack/ironLibrary/model/BookTest.java | 10 ++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/model/Book.java create mode 100644 src/test/java/com/ironhack/ironLibrary/model/BookTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java new file mode 100644 index 00000000..c43b165e --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -0,0 +1,17 @@ +package com.ironhack.ironLibrary.model; + +import jakarta.persistence.Entity; +import lombok.*; +import jakarta.persistence.*; + +@Data +@Entity +public class Book { + @Id + @Setter(AccessLevel.NONE) + private String isbn; + private String title; + private String category; + private Integer quantity; + +} diff --git a/src/test/java/com/ironhack/ironLibrary/model/BookTest.java b/src/test/java/com/ironhack/ironLibrary/model/BookTest.java new file mode 100644 index 00000000..d8d6b36e --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/model/BookTest.java @@ -0,0 +1,10 @@ +package com.ironhack.ironLibrary.model; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +public class BookTest { + +} From 5d88474052145b3a92dc9adea1a5ab0bcb7e57cd Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Sat, 16 Mar 2024 15:57:42 +0100 Subject: [PATCH 012/112] add junit dependency --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 4d645198..c78b9135 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,12 @@ org.springframework.boot spring-boot-starter-web + + org.junit.jupiter + junit-jupiter-api + 5.10.2 + test + From f950fb827366075a124b95781ddf1fa64612432c Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 16 Mar 2024 16:03:29 +0100 Subject: [PATCH 013/112] basic student class, second iteration --- pom.xml | 8 +++++++ .../ironhack/ironLibrary/model/Student.java | 7 +++++-- .../ironLibrary/model/StudentTest.java | 21 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/ironhack/ironLibrary/model/StudentTest.java diff --git a/pom.xml b/pom.xml index 4d645198..a9053523 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,14 @@ org.springframework.boot spring-boot-starter-web + + org.junit.jupiter + junit-jupiter-api + 5.10.2 + test + + + diff --git a/src/main/java/com/ironhack/ironLibrary/model/Student.java b/src/main/java/com/ironhack/ironLibrary/model/Student.java index b9fa260c..fc0a15b7 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Student.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Student.java @@ -12,12 +12,15 @@ public class Student { @Setter(AccessLevel.NONE) @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private String usn; + private Integer usn; private String name; public Student() { } - + public Student(Integer usn, String name) { + this.usn = usn; + this.name = name; + } } diff --git a/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java b/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java new file mode 100644 index 00000000..cb2cfa0b --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java @@ -0,0 +1,21 @@ +package com.ironhack.ironLibrary.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class StudentTest { + + + @Test + void createStudent(){ + + Student studentQA = new Student(); + Student studentQA2 = new Student(1,"Test"); + + assertNotNull(studentQA); + assertNotNull(studentQA2); + + } + +} \ No newline at end of file From 6afd199db9c95669fe62d1015801b86b9461ef1c Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Sat, 16 Mar 2024 16:06:20 +0100 Subject: [PATCH 014/112] update actions version to v4 --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d00a0e20..d19d7b9c 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -21,9 +21,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' From 222c83afed17c3d4465efb96948fb3bc20e36a3d Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 16 Mar 2024 16:18:42 +0100 Subject: [PATCH 015/112] deleting utils validator --- src/main/java/utils/Validator.java | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/main/java/utils/Validator.java diff --git a/src/main/java/utils/Validator.java b/src/main/java/utils/Validator.java deleted file mode 100644 index 2e67ffd1..00000000 --- a/src/main/java/utils/Validator.java +++ /dev/null @@ -1,6 +0,0 @@ -package utils; - -public class Validator { - - -} From 714b429a7c7861bd6f19ef2de274ec8647e06c72 Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Sat, 16 Mar 2024 16:22:41 +0100 Subject: [PATCH 016/112] author test, change version github actions --- .github/workflows/maven.yml | 4 ++-- .../com/ironhack/ironLibrary/model/Author.java | 6 +++--- .../ironhack/ironLibrary/model/AuthorTest.java | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d19d7b9c..d00a0e20 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -21,9 +21,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v3 - name: Set up JDK 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' diff --git a/src/main/java/com/ironhack/ironLibrary/model/Author.java b/src/main/java/com/ironhack/ironLibrary/model/Author.java index b8c9a5d1..97fb29fe 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Author.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Author.java @@ -1,11 +1,11 @@ package com.ironhack.ironLibrary.model; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Data; -import lombok.Setter; +import lombok.*; @Data +@NoArgsConstructor +@AllArgsConstructor @Entity @Table(name = "authors") public class Author { diff --git a/src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java b/src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java new file mode 100644 index 00000000..d5197523 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java @@ -0,0 +1,17 @@ +package com.ironhack.ironLibrary.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class AuthorTest { + + @Test + void createAuthor(){ + Author authorOne = new Author(); + Author authorTwo = new Author(); + + assertNotNull(authorOne); + assertNotNull(authorTwo); + } +} From d55eee398abb17e91e0ef88036e87663875575a5 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 16:24:06 +0100 Subject: [PATCH 017/112] chore: checkISBNFormat and test --- .github/workflows/maven.yml | 1 + .../ironhack/ironLibrary/utils/Validator.java | 14 ++++++++++ src/main/java/utils/Validator.java | 6 ----- .../ironLibrary/utils/ValidatorTest.java | 26 +++++++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) delete mode 100644 src/main/java/utils/Validator.java create mode 100644 src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d00a0e20..eff3d772 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -22,6 +22,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java index a7069faa..3389131b 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -1,6 +1,20 @@ package com.ironhack.ironLibrary.utils; + +import java.util.regex.Pattern; + public class Validator { + public static boolean checkISBNFormat(String maybeISBN){ + return patternMatches(maybeISBN, "^(?=(?:\\D*\\d){10}(?:(?:\\D*\\d){3})?$)[\\d-]+$"); + } + + + + private static boolean patternMatches(String inputString, String regexPattern) { + return Pattern.compile(regexPattern) + .matcher(inputString) + .matches(); + } } diff --git a/src/main/java/utils/Validator.java b/src/main/java/utils/Validator.java deleted file mode 100644 index 2e67ffd1..00000000 --- a/src/main/java/utils/Validator.java +++ /dev/null @@ -1,6 +0,0 @@ -package utils; - -public class Validator { - - -} diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java new file mode 100644 index 00000000..487a8ca3 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java @@ -0,0 +1,26 @@ +package com.ironhack.ironLibrary.utils; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class ValidatorTest { + + @ParameterizedTest + @DisplayName("Should validate correct ISBN") + @ValueSource(strings = {"978-92-95-055-02-5", "971-52-15-055-02-5", "971-52-15-755-12-3"} ) + void isCheckISBNFormatValid_when_correct_ISBN(String isbn) { + assertTrue(Validator.checkISBNFormat(isbn)); + } + + @ParameterizedTest + @DisplayName("Should invalidate incorrect ISBN") + @ValueSource(strings = {"a78-92-952-055-02-5", "p71-52-1sd-055-02-5", "xxxs-52-15-755-12-0w"} ) + void isCheckISBNFormatNotValid_when_incorrect_ISBN(String isbn) { + assertFalse(Validator.checkISBNFormat(isbn)); + } +} \ No newline at end of file From 120885ab75370cd5cd0ceac31b9248d96952bb38 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 16:47:18 +0100 Subject: [PATCH 018/112] chore: add mysql workflow --- .github/workflows/maven.yml | 17 ++++++++++++++++- .../ironhack/ironLibrary/model/StudentTest.java | 3 --- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index eff3d772..8d4650e2 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -18,7 +18,22 @@ jobs: build: runs-on: ubuntu-latest - + env: + MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} + MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} + MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} + + services: + mysql: + image: mysql:latest + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} + MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} + MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - name: Checkout repository uses: actions/checkout@v3 diff --git a/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java b/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java index cb2cfa0b..6184427d 100644 --- a/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java +++ b/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java @@ -9,13 +9,10 @@ class StudentTest { @Test void createStudent(){ - Student studentQA = new Student(); Student studentQA2 = new Student(1,"Test"); - assertNotNull(studentQA); assertNotNull(studentQA2); - } } \ No newline at end of file From 816a7de74fb92fcba2b20663d486fb1adc6409ce Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 16:50:46 +0100 Subject: [PATCH 019/112] test workflow --- .github/workflows/maven.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8d4650e2..339ab8d3 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -16,7 +16,6 @@ on: jobs: build: - runs-on: ubuntu-latest env: MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} From 9174bc74b3e3cf40df769acd1c677ee455240755 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 16:57:08 +0100 Subject: [PATCH 020/112] add junit jupiter params --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index a9053523..e5606e23 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,12 @@ 5.10.2 test + + org.junit.jupiter + junit-jupiter-params + 5.10.2 + test + From 2b20c7a541ae5b72dd14d5a5d6b1e6f51bce6532 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 17:01:18 +0100 Subject: [PATCH 021/112] remove anotation --- .../java/com/ironhack/ironLibrary/utils/ValidatorTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java index 487a8ca3..178897fe 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java @@ -1,13 +1,14 @@ package com.ironhack.ironLibrary.utils; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.*; -@SpringBootTest + class ValidatorTest { @ParameterizedTest From d27f47a780f83c86f8907a527afe4f2232a66442 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 17:04:55 +0100 Subject: [PATCH 022/112] remove contextloadtest --- .../ironLibrary/IronLibraryApplicationTests.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java index f997ff2d..cf73bbb4 100644 --- a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java +++ b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java @@ -3,11 +3,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest -class IronLibraryApplicationTests { - - @Test - void contextLoads() { - } - -} +//@SpringBootTest +//class IronLibraryApplicationTests { +// +//} From 07d60e471ec810c9db67d5298340e85dbd66248c Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 17:31:24 +0100 Subject: [PATCH 023/112] checkEmailValidator and test --- .../ironhack/ironLibrary/utils/Validator.java | 4 ++++ .../ironLibrary/utils/ValidatorTest.java | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java index 3389131b..ed8f5b49 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -9,6 +9,10 @@ public static boolean checkISBNFormat(String maybeISBN){ return patternMatches(maybeISBN, "^(?=(?:\\D*\\d){10}(?:(?:\\D*\\d){3})?$)[\\d-]+$"); } + public static boolean checkEmailFormat(String email){ + return patternMatches(email, "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"); + } + private static boolean patternMatches(String inputString, String regexPattern) { diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java index 487a8ca3..060a6251 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java @@ -1,13 +1,14 @@ package com.ironhack.ironLibrary.utils; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.*; -@SpringBootTest + class ValidatorTest { @ParameterizedTest @@ -23,4 +24,18 @@ void isCheckISBNFormatValid_when_correct_ISBN(String isbn) { void isCheckISBNFormatNotValid_when_incorrect_ISBN(String isbn) { assertFalse(Validator.checkISBNFormat(isbn)); } + + @ParameterizedTest + @DisplayName("Should validate correct Email") + @ValueSource(strings = {"test@edu.es", "ironhack_private@ironhack.es", "no-reply@ironhack.com"} ) + void isCheckEmailValid_when_correct_Email(String email) { + assertTrue(Validator.checkEmailFormat(email)); + } + + @ParameterizedTest + @DisplayName("Should validate correct Email") + @ValueSource(strings = {"test@edu.e", "ironhack_!private@ironhack.es", "@ironhack.com"} ) + void isCheckEmailInvalid_when_incorrect_Email(String email) { + assertFalse(Validator.checkEmailFormat(email)); + } } \ No newline at end of file From b5135cd57f4d93221c8b39cf874355e152b1c52f Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 16 Mar 2024 17:32:33 +0100 Subject: [PATCH 024/112] remove unused imports --- src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java index 060a6251..c5f70182 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java @@ -1,10 +1,8 @@ package com.ironhack.ironLibrary.utils; import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.springframework.boot.test.context.SpringBootTest; import static org.junit.jupiter.api.Assertions.*; From 004ffc6b4ed062cd99f7518c61eac4ff73a836f6 Mon Sep 17 00:00:00 2001 From: Xavi Soria Date: Sun, 17 Mar 2024 14:59:10 +0100 Subject: [PATCH 025/112] Create Issue class an Integer validator --- .../ironLibrary/IronLibraryApplication.java | 7 ++++ .../com/ironhack/ironLibrary/model/Issue.java | 26 +++++++++++++ .../ironhack/ironLibrary/utils/Validator.java | 11 ++++++ .../ironhack/ironLibrary/model/IssueTest.java | 25 ++++++++++++ .../ironLibrary/utils/ValidatorTest.java | 2 + .../utils/ValidatorTestInteger.java | 39 +++++++++++++++++++ 6 files changed, 110 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/model/Issue.java create mode 100644 src/test/java/com/ironhack/ironLibrary/model/IssueTest.java create mode 100644 src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestInteger.java diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index 2497e923..4f756672 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -1,5 +1,6 @@ package com.ironhack.ironLibrary; +import com.ironhack.ironLibrary.utils.Validator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -11,4 +12,10 @@ public static void main(String[] args) { ); } + + } + + + + diff --git a/src/main/java/com/ironhack/ironLibrary/model/Issue.java b/src/main/java/com/ironhack/ironLibrary/model/Issue.java new file mode 100644 index 00000000..cb383e29 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/model/Issue.java @@ -0,0 +1,26 @@ +package com.ironhack.ironLibrary.model; + +import jakarta.persistence.Entity; +import jakarta.persistence.*; +import lombok.*; +@Entity +@Table(name = "issue") +@Data +@NoArgsConstructor +public class Issue { + @Setter(AccessLevel.NONE) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer issueId; + private String issueDate; + private String returnDate; + private Student issueStudent; + private Book issueBook; + + public Issue(String issueDate, String returnDate, Student issueStudent, Book issueBook) { + this.issueDate = issueDate; + this.returnDate = returnDate; + this.issueStudent = issueStudent; + this.issueBook = issueBook; + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java index 3389131b..7f0b2a6b 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -17,4 +17,15 @@ private static boolean patternMatches(String inputString, String regexPattern) { .matches(); } + public static boolean validateInteger(String input) { + try { + if (input == null || input.trim().isEmpty()) { + return false; + } + Integer.parseInt(input); + return true; + } catch (NumberFormatException e) { + return false; + } + } } diff --git a/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java b/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java new file mode 100644 index 00000000..9f3182a4 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java @@ -0,0 +1,25 @@ +package com.ironhack.ironLibrary.model; + + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; +public class IssueTest { + + @Test + public void createIssue(){ + Student student = new Student(1, "Carlos"); + Book book = new Book(); + Issue IssueOne = new Issue(); + Issue IssueTwo = new Issue("17/03/2024", "24/03/2024", student, book); + + assertNotNull(IssueOne); + assertNotNull(IssueTwo); + assertEquals("17/03/2024", IssueTwo.getIssueDate()); + assertEquals("24/03/2024", IssueTwo.getReturnDate()); + assertEquals(student, IssueTwo.getIssueStudent()); + assertEquals(book, IssueTwo.getIssueBook()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java index 487a8ca3..7379ca66 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java @@ -23,4 +23,6 @@ void isCheckISBNFormatValid_when_correct_ISBN(String isbn) { void isCheckISBNFormatNotValid_when_incorrect_ISBN(String isbn) { assertFalse(Validator.checkISBNFormat(isbn)); } + + } \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestInteger.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestInteger.java new file mode 100644 index 00000000..7190fa6d --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestInteger.java @@ -0,0 +1,39 @@ +package com.ironhack.ironLibrary.utils; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ValidatorTestInteger { + + + @Test + public void testValidateIntegerWithValidInput() { + Validator validator = new Validator(); + String validInput = "12345"; + assertTrue(validator.validateInteger(validInput)); + } + + @Test + public void testValidateIntegerWithInvalidInput() { + Validator validator = new Validator(); + String invalidInput = "abc"; + String invalidInput2 = "226,98"; + assertFalse(validator.validateInteger(invalidInput)); + assertFalse(validator.validateInteger(invalidInput2)); + } + + @Test + public void testValidateNonEmptyIntegerWithEmptyInput() { + Validator validator = new Validator(); + assertFalse(validator.validateInteger("")); + } + + @Test + public void testValidateNonEmptyIntegerWithNullInput() { + Validator validator = new Validator(); + assertFalse(validator.validateInteger(null)); + } + + +} From 33313199d4069dcbec0364e9544cecb9c29975ea Mon Sep 17 00:00:00 2001 From: Arian Date: Thu, 21 Mar 2024 21:18:08 +0100 Subject: [PATCH 026/112] Create relations --- src/main/java/com/ironhack/ironLibrary/model/Author.java | 4 +++- src/main/java/com/ironhack/ironLibrary/model/Issue.java | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Author.java b/src/main/java/com/ironhack/ironLibrary/model/Author.java index 97fb29fe..4db1a9c1 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Author.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Author.java @@ -15,5 +15,7 @@ public class Author { private Integer authorId; private String name; private String email; - //private Book authorBook; + @OneToOne + @JoinColumn(name = "isbn") + private Book authorBook; } diff --git a/src/main/java/com/ironhack/ironLibrary/model/Issue.java b/src/main/java/com/ironhack/ironLibrary/model/Issue.java index cb383e29..64bd6817 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Issue.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Issue.java @@ -14,7 +14,11 @@ public class Issue { private Integer issueId; private String issueDate; private String returnDate; + @OneToOne + @JoinColumn(name = "usn") private Student issueStudent; + @OneToOne + @JoinColumn(name = "isbn") private Book issueBook; public Issue(String issueDate, String returnDate, Student issueStudent, Book issueBook) { From 5c1c07f3767e5058712cfd858b2906fc856c1ac7 Mon Sep 17 00:00:00 2001 From: Xavi Soria Date: Fri, 22 Mar 2024 16:49:28 +0100 Subject: [PATCH 027/112] Validator for Book and General strings --- .../com/ironhack/ironLibrary/model/Book.java | 6 ++ .../ironhack/ironLibrary/utils/Validator.java | 10 +++ .../utils/ValidatorTestStrings.java | 62 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestStrings.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java index c43b165e..eb62155c 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Book.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -6,12 +6,18 @@ @Data @Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "books") public class Book { @Id @Setter(AccessLevel.NONE) + @GeneratedValue(strategy = GenerationType.IDENTITY) private String isbn; private String title; private String category; private Integer quantity; + + } diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java index 5a133b29..7f243c6a 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -32,4 +32,14 @@ public static boolean validateInteger(String input) { return false; } } + + public static boolean notBlankValidatorBooks(String input) { + return input != null && !input.trim().isEmpty(); + } + + public static boolean validateStringGeneralFormat(String input) { + return input != null && !input.isEmpty() && patternMatches(input, "^[a-zA-ZÀ-ÿ\\s]*$"); + } } + + diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestStrings.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestStrings.java new file mode 100644 index 00000000..c3dbc736 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTestStrings.java @@ -0,0 +1,62 @@ +package com.ironhack.ironLibrary.utils; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ValidatorTestStrings { + + @Test + public void testNotBlankValidatorBooksValidInput() { + String input = "The Book Title"; + assertTrue(Validator.notBlankValidatorBooks(input)); + } + + @Test + public void testNotBlankValidatorBooksNullInput() { + String input = null; + assertFalse(Validator.notBlankValidatorBooks(input)); + } + + @Test + public void testNotBlankValidatorBooksEmptyInput() { + String input = ""; + assertFalse(Validator.notBlankValidatorBooks(input)); + } + + @Test + public void testNotBlankValidatorBooksWhitespaceInput() { + String input = " "; + assertFalse(Validator.notBlankValidatorBooks(input)); + } + + @Test + public void testValidateStringGeneralFormatWithValidInput() { + String input = "John Doe"; + assertTrue(Validator.validateStringGeneralFormat(input)); + } + + @Test + public void testValidateStringGeneralFormatWithAccentedCharacters() { + String input = "José García"; + assertTrue(Validator.validateStringGeneralFormat(input)); + } + + @Test + public void testValidateStringGeneralFormatWithInvalidInput() { + String input = "123 Main Street"; + assertFalse(Validator.validateStringGeneralFormat(input)); + } + + @Test + public void testValidateStringGeneralFormatWithEmptyInput() { + String input = ""; + assertFalse(Validator.validateStringGeneralFormat(input)); + } + + @Test + public void testValidateStringGeneralFormatWithNullInput() { + String input = null; + assertFalse(Validator.validateStringGeneralFormat(input)); + } +} \ No newline at end of file From bdfb2fdc51ebc6b3d2ec8b97fc26ab9f198618f9 Mon Sep 17 00:00:00 2001 From: Xavi Soria Date: Sat, 23 Mar 2024 08:51:46 +0100 Subject: [PATCH 028/112] Validator for Book and General strings --- src/main/java/com/ironhack/ironLibrary/model/Book.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java index eb62155c..a135bc26 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Book.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -12,7 +12,6 @@ public class Book { @Id @Setter(AccessLevel.NONE) - @GeneratedValue(strategy = GenerationType.IDENTITY) private String isbn; private String title; private String category; From 69cf232d2e6614a57b7a499f3e3c6b9612c492e4 Mon Sep 17 00:00:00 2001 From: Xavi Soria Date: Sat, 23 Mar 2024 08:57:53 +0100 Subject: [PATCH 029/112] Validator for Book and General strings --- src/main/java/com/ironhack/ironLibrary/model/Book.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java index a135bc26..4b140c3e 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Book.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -12,6 +12,7 @@ public class Book { @Id @Setter(AccessLevel.NONE) + private String isbn; private String title; private String category; From 22757831a87249714e5f02a925c41a47821f5f43 Mon Sep 17 00:00:00 2001 From: Xavi Soria Date: Sat, 23 Mar 2024 08:58:26 +0100 Subject: [PATCH 030/112] Validator for Book and General strings --- src/main/java/com/ironhack/ironLibrary/model/Book.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java index 4b140c3e..a135bc26 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Book.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -12,7 +12,6 @@ public class Book { @Id @Setter(AccessLevel.NONE) - private String isbn; private String title; private String category; From 01da1a0a46bad704805bccac25259597e46c3dbf Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Sat, 23 Mar 2024 10:37:46 +0100 Subject: [PATCH 031/112] create author repository & improve author testing --- src/main/java/com/ironhack/ironLibrary/model/Author.java | 7 ++++++- .../ironLibrary/repository/AuthorRepository.java | 9 +++++++++ .../java/com/ironhack/ironLibrary/model/AuthorTest.java | 6 +++++- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Author.java b/src/main/java/com/ironhack/ironLibrary/model/Author.java index 4db1a9c1..5b526880 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Author.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Author.java @@ -5,7 +5,6 @@ @Data @NoArgsConstructor -@AllArgsConstructor @Entity @Table(name = "authors") public class Author { @@ -18,4 +17,10 @@ public class Author { @OneToOne @JoinColumn(name = "isbn") private Book authorBook; + + public Author(String name, String email, Book authorBook){ + this.name = name; + this.email = email; + this.authorBook = authorBook; + } } diff --git a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java new file mode 100644 index 00000000..f3d05952 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java @@ -0,0 +1,9 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Author; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AuthorRepository extends JpaRepository { +} diff --git a/src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java b/src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java index d5197523..d6d69ef4 100644 --- a/src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java +++ b/src/test/java/com/ironhack/ironLibrary/model/AuthorTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; public class AuthorTest { @@ -9,9 +10,12 @@ public class AuthorTest { @Test void createAuthor(){ Author authorOne = new Author(); - Author authorTwo = new Author(); + Book book = new Book("978-3-16-148410-0", "Test book", "Tester", 2); + Author authorTwo = new Author("Carlos Diaz","carlosdiaz@mail.com", book); assertNotNull(authorOne); assertNotNull(authorTwo); + assertEquals("Carlos Diaz", authorTwo.getName()); + assertEquals("Test book", authorTwo.getAuthorBook().getTitle()); } } From 3e37e8f26989f6973cacaf9503ce8b8c7877fe00 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 13:49:29 +0100 Subject: [PATCH 032/112] Add BookRepository and test for model instance and bookRepository as well --- .../com/ironhack/ironLibrary/model/Book.java | 3 - .../repository/BookRepository.java | 9 +++ .../ironhack/ironLibrary/model/BookTest.java | 61 ++++++++++++++++- .../repository/BookRepositoryTest.java | 66 +++++++++++++++++++ 4 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java create mode 100644 src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java index a135bc26..74dc3006 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Book.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -16,7 +16,4 @@ public class Book { private String title; private String category; private Integer quantity; - - - } diff --git a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java new file mode 100644 index 00000000..d4f5426a --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java @@ -0,0 +1,9 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Book; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BookRepository extends JpaRepository { +} diff --git a/src/test/java/com/ironhack/ironLibrary/model/BookTest.java b/src/test/java/com/ironhack/ironLibrary/model/BookTest.java index d8d6b36e..8bc66092 100644 --- a/src/test/java/com/ironhack/ironLibrary/model/BookTest.java +++ b/src/test/java/com/ironhack/ironLibrary/model/BookTest.java @@ -1,10 +1,65 @@ package com.ironhack.ironLibrary.model; -import org.junit.jupiter.api.BeforeAll; +import com.ironhack.ironLibrary.utils.Validator; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; +import static org.junit.jupiter.api.Assertions.*; + -@SpringBootTest public class BookTest { + private Book dummyBook; + private Book dummyBook2; + + + @BeforeEach + void setUp() { + dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + dummyBook2 = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + } + + @Test + void shouldBeCorrectInstantiated(){ + assertEquals("novel", dummyBook.getCategory()); + assertEquals("978-84-415-4301-0", dummyBook.getIsbn()); + assertEquals("The unicorn project", dummyBook.getTitle()); + assertEquals(1, dummyBook.getQuantity()); + } + + @Test + void shouldBeTheSameObject(){ + assertEquals(dummyBook, dummyBook2); + } + + @Test + void shouldBeTheSameHashCode(){ + assertEquals(dummyBook.hashCode(), dummyBook2.hashCode()); + } + @Test + void shouldBeUpdateQuantityToTen(){ + dummyBook.setQuantity(10); + assertEquals(10, dummyBook.getQuantity()); + } + @Test + void shouldUpdateCategory(){ + dummyBook.setCategory("comedy"); + assertEquals("comedy", dummyBook.getCategory()); + } + + @Test + void shouldUpdateTitle(){ + dummyBook.setTitle("The fenix project"); + assertEquals("The fenix project", dummyBook.getTitle()); + } + + @Test + void shouldBePassISBNValidator(){ + assertTrue(Validator.checkISBNFormat(dummyBook.getIsbn())); + } + + @Test + void shouldBePassNotNullTitleValidator(){ + assertTrue(Validator.notBlankValidatorBooks(dummyBook.getTitle())); + } + } diff --git a/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java new file mode 100644 index 00000000..e3c8d950 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java @@ -0,0 +1,66 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Book; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class BookRepositoryTest { + + @Autowired + private BookRepository bookRepository; + + private Book dummyBook; + @BeforeEach + void setUp() { + dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + bookRepository.save(dummyBook); + } + + @AfterEach + void tearDown() { + bookRepository.deleteAll(); + } + + @Test + void shouldBeGetTheBook(){ + Optional maybeBook = bookRepository.findById("978-84-415-4301-0"); + assertTrue(maybeBook.isPresent()); + } + + + @Test + void shouldBeOneQuantityBook(){ + Optional maybeBook = bookRepository.findById("978-84-415-4301-0"); + if(maybeBook.isPresent()){ + Book book = maybeBook.get(); + assertEquals(1, book.getQuantity()); + } + } + + @Test + void shouldBeTheCorrectTitle(){ + Optional maybeBook = bookRepository.findById("978-84-415-4301-0"); + if(maybeBook.isPresent()){ + Book book = maybeBook.get(); + assertEquals("The unicorn project", book.getTitle()); + } + } + + @Test + void shouldBeTheCorrectCategory(){ + Optional maybeBook = bookRepository.findById("978-84-415-4301-0"); + if(maybeBook.isPresent()){ + Book book = maybeBook.get(); + assertEquals("novel", book.getCategory()); + } + } + +} \ No newline at end of file From 599df3eaf000834e0014213c693e40a84f056394 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 14:14:46 +0100 Subject: [PATCH 033/112] Change workflow to do the springboot test --- .github/workflows/maven.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 339ab8d3..469da3ac 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -46,5 +46,7 @@ jobs: - name: Build with Maven run: mvn -B clean package --file pom.xml - - name: Run unit tests - run : mvn test --file pom.xml + #- name: Run unit tests + # run : mvn test --file pom.xml + - name: Run Spring Boot tests + run: mvn -B test -Dspring.datasource.url=jdbc:mysql://localhost:3306/${{ secrets.MYSQL_DATABASE }} -Dspring.datasource.username=${{ secrets.MYSQL_USER }} -Dspring.datasource.password=${{ secrets.MYSQL_PASSWORD }} From 1a77906922236f5401f9863ef2ad0219769e577c Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 14:18:44 +0100 Subject: [PATCH 034/112] Uncomment IronLibraryApplicationTest --- .../ironhack/ironLibrary/IronLibraryApplicationTests.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java index cf73bbb4..d0c20cd2 100644 --- a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java +++ b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -//@SpringBootTest -//class IronLibraryApplicationTests { -// -//} +@SpringBootTest +class IronLibraryApplicationTests { + +} From d53a619c48e04c6d55d34428d049249cf2ae4622 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 14:31:21 +0100 Subject: [PATCH 035/112] Fix: workflow to pass repository Springboot Application tests --- .github/workflows/maven.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 469da3ac..5d314498 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -46,7 +46,7 @@ jobs: - name: Build with Maven run: mvn -B clean package --file pom.xml - #- name: Run unit tests - # run : mvn test --file pom.xml - - name: Run Spring Boot tests - run: mvn -B test -Dspring.datasource.url=jdbc:mysql://localhost:3306/${{ secrets.MYSQL_DATABASE }} -Dspring.datasource.username=${{ secrets.MYSQL_USER }} -Dspring.datasource.password=${{ secrets.MYSQL_PASSWORD }} + - name: Run unit tests + run : mvn test --file pom.xml + - name: Run repository tests + run: mvn -B test -Dtest=com.ironhack.ironLibrary.repository.* --file pom.xml From 2009d960813785fe47c732f7180ef15c248b4afa Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 14:36:13 +0100 Subject: [PATCH 036/112] Fix: Add Context load to IronLibraryApplicationTest to load Springboot Context --- .../ironhack/ironLibrary/IronLibraryApplicationTests.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java index d0c20cd2..784294a1 100644 --- a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java +++ b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java @@ -5,5 +5,8 @@ @SpringBootTest class IronLibraryApplicationTests { + @Test + void contextLoads() { -} + } +} \ No newline at end of file From 9cc4943285083014948037ed503421a9f7648897 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 14:38:47 +0100 Subject: [PATCH 037/112] Fix --- .../com/ironhack/ironLibrary/IronLibraryApplicationTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java index 784294a1..f4b290a7 100644 --- a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java +++ b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest +@SpringBootTest(classes = IronLibraryApplication.class) class IronLibraryApplicationTests { @Test void contextLoads() { From 18dac783c886646fc7660ac6b8c965dad72f29d7 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 15:10:38 +0100 Subject: [PATCH 038/112] Fix --- .../java/com/ironhack/ironLibrary/IronLibraryApplication.java | 2 -- .../com/ironhack/ironLibrary/IronLibraryApplicationTests.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index 4f756672..616b022f 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -12,8 +12,6 @@ public static void main(String[] args) { ); } - - } diff --git a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java index f4b290a7..784294a1 100644 --- a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java +++ b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest(classes = IronLibraryApplication.class) +@SpringBootTest class IronLibraryApplicationTests { @Test void contextLoads() { From f7c9545faaee50e3d878c383bcaec7d43b276ec8 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 15:14:27 +0100 Subject: [PATCH 039/112] hardcode datasource property to check if it works --- src/test/resources/application.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index df8acaee..b5a94ccb 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,7 +1,7 @@ spring.application.name=ironLibrary -spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}_test?createDatabaseIfNotExist=TRUE -spring.datasource.username=${MYSQL_USERNAME} -spring.datasource.password=${MYSQL_PASSWORD} +spring.datasource.url=jdbc:mysql://localhost:3306/library_test?createDatabaseIfNotExist=TRUE +spring.datasource.username=root +spring.datasource.password=root spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver From 11a0b2e55d3965f0f5d52a3a8adeb529263a0757 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 15:47:34 +0100 Subject: [PATCH 040/112] Fix --- .github/workflows/maven.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 5d314498..66f36f4a 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -48,5 +48,6 @@ jobs: - name: Run unit tests run : mvn test --file pom.xml - - name: Run repository tests - run: mvn -B test -Dtest=com.ironhack.ironLibrary.repository.* --file pom.xml + - name: Run Spring Boot tests + run: mvn -B test -Dspring.datasource.url=jdbc:mysql://localhost:3306/${{ secrets.MYSQL_DATABASE }} -Dspring.datasource.username=${{ secrets.MYSQL_USERNAME }} -Dspring.datasource.password=${{ secrets.MYSQL_PASSWORD }} + From 817ba6aa4cfca223a5f122dad717491d43d7bda9 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 15:59:03 +0100 Subject: [PATCH 041/112] Fix --- .github/workflows/maven.yml | 3 +-- src/test/resources/application.properties | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 66f36f4a..534513ef 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -48,6 +48,5 @@ jobs: - name: Run unit tests run : mvn test --file pom.xml - - name: Run Spring Boot tests - run: mvn -B test -Dspring.datasource.url=jdbc:mysql://localhost:3306/${{ secrets.MYSQL_DATABASE }} -Dspring.datasource.username=${{ secrets.MYSQL_USERNAME }} -Dspring.datasource.password=${{ secrets.MYSQL_PASSWORD }} + diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index b5a94ccb..df8acaee 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,7 +1,7 @@ spring.application.name=ironLibrary -spring.datasource.url=jdbc:mysql://localhost:3306/library_test?createDatabaseIfNotExist=TRUE -spring.datasource.username=root -spring.datasource.password=root +spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}_test?createDatabaseIfNotExist=TRUE +spring.datasource.username=${MYSQL_USERNAME} +spring.datasource.password=${MYSQL_PASSWORD} spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver From a69d0289e651ff2bd69eb1142ed8c26fb5d7a6cc Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:07:51 +0100 Subject: [PATCH 042/112] Modify Workflow yaml --- .github/workflows/maven.yml | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 534513ef..b6c31f8e 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -33,20 +33,28 @@ jobs: ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - name: Build with Maven - run: mvn -B clean package --file pom.xml - - - name: Run unit tests - run : mvn test --file pom.xml + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Create MySQL User + run: | + echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql + mysql -h localhost -P 3306 -u ${{ secrets.MYSQL_USERNAME }} -p${{ secrets.MYSQL_PASSWORD }} < create_user.sql + + - name: Build with Maven + run: mvn -B clean package --file pom.xml + + - name: Run unit tests + run: mvn test --file pom.xml + From 189586bda46a03d4b5212b9e8e04e958bf5110f9 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:10:06 +0100 Subject: [PATCH 043/112] Modify Workflow yaml --- .github/workflows/maven.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index b6c31f8e..8d388b79 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -45,16 +45,10 @@ jobs: distribution: 'temurin' cache: maven - - name: Create MySQL User - run: | - echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql - mysql -h localhost -P 3306 -u ${{ secrets.MYSQL_USERNAME }} -p${{ secrets.MYSQL_PASSWORD }} < create_user.sql - - name: Build with Maven run: mvn -B clean package --file pom.xml - name: Run unit tests - run: mvn test --file pom.xml - + run : mvn test --file pom.xml From 6fa31344f4d35a74c487bfb33bef59be5a9ba146 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:16:59 +0100 Subject: [PATCH 044/112] Modify Workflow yaml --- .github/workflows/maven.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8d388b79..46acf771 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -45,6 +45,12 @@ jobs: distribution: 'temurin' cache: maven + - name: Configure MySQL User + run: | + echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql + echo "FLUSH PRIVILEGES;" >> create_user.sql + mysql -h 127.0.0.1 -P 3306 -u root -p root < create_user.sql + - name: Build with Maven run: mvn -B clean package --file pom.xml From 331b282108bac9c2f7dbe750488380bd80763040 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:21:48 +0100 Subject: [PATCH 045/112] Modify Workflow yaml --- .github/workflows/maven.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 46acf771..919f6311 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -49,7 +49,8 @@ jobs: run: | echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql echo "FLUSH PRIVILEGES;" >> create_user.sql - mysql -h 127.0.0.1 -P 3306 -u root -p root < create_user.sql + mysql -h 172.18.0.1 -P 3306 -u root -proot < create_user.sql + - name: Build with Maven run: mvn -B clean package --file pom.xml From e8e139fc67685341b1aa4c4bb3a447c8e94adcbb Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:40:34 +0100 Subject: [PATCH 046/112] Modify Workflow yaml --- .github/workflows/maven.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 919f6311..50ac30e3 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -27,9 +27,10 @@ jobs: image: mysql:latest env: MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} - MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} - MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} + MYSQL_DATABASE: ${{secrets.MYSQL_DATABASE}} + MYSQL_USERNAME: ${{secrets.MYSQL_USERNAME}} + MYSQL_PASSWORD: ${{secrets.MYSQL_PASSWORD}} + MYSQL_ALLOW_EMPTY_PASSWORD: yes ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 @@ -49,7 +50,7 @@ jobs: run: | echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql echo "FLUSH PRIVILEGES;" >> create_user.sql - mysql -h 172.18.0.1 -P 3306 -u root -proot < create_user.sql + mysql -h 172.18.0.1 -P 3306 -u root -p root < create_user.sql - name: Build with Maven From 6cd443a981bac3c77d65afd522cb539797d42636 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:43:23 +0100 Subject: [PATCH 047/112] Modify Workflow yaml --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 50ac30e3..9b8cb579 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -48,9 +48,9 @@ jobs: - name: Configure MySQL User run: | - echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql + echo "CREATE USER 'runner'@'127.0.0.1';" > create_user.sql echo "FLUSH PRIVILEGES;" >> create_user.sql - mysql -h 172.18.0.1 -P 3306 -u root -p root < create_user.sql + mysql -h 127.0.0.1 -P 3306 -u root -p root < create_user.sql - name: Build with Maven From 1e96bd54c865ca307813d2365326ba0f874fd6e2 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:48:50 +0100 Subject: [PATCH 048/112] Modify Workflow yaml --- .github/workflows/maven.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 9b8cb579..50bb33e0 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -30,7 +30,6 @@ jobs: MYSQL_DATABASE: ${{secrets.MYSQL_DATABASE}} MYSQL_USERNAME: ${{secrets.MYSQL_USERNAME}} MYSQL_PASSWORD: ${{secrets.MYSQL_PASSWORD}} - MYSQL_ALLOW_EMPTY_PASSWORD: yes ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 @@ -48,9 +47,9 @@ jobs: - name: Configure MySQL User run: | - echo "CREATE USER 'runner'@'127.0.0.1';" > create_user.sql + echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql echo "FLUSH PRIVILEGES;" >> create_user.sql - mysql -h 127.0.0.1 -P 3306 -u root -p root < create_user.sql + mysql -h '172.18.0.1 -P 3306 -u root < create_user.sql - name: Build with Maven From de91a363e16d0c59423e8eb8f50e4459d670cf49 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:50:36 +0100 Subject: [PATCH 049/112] Modify Workflow yaml --- .github/workflows/maven.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 50bb33e0..d27c9225 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -26,7 +26,7 @@ jobs: mysql: image: mysql:latest env: - MYSQL_ROOT_PASSWORD: root + #MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: ${{secrets.MYSQL_DATABASE}} MYSQL_USERNAME: ${{secrets.MYSQL_USERNAME}} MYSQL_PASSWORD: ${{secrets.MYSQL_PASSWORD}} @@ -45,13 +45,6 @@ jobs: distribution: 'temurin' cache: maven - - name: Configure MySQL User - run: | - echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql - echo "FLUSH PRIVILEGES;" >> create_user.sql - mysql -h '172.18.0.1 -P 3306 -u root < create_user.sql - - - name: Build with Maven run: mvn -B clean package --file pom.xml From 504e69433e7f9902ec81c9c6b074bfd24858ed64 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:54:27 +0100 Subject: [PATCH 050/112] Modify Workflow yaml --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d27c9225..d906e0d8 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -26,9 +26,9 @@ jobs: mysql: image: mysql:latest env: - #MYSQL_ROOT_PASSWORD: root + MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: ${{secrets.MYSQL_DATABASE}} - MYSQL_USERNAME: ${{secrets.MYSQL_USERNAME}} + MYSQL_USERNAME: runner MYSQL_PASSWORD: ${{secrets.MYSQL_PASSWORD}} ports: - 3306:3306 From d230d707fc24ca5cd74cc6a8761053f66e088c9a Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 16:57:37 +0100 Subject: [PATCH 051/112] Modify Workflow yaml --- src/test/resources/application.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index df8acaee..9260af07 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,7 +1,7 @@ spring.application.name=ironLibrary -spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}_test?createDatabaseIfNotExist=TRUE -spring.datasource.username=${MYSQL_USERNAME} -spring.datasource.password=${MYSQL_PASSWORD} +spring.datasource.url=jdbc:mysql://localhost:3306/library_test?createDatabaseIfNotExist=TRUE +spring.datasource.username=runner +spring.datasource.password= spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver From 242ddb3126aca387b1211edac67e9fed173e143b Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 17:03:57 +0100 Subject: [PATCH 052/112] Modify Workflow yaml --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d906e0d8..bf3e55ab 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -21,7 +21,7 @@ jobs: MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} - + MYSQL_ALLOW_EMPTY_PASSWORD: "true" services: mysql: image: mysql:latest From 30fc3be3926f69827b5bb63d17ec0107e798bee1 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 17:07:30 +0100 Subject: [PATCH 053/112] Modify Workflow yaml --- .github/workflows/maven.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index bf3e55ab..23a46211 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -45,6 +45,12 @@ jobs: distribution: 'temurin' cache: maven + - name: Configure MySQL User + run: | + echo "CREATE USER 'runner+'@'172.18.0.1';" > create_user.sql + echo "FLUSH PRIVILEGES;" >> create_user.sql + mysql -h 127.0.0.1 -P 3306 -u root < create_user.sql + - name: Build with Maven run: mvn -B clean package --file pom.xml From 7c0cbe7a609d56b36e40602fde5e33c7664e01f2 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 17:07:47 +0100 Subject: [PATCH 054/112] Modify Workflow yaml --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 23a46211..9128d31f 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -47,7 +47,7 @@ jobs: - name: Configure MySQL User run: | - echo "CREATE USER 'runner+'@'172.18.0.1';" > create_user.sql + echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql echo "FLUSH PRIVILEGES;" >> create_user.sql mysql -h 127.0.0.1 -P 3306 -u root < create_user.sql From e15ecc983289ac0c327fb20ec21d815fccecf5dd Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 17:09:43 +0100 Subject: [PATCH 055/112] Modify Workflow yaml --- .github/workflows/maven.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 9128d31f..32789cef 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -17,19 +17,14 @@ on: jobs: build: runs-on: ubuntu-latest - env: - MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} - MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} - MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} - MYSQL_ALLOW_EMPTY_PASSWORD: "true" services: mysql: image: mysql:latest env: MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: ${{secrets.MYSQL_DATABASE}} - MYSQL_USERNAME: runner - MYSQL_PASSWORD: ${{secrets.MYSQL_PASSWORD}} + MYSQL_DATABASE: library + MYSQL_USERNAME: root + MYSQL_PASSWORD: root ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 From b714344bc62272c88da3e61a4363a5c2397cd890 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 17:11:01 +0100 Subject: [PATCH 056/112] Modify Workflow yaml --- .github/workflows/maven.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 32789cef..1f7e8f2f 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -40,11 +40,6 @@ jobs: distribution: 'temurin' cache: maven - - name: Configure MySQL User - run: | - echo "CREATE USER 'runner'@'172.18.0.1';" > create_user.sql - echo "FLUSH PRIVILEGES;" >> create_user.sql - mysql -h 127.0.0.1 -P 3306 -u root < create_user.sql - name: Build with Maven run: mvn -B clean package --file pom.xml From e21a20fe006afc004210b16cb09b43b5e338827f Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 17:12:56 +0100 Subject: [PATCH 057/112] Modify Workflow yaml --- .github/workflows/maven.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 1f7e8f2f..3582ed9a 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -17,18 +17,22 @@ on: jobs: build: runs-on: ubuntu-latest + env: + MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} + MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} + MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} + services: mysql: image: mysql:latest env: MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: library - MYSQL_USERNAME: root - MYSQL_PASSWORD: root + MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} + MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} + MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} ports: - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - steps: - name: Checkout repository uses: actions/checkout@v3 @@ -39,12 +43,8 @@ jobs: java-version: '17' distribution: 'temurin' cache: maven - - - name: Build with Maven run: mvn -B clean package --file pom.xml - name: Run unit tests - run : mvn test --file pom.xml - - + run : mvn test --file pom.xml \ No newline at end of file From 2cd9cb106fcee41f027a09e99cb5cb0c9ea84177 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 30 Mar 2024 17:16:44 +0100 Subject: [PATCH 058/112] Modify Workflow yaml --- .github/workflows/maven.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 3582ed9a..351be891 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -43,6 +43,9 @@ jobs: java-version: '17' distribution: 'temurin' cache: maven + + - name: Debug MySQL connection + run: mysql -h localhost -u $MYSQL_USERNAME --password=$MYSQL_PASSWORD -e 'SHOW DATABASES;' - name: Build with Maven run: mvn -B clean package --file pom.xml From ba192a1f662fcd4399be59398bf619bc5681354e Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Sun, 31 Mar 2024 14:07:17 +0200 Subject: [PATCH 059/112] book test and book model --- .../com/ironhack/ironLibrary/model/Book.java | 2 ++ .../ironhack/ironLibrary/model/BookTest.java | 32 ++++++++++++++++++- src/test/resources/application.properties | 1 - 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java index c43b165e..1626f7c7 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Book.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -5,6 +5,8 @@ import jakarta.persistence.*; @Data +@AllArgsConstructor +@NoArgsConstructor @Entity public class Book { @Id diff --git a/src/test/java/com/ironhack/ironLibrary/model/BookTest.java b/src/test/java/com/ironhack/ironLibrary/model/BookTest.java index d8d6b36e..2ea62caf 100644 --- a/src/test/java/com/ironhack/ironLibrary/model/BookTest.java +++ b/src/test/java/com/ironhack/ironLibrary/model/BookTest.java @@ -4,7 +4,37 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class BookTest { + static Book book; + + @BeforeAll + static void setUp(){ + book = new Book("978-0-670-82162-0", "title", "Romance", 12); + } + @Test + public void BookSetterAndGetterTitleTest() { + book.setTitle("newTitle"); + assertEquals("newTitle", "newTitle"); + } + + @Test + public void BookSetterAndGetterCategoryTest() { + book.setCategory("terror"); + assertEquals("terror", book.getCategory()); + } + + @Test + public void BookSetterAndGetterQuantityTest() { + book.setQuantity(3); + assertEquals(3, book.getQuantity()); + } + @Test + void BookDefaultConstructorTest(){ + Book book = new Book(); + assertNotNull(book); + } } diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index df8acaee..167bf5ad 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -6,7 +6,6 @@ spring.datasource.password=${MYSQL_PASSWORD} spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect -##spring.jpa.hibernate.ddl-auto=validate spring.jpa.show-sql=true spring.jpa.open-in-view=true From c2625c7cda851c48682c6efa6008cb821ffe6ec6 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Sun, 31 Mar 2024 14:11:09 +0200 Subject: [PATCH 060/112] update book class --- src/main/java/com/ironhack/ironLibrary/model/Book.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Book.java b/src/main/java/com/ironhack/ironLibrary/model/Book.java index aa99051c..7d00969e 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Book.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Book.java @@ -5,11 +5,9 @@ import jakarta.persistence.*; @Data -@AllArgsConstructor -@NoArgsConstructor -@Entity @NoArgsConstructor @AllArgsConstructor +@Entity @Table(name = "books") public class Book { @Id @@ -19,6 +17,4 @@ public class Book { private String category; private Integer quantity; - - } From dda9caf3c71549b73b73f6cfef7e64d8991abe99 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 31 Mar 2024 14:11:51 +0200 Subject: [PATCH 061/112] Setup mysql on a workflow --- .github/workflows/maven.yml | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 351be891..2ff20e10 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -22,18 +22,22 @@ jobs: MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} - services: - mysql: - image: mysql:latest - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} - MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} - MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + #services: + #mysql: + #image: mysql:latest + #env: + #MYSQL_ROOT_PASSWORD: root + #MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} + #MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} + #MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} + #ports: + #- 3306:3306 + #options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: + - name: Set up MySQL + run : | + sudo /etc/init.d/mysql start + mysql -e 'CREATE DATABASE ${{env.MYSQL_DATABASE}};' -u${{env.MYSQL_USERNAME}} -p${{env.MYSQL_PASSWORD}} - name: Checkout repository uses: actions/checkout@v3 @@ -44,8 +48,8 @@ jobs: distribution: 'temurin' cache: maven - - name: Debug MySQL connection - run: mysql -h localhost -u $MYSQL_USERNAME --password=$MYSQL_PASSWORD -e 'SHOW DATABASES;' + #- name: Debug MySQL connection + #run: mysql -h localhost -u $MYSQL_USERNAME --password=$MYSQL_PASSWORD -e 'SHOW DATABASES;' - name: Build with Maven run: mvn -B clean package --file pom.xml From 8d2e28f8130c3f4fe9597f4ae8a4bf7fe39bca12 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 31 Mar 2024 14:13:52 +0200 Subject: [PATCH 062/112] Fix --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 2ff20e10..00fc37fe 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -35,9 +35,9 @@ jobs: #options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - name: Set up MySQL - run : | + run: | sudo /etc/init.d/mysql start - mysql -e 'CREATE DATABASE ${{env.MYSQL_DATABASE}};' -u${{env.MYSQL_USERNAME}} -p${{env.MYSQL_PASSWORD}} + mysql -e 'CREATE DATABASE ${{ env.MYSQL_DATABASE }};' -u${{ env.MYSQL_USERNAME }} -p${{ env.MYSQL_PASSWORD }} - name: Checkout repository uses: actions/checkout@v3 From bb01c2825f8f72762edcd7bd18ba51c0ad15acad Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 31 Mar 2024 14:17:52 +0200 Subject: [PATCH 063/112] Fix --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 00fc37fe..8cc29860 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -19,8 +19,8 @@ jobs: runs-on: ubuntu-latest env: MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} - MYSQL_USERNAME: ${{ secrets.MYSQL_USERNAME }} - MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }} + MYSQL_USERNAME: root + MYSQL_PASSWORD: root #services: #mysql: From 006a3b4bd0477ac8d8ede9e6e2ce0b356a566ad2 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 31 Mar 2024 14:18:36 +0200 Subject: [PATCH 064/112] Fix --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8cc29860..77608481 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -18,7 +18,7 @@ jobs: build: runs-on: ubuntu-latest env: - MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} + MYSQL_DATABASE: library MYSQL_USERNAME: root MYSQL_PASSWORD: root From 321e7fd9546a3cf6382c679fd403b243e6af82e3 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 31 Mar 2024 14:20:57 +0200 Subject: [PATCH 065/112] Fix --- .github/workflows/maven.yml | 2 +- src/test/resources/application.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 77608481..5d36283c 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -18,7 +18,7 @@ jobs: build: runs-on: ubuntu-latest env: - MYSQL_DATABASE: library + MYSQL_DATABASE: library_test MYSQL_USERNAME: root MYSQL_PASSWORD: root diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 9260af07..b5a94ccb 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,7 +1,7 @@ spring.application.name=ironLibrary spring.datasource.url=jdbc:mysql://localhost:3306/library_test?createDatabaseIfNotExist=TRUE -spring.datasource.username=runner -spring.datasource.password= +spring.datasource.username=root +spring.datasource.password=root spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver From 5c41093c70e08b71a19b7cdc8df4d15812cfcdba Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Sun, 31 Mar 2024 14:48:17 +0200 Subject: [PATCH 066/112] add student repo and tests --- .../repository/StudentRepository.java | 11 ++++++ .../repository/StudentRepositoryTest.java | 38 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java create mode 100644 src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java new file mode 100644 index 00000000..dd1783fc --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java @@ -0,0 +1,11 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Student; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import java.util.Optional; + +@Repository +public interface StudentRepository extends JpaRepository { + Optional findByUsnAndName(Integer usn, String name); +} diff --git a/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java new file mode 100644 index 00000000..d4a4c237 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java @@ -0,0 +1,38 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Student; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest +public class StudentRepositoryTest { + @Autowired + private StudentRepository studentRepository; + + @BeforeEach + void setUp() { + Student student = new Student(1, "Student1"); + student = studentRepository.save(student); + } + + @AfterEach + void tearDown() { + studentRepository.deleteAll(); + studentRepository.flush(); + } + + @Test + void findByUsnAndNameTest() { + Optional student = studentRepository.findByUsnAndName(1, "Student1"); + assertTrue(student.isPresent()); + assertEquals("Student1", student.get().getName()); + } +} From 583079eaa74c45d57d4d451e57e4698b9cbc5224 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 31 Mar 2024 20:19:21 +0200 Subject: [PATCH 067/112] Create JPA to findAllByCategory and test --- .../repository/BookRepository.java | 4 +++ .../repository/BookRepositoryTest.java | 26 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java index d4f5426a..0a6e868c 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java @@ -4,6 +4,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + @Repository public interface BookRepository extends JpaRepository { + Optional> findAllByCategory(String Category); } diff --git a/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java index e3c8d950..3c438f64 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java @@ -7,13 +7,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest class BookRepositoryTest { - + int quantityOfNovelBooks = 0; @Autowired private BookRepository bookRepository; @@ -63,4 +64,27 @@ void shouldBeTheCorrectCategory(){ } } + @Test + void shouldGetAllBooksUsingFindAllByCategory() { + Book newBook = new Book("978-84-415-4302-0", "The fenix project", "novel", 10); + bookRepository.save(newBook); + Optional> maybeListOfBooks = bookRepository.findAllByCategory("novel"); + if(maybeListOfBooks.isPresent()){ + List listOfBooks = maybeListOfBooks.get(); + assertEquals(2, listOfBooks.size()); + } + } + + @Test + void shouldGetTheRightQuantityOfBooksUsingFindAllByCategory(){ + Book newBooks = new Book("978-84-415-4302-0", "The fenix project", "novel", 10); + bookRepository.save(newBooks); + Optional> maybeListOfBooks = bookRepository.findAllByCategory("novel"); + if(maybeListOfBooks.isPresent()){ + maybeListOfBooks.get().forEach(book -> { + quantityOfNovelBooks = quantityOfNovelBooks + book.getQuantity(); + }); + assertEquals(11, quantityOfNovelBooks); + } + } } \ No newline at end of file From 6816c1d64c38a8dc270b06f687153ca4a673c435 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 31 Mar 2024 21:01:05 +0200 Subject: [PATCH 068/112] Feature: implement JPA findOneByTitle and tested --- .../ironLibrary/repository/BookRepository.java | 1 + .../ironLibrary/repository/BookRepositoryTest.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java index 0a6e868c..5712fbf5 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java @@ -10,4 +10,5 @@ @Repository public interface BookRepository extends JpaRepository { Optional> findAllByCategory(String Category); + Optional findOneByTitle(String Title); } diff --git a/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java index 3c438f64..ccdc3b34 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java @@ -87,4 +87,16 @@ void shouldGetTheRightQuantityOfBooksUsingFindAllByCategory(){ assertEquals(11, quantityOfNovelBooks); } } + + @Test + void shouldGetTheRightBookUsingFindOneByTitle() { + Optional maybeBook = bookRepository.findOneByTitle("The unicorn project"); + maybeBook.ifPresent(book -> assertEquals("The unicorn project", book.getTitle())); + } + + @Test + void shouldGetFalseIfWeFindTheWrongTitleUsingFindOneByTitle() { + Optional maybeBook = bookRepository.findOneByTitle("The unicorn project"); + maybeBook.ifPresent(book -> assertNotEquals("The fenix project", book.getTitle())); + } } \ No newline at end of file From d0d6b76b57e2b9b417ecd50a91729267ce749a4c Mon Sep 17 00:00:00 2001 From: Arian Date: Tue, 2 Apr 2024 21:00:06 +0200 Subject: [PATCH 069/112] Feature: implement JPQL to find Book by Author && test --- .../ironhack/ironLibrary/model/Author.java | 2 +- .../repository/AuthorRepository.java | 10 ++++ .../repository/AuthorRepositoryTest.java | 56 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Author.java b/src/main/java/com/ironhack/ironLibrary/model/Author.java index 5b526880..18ff3e81 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Author.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Author.java @@ -14,7 +14,7 @@ public class Author { private Integer authorId; private String name; private String email; - @OneToOne + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "isbn") private Book authorBook; diff --git a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java index f3d05952..fc63a63f 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java @@ -1,9 +1,19 @@ package com.ironhack.ironLibrary.repository; import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface AuthorRepository extends JpaRepository { + + @Query("SELECT b From Author a JOIN a.authorBook b WHERE a.name = ?1") + Optional findBookByAuthor(String authorName); } + +// TO ASK +// DA IGUAL SI PASaMOS LOS DATOS EN LOWERCASE O UPPER ? diff --git a/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java new file mode 100644 index 00000000..301b1d74 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java @@ -0,0 +1,56 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class AuthorRepositoryTest { + + @Autowired + private BookRepository bookRepository; + + @Autowired + private AuthorRepository authorRepository; + + private Author dummyAuthor; + private Book dummyBook; + + @BeforeEach + void setUp() { + dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + dummyAuthor = new Author("Gene Kim", "g.kim@gmail.com", dummyBook); + authorRepository.save(dummyAuthor); + } + + @AfterEach + void tearDown() { + authorRepository.deleteAll(); + } + + @Test + void shouldReturnACorrectBookIfUseFindBookByAuthor() { + Optional maybeBook = authorRepository.findBookByAuthor("Gene Kim"); + assertTrue(maybeBook.isPresent(), "The book should not be null"); + maybeBook.ifPresent(book -> { + assertEquals("The unicorn project", book.getTitle()); + assertEquals("978-84-415-4301-0", book.getIsbn()); + assertEquals(1, book.getQuantity()); + assertEquals("novel", book.getCategory()); + }); + } + + @Test + void shouldReturnEmptyIfWeWantToFindABookByAuthorThatNotExist(){ + Optional maybeBook = authorRepository.findBookByAuthor("J.K Rowling"); + assertFalse(maybeBook.isPresent()); + } +} \ No newline at end of file From 3ad9812ca8d13531d11a8dc5c1394737ddba019e Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Tue, 2 Apr 2024 21:40:57 +0200 Subject: [PATCH 070/112] student repo --- .../repository/StudentRepositoryTest.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java index d4a4c237..07ff8e61 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java @@ -1,6 +1,7 @@ package com.ironhack.ironLibrary.repository; import com.ironhack.ironLibrary.model.Student; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -19,20 +20,27 @@ public class StudentRepositoryTest { @BeforeEach void setUp() { - Student student = new Student(1, "Student1"); - student = studentRepository.save(student); + Student student1 = new Student(1, "Student1"); + Student student2 = new Student(2, "Student2"); + studentRepository.save(student1); + studentRepository.save(student2); } @AfterEach void tearDown() { studentRepository.deleteAll(); - studentRepository.flush(); + // studentRepository.flush(); + } + + @Test + void checkSaveItem() { + assertEquals(2, studentRepository.count()); } @Test void findByUsnAndNameTest() { - Optional student = studentRepository.findByUsnAndName(1, "Student1"); + Optional student = studentRepository.findByUsnAndName(2, "Student2"); assertTrue(student.isPresent()); - assertEquals("Student1", student.get().getName()); + assertEquals("Student2", student.get().getName()); } } From d74861f44ce9d721fd83c1f2fb8e99ec3d02e82f Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Tue, 2 Apr 2024 21:56:07 +0200 Subject: [PATCH 071/112] add isuue repo and its tests --- .../repository/IssueRepository.java | 10 +++++ .../repository/IssueRepositoryTest.java | 40 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java create mode 100644 src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java new file mode 100644 index 00000000..e7ba02f1 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java @@ -0,0 +1,10 @@ +package com.ironhack.ironLibrary.repository; + + +import com.ironhack.ironLibrary.model.Issue; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface IssueRepository extends JpaRepository { +} diff --git a/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java new file mode 100644 index 00000000..52a51a2b --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java @@ -0,0 +1,40 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Issue; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import java.util.Optional; +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +public class IssueRepositoryTest { + + @Autowired + private IssueRepository issueRepository; + + @BeforeEach + void setUp() { + Issue issue = new Issue(); + issueRepository.save(issue); + } + + @AfterEach + void tearDown() { + issueRepository.deleteAll(); + } + + @Test + void saveItemTest() { + assertEquals(1, issueRepository.count()); + } + + @Test + void deleteItemTest() { + Optional firstIssue = issueRepository.findAll().stream().findFirst(); + assertTrue(firstIssue.isPresent()); + issueRepository.delete(firstIssue.get()); + assertEquals(0, issueRepository.count()); + } + +} From 50858effd7ba05c5e47275c5312c2b808b61eb38 Mon Sep 17 00:00:00 2001 From: Arian Date: Wed, 3 Apr 2024 19:23:22 +0200 Subject: [PATCH 072/112] Feature: Implement JPQL to find a book-issued by USN --- .../com/ironhack/ironLibrary/model/Issue.java | 4 +- .../ironhack/ironLibrary/model/Student.java | 11 ++- .../repository/AuthorRepository.java | 2 - .../repository/IssueRepository.java | 15 ++++ .../repository/StudentRepository.java | 2 +- .../ironhack/ironLibrary/model/IssueTest.java | 2 +- .../ironLibrary/model/StudentTest.java | 2 +- .../repository/IssueRepositoryTest.java | 79 +++++++++++++++++++ .../repository/StudentRepositoryTest.java | 7 +- 9 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java create mode 100644 src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Issue.java b/src/main/java/com/ironhack/ironLibrary/model/Issue.java index 64bd6817..800acd1e 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Issue.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Issue.java @@ -14,10 +14,10 @@ public class Issue { private Integer issueId; private String issueDate; private String returnDate; - @OneToOne + @ManyToOne @JoinColumn(name = "usn") private Student issueStudent; - @OneToOne + @ManyToOne @JoinColumn(name = "isbn") private Book issueBook; diff --git a/src/main/java/com/ironhack/ironLibrary/model/Student.java b/src/main/java/com/ironhack/ironLibrary/model/Student.java index fc0a15b7..6c581f62 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Student.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Student.java @@ -11,16 +11,21 @@ public class Student { @Setter(AccessLevel.NONE) @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer usn; +// @GeneratedValue(strategy = GenerationType.UUID) + private String usn; private String name; public Student() { } - public Student(Integer usn, String name) { + public Student(String usn, String name) { this.usn = usn; this.name = name; } + + public Student(String name){ + setName(name); + } + } diff --git a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java index fc63a63f..8606f2b8 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java @@ -15,5 +15,3 @@ public interface AuthorRepository extends JpaRepository { Optional findBookByAuthor(String authorName); } -// TO ASK -// DA IGUAL SI PASaMOS LOS DATOS EN LOWERCASE O UPPER ? diff --git a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java new file mode 100644 index 00000000..038e263b --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java @@ -0,0 +1,15 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Optional; + +public interface IssueRepository extends JpaRepository { + @Query("SELECT b from Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") + Optional> findAllBooksByUsn(String Usn); + +} diff --git a/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java index dd1783fc..bf425774 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java @@ -7,5 +7,5 @@ @Repository public interface StudentRepository extends JpaRepository { - Optional findByUsnAndName(Integer usn, String name); + Optional findByUsnAndName(String usn, String name); } diff --git a/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java b/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java index 9f3182a4..78adf9ed 100644 --- a/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java +++ b/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java @@ -9,7 +9,7 @@ public class IssueTest { @Test public void createIssue(){ - Student student = new Student(1, "Carlos"); + Student student = new Student("09003688800", "Carlos"); Book book = new Book(); Issue IssueOne = new Issue(); Issue IssueTwo = new Issue("17/03/2024", "24/03/2024", student, book); diff --git a/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java b/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java index 6184427d..130e06e8 100644 --- a/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java +++ b/src/test/java/com/ironhack/ironLibrary/model/StudentTest.java @@ -10,7 +10,7 @@ class StudentTest { @Test void createStudent(){ Student studentQA = new Student(); - Student studentQA2 = new Student(1,"Test"); + Student studentQA2 = new Student("09003688800","Test"); assertNotNull(studentQA); assertNotNull(studentQA2); } diff --git a/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java new file mode 100644 index 00000000..077726f0 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java @@ -0,0 +1,79 @@ +package com.ironhack.ironLibrary.repository; + +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import com.ironhack.ironLibrary.model.Student; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class IssueRepositoryTest { + + @Autowired + private IssueRepository issueRepository; + @Autowired + private BookRepository bookRepository; + @Autowired + private StudentRepository studentRepository; + + private Book dummyBook; + private Book dummyBook2; + private Student dummyStudent; + + private Student dummyStudent2; + + private Issue dummyIssue; + private Issue dummyIssue2; + + + @BeforeEach + void setUp() { + + dummyStudent = new Student("09003688800", "Pedro"); + dummyStudent2 = new Student("09003688801","Maria"); + studentRepository.save(dummyStudent); + + dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + dummyBook2 = new Book("978-84-415-4302-0", "The fenix project", "novel", 1); + bookRepository.saveAll(List.of(dummyBook, dummyBook2)); + + dummyIssue = new Issue("03/04/2024", "10/04/2024",dummyStudent, dummyBook); +// dummyIssue2 = new Issue("10/04/2024", "20/04/2024",dummyStudent, dummyBook2); +// issueRepository.saveAll(List.of(dummyIssue, dummyIssue2)); + issueRepository.save(dummyIssue); + } + + @AfterEach + void tearDown() { + issueRepository.deleteAll(); + bookRepository.deleteAll(); + studentRepository.deleteAll(); + + } + + @Test + void shouldFindOneBookIdWeUseFindAllBooksByUsn() { + Optional> maybeListOfBooksIssued = issueRepository.findAllBooksByUsn(dummyStudent.getUsn()); + if(maybeListOfBooksIssued.isPresent()){ + List listOfBooksIssued = maybeListOfBooksIssued.get(); + assertEquals(1, listOfBooksIssued.size()); + } + } + + @Test + void shouldNotFindAnyBookIdWeUseFindAllBooksByUsn() { + Optional> maybeListOfBooksIssued = issueRepository.findAllBooksByUsn(dummyStudent2.getUsn()); + if(maybeListOfBooksIssued.isPresent()){ + List listOfBooksIssued = maybeListOfBooksIssued.get(); + assertEquals(0, listOfBooksIssued.size()); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java index 07ff8e61..5a742435 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/StudentRepositoryTest.java @@ -20,8 +20,8 @@ public class StudentRepositoryTest { @BeforeEach void setUp() { - Student student1 = new Student(1, "Student1"); - Student student2 = new Student(2, "Student2"); + Student student1 = new Student("09003688800", "Student1"); + Student student2 = new Student("09003688801", "Student2"); studentRepository.save(student1); studentRepository.save(student2); } @@ -29,7 +29,6 @@ void setUp() { @AfterEach void tearDown() { studentRepository.deleteAll(); - // studentRepository.flush(); } @Test @@ -39,7 +38,7 @@ void checkSaveItem() { @Test void findByUsnAndNameTest() { - Optional student = studentRepository.findByUsnAndName(2, "Student2"); + Optional student = studentRepository.findByUsnAndName("09003688801", "Student2"); assertTrue(student.isPresent()); assertEquals("Student2", student.get().getName()); } From b4336bc0ac308a4adb66e828105986ef2336149e Mon Sep 17 00:00:00 2001 From: Arian Date: Wed, 3 Apr 2024 19:29:12 +0200 Subject: [PATCH 073/112] Refactor: Refactor relationship of issue model --- src/main/java/com/ironhack/ironLibrary/model/Issue.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Issue.java b/src/main/java/com/ironhack/ironLibrary/model/Issue.java index 800acd1e..64bd6817 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Issue.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Issue.java @@ -14,10 +14,10 @@ public class Issue { private Integer issueId; private String issueDate; private String returnDate; - @ManyToOne + @OneToOne @JoinColumn(name = "usn") private Student issueStudent; - @ManyToOne + @OneToOne @JoinColumn(name = "isbn") private Book issueBook; From 9325f051308b0ba88b768420497b501010a8c2c8 Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Wed, 3 Apr 2024 19:30:55 +0200 Subject: [PATCH 074/112] findAllBookJoinAuthor --- .../com/ironhack/ironLibrary/repository/AuthorRepository.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java index fc63a63f..6776c6af 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository @@ -13,6 +14,9 @@ public interface AuthorRepository extends JpaRepository { @Query("SELECT b From Author a JOIN a.authorBook b WHERE a.name = ?1") Optional findBookByAuthor(String authorName); + + @Query("SELECT b.*, a.name, a.email FROM Author a INNER JOIN book b ON a.authorBook = b") + public List } // TO ASK From 324591f422ec1c854187bc4e38b837e977d08a01 Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Wed, 3 Apr 2024 19:40:48 +0200 Subject: [PATCH 075/112] define test --- .../ironhack/ironLibrary/repository/AuthorRepository.java | 4 ++-- .../ironLibrary/repository/AuthorRepositoryTest.java | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java index 6776c6af..03e47579 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java @@ -15,8 +15,8 @@ public interface AuthorRepository extends JpaRepository { @Query("SELECT b From Author a JOIN a.authorBook b WHERE a.name = ?1") Optional findBookByAuthor(String authorName); - @Query("SELECT b.*, a.name, a.email FROM Author a INNER JOIN book b ON a.authorBook = b") - public List + @Query("SELECT b.*, a.name, a.email FROM Author a JOIN a.authorBook b") + public List findAllWithAuthor(); } // TO ASK diff --git a/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java index 301b1d74..fda24aca 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java @@ -53,4 +53,10 @@ void shouldReturnEmptyIfWeWantToFindABookByAuthorThatNotExist(){ Optional maybeBook = authorRepository.findBookByAuthor("J.K Rowling"); assertFalse(maybeBook.isPresent()); } + + @Test + void getAllBookWithAuthor(){ + + } + } \ No newline at end of file From f0c5c567b814daf99a24452790eb7f269b306f00 Mon Sep 17 00:00:00 2001 From: victoriaschwin Date: Thu, 4 Apr 2024 20:55:39 +0200 Subject: [PATCH 076/112] getAllBooksWithAuthors --- .../repository/AuthorRepository.java | 6 +- .../repository/AuthorRepositoryTest.java | 55 ++++++++++++++++--- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java index 03e47579..baab9114 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java @@ -15,8 +15,10 @@ public interface AuthorRepository extends JpaRepository { @Query("SELECT b From Author a JOIN a.authorBook b WHERE a.name = ?1") Optional findBookByAuthor(String authorName); - @Query("SELECT b.*, a.name, a.email FROM Author a JOIN a.authorBook b") - public List findAllWithAuthor(); + @Query("SELECT b,a FROM Author a JOIN Book b ON a.authorBook = b") + Optional > findAllBooksWithAuthors(); + + } // TO ASK diff --git a/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java index fda24aca..ced2c2a8 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/AuthorRepositoryTest.java @@ -8,6 +8,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; @@ -15,20 +17,27 @@ @SpringBootTest class AuthorRepositoryTest { - @Autowired - private BookRepository bookRepository; - @Autowired private AuthorRepository authorRepository; - private Author dummyAuthor; - private Book dummyBook; + private List dummyListAuthor; + private List dummyListBook; @BeforeEach void setUp() { - dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); - dummyAuthor = new Author("Gene Kim", "g.kim@gmail.com", dummyBook); - authorRepository.save(dummyAuthor); + dummyListBook = new ArrayList<>(); + dummyListBook.add(new Book("978-84-415-4301-0", "The unicorn project", "novel", 1)); + dummyListBook.add(new Book("978-84-415-4301-1", "Siddarta", "novel",3)); + dummyListBook.add(new Book("978-84-415-4301-2","La condesa sangrienta", "novel", 10)); + dummyListBook.add(new Book("978-84-415-4301-3","Sherlock Holmes","crime",1 )); + + dummyListAuthor = new ArrayList<>(); + dummyListAuthor.add(new Author("Gene Kim", "g.kim@gmail.com", dummyListBook.get(0))); + dummyListAuthor.add(new Author("Herman Hesse", "h.hesse@gmail.com",dummyListBook.get(1))); + dummyListAuthor.add(new Author("Alejandra Pizarnik", "alejandra.pizarnik@gmail.com",dummyListBook.get(2))); + dummyListAuthor.add(new Author("Arthur Conan Doyle","a.c.doyle@mail.com", dummyListBook.get(3))); + + authorRepository.saveAll(dummyListAuthor); } @AfterEach @@ -55,8 +64,36 @@ void shouldReturnEmptyIfWeWantToFindABookByAuthorThatNotExist(){ } @Test - void getAllBookWithAuthor(){ + void getAllBooksWithAuthor(){ + List listObject = new ArrayList<>(); + + Optional> getBooks = authorRepository.findAllBooksWithAuthors(); + if(getBooks.isPresent()){ + listObject = getBooks.get(); + } + assertEquals(4, listObject.size()); + } + + @Test + void allBookAuthorsAreCorrect(){ + List listObject = new ArrayList<>(); + List listAuthor = new ArrayList<>(); + + Optional> getBooks = authorRepository.findAllBooksWithAuthors(); + + if(getBooks.isPresent()){ + listObject = getBooks.get(); + } + for( Object[] a : listObject){ + listAuthor.add((Author) a[1]); + } + + assertEquals("Gene Kim", listAuthor.get(0).getName()); + assertEquals("Herman Hesse", listAuthor.get(1).getName()); + assertEquals("Alejandra Pizarnik", listAuthor.get(2).getName()); + assertEquals("Arthur Conan Doyle", listAuthor.get(3).getName()); } + } \ No newline at end of file From ccec24b9672ba71c7c3094bb02cc82289f2df058 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Thu, 4 Apr 2024 23:44:15 +0200 Subject: [PATCH 077/112] date formatter and data output test classes --- .../com/ironhack/ironLibrary/model/Issue.java | 23 +++- .../ironLibrary/utils/DataOutput.java | 67 ++++++++++ .../ironLibrary/utils/DateFormatter.java | 22 ++++ .../ironhack/ironLibrary/model/IssueTest.java | 8 +- .../ironLibrary/utils/DataOutputTest.java | 123 ++++++++++++++++++ .../ironLibrary/utils/DateFormatterTest.java | 29 +++++ 6 files changed, 261 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/DateFormatter.java create mode 100644 src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java create mode 100644 src/test/java/com/ironhack/ironLibrary/utils/DateFormatterTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/model/Issue.java b/src/main/java/com/ironhack/ironLibrary/model/Issue.java index 64bd6817..ea0e28b5 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Issue.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Issue.java @@ -3,6 +3,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.*; import lombok.*; + +import java.time.LocalDateTime; + @Entity @Table(name = "issue") @Data @@ -12,8 +15,14 @@ public class Issue { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer issueId; - private String issueDate; - private String returnDate; + + @Setter(AccessLevel.NONE) + private LocalDateTime issueDate; + + @Setter(AccessLevel.NONE) + private LocalDateTime returnDate; + + //"2024-04-04 12:30:45". @OneToOne @JoinColumn(name = "usn") private Student issueStudent; @@ -21,10 +30,10 @@ public class Issue { @JoinColumn(name = "isbn") private Book issueBook; - public Issue(String issueDate, String returnDate, Student issueStudent, Book issueBook) { - this.issueDate = issueDate; - this.returnDate = returnDate; - this.issueStudent = issueStudent; - this.issueBook = issueBook; + public Issue(Student issueStudent, Book issueBook) { + this.issueDate = LocalDateTime.now(); + this.returnDate = issueDate.plusDays(7); + setIssueStudent(issueStudent); + setIssueBook(issueBook); } } diff --git a/src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java b/src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java new file mode 100644 index 00000000..6dc86c26 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java @@ -0,0 +1,67 @@ +package com.ironhack.ironLibrary.utils; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import com.ironhack.ironLibrary.model.Student; +import de.vandermeer.asciithemes.TA_GridThemes; +import de.vandermeer.skb.interfaces.transformers.textformat.TextAlignment; +import de.vandermeer.asciitable.AsciiTable; + +import java.util.List; + +public class DataOutput { + + private static AsciiTable createAsciiTable(){ + AsciiTable asciiTable = new AsciiTable(); + asciiTable.getContext().setGridTheme(TA_GridThemes.NONE); + asciiTable.setTextAlignment(TextAlignment.LEFT); + return asciiTable; + } + public static String oneBookTable(Book book){ + AsciiTable asciiTable = createAsciiTable(); + asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books"); + asciiTable.addRow(book.getIsbn(), book.getTitle(), book.getCategory(), book.getQuantity()); + return asciiTable.render(); + } + + public static String listBookTable(List books){ + AsciiTable asciiTable = createAsciiTable(); + asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books"); + for (Book book : books){ + asciiTable.addRow(book.getIsbn(), book.getTitle(), book.getCategory(), book.getQuantity()); + } + return asciiTable.render(); + } + + public static String listBookTableWithAuthor(List lstObjects){ + AsciiTable asciiTable = createAsciiTable(); + asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books", + "Author name", "Author mail"); + for (Object[] obj : lstObjects){ + Book book = (Book) obj[0]; + Author author = (Author) obj[1]; + asciiTable.addRow(book.getIsbn(), book.getTitle(), book.getCategory(), book.getQuantity(), + author.getName(), author.getEmail()); + } + return asciiTable.render(); + } + + public static String bookIssuedDate(Issue issue){ + return "Book issued. Return date : " + DateFormatter.largeDateFormat(issue.getReturnDate()); + } + + //TODO: check this method - check inputs? + public static String listBookTableByUsn(List lstObjects){ + AsciiTable asciiTable = createAsciiTable(); + asciiTable.addRow("Book Title", "Student Name", "Return date"); + for (Object[] obj : lstObjects){ + Book book = (Book) obj[0]; + Student student = (Student) obj[1]; + Issue issue = (Issue) obj[2]; + asciiTable.addRow(book.getTitle(), student.getName(), + DateFormatter.simpleDateFormat(issue.getReturnDate())); + } + return asciiTable.render(); + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/utils/DateFormatter.java b/src/main/java/com/ironhack/ironLibrary/utils/DateFormatter.java new file mode 100644 index 00000000..02bc8039 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/DateFormatter.java @@ -0,0 +1,22 @@ +package com.ironhack.ironLibrary.utils; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + +public class DateFormatter { + + public static String simpleDateFormat(LocalDateTime returnDate){ + DateTimeFormatter formatDate1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return returnDate.format(formatDate1); + } + + public static String largeDateFormat(LocalDateTime returnDate){ + DateTimeFormatter formatDate2 = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", + Locale.ENGLISH); + ZonedDateTime zonedDateTime = returnDate.atZone(ZoneId.of("Europe/Helsinki")); + return zonedDateTime.format(formatDate2); + } +} diff --git a/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java b/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java index 9f3182a4..6ab7daae 100644 --- a/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java +++ b/src/test/java/com/ironhack/ironLibrary/model/IssueTest.java @@ -12,14 +12,14 @@ public void createIssue(){ Student student = new Student(1, "Carlos"); Book book = new Book(); Issue IssueOne = new Issue(); - Issue IssueTwo = new Issue("17/03/2024", "24/03/2024", student, book); + Issue IssueTwo = new Issue(student, book); assertNotNull(IssueOne); assertNotNull(IssueTwo); - assertEquals("17/03/2024", IssueTwo.getIssueDate()); - assertEquals("24/03/2024", IssueTwo.getReturnDate()); + assertNotNull(IssueTwo.getIssueDate()); + assertNotNull(IssueTwo.getReturnDate()); + assertNotNull(IssueTwo); assertEquals(student, IssueTwo.getIssueStudent()); assertEquals(book, IssueTwo.getIssueBook()); } - } \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java b/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java new file mode 100644 index 00000000..2af82bff --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java @@ -0,0 +1,123 @@ +package com.ironhack.ironLibrary.utils; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import com.ironhack.ironLibrary.model.Student; +import de.vandermeer.asciitable.AsciiTable; +import de.vandermeer.asciithemes.TA_GridThemes; +import de.vandermeer.skb.interfaces.transformers.textformat.TextAlignment; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DataOutputTest { + + private static Book book1; + private static Book book2; + private static List books; + + private static Author author1; + private static Author author2; + + private static Student student1; + private static Student student2; + + private static Issue issue1; + private static Issue issue2; + + + @BeforeAll + static void setUp(){ + book1 = new Book("978-92-95-055-02-1", "First title", "romance", 3); + book2 = new Book("978-92-95-055-02-2", "Second title", "terror", 5); + books = new ArrayList<>(); + books.add(book1); + books.add(book2); + + author1 = new Author("Author first", "author@email.com", book1); + author2 = new Author("Author second", "author2@email.com", book2); + + student1 = new Student(1, "First student"); + student2 = new Student(2, "Second student"); + + issue1 = new Issue(student1, book1); + issue2 = new Issue(student2, book2); + + } + + + @Test + @DisplayName("Validate oneBookTable output") + void oneBookTableTest(){ + AsciiTable asciiTable = new AsciiTable(); + asciiTable.getContext().setGridTheme(TA_GridThemes.NONE); + asciiTable.setTextAlignment(TextAlignment.LEFT); + asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books"); + asciiTable.addRow(book1.getIsbn(), book1.getTitle(), book1.getCategory(), book1.getQuantity()); + + assertEquals(asciiTable.render(), DataOutput.oneBookTable(book1)); + } + + @Test + @DisplayName("Validate listBookTable output") + void listBookTableTest(){ + AsciiTable asciiTable = new AsciiTable(); + asciiTable.getContext().setGridTheme(TA_GridThemes.NONE); + asciiTable.setTextAlignment(TextAlignment.LEFT); + asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books"); + for (Book book : books){ + asciiTable.addRow(book.getIsbn(), book.getTitle(), book.getCategory(), book.getQuantity()); + } + assertEquals(asciiTable.render(), DataOutput.listBookTable(books)); + } + + @Test + @DisplayName("Validate listBookTable output with empty list") + void listBookTableEmptyListTest(){ + AsciiTable asciiTable = new AsciiTable(); + asciiTable.getContext().setGridTheme(TA_GridThemes.NONE); + asciiTable.setTextAlignment(TextAlignment.LEFT); + List noneBooks = new ArrayList<>(); + asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books"); + assertEquals(asciiTable.render(), DataOutput.listBookTable(noneBooks)); + } + + @Test + @DisplayName("Validate listBookTableWithAuthor output") + void listBookTableWithAuthorTest(){ + + List lstObjects= new ArrayList<>(); + lstObjects.add(new Object[]{book1, author1}); + lstObjects.add(new Object[]{book2, author2}); + + AsciiTable asciiTable = new AsciiTable(); + asciiTable.getContext().setGridTheme(TA_GridThemes.NONE); + asciiTable.setTextAlignment(TextAlignment.LEFT); + asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books", + "Author name", "Author mail"); + for (Object[] obj : lstObjects){ + Book book = (Book) obj[0]; + Author author = (Author) obj[1]; + asciiTable.addRow(book.getIsbn(), book.getTitle(), book.getCategory(), book.getQuantity(), + author.getName(), author.getEmail()); + } + assertEquals(asciiTable.render(), DataOutput.listBookTableWithAuthor(lstObjects)); + } + + @Test + @DisplayName("Validate bookIssuedDate output") + void bookIssuedDateTest(){ + assertEquals("Book issued. Return date : " + DateFormatter.largeDateFormat(issue1.getReturnDate()), + DataOutput.bookIssuedDate(issue1)); + } + + //TODO: test Validate listBookTableByUsn + + +} diff --git a/src/test/java/com/ironhack/ironLibrary/utils/DateFormatterTest.java b/src/test/java/com/ironhack/ironLibrary/utils/DateFormatterTest.java new file mode 100644 index 00000000..0d8bfad9 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/utils/DateFormatterTest.java @@ -0,0 +1,29 @@ +package com.ironhack.ironLibrary.utils; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Locale; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DateFormatterTest { + @Test + @DisplayName("Validate proper format date: yyyy-MM-dd HH:mm:ss") + void simpleDateFormatTest() { + LocalDateTime time = LocalDateTime.now(); + assertEquals(time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), + DateFormatter.simpleDateFormat(time)); + } + + @Test + @DisplayName("Validate proper format date: EEE MMM dd HH:mm:ss zzz yyyy") + void largeDateFormatTest() { + LocalDateTime time = LocalDateTime.now(); + DateTimeFormatter formatDate = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", + Locale.ENGLISH); + assertEquals(time.atZone(ZoneId.of("Europe/Helsinki")).format(formatDate), + DateFormatter.largeDateFormat(time)); + } +} From a136591de3102c5fbf7577fb97abc480f49a46c7 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Fri, 5 Apr 2024 00:01:19 +0200 Subject: [PATCH 078/112] Menu service implementation and command runner --- .../ironLibrary/IronLibraryApplication.java | 16 +++- .../repository/BookRepository.java | 2 + .../service/AuthorServiceImpl.java | 18 ++++ .../ironLibrary/service/BookServiceImpl.java | 24 ++++++ .../ironLibrary/service/IAuthorService.java | 6 ++ .../ironLibrary/service/IBookService.java | 8 ++ .../ironLibrary/service/IMenuService.java | 6 ++ .../ironLibrary/service/MenuServiceImpl.java | 85 +++++++++++++++++++ .../ironhack/ironLibrary/utils/Validator.java | 49 +++++++++++ .../repository/BookRepositoryTest.java | 12 +++ .../service/AuthorServiceImplTest.java | 58 +++++++++++++ .../service/BookServiceImplTest.java | 57 +++++++++++++ 12 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IBookService.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IMenuService.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java create mode 100644 src/test/java/com/ironhack/ironLibrary/service/AuthorServiceImplTest.java create mode 100644 src/test/java/com/ironhack/ironLibrary/service/BookServiceImplTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index 616b022f..25bdb284 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -1,17 +1,29 @@ package com.ironhack.ironLibrary; -import com.ironhack.ironLibrary.utils.Validator; +import com.ironhack.ironLibrary.service.IMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import java.util.List; + @SpringBootApplication -public class IronLibraryApplication { +public class IronLibraryApplication implements CommandLineRunner { + @Autowired + IMenuService menuService; public static void main(String[] args) { SpringApplication.run(IronLibraryApplication.class, args ); } + @Override + public void run(String... args) throws Exception { + List bookAndAuthorInformation = menuService.getNewBookInformation(); + menuService.addBook(bookAndAuthorInformation); + } + } diff --git a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java index 5712fbf5..c997a9d7 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java @@ -11,4 +11,6 @@ public interface BookRepository extends JpaRepository { Optional> findAllByCategory(String Category); Optional findOneByTitle(String Title); + + Optional findByIsbn(String isbn); } diff --git a/src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java new file mode 100644 index 00000000..7221e7a9 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java @@ -0,0 +1,18 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.repository.AuthorRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class AuthorServiceImpl implements IAuthorService{ + + @Autowired + private AuthorRepository authorRepository; + + @Override + public Author save(Author author) { + return authorRepository.save(author); + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java new file mode 100644 index 00000000..ba0c02ba --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java @@ -0,0 +1,24 @@ +package com.ironhack.ironLibrary.service; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.repository.BookRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class BookServiceImpl implements IBookService{ + + @Autowired + private BookRepository bookRepository; + + @Override + public Book save(Book book) { + return bookRepository.save(book); + } + + @Override + public Optional findByIsbn(String isbn) { + return bookRepository.findByIsbn(isbn); + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java b/src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java new file mode 100644 index 00000000..cd729f51 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java @@ -0,0 +1,6 @@ +package com.ironhack.ironLibrary.service; +import com.ironhack.ironLibrary.model.Author; + +public interface IAuthorService { + Author save (Author author); +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IBookService.java b/src/main/java/com/ironhack/ironLibrary/service/IBookService.java new file mode 100644 index 00000000..64ca8cae --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IBookService.java @@ -0,0 +1,8 @@ +package com.ironhack.ironLibrary.service; +import com.ironhack.ironLibrary.model.Book; + +import java.util.Optional; +public interface IBookService { + Book save (Book book); + Optional findByIsbn(String isbn); +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java new file mode 100644 index 00000000..e5a7b6c9 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -0,0 +1,6 @@ +package com.ironhack.ironLibrary.service; +import java.util.List; +public interface IMenuService { + void addBook (List bookAndAuthorInformation); + List getNewBookInformation(); +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java new file mode 100644 index 00000000..aed3b917 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -0,0 +1,85 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; +import org.springframework.beans.factory.annotation.Autowired; + + + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import com.ironhack.ironLibrary.utils.Validator; +import org.springframework.stereotype.Service; + +@Service +public class MenuServiceImpl implements IMenuService{ + + @Autowired + private IAuthorService authorService; + @Autowired + private IBookService bookService; + + /** + * TODO Testing + * @return + */ + public List getNewBookInformation(){ + + List bookAndAuthorDetails = new ArrayList<>(); + + String isbn = Validator.userInput("Enter isbn: ",true, "checkISBNFormat", + "The ISBN must follow the next format: 978-92-95055-02-5"); + bookAndAuthorDetails.add(isbn); + String title = Validator.userInput("Enter title: ", false, "NULL", "NULL"); + bookAndAuthorDetails.add(title); + String category = Validator.userInput("Enter category: ", true, "validateStringGeneralFormat", + "The category only accepts letters"); + bookAndAuthorDetails.add(category); + String authorName = Validator.userInput("Enter author name: ", true, "validateStringGeneralFormat", + "The author name only accepts letters"); + bookAndAuthorDetails.add(authorName); + String email = Validator.userInput("Enter author email: ", true, "checkEmailFormat", + "The email must contains an @ and a . "); + bookAndAuthorDetails.add(email); + String quantity = Validator.userInput("Enter number of books: ", true, "validateInteger", + "The quantity only accepts numbers"); + bookAndAuthorDetails.add(quantity); + + return bookAndAuthorDetails; + } + + /** + * TODO Testing + * @param bookAndAuthorInformation + */ + + public void addBook(List bookAndAuthorInformation) { + + String isbn = bookAndAuthorInformation.get(0); + String title = bookAndAuthorInformation.get(1); + String category = bookAndAuthorInformation.get(2); + String authorName = bookAndAuthorInformation.get(3); + String email = bookAndAuthorInformation.get(4); + int quantity = Integer.parseInt(bookAndAuthorInformation.get(5)); + + Book newBook = new Book(isbn, title, category, quantity); + Author author = new Author(); + author.setName(authorName); + author.setEmail(email); + author.setAuthorBook(newBook); + + Optional optionalBook = bookService.findByIsbn(isbn); + + if(optionalBook.isPresent()){ + Book book = optionalBook.get(); + book.setCategory(category); + book.setQuantity(quantity); + book.setTitle(title); + bookService.save(book); + }else{ + authorService.save(author); + bookService.save(newBook); + } + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java index 7f243c6a..bd074294 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -1,6 +1,7 @@ package com.ironhack.ironLibrary.utils; +import java.util.Scanner; import java.util.regex.Pattern; public class Validator { @@ -40,6 +41,54 @@ public static boolean notBlankValidatorBooks(String input) { public static boolean validateStringGeneralFormat(String input) { return input != null && !input.isEmpty() && patternMatches(input, "^[a-zA-ZÀ-ÿ\\s]*$"); } + + /** + * TODO Testing + * @param printText + * @param validTheNextInput + * @param methodName + * @param suggestedInputFormat + * @return + */ + public static String userInput(String printText, boolean validTheNextInput, String methodName, String suggestedInputFormat){ + String userInputText; + boolean result = false; + do{ + System.out.print(printText); + Scanner scanner = new Scanner(System.in); + userInputText = scanner.nextLine(); + if(validTheNextInput){ + try{ + switch(methodName){ + case "checkISBNFormat": + result = Validator.checkISBNFormat(userInputText); + break; + case "validateStringGeneralFormat": + result = Validator.validateStringGeneralFormat(userInputText); + break; + case "checkEmailFormat": + result = Validator.checkEmailFormat(userInputText); + break; + case "validateInteger": + result = Validator.validateInteger(userInputText); + break; + case "notBlankValidatorBooks": + result = Validator.notBlankValidatorBooks(userInputText); + break; + } + if(!result){ + System.out.println("Sorry, but the input format it's incorrect. Please try again: "); + System.out.println(suggestedInputFormat); + } + }catch (Exception e) { + e.printStackTrace(); + } + }else{ + result = true; + } + }while(!result); + return userInputText; + }; } diff --git a/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java index ccdc3b34..09b9fdd0 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/BookRepositoryTest.java @@ -99,4 +99,16 @@ void shouldGetFalseIfWeFindTheWrongTitleUsingFindOneByTitle() { Optional maybeBook = bookRepository.findOneByTitle("The unicorn project"); maybeBook.ifPresent(book -> assertNotEquals("The fenix project", book.getTitle())); } + + @Test + void testFindByIsbn_HappyPath(){ + Optional maybeBook = bookRepository.findByIsbn("978-84-415-4301-0"); + maybeBook.ifPresent(book -> assertEquals("The unicorn project", book.getTitle())); + } + + @Test + void testFindByIsbn_NegativePath_NonISBNRegisteredOnDataBase(){ + Optional optionalBook = bookRepository.findByIsbn("978-84-415-4301-1"); + assertTrue(optionalBook.isEmpty(), "Expected Optional to be empty"); + } } \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/service/AuthorServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/AuthorServiceImplTest.java new file mode 100644 index 00000000..7c3a3706 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/service/AuthorServiceImplTest.java @@ -0,0 +1,58 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.repository.AuthorRepository; +import com.ironhack.ironLibrary.repository.BookRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class AuthorServiceImplTest { + + @Autowired + private AuthorRepository authorRepository; + @Autowired + private BookRepository bookRepository; + + @Autowired + private IAuthorService authorService; + + private Author dummyAuthor, dummyAuthor2; + private Book dummyBook, dummyBook2; + + @BeforeEach + void setUp() { + dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + dummyAuthor = new Author("Gene Kim", "g.kim@gmail.com", dummyBook); + dummyBook2 = new Book("978-84-415-4301-1", "The unicorn project II", "novel", 1); + dummyAuthor2 = new Author("Gene Kim2", "g.kim@gmail.com", dummyBook2); + authorRepository.save(dummyAuthor); + authorService.save(dummyAuthor2); + } + + @AfterEach + void tearDown() { + authorRepository.deleteAll(); + } + + @Test + void validateSameBehaviorUsingRepositoryOrServiceClass(){ + List authorList = authorRepository.findAll(); + + Author author1 = authorList.get(0); + Author author2 = authorList.get(1); + + assertNotEquals(author1, author2); + } + + +} \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/service/BookServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/BookServiceImplTest.java new file mode 100644 index 00000000..dd9d9104 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/service/BookServiceImplTest.java @@ -0,0 +1,57 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.repository.AuthorRepository; +import com.ironhack.ironLibrary.repository.BookRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +@SpringBootTest +class BookServiceImplTest { + + @Autowired + private AuthorRepository authorRepository; + @Autowired + private BookRepository bookRepository; + + @Autowired + private IAuthorService authorService; + + @Autowired + private IBookService bookService; + + private Author dummyAuthor, dummyAuthor2; + private Book dummyBook, dummyBook2; + + @BeforeEach + void setUp() { + dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + dummyAuthor = new Author("Gene Kim", "g.kim@gmail.com", dummyBook); + dummyBook2 = new Book("978-84-415-4301-1", "The unicorn project II", "novel", 1); + dummyAuthor2 = new Author("Gene Kim2", "g.kim@gmail.com", dummyBook2); + authorRepository.save(dummyAuthor); + authorService.save(dummyAuthor2); + } + + @AfterEach + void tearDown() { + authorRepository.deleteAll(); + } + + @Test + void validateSameBehaviorUsingRepositoryOrServiceClass(){ + + Book book1 = bookService.findByIsbn("978-84-415-4301-0").get(); + Book book2 = bookService.findByIsbn("978-84-415-4301-1").get(); + + assertNotEquals(book1, book2); + } + + +} From c1665f67bce6a3f6428a7400d32019e3f002a712 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Fri, 5 Apr 2024 00:02:20 +0200 Subject: [PATCH 079/112] issue repo and pom adding table ascii dependency --- pom.xml | 5 ++ .../repository/IssueRepositoryTest.java | 81 +++++++++---------- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/pom.xml b/pom.xml index 5d86ed43..db9b4301 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,11 @@ 5.10.2 test + + de.vandermeer + asciitable + 0.3.2 + diff --git a/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java index 44381666..4b3f2038 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java @@ -27,13 +27,10 @@ class IssueRepositoryTest { private Book dummyBook; private Book dummyBook2; private Student dummyStudent; - private Student dummyStudent2; - private Issue dummyIssue; private Issue dummyIssue2; - @BeforeEach void setUp() { Issue issue = new Issue(); @@ -44,52 +41,48 @@ void setUp() { dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); dummyBook2 = new Book("978-84-415-4302-0", "The fenix project", "novel", 1); bookRepository.saveAll(List.of(dummyBook, dummyBook2)); - - dummyIssue = new Issue("03/04/2024", "10/04/2024", dummyStudent, dummyBook); -// dummyIssue2 = new Issue("10/04/2024", "20/04/2024",dummyStudent, dummyBook2); -// issueRepository.saveAll(List.of(dummyIssue, dummyIssue2)); + + dummyIssue = new Issue(dummyStudent, dummyBook); issueRepository.save(issue); } - @AfterEach - void tearDown() { - issueRepository.deleteAll(); - bookRepository.deleteAll(); - studentRepository.deleteAll(); - - } - - @Test - void shouldFindOneBookIdWeUseFindAllBooksByUsn() { - issueRepository.save(dummyIssue); - Optional> maybeListOfBooksIssued = issueRepository.findAllBooksByUsn(dummyStudent.getUsn()); - if (maybeListOfBooksIssued.isPresent()) { - List listOfBooksIssued = maybeListOfBooksIssued.get(); - assertEquals(1, listOfBooksIssued.size()); - } - } + @AfterEach + void tearDown() { + issueRepository.deleteAll(); + bookRepository.deleteAll(); + studentRepository.deleteAll(); + } - @Test - void shouldNotFindAnyBookIdWeUseFindAllBooksByUsn() { - Optional> maybeListOfBooksIssued = issueRepository.findAllBooksByUsn(dummyStudent2.getUsn()); - if (maybeListOfBooksIssued.isPresent()) { - List listOfBooksIssued = maybeListOfBooksIssued.get(); - assertEquals(0, listOfBooksIssued.size()); - } - } + @Test + void shouldFindOneBookIdWeUseFindAllBooksByUsn() { + issueRepository.save(dummyIssue); + Optional> maybeListOfBooksIssued = issueRepository.findAllBooksByUsn(dummyStudent.getUsn()); + if (maybeListOfBooksIssued.isPresent()) { + List listOfBooksIssued = maybeListOfBooksIssued.get(); + assertEquals(1, listOfBooksIssued.size()); + } + } - @Test - void saveItemTest() { - assertEquals(1, issueRepository.count()); - } + @Test + void shouldNotFindAnyBookIdWeUseFindAllBooksByUsn() { + Optional> maybeListOfBooksIssued = issueRepository.findAllBooksByUsn(dummyStudent2.getUsn()); + if (maybeListOfBooksIssued.isPresent()) { + List listOfBooksIssued = maybeListOfBooksIssued.get(); + assertEquals(0, listOfBooksIssued.size()); + } + } - @Test - void deleteItemTest() { - Optional firstIssue = issueRepository.findAll().stream().findFirst(); - assertTrue(firstIssue.isPresent()); - issueRepository.delete(firstIssue.get()); - assertEquals(0, issueRepository.count()); - } + @Test + void saveItemTest() { + assertEquals(1, issueRepository.count()); + } - } + @Test + void deleteItemTest() { + Optional firstIssue = issueRepository.findAll().stream().findFirst(); + assertTrue(firstIssue.isPresent()); + issueRepository.delete(firstIssue.get()); + assertEquals(0, issueRepository.count()); + } +} From 442c27ede21802462436ee4c34b6817c314d032a Mon Sep 17 00:00:00 2001 From: esmartdie Date: Fri, 5 Apr 2024 00:09:56 +0200 Subject: [PATCH 080/112] deleting command runner changes --- .../ironhack/ironLibrary/IronLibraryApplication.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index 25bdb284..0e4771d4 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -9,21 +9,13 @@ import java.util.List; @SpringBootApplication -public class IronLibraryApplication implements CommandLineRunner { - - @Autowired - IMenuService menuService; +public class IronLibraryApplication { + public static void main(String[] args) { SpringApplication.run(IronLibraryApplication.class, args ); } - @Override - public void run(String... args) throws Exception { - List bookAndAuthorInformation = menuService.getNewBookInformation(); - menuService.addBook(bookAndAuthorInformation); - } - } From 32d57cd609d91c1e3d610d671731be410c81265f Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Fri, 5 Apr 2024 00:12:29 +0200 Subject: [PATCH 081/112] solve errors --- src/main/java/com/ironhack/ironLibrary/model/Issue.java | 1 - .../java/com/ironhack/ironLibrary/utils/DataOutputTest.java | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/model/Issue.java b/src/main/java/com/ironhack/ironLibrary/model/Issue.java index ea0e28b5..ef31d519 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Issue.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Issue.java @@ -22,7 +22,6 @@ public class Issue { @Setter(AccessLevel.NONE) private LocalDateTime returnDate; - //"2024-04-04 12:30:45". @OneToOne @JoinColumn(name = "usn") private Student issueStudent; diff --git a/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java b/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java index 2af82bff..5345b500 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java @@ -43,8 +43,8 @@ static void setUp(){ author1 = new Author("Author first", "author@email.com", book1); author2 = new Author("Author second", "author2@email.com", book2); - student1 = new Student(1, "First student"); - student2 = new Student(2, "Second student"); + student1 = new Student("01", "First student"); + student2 = new Student("02", "Second student"); issue1 = new Issue(student1, book1); issue2 = new Issue(student2, book2); From a0094ea70ff461e7671a56552a5cefaa0bac43e7 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 6 Apr 2024 09:29:02 +0200 Subject: [PATCH 082/112] vf --- .../java/com/ironhack/ironLibrary/IronLibraryApplication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index 0e4771d4..42c4e85f 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -10,7 +10,7 @@ @SpringBootApplication public class IronLibraryApplication { - + public static void main(String[] args) { SpringApplication.run(IronLibraryApplication.class, args ); From e1f2f1a850b079e92c1ad5b76a664386fab679bc Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 6 Apr 2024 10:42:29 +0200 Subject: [PATCH 083/112] addBook feature basic test added --- .../repository/AuthorRepository.java | 3 + .../service/AuthorServiceImpl.java | 19 +++ .../ironLibrary/service/BookServiceImpl.java | 11 ++ .../ironLibrary/service/IAuthorService.java | 8 ++ .../ironLibrary/service/IBookService.java | 4 + .../ironLibrary/service/MenuServiceImpl.java | 29 +++-- .../InvalidBookInformationException.java | 7 ++ .../service/MenuServiceImplTest.java | 116 ++++++++++++++++++ 8 files changed, 188 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java create mode 100644 src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java index f78f3771..82a05332 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/AuthorRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import javax.swing.text.html.Option; import java.util.List; import java.util.Optional; @@ -18,6 +19,8 @@ public interface AuthorRepository extends JpaRepository { @Query("SELECT b,a FROM Author a JOIN Book b ON a.authorBook = b") Optional > findAllBooksWithAuthors(); + Optional findByAuthorBook(Book book); + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java index 7221e7a9..7a92bf4b 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/AuthorServiceImpl.java @@ -1,10 +1,14 @@ package com.ironhack.ironLibrary.service; import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; import com.ironhack.ironLibrary.repository.AuthorRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Optional; + @Service public class AuthorServiceImpl implements IAuthorService{ @@ -15,4 +19,19 @@ public class AuthorServiceImpl implements IAuthorService{ public Author save(Author author) { return authorRepository.save(author); } + + @Override + public Optional findBookByAuthor(String authorName) { + return authorRepository.findBookByAuthor(authorName); + } + + @Override + public Optional> findAllBooksWithAuthors() { + return authorRepository.findAllBooksWithAuthors(); + } + + @Override + public Optional findByAuthorBook(Book book) { + return authorRepository.findByAuthorBook(book); + } } diff --git a/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java index ba0c02ba..87ecb72b 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; import java.util.Optional; @Service @@ -21,4 +22,14 @@ public Book save(Book book) { public Optional findByIsbn(String isbn) { return bookRepository.findByIsbn(isbn); } + + @Override + public Optional> findAllByCategory(String category) { + return bookRepository.findAllByCategory(category); + } + + @Override + public Optional findOneByTitle(String title) { + return bookRepository.findOneByTitle(title); + } } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java b/src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java index cd729f51..fec9fc70 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IAuthorService.java @@ -1,6 +1,14 @@ package com.ironhack.ironLibrary.service; import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; + +import java.util.List; +import java.util.Optional; public interface IAuthorService { Author save (Author author); + Optional findBookByAuthor(String authorName); + Optional > findAllBooksWithAuthors(); + + Optional findByAuthorBook(Book book); } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IBookService.java b/src/main/java/com/ironhack/ironLibrary/service/IBookService.java index 64ca8cae..607c5c84 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IBookService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IBookService.java @@ -1,8 +1,12 @@ package com.ironhack.ironLibrary.service; import com.ironhack.ironLibrary.model.Book; +import java.util.List; import java.util.Optional; public interface IBookService { Book save (Book book); Optional findByIsbn(String isbn); + Optional> findAllByCategory(String Category); + Optional findOneByTitle(String Title); + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index aed3b917..d7928954 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -2,6 +2,7 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.utils.InvalidBookInformationException; import org.springframework.beans.factory.annotation.Autowired; @@ -49,25 +50,33 @@ public List getNewBookInformation(){ return bookAndAuthorDetails; } - /** - * TODO Testing - * @param bookAndAuthorInformation - */ public void addBook(List bookAndAuthorInformation) { + if (bookAndAuthorInformation.size() != 6) { + throw new InvalidBookInformationException( + "The book and author information must be a six-element string list."); + } + String isbn = bookAndAuthorInformation.get(0); String title = bookAndAuthorInformation.get(1); String category = bookAndAuthorInformation.get(2); String authorName = bookAndAuthorInformation.get(3); String email = bookAndAuthorInformation.get(4); - int quantity = Integer.parseInt(bookAndAuthorInformation.get(5)); + String quantityStr = bookAndAuthorInformation.get(5); + + if (!Validator.checkISBNFormat(isbn) || + !Validator.validateStringGeneralFormat(category) || + !Validator.validateStringGeneralFormat(authorName) || + !Validator.checkEmailFormat(email) || + !Validator.validateInteger(quantityStr)) { + throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); + } + + int quantity = Integer.parseInt(quantityStr); Book newBook = new Book(isbn, title, category, quantity); - Author author = new Author(); - author.setName(authorName); - author.setEmail(email); - author.setAuthorBook(newBook); + Author author = new Author(authorName, email, newBook); Optional optionalBook = bookService.findByIsbn(isbn); @@ -83,3 +92,5 @@ public void addBook(List bookAndAuthorInformation) { } } } + + diff --git a/src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java b/src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java new file mode 100644 index 00000000..b6e65e4b --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java @@ -0,0 +1,7 @@ +package com.ironhack.ironLibrary.utils; + +public class InvalidBookInformationException extends RuntimeException{ + public InvalidBookInformationException(String message) { + super(message); + } +} diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java new file mode 100644 index 00000000..ef21e797 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -0,0 +1,116 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Author; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.utils.InvalidBookInformationException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class MenuServiceImplTest { + + @Autowired + private IBookService bookService; + + @Autowired + private IAuthorService authorService; + + @Autowired + private IMenuService menuService; + + @Test + public void testAddBookWithValidInformation() { + List validInformation = Arrays.asList( + "978-84-415-4302-0", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + + assertDoesNotThrow(() -> menuService.addBook(validInformation)); + + } + + @Test + public void testAddBookWithInvalidInformation() { + List invalidInformation = Arrays.asList( + "XXX-YYY-JJJ", + "1 Book", + "Fiction", + "Superm@n", + "my mail", + "hey" + ); + + InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, + () -> menuService.addBook(invalidInformation)); + assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); + } + + @Test + public void testAddBookWithIncompleteInformation() { + List incompleteInformation = Arrays.asList( + "978-84-415-4302-0", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com" + ); + + InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, + () -> menuService.addBook(incompleteInformation)); + assertEquals("The book and author information must be a six-element string list.", exception.getMessage()); + } + @Test + public void testAddBookWithExtraInformation() { + List incompleteInformation = Arrays.asList( + "978-84-415-4302-0", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10", + "10" + ); + + InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, + () -> menuService.addBook(incompleteInformation)); + assertEquals("The book and author information must be a six-element string list.", exception.getMessage()); + } + + @Test + public void testAddBookSaveAndFindByIsbn() { + List validInformation = Arrays.asList( + "978-84-415-4302-0", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + + assertDoesNotThrow(() -> menuService.addBook(validInformation)); + + Book savedBook = bookService.findByIsbn("978-84-415-4302-0").orElse(null); + assertNotNull(savedBook); + assertEquals("978-84-415-4302-0", savedBook.getIsbn()); + assertEquals("The fenix project", savedBook.getTitle()); + assertEquals("novel", savedBook.getCategory()); + assertEquals(10, savedBook.getQuantity()); + + + Author savedAuthor = authorService.findByAuthorBook(savedBook).get(); + assertNotNull(savedAuthor); + assertEquals("Gene Kim", savedAuthor.getName()); + assertEquals("g.kim@gmail.com", savedAuthor.getEmail()); + } + +} \ No newline at end of file From 33c62868a9aa02bf24948ab7397b07cf4b284c16 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 6 Apr 2024 10:48:53 +0200 Subject: [PATCH 084/112] adding after each on menuService test --- .../ironLibrary/service/MenuServiceImplTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index ef21e797..de4de00f 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -2,7 +2,9 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.repository.AuthorRepository; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -24,6 +26,10 @@ class MenuServiceImplTest { @Autowired private IMenuService menuService; + @Autowired + private AuthorRepository authorRepository; + + @Test public void testAddBookWithValidInformation() { List validInformation = Arrays.asList( @@ -113,4 +119,9 @@ public void testAddBookSaveAndFindByIsbn() { assertEquals("g.kim@gmail.com", savedAuthor.getEmail()); } + @AfterEach + void tearDown() { + authorRepository.deleteAll(); + } + } \ No newline at end of file From 2b41bb154c21ded4fc0132bbf8f449c938ce6358 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 6 Apr 2024 11:28:31 +0200 Subject: [PATCH 085/112] add userInput valid isbn test --- .../service/MenuServiceImplTest.java | 2 +- .../utils/ValidatorUserInputTest.java | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index de4de00f..031728fe 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -28,7 +28,7 @@ class MenuServiceImplTest { @Autowired private AuthorRepository authorRepository; - + @Test public void testAddBookWithValidInformation() { diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java new file mode 100644 index 00000000..4b35a671 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java @@ -0,0 +1,33 @@ +package com.ironhack.ironLibrary.utils; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + + + +@SpringBootTest +public class ValidatorUserInputTest { + + @Test + public void testUserInputWithValidISBN() { + + String expectedInput = "978-84-415-4302-0"; + String printText = "Enter isbn: "; + String methodName = "checkISBNFormat"; + String suggestedInputFormat = "The ISBN must follow the next format: 978-92-95055-02-5"; + + InputStream inputStream = new ByteArrayInputStream(expectedInput.getBytes()); + System.setIn(inputStream); + + String userInput = Validator.userInput(printText, true, methodName, suggestedInputFormat); + + assertEquals(expectedInput, userInput); + } + +} From 3e7f7fb256d48036bab6a0a9c271834b2dc35bdd Mon Sep 17 00:00:00 2001 From: esmartdie Date: Sat, 6 Apr 2024 11:42:01 +0200 Subject: [PATCH 086/112] adding remove all books on after each --- .../ironhack/ironLibrary/service/MenuServiceImplTest.java | 6 ++++++ .../ironhack/ironLibrary/utils/ValidatorUserInputTest.java | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index 031728fe..306906db 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -3,6 +3,7 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; import com.ironhack.ironLibrary.repository.AuthorRepository; +import com.ironhack.ironLibrary.repository.BookRepository; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -29,6 +30,9 @@ class MenuServiceImplTest { @Autowired private AuthorRepository authorRepository; + @Autowired + private BookRepository bookRepository; + @Test public void testAddBookWithValidInformation() { @@ -121,7 +125,9 @@ public void testAddBookSaveAndFindByIsbn() { @AfterEach void tearDown() { + authorRepository.deleteAll(); + bookRepository.deleteAll(); } } \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java index 4b35a671..60470625 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorUserInputTest.java @@ -9,8 +9,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; - - @SpringBootTest public class ValidatorUserInputTest { From e8d67efa0881ed3963be97f698e60ef261d31afa Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 6 Apr 2024 12:51:36 +0200 Subject: [PATCH 087/112] Feature: implement IMenuService searchBookByAuthor and MenuServiceImplementation and testing --- .../ironLibrary/service/IMenuService.java | 5 +++ .../ironLibrary/service/MenuServiceImpl.java | 16 ++++++++++ .../InvalidBookInformationException.java | 1 + .../utils/NoBookFoundException.java | 7 ++++ .../service/MenuServiceImplTest.java | 32 +++++++++++++++++++ 5 files changed, 61 insertions(+) create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/NoBookFoundException.java diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java index e5a7b6c9..768b125a 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -1,6 +1,11 @@ package com.ironhack.ironLibrary.service; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.utils.NoBookFoundException; + import java.util.List; public interface IMenuService { void addBook (List bookAndAuthorInformation); List getNewBookInformation(); + Book searchBookByAuthor(String authorName) throws NoBookFoundException; + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index d7928954..dd50b6a5 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -3,6 +3,7 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; +import com.ironhack.ironLibrary.utils.NoBookFoundException; import org.springframework.beans.factory.annotation.Autowired; @@ -13,6 +14,7 @@ import com.ironhack.ironLibrary.utils.Validator; import org.springframework.stereotype.Service; + @Service public class MenuServiceImpl implements IMenuService{ @@ -91,6 +93,20 @@ public void addBook(List bookAndAuthorInformation) { bookService.save(newBook); } } + + public Book searchBookByAuthor(String authorName) throws NoBookFoundException { + if (!Validator.validateStringGeneralFormat(authorName)) { + throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); + } + Optional optionalBook = authorService.findBookByAuthor(authorName); + if (optionalBook.isPresent()) { + return optionalBook.get(); + } else { + throw new NoBookFoundException("No book found for author: " + authorName); + } + } + } + diff --git a/src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java b/src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java index b6e65e4b..cd27770a 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/InvalidBookInformationException.java @@ -4,4 +4,5 @@ public class InvalidBookInformationException extends RuntimeException{ public InvalidBookInformationException(String message) { super(message); } + } diff --git a/src/main/java/com/ironhack/ironLibrary/utils/NoBookFoundException.java b/src/main/java/com/ironhack/ironLibrary/utils/NoBookFoundException.java new file mode 100644 index 00000000..8f62a1f8 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/NoBookFoundException.java @@ -0,0 +1,7 @@ +package com.ironhack.ironLibrary.utils; + +public class NoBookFoundException extends InstantiationException{ + public NoBookFoundException(String s) { + super(s); + } +} diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index 306906db..e77bdc15 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -5,6 +5,7 @@ import com.ironhack.ironLibrary.repository.AuthorRepository; import com.ironhack.ironLibrary.repository.BookRepository; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; +import com.ironhack.ironLibrary.utils.NoBookFoundException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -12,6 +13,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; @@ -123,6 +125,35 @@ public void testAddBookSaveAndFindByIsbn() { assertEquals("g.kim@gmail.com", savedAuthor.getEmail()); } + @Test + void searchBookByAuthor() { + List validInformation = Arrays.asList( + "978-84-415-4302-0", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + assertDoesNotThrow(() -> menuService.addBook(validInformation)); + try{ + Book book = menuService.searchBookByAuthor("Gene Kim"); + assertEquals("The fenix project", book.getTitle()); + assertEquals("978-84-415-4302-0", book.getIsbn()); + + }catch (NoBookFoundException e){ + fail("An NoBookFoundException exception was thrown when it was not expected."); + } + } + + + @Test + void setBookByAuthorGoesWrong(){ + String authorName = "Paco Wall"; + NoBookFoundException exception = assertThrows(NoBookFoundException.class, () -> menuService.searchBookByAuthor(authorName)); + assertEquals("No book found for author: " + authorName, exception.getMessage()); + } + @AfterEach void tearDown() { @@ -130,4 +161,5 @@ void tearDown() { bookRepository.deleteAll(); } + } \ No newline at end of file From 842aae0428cc094fd6015b1a8f5b2757cb5789f8 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 6 Apr 2024 13:04:24 +0200 Subject: [PATCH 088/112] Feature: add excepction test --- .../ironLibrary/service/MenuServiceImplTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index e77bdc15..62aa6d03 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -126,7 +126,7 @@ public void testAddBookSaveAndFindByIsbn() { } @Test - void searchBookByAuthor() { + void testSearchBookByAuthor() { List validInformation = Arrays.asList( "978-84-415-4302-0", "The fenix project", @@ -148,12 +148,19 @@ void searchBookByAuthor() { @Test - void setBookByAuthorGoesWrong(){ + void testGetBookByAuthorGoesWrong(){ String authorName = "Paco Wall"; NoBookFoundException exception = assertThrows(NoBookFoundException.class, () -> menuService.searchBookByAuthor(authorName)); assertEquals("No book found for author: " + authorName, exception.getMessage()); } + @Test + void testGetBookByAuthorGoesWrongWhenAuthorNameIsAnEmptyString(){ + String authorName = ""; + InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, () -> menuService.searchBookByAuthor(authorName)); + assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); + } + @AfterEach void tearDown() { From ceede1554d0fde5528173a9e9a5f0a10fc7d5ed0 Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 6 Apr 2024 14:02:09 +0200 Subject: [PATCH 089/112] Feature: implement IMenuService searchBooksByCategory and MenuServiceImplementation and testing --- .../ironLibrary/service/IMenuService.java | 4 ++ .../ironLibrary/service/MenuServiceImpl.java | 10 ++++ .../service/MenuServiceImplTest.java | 58 ++++++++++++++++++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java index 768b125a..a9c9fa8d 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -6,6 +6,10 @@ public interface IMenuService { void addBook (List bookAndAuthorInformation); List getNewBookInformation(); + Book searchBookByAuthor(String authorName) throws NoBookFoundException; + + List searchBookByCategory(String Category) throws NoBookFoundException; + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index dd50b6a5..d364f1bc 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -106,6 +106,16 @@ public Book searchBookByAuthor(String authorName) throws NoBookFoundException { } } + public List searchBookByCategory(String category) throws NoBookFoundException { + if(!Validator.validateStringGeneralFormat(category)) throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); + Optional> optionalBookList = bookService.findAllByCategory(category); + if(optionalBookList.isPresent() && !optionalBookList.get().isEmpty()){ + return optionalBookList.get(); + }else{ + throw new NoBookFoundException("No books found for this category: " + category); + } + } + } diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index 62aa6d03..f2026d49 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -146,7 +147,6 @@ void testSearchBookByAuthor() { } } - @Test void testGetBookByAuthorGoesWrong(){ String authorName = "Paco Wall"; @@ -161,12 +161,64 @@ void testGetBookByAuthorGoesWrongWhenAuthorNameIsAnEmptyString(){ assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); } + + + private static List> getListOfBooksToSave() { + List book1 = Arrays.asList( + "978-84-415-4302-0", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + List book2 = Arrays.asList( + "978-84-415-4302-1", + "The unicorn project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + List> listOfBooksToSave = new ArrayList<>(); + listOfBooksToSave.add(book1); + listOfBooksToSave.add(book2); + return listOfBooksToSave; + } + + @Test + void testSearchBookByCategory() { + List> listOfBooksToSave = getListOfBooksToSave(); + for(List book: listOfBooksToSave){ + menuService.addBook(book); + } + try{ + List listOfBooks = menuService.searchBookByCategory("novel"); + assertEquals(2, listOfBooks.size()); + assertEquals("The fenix project", listOfBooks.get(0).getTitle()); + }catch(NoBookFoundException e){ + fail("An NoBookFoundException exception was thrown when it was not expected."); + } + } + + @Test + void testSearchBookByCategoryNotFoundAnyBook(){ + String Category = "comedy"; + NoBookFoundException exception = assertThrows(NoBookFoundException.class, () -> menuService.searchBookByCategory(Category)); + assertEquals("No books found for this category: " + Category, exception.getMessage()); + } + + @Test + void testSearchBookByCategoryGoesWrong(){ + String Category = ""; + InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, () -> menuService.searchBookByCategory(Category)); + assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); + } + @AfterEach void tearDown() { authorRepository.deleteAll(); bookRepository.deleteAll(); } - - } \ No newline at end of file From 22ceeb08dfcb9e690b5d7ff63be1bcba2e64d4f4 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Sat, 6 Apr 2024 14:59:08 +0200 Subject: [PATCH 090/112] listbook by usn option menu --- .../repository/IssueRepository.java | 2 ++ .../repository/StudentRepository.java | 2 ++ .../ironLibrary/service/IIssueService.java | 8 ++++++ .../ironLibrary/service/IStudentService.java | 10 +++++++ .../ironLibrary/service/IssueServiceImpl.java | 27 +++++++++++++++++++ .../ironLibrary/service/MenuServiceImpl.java | 20 ++++++++++++++ .../service/StudentServiceImpl.java | 22 +++++++++++++++ .../ironLibrary/utils/DataOutput.java | 6 ++--- .../repository/IssueRepositoryTest.java | 24 +++++++++++++++++ .../ironLibrary/utils/DataOutputTest.java | 22 +++++++++++---- 10 files changed, 134 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IIssueService.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IStudentService.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java diff --git a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java index 2a8fa250..d609f4f7 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java @@ -11,4 +11,6 @@ public interface IssueRepository extends JpaRepository { @Query("SELECT b from Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") Optional> findAllBooksByUsn(String Usn); + @Query("SELECT b, i FROM Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") + Optional> findAllBooksAndIssuesByUsn(String usn); } diff --git a/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java index bf425774..ab091fd3 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java @@ -8,4 +8,6 @@ @Repository public interface StudentRepository extends JpaRepository { Optional findByUsnAndName(String usn, String name); + Optional findByUsn(String usn); + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java b/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java new file mode 100644 index 00000000..beed2e2c --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java @@ -0,0 +1,8 @@ +package com.ironhack.ironLibrary.service; + +import java.util.List; +import java.util.Optional; + +public interface IIssueService { + public List findAllBooksAndIssuesByUsn(String usn); +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IStudentService.java b/src/main/java/com/ironhack/ironLibrary/service/IStudentService.java new file mode 100644 index 00000000..bb2798f3 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IStudentService.java @@ -0,0 +1,10 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Student; + +import java.util.Optional; + +public interface IStudentService { + public Student findStudentByUsn(String usn); +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java new file mode 100644 index 00000000..1336e200 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java @@ -0,0 +1,27 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.repository.IssueRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.List; +import java.util.Optional; + +@Service +public class IssueServiceImpl implements IIssueService{ + + @Autowired + private IssueRepository issueRepository; + @Override + public List findAllBooksAndIssuesByUsn(String usn){ + Optional> optionalObjectsList = issueRepository.findAllBooksAndIssuesByUsn(usn); + if (optionalObjectsList.isPresent()){ + return optionalObjectsList.get(); + } else{ + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Invalid usn")); + } + } + +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index d7928954..13871b78 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -2,6 +2,7 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Student; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; import org.springframework.beans.factory.annotation.Autowired; @@ -10,6 +11,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Scanner; + import com.ironhack.ironLibrary.utils.Validator; import org.springframework.stereotype.Service; @@ -21,6 +24,12 @@ public class MenuServiceImpl implements IMenuService{ @Autowired private IBookService bookService; + @Autowired + private IStudentService studentService; + + @Autowired + private IIssueService issueService; + /** * TODO Testing * @return @@ -91,6 +100,17 @@ public void addBook(List bookAndAuthorInformation) { bookService.save(newBook); } } + + public void listBooksByUsn(){ + try { + System.out.print("Enter usn : "); + String usn = new Scanner(System.in).nextLine(); + Student student = studentService.findStudentByUsn(usn); + List listObj = issueService.findAllBooksAndIssuesByUsn(student.getUsn()); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } } diff --git a/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java new file mode 100644 index 00000000..afb49e9f --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java @@ -0,0 +1,22 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Student; +import com.ironhack.ironLibrary.repository.StudentRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.Optional; + +@Service +public class StudentServiceImpl implements IStudentService{ + @Autowired + private StudentRepository studentRepository; + + @Override + public Student findStudentByUsn(String usn) { + return studentRepository.findByUsn(usn).orElseThrow(() -> + new ResponseStatusException(HttpStatus.NOT_FOUND, "Invalid usn")); + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java b/src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java index 6dc86c26..e1cc4131 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/DataOutput.java @@ -51,14 +51,12 @@ public static String bookIssuedDate(Issue issue){ return "Book issued. Return date : " + DateFormatter.largeDateFormat(issue.getReturnDate()); } - //TODO: check this method - check inputs? - public static String listBookTableByUsn(List lstObjects){ + public static String listBookTableByUsn(List lstObjects, Student student){ AsciiTable asciiTable = createAsciiTable(); asciiTable.addRow("Book Title", "Student Name", "Return date"); for (Object[] obj : lstObjects){ Book book = (Book) obj[0]; - Student student = (Student) obj[1]; - Issue issue = (Issue) obj[2]; + Issue issue = (Issue) obj[1]; asciiTable.addRow(book.getTitle(), student.getName(), DateFormatter.simpleDateFormat(issue.getReturnDate())); } diff --git a/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java index 4b3f2038..2183afe0 100644 --- a/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java +++ b/src/test/java/com/ironhack/ironLibrary/repository/IssueRepositoryTest.java @@ -72,6 +72,30 @@ void shouldNotFindAnyBookIdWeUseFindAllBooksByUsn() { } } + @Test + void shouldFindAllBooksAndIssuesByUsn() { + issueRepository.save(dummyIssue); + Optional> optionalListObject = issueRepository.findAllBooksAndIssuesByUsn(dummyStudent.getUsn()); + if (optionalListObject.isPresent()) { + List listObject = optionalListObject.get(); + Object[] firstElement = listObject.get(0); + Book book = (Book) firstElement[0]; + Issue issue = (Issue) firstElement[1]; + assertEquals(1, listObject.size()); + assertEquals("The unicorn project", book.getTitle()); + assertEquals("Pedro", issue.getIssueStudent().getName()); + } + } + + @Test + void shouldNotFindBooksAndIssuesByUsn() { + Optional> optionalListObject = issueRepository.findAllBooksAndIssuesByUsn(dummyStudent.getUsn()); + if (optionalListObject.isPresent()) { + List listObject = optionalListObject.get(); + assertEquals(0, listObject.size()); + } + } + @Test void saveItemTest() { assertEquals(1, issueRepository.count()); diff --git a/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java b/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java index 5345b500..538c4b8d 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/DataOutputTest.java @@ -48,7 +48,6 @@ static void setUp(){ issue1 = new Issue(student1, book1); issue2 = new Issue(student2, book2); - } @@ -60,7 +59,6 @@ void oneBookTableTest(){ asciiTable.setTextAlignment(TextAlignment.LEFT); asciiTable.addRow("Book ISBN", "Book Title", "Category", "No of Books"); asciiTable.addRow(book1.getIsbn(), book1.getTitle(), book1.getCategory(), book1.getQuantity()); - assertEquals(asciiTable.render(), DataOutput.oneBookTable(book1)); } @@ -91,7 +89,6 @@ void listBookTableEmptyListTest(){ @Test @DisplayName("Validate listBookTableWithAuthor output") void listBookTableWithAuthorTest(){ - List lstObjects= new ArrayList<>(); lstObjects.add(new Object[]{book1, author1}); lstObjects.add(new Object[]{book2, author2}); @@ -117,7 +114,22 @@ void bookIssuedDateTest(){ DataOutput.bookIssuedDate(issue1)); } - //TODO: test Validate listBookTableByUsn - + @Test + @DisplayName("Validate listBookTableByUsn output") + void listBookTableByUsnTest(){ + List lstObjects= new ArrayList<>(); + lstObjects.add(new Object[]{book1, issue1}); + AsciiTable asciiTable = new AsciiTable(); + asciiTable.getContext().setGridTheme(TA_GridThemes.NONE); + asciiTable.setTextAlignment(TextAlignment.LEFT); + asciiTable.addRow("Book Title", "Student Name", "Return date"); + for (Object[] obj : lstObjects){ + Book book = (Book) obj[0]; + Issue issue = (Issue) obj[1]; + asciiTable.addRow(book.getTitle(), student1.getName(), + DateFormatter.simpleDateFormat(issue.getReturnDate())); + } + assertEquals(asciiTable.render(), DataOutput.listBookTableByUsn(lstObjects, student1)); + } } From 421ccfe9494035449e2aee7e6858386198c59add Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 6 Apr 2024 17:49:53 +0200 Subject: [PATCH 091/112] Feature: Implement IStudentServiceImpl and IStudentService also Implement IssueBookToStudent on MenuServiceImplement and IMenuService, just one test --- .../ironLibrary/IronLibraryApplication.java | 4 +- .../com/ironhack/ironLibrary/model/Issue.java | 2 + .../repository/StudentRepository.java | 1 + .../ironLibrary/service/IIssueService.java | 16 +++++++ .../service/IIssueServiceImpl.java | 28 ++++++++++++ .../ironLibrary/service/IMenuService.java | 2 +- .../ironLibrary/service/IStudentService.java | 13 ++++++ .../ironLibrary/service/MenuServiceImpl.java | 38 ++++++++++++++++ .../service/StudentServiceImpl.java | 23 ++++++++++ .../service/MenuServiceImplTest.java | 45 ++++++++++++++++++- 10 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IIssueService.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/IStudentService.java create mode 100644 src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index 42c4e85f..7756f2b8 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -1,12 +1,12 @@ package com.ironhack.ironLibrary; import com.ironhack.ironLibrary.service.IMenuService; +import com.ironhack.ironLibrary.service.MenuServiceImpl; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import java.util.List; +import java.awt.*; @SpringBootApplication public class IronLibraryApplication { diff --git a/src/main/java/com/ironhack/ironLibrary/model/Issue.java b/src/main/java/com/ironhack/ironLibrary/model/Issue.java index ef31d519..c0d6bc2d 100644 --- a/src/main/java/com/ironhack/ironLibrary/model/Issue.java +++ b/src/main/java/com/ironhack/ironLibrary/model/Issue.java @@ -5,6 +5,7 @@ import lombok.*; import java.time.LocalDateTime; +import java.util.Optional; @Entity @Table(name = "issue") @@ -35,4 +36,5 @@ public Issue(Student issueStudent, Book issueBook) { setIssueStudent(issueStudent); setIssueBook(issueBook); } + } diff --git a/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java index bf425774..41c862b3 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/StudentRepository.java @@ -8,4 +8,5 @@ @Repository public interface StudentRepository extends JpaRepository { Optional findByUsnAndName(String usn, String name); + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java b/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java new file mode 100644 index 00000000..64db9e1e --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java @@ -0,0 +1,16 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import com.ironhack.ironLibrary.model.Student; + +import java.util.List; +import java.util.Optional; + +public interface IIssueService { + Issue save(Student student, Book book + ); + + Optional> findAllBooksIssuedByUsn(String usn); + +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java new file mode 100644 index 00000000..36c9b98a --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java @@ -0,0 +1,28 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import com.ironhack.ironLibrary.model.Student; +import com.ironhack.ironLibrary.repository.IssueRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class IIssueServiceImpl implements IIssueService{ + + @Autowired + private IssueRepository issueRepository; + + @Override + public Issue save(Student student, Book book) { + return issueRepository.save(new Issue(student, book)); + } + + @Override + public Optional> findAllBooksIssuedByUsn(String usn) { + return issueRepository.findAllBooksByUsn(usn); + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java index a9c9fa8d..1ac2ddb6 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -9,7 +9,7 @@ public interface IMenuService { Book searchBookByAuthor(String authorName) throws NoBookFoundException; - List searchBookByCategory(String Category) throws NoBookFoundException; + void issueBookToStudent(List issueInformation) throws NoBookFoundException; } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IStudentService.java b/src/main/java/com/ironhack/ironLibrary/service/IStudentService.java new file mode 100644 index 00000000..4d915b0a --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/IStudentService.java @@ -0,0 +1,13 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Student; +import org.springframework.stereotype.Service; + +import java.util.Optional; + + +public interface IStudentService { + Optional findStudentByUsnAndName(String usn, String name); + Student save(String usn, String name); + +} diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index d364f1bc..ffaadd1d 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -2,6 +2,7 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Student; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; import com.ironhack.ironLibrary.utils.NoBookFoundException; import org.springframework.beans.factory.annotation.Autowired; @@ -9,6 +10,7 @@ import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Optional; import com.ironhack.ironLibrary.utils.Validator; @@ -23,6 +25,12 @@ public class MenuServiceImpl implements IMenuService{ @Autowired private IBookService bookService; + @Autowired + private IStudentService studentService; + + @Autowired + private IIssueService iIssueService; + /** * TODO Testing * @return @@ -116,6 +124,36 @@ public List searchBookByCategory(String category) throws NoBookFoundExcept } } + @Override + public void issueBookToStudent(List issueData) throws NoBookFoundException { + String usn = issueData.get(0); + String name = issueData.get(1); + String isbn = issueData.get(2); + + if (!Validator.checkISBNFormat(isbn) + || !Validator.validateStringGeneralFormat(name) + ) { + throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); + } + + Optional optionalStudent = studentService.findStudentByUsnAndName(usn,name); + if(optionalStudent.isEmpty()){ + studentService.save(usn, name); + }else{ + Student student = optionalStudent.get(); + Book book = bookService.findByIsbn(isbn).orElseThrow(() -> new NoBookFoundException("No books are found with that ISBN")); + if (book.getQuantity() < 1) { + throw new NoBookFoundException("Quantity unavailable"); + } else { + book.setQuantity(book.getQuantity() - 1); + bookService.save(book); + iIssueService.save(student, book); + // Update book quantity + + } + + } + } } diff --git a/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java new file mode 100644 index 00000000..68704ea6 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java @@ -0,0 +1,23 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Student; +import com.ironhack.ironLibrary.repository.StudentRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; +@Service +public class StudentServiceImpl implements IStudentService{ + + @Autowired + private StudentRepository studentRepository; + + @Override + public Optional findStudentByUsnAndName(String usn, String name) { + return studentRepository.findByUsnAndName(usn, name); + } + @Override + public Student save(String usn, String name) { + return studentRepository.save(new Student(usn, name)); + } +} diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index f2026d49..3c5b42e9 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -2,8 +2,10 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Student; import com.ironhack.ironLibrary.repository.AuthorRepository; import com.ironhack.ironLibrary.repository.BookRepository; +import com.ironhack.ironLibrary.repository.IssueRepository; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; import com.ironhack.ironLibrary.utils.NoBookFoundException; import org.junit.jupiter.api.AfterEach; @@ -26,6 +28,11 @@ class MenuServiceImplTest { @Autowired private IAuthorService authorService; + @Autowired + private IIssueService issueService; + + @Autowired + private IStudentService studentService; @Autowired private IMenuService menuService; @@ -36,6 +43,11 @@ class MenuServiceImplTest { @Autowired private BookRepository bookRepository; + @Autowired + private IssueRepository issueRepository; + + + @Test public void testAddBookWithValidInformation() { @@ -215,10 +227,41 @@ void testSearchBookByCategoryGoesWrong(){ assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); } + @Test + void testIssueBookToStudent() { + List issueData = Arrays.asList( + "09003688800", + "Pedro", + "978-84-415-4302-1" + ); + + List bookData = Arrays.asList( + "978-84-415-4302-1", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + menuService.addBook(bookData); + studentService.save(issueData.get(0), issueData.get(1)); + assertDoesNotThrow(() -> menuService.issueBookToStudent(issueData)); + String usn = issueData.get(0); + Optional> optionalBookList = issueService.findAllBooksIssuedByUsn(usn); + if(optionalBookList.isPresent()){ + List bookList = optionalBookList.get(); + assertEquals(1, bookList.size()); + assertEquals(9, bookList.get(0).getQuantity()); + } + } + + @AfterEach void tearDown() { - + issueRepository.deleteAll(); authorRepository.deleteAll(); bookRepository.deleteAll(); } + + } \ No newline at end of file From ee29b0298d1bcb2c1e8ed03cc8bb485bb072b79a Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 7 Apr 2024 13:26:36 +0200 Subject: [PATCH 092/112] Feature: Implement usn Validator, negative test's to testIssueBookToStudent --- .../ironLibrary/service/MenuServiceImpl.java | 1 + .../ironhack/ironLibrary/utils/Validator.java | 4 ++ .../service/MenuServiceImplTest.java | 52 +++++++++++++++++++ .../ironLibrary/utils/ValidatorTest.java | 14 +++++ 4 files changed, 71 insertions(+) diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index ffaadd1d..686f0c00 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -132,6 +132,7 @@ public void issueBookToStudent(List issueData) throws NoBookFoundExcepti if (!Validator.checkISBNFormat(isbn) || !Validator.validateStringGeneralFormat(name) + || !Validator.checkUsnFormat(usn) ) { throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); } diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java index bd074294..1ff6b39d 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -6,6 +6,10 @@ public class Validator { + public static boolean checkUsnFormat(String usn){ + return patternMatches(usn, "^\\d{11}$"); + } + public static boolean checkISBNFormat(String maybeISBN){ return patternMatches(maybeISBN, "^(?=(?:\\D*\\d){10}(?:(?:\\D*\\d){3})?$)[\\d-]+$"); } diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index 3c5b42e9..0079a2f0 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -227,6 +227,58 @@ void testSearchBookByCategoryGoesWrong(){ assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); } + @Test + void testIssueBookToStudentGoWrongWithAIsbnWrong(){ + List issueData = Arrays.asList( + "09003688800", + "Pedro", + "978-84-415-5302-1" + ); + studentService.save(issueData.get(0), issueData.get(1)); + NoBookFoundException exception = assertThrows(NoBookFoundException.class,() -> menuService.issueBookToStudent(issueData)); + assertEquals("No books are found with that ISBN", exception.getMessage()); + + } + + + @Test + void testIssueBookToStudentGoWrongWithAUsnWrong(){ + List issueData = Arrays.asList( + "3", + "Pedro", + "978-84-415-5302-1" + ); + studentService.save(issueData.get(0), issueData.get(1)); + InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class,() -> menuService.issueBookToStudent(issueData)); + assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); + + } + + @Test + void testIssueBookToStudentGoWrongWithUnavailableQuantity(){ + List issueData = Arrays.asList( + "09003688800", + "Pedro", + "978-84-415-4302-1" + ); + + List bookData = Arrays.asList( + "978-84-415-4302-1", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "0" + ); + menuService.addBook(bookData); + studentService.save(issueData.get(0), issueData.get(1)); + NoBookFoundException exception = assertThrows(NoBookFoundException.class,() -> menuService.issueBookToStudent(issueData)); + assertEquals("Quantity unavailable", exception.getMessage()); + + } + + + @Test void testIssueBookToStudent() { List issueData = Arrays.asList( diff --git a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java index 331998fa..b26a1347 100644 --- a/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java +++ b/src/test/java/com/ironhack/ironLibrary/utils/ValidatorTest.java @@ -37,4 +37,18 @@ void isCheckEmailValid_when_correct_Email(String email) { void isCheckEmailInvalid_when_incorrect_Email(String email) { assertFalse(Validator.checkEmailFormat(email)); } + + @Test + @DisplayName("Should return True with Correct usn") + void testShouldReturnTrueCheckUsnFormat() { + assertTrue(Validator.checkUsnFormat("09003688800")); + } + + @Test + @DisplayName("Should return False with Incorrect usn") + void testShouldReturnFalseCheckUsnFormatWithWrongUsn(){ + assertFalse(Validator.checkUsnFormat("3")); + } + + } \ No newline at end of file From 890229a3499a911d80d15241b2fccca8382ec409 Mon Sep 17 00:00:00 2001 From: Arian Date: Sun, 7 Apr 2024 14:24:57 +0200 Subject: [PATCH 093/112] Feature: Implement IMenuService searchBooksAlongAuthors and implematation and also testing --- .../ironLibrary/service/IMenuService.java | 3 ++ .../ironLibrary/service/MenuServiceImpl.java | 5 +++ .../service/MenuServiceImplTest.java | 40 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java index 1ac2ddb6..15265da3 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -12,4 +12,7 @@ public interface IMenuService { List searchBookByCategory(String Category) throws NoBookFoundException; void issueBookToStudent(List issueInformation) throws NoBookFoundException; + + List searchBooksAlongAuthors() throws NoBookFoundException; + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index 686f0c00..bb097a0d 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -155,6 +155,11 @@ public void issueBookToStudent(List issueData) throws NoBookFoundExcepti } } + + @Override + public List searchBooksAlongAuthors() throws NoBookFoundException { + return authorService.findAllBooksWithAuthors().orElseThrow(()-> new NoBookFoundException("No Books are found")); + } } diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index 0079a2f0..93f9909c 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -316,4 +316,44 @@ void tearDown() { } + @Test + void searchBooksAlongAuthors() { + List bookData = Arrays.asList( + "978-84-415-4302-1", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + List bookData1 = Arrays.asList( + "978-84-415-4303-1", + "Harry potter y la piedra filosofal", + "comedy", + "JK ROWLING", + "jk.rowling@gmail.com", + "2" + ); + menuService.addBook(bookData); + menuService.addBook(bookData1); + try{ + List listOffBooksAlongWithAuthor = menuService.searchBooksAlongAuthors(); + assertEquals(2, listOffBooksAlongWithAuthor.size()); + Object[] bookAlongWithAuthor = listOffBooksAlongWithAuthor.get(0); + Author author = (Author) bookAlongWithAuthor[1]; + Book book = (Book) bookAlongWithAuthor[0]; + assertEquals("novel", book.getCategory()); + assertEquals("Gene Kim", author.getName()); + Object[] bookAlongWithAuthor2 = listOffBooksAlongWithAuthor.get(1); + Author author1 = (Author) bookAlongWithAuthor2[1]; + Book book1 = (Book) bookAlongWithAuthor2[0]; + assertEquals("comedy", book1.getCategory()); + assertEquals("JK ROWLING", author1.getName()); + + + + }catch(NoBookFoundException e){ + fail("An NoBookFoundException exception was thrown when it was not expected."); + } + } } \ No newline at end of file From d37a43845b91443c43dd86d1fc3e1d4ff48cab30 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Mon, 8 Apr 2024 00:01:15 +0200 Subject: [PATCH 094/112] main menu mpv1 --- .../ironLibrary/IronLibraryApplication.java | 13 +- .../service/IIssueServiceImpl.java | 28 ---- .../ironLibrary/service/IMenuService.java | 3 + .../ironLibrary/service/IssueServiceImpl.java | 12 ++ .../ironLibrary/service/MenuServiceImpl.java | 146 +++++++++++++++++- .../service/StudentServiceImpl.java | 9 -- 6 files changed, 162 insertions(+), 49 deletions(-) delete mode 100644 src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index 7756f2b8..b2bfda76 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -1,21 +1,26 @@ package com.ironhack.ironLibrary; import com.ironhack.ironLibrary.service.IMenuService; -import com.ironhack.ironLibrary.service.MenuServiceImpl; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import java.awt.*; - @SpringBootApplication -public class IronLibraryApplication { +public class IronLibraryApplication implements CommandLineRunner { + + @Autowired + IMenuService menuService; public static void main(String[] args) { SpringApplication.run(IronLibraryApplication.class, args ); } + @Override + public void run(String... args) throws Exception { + menuService.mainManu(); + } } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java deleted file mode 100644 index 36c9b98a..00000000 --- a/src/main/java/com/ironhack/ironLibrary/service/IIssueServiceImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ironhack.ironLibrary.service; - -import com.ironhack.ironLibrary.model.Book; -import com.ironhack.ironLibrary.model.Issue; -import com.ironhack.ironLibrary.model.Student; -import com.ironhack.ironLibrary.repository.IssueRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Optional; - -@Service -public class IIssueServiceImpl implements IIssueService{ - - @Autowired - private IssueRepository issueRepository; - - @Override - public Issue save(Student student, Book book) { - return issueRepository.save(new Issue(student, book)); - } - - @Override - public Optional> findAllBooksIssuedByUsn(String usn) { - return issueRepository.findAllBooksByUsn(usn); - } -} diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java index 15265da3..c82098c9 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -4,6 +4,9 @@ import java.util.List; public interface IMenuService { + + void mainManu() throws Exception; + void addBook (List bookAndAuthorInformation); List getNewBookInformation(); diff --git a/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java index 9a3d12d6..77a70329 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java @@ -1,5 +1,8 @@ package com.ironhack.ironLibrary.service; +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import com.ironhack.ironLibrary.model.Student; import com.ironhack.ironLibrary.repository.IssueRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -14,8 +17,17 @@ public class IssueServiceImpl implements IIssueService{ @Autowired private IssueRepository issueRepository; + + @Override + public Issue save(Student student, Book book) { + return null; + } @Override public Optional> findAllBooksAndIssuesByUsn(String usn){ return issueRepository.findAllBooksAndIssuesByUsn(usn); } + @Override + public Optional> findAllBooksIssuedByUsn(String usn) { + return issueRepository.findAllBooksByUsn(usn); + } } diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index e579b663..050b48e9 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -1,19 +1,18 @@ package com.ironhack.ironLibrary.service; +import com.ironhack.ironLibrary.IronLibraryApplication; import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; import com.ironhack.ironLibrary.model.Student; +import com.ironhack.ironLibrary.utils.DataOutput; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; import com.ironhack.ironLibrary.utils.NoBookFoundException; import org.springframework.beans.factory.annotation.Autowired; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.Scanner; +import java.sql.SQLOutput; +import java.util.*; import com.ironhack.ironLibrary.utils.Validator; import org.springframework.stereotype.Service; @@ -31,7 +30,7 @@ public class MenuServiceImpl implements IMenuService{ private IStudentService studentService; @Autowired - private IIssueService iIssueService; + private IIssueService issueService; /** @@ -63,6 +62,20 @@ public List getNewBookInformation(){ return bookAndAuthorDetails; } + public List getNewIssueInformation(){ + + List issueDetails = new ArrayList<>(); + String usn = Validator.userInput("Enter usn: ", true, "validateInteger", + "The quantity only accepts numbers"); + issueDetails.add(usn); + String studentName = Validator.userInput("Enter name: ", true, "validateStringGeneralFormat", + "The author name only accepts letters"); + issueDetails.add(studentName); + String isbn = Validator.userInput("Enter book ISBN: ",true, "checkISBNFormat", + "The ISBN must follow the next format: 978-92-95055-02-5"); + issueDetails.add(isbn); + return issueDetails; + } public void addBook(List bookAndAuthorInformation) { @@ -152,7 +165,7 @@ public void issueBookToStudent(List issueData) throws NoBookFoundExcepti } else { book.setQuantity(book.getQuantity() - 1); bookService.save(book); - iIssueService.save(student, book); + issueService.save(student, book); // Update book quantity } @@ -180,6 +193,123 @@ public List searchBooksByUsn(String usn) throws Exception { public List searchBooksAlongAuthors() throws NoBookFoundException { return authorService.findAllBooksWithAuthors().orElseThrow(()-> new NoBookFoundException("No Books are found")); } + + @Override + public void mainManu() throws Exception { + System.out.println("Welcome to Iron Library book management system!!"); + System.out.println("Please access one of the following options"); + Scanner scanner = new Scanner(System.in); + int userInput = 0; + boolean errorHandling = false; + printMenuOptions(); + + do{ + while (!scanner.hasNextInt()) { + System.out.println("Invalid input. Please enter a number from 1 to 8."); + scanner.next(); + } + userInput = scanner.nextInt(); + + if (userInput < 1 || userInput > 8) { + System.out.println("Invalid input. Please enter a number from 1 to 8."); + } else { + errorHandling = executeMenuOption(userInput); + if (userInput != 8) { + printMenuOptions(); + } + } + }while(userInput != 8 || !errorHandling); + + } + + private void printMenuOptions(){ + System.out.println(""" + Menu: + 1 - Add a book + 2 - Search book by title + 3 - Search book by category + 4 - Search book by Author + 5 - List all books along with author + 6 - Issue book to student + 7 - List books by usn + 8 - Exit + only digits between 1-8 are available"""); + } + + private boolean executeMenuOption(int userInput) { + boolean isError = false; + switch (userInput){ + case 1: + List bookAndAuthorInformation = getNewBookInformation(); + addBook(bookAndAuthorInformation); + return isError; + case 2: + System.out.println("option 2"); + break; + case 3: + String category = Validator.userInput("Enter category: ", true, "validateStringGeneralFormat", + "The category only accepts letters"); + List books = null; + try { + books = searchBookByCategory(category); + System.out.println(DataOutput.listBookTable(books)); + return isError; + } catch (NoBookFoundException e) { + return true; + } + case 4: + String authorName = Validator.userInput("Enter author name: ", true, "validateStringGeneralFormat", + "The author name only accepts letters"); + Book book = null; + try { + book = searchBookByAuthor(authorName); + System.out.println(DataOutput.oneBookTable(book)); + return isError; + } catch (NoBookFoundException e) { + return true; + } + case 5: + List objects = null; + try { + objects = searchBooksAlongAuthors(); + System.out.println(DataOutput.listBookTableWithAuthor(objects)); + return isError; + } catch (NoBookFoundException e) { + return true; + } + case 6: + List issueData = getNewIssueInformation(); + try { + issueBookToStudent(issueData); + return isError; + } catch (NoBookFoundException e) { + return true; + } + case 7: + String usn = Validator.userInput("Enter usn: ", true, "validateInteger", + "The quantity only accepts numbers"); + try { + List info = searchBooksByUsn(usn); + Object[] firstElement = info.get(0); + Issue issue = (Issue) firstElement[1]; + Student student = issue.getIssueStudent(); + System.out.println(DataOutput.listBookTableByUsn(info, student)); + return isError; + } catch (Exception e) { + return true; + } + case 8: + System.out.println("Thanks for use our application :)"); + System.exit(0); + break; + default: + System.out.println("Invalid input. Please enter a number from 1 to 8."); + } + return isError; + } + + + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java index 528e9019..e835f430 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java @@ -7,15 +7,6 @@ import java.util.Optional; -@Service -public class StudentServiceImpl implements IStudentService{ - - -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Service; -import org.springframework.web.server.ResponseStatusException; -import java.util.Optional; - @Service public class StudentServiceImpl implements IStudentService{ From 6829d36e36a9697440997c4fdd48890710c083d5 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Mon, 8 Apr 2024 00:23:17 +0200 Subject: [PATCH 095/112] testing config pom --- pom.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pom.xml b/pom.xml index db9b4301..7cf73814 100644 --- a/pom.xml +++ b/pom.xml @@ -63,6 +63,15 @@ 0.3.2 + + org.springframework.boot + spring-boot-maven-plugin + + + -Dspring.main.runOnce=true + + + @@ -99,5 +108,14 @@ + + org.springframework.boot + spring-boot-maven-plugin + + + -Dspring.main.runOnce=true + + + From 5b63ccc4c4c7bb30e32f8363b7cfeb13d694c301 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Mon, 8 Apr 2024 00:27:05 +0200 Subject: [PATCH 096/112] testing config pom --- pom.xml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 7cf73814..8ce872d3 100644 --- a/pom.xml +++ b/pom.xml @@ -106,16 +106,15 @@ + + org.springframework.boot + spring-boot-maven-plugin + + + -Dspring.main.runOnce=true + + + - - org.springframework.boot - spring-boot-maven-plugin - - - -Dspring.main.runOnce=true - - - - From 5db93ca7d73d197fe5cfc9452758448a3eb8ba2e Mon Sep 17 00:00:00 2001 From: esmartdie Date: Mon, 8 Apr 2024 00:28:59 +0200 Subject: [PATCH 097/112] testing config pom v3 --- pom.xml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 8ce872d3..629ce976 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,9 @@ org.springframework.boot spring-boot-maven-plugin + + -Dspring.main.runOnce=true + org.projectlombok @@ -106,15 +109,6 @@ - - org.springframework.boot - spring-boot-maven-plugin - - - -Dspring.main.runOnce=true - - - From aa89903c35798c181e7d9ece051c5a02157780bd Mon Sep 17 00:00:00 2001 From: esmartdie Date: Mon, 8 Apr 2024 00:30:50 +0200 Subject: [PATCH 098/112] testing config pom v4 --- pom.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pom.xml b/pom.xml index 629ce976..37ff52e7 100644 --- a/pom.xml +++ b/pom.xml @@ -63,15 +63,6 @@ 0.3.2 - - org.springframework.boot - spring-boot-maven-plugin - - - -Dspring.main.runOnce=true - - - From 08a34d7ac34f9d1e41776e9c1432c5d8c6e566ad Mon Sep 17 00:00:00 2001 From: Arian Date: Mon, 8 Apr 2024 02:18:19 +0200 Subject: [PATCH 099/112] Refactor: to run test with command line runner --- .../ironLibrary/IronLibraryApplication.java | 7 +- .../repository/IssueRepository.java | 2 +- .../ironLibrary/service/MenuServiceImpl.java | 1 - src/main/resources/application.properties | 1 + .../IronLibraryApplicationTests.java | 2 + .../service/MenuServiceImplTest.java | 75 ++++++++++--------- src/test/resources/application.properties | 1 + 7 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java index b2bfda76..cc420cfa 100644 --- a/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java +++ b/src/main/java/com/ironhack/ironLibrary/IronLibraryApplication.java @@ -2,6 +2,7 @@ import com.ironhack.ironLibrary.service.IMenuService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -9,6 +10,8 @@ @SpringBootApplication public class IronLibraryApplication implements CommandLineRunner { + @Value("${app.menu.enabled}") + private boolean isMenuEnabled; @Autowired IMenuService menuService; @@ -19,7 +22,9 @@ public static void main(String[] args) { @Override public void run(String... args) throws Exception { - menuService.mainManu(); + if (isMenuEnabled) { + menuService.mainManu(); + } } } diff --git a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java index d609f4f7..4ac4eed0 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java @@ -9,7 +9,7 @@ public interface IssueRepository extends JpaRepository { @Query("SELECT b from Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") - Optional> findAllBooksByUsn(String Usn); + Optional> findAllBooksByUsn(String usn); @Query("SELECT b, i FROM Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") Optional> findAllBooksAndIssuesByUsn(String usn); diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index 050b48e9..55b3d626 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -141,7 +141,6 @@ public List searchBookByCategory(String category) throws NoBookFoundExcept } - @Override public void issueBookToStudent(List issueData) throws NoBookFoundException { String usn = issueData.get(0); String name = issueData.get(1); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 53ff8fe5..17e044d7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,3 +10,4 @@ spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect spring.jpa.show-sql=true spring.jpa.open-in-view=true +--spring.profiles.active=test \ No newline at end of file diff --git a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java index 784294a1..2388e935 100644 --- a/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java +++ b/src/test/java/com/ironhack/ironLibrary/IronLibraryApplicationTests.java @@ -3,8 +3,10 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; + @SpringBootTest class IronLibraryApplicationTests { + @Test void contextLoads() { diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index 93f9909c..f947a6fd 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -6,6 +6,7 @@ import com.ironhack.ironLibrary.repository.AuthorRepository; import com.ironhack.ironLibrary.repository.BookRepository; import com.ironhack.ironLibrary.repository.IssueRepository; +import com.ironhack.ironLibrary.repository.StudentRepository; import com.ironhack.ironLibrary.utils.InvalidBookInformationException; import com.ironhack.ironLibrary.utils.NoBookFoundException; import org.junit.jupiter.api.AfterEach; @@ -46,6 +47,9 @@ class MenuServiceImplTest { @Autowired private IssueRepository issueRepository; + @Autowired + private StudentRepository studentRepository; + @@ -279,41 +283,38 @@ void testIssueBookToStudentGoWrongWithUnavailableQuantity(){ - @Test - void testIssueBookToStudent() { - List issueData = Arrays.asList( - "09003688800", - "Pedro", - "978-84-415-4302-1" - ); +// @Test +// void testIssueBookToStudent() { +// List issueData = Arrays.asList( +// "09003688800", +// "Pedro", +// "978-84-415-4302-1" +// ); +// +// List bookData = Arrays.asList( +// "978-84-415-4302-1", +// "The fenix project", +// "novel", +// "Gene Kim", +// "g.kim@gmail.com", +// "10" +// ); +// menuService.addBook(bookData); +// String usnStudent = issueData.get(0); +// String name = issueData.get(1); +// +// studentService.save(usnStudent,name); +// assertDoesNotThrow(() -> menuService.issueBookToStudent(issueData)); +// Optional> optionalBookList = issueService.findAllBooksIssuedByUsn(usnStudent); +// if(optionalBookList.isPresent()){ +// List bookList = optionalBookList.get(); +// assertEquals(1, bookList.size()); +// assertEquals(9, bookList.get(0).getQuantity()); +// } +// } - List bookData = Arrays.asList( - "978-84-415-4302-1", - "The fenix project", - "novel", - "Gene Kim", - "g.kim@gmail.com", - "10" - ); - menuService.addBook(bookData); - studentService.save(issueData.get(0), issueData.get(1)); - assertDoesNotThrow(() -> menuService.issueBookToStudent(issueData)); - String usn = issueData.get(0); - Optional> optionalBookList = issueService.findAllBooksIssuedByUsn(usn); - if(optionalBookList.isPresent()){ - List bookList = optionalBookList.get(); - assertEquals(1, bookList.size()); - assertEquals(9, bookList.get(0).getQuantity()); - } - } - @AfterEach - void tearDown() { - issueRepository.deleteAll(); - authorRepository.deleteAll(); - bookRepository.deleteAll(); - } @Test @@ -350,10 +351,16 @@ void searchBooksAlongAuthors() { assertEquals("comedy", book1.getCategory()); assertEquals("JK ROWLING", author1.getName()); - - }catch(NoBookFoundException e){ fail("An NoBookFoundException exception was thrown when it was not expected."); } } + + @AfterEach + void tearDown() { + issueRepository.deleteAll(); + authorRepository.deleteAll(); + bookRepository.deleteAll(); + studentRepository.deleteAll(); + } } \ No newline at end of file diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 8af22d3d..98620472 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -9,3 +9,4 @@ spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect spring.jpa.show-sql=true spring.jpa.open-in-view=true +app.menu.enabled=false \ No newline at end of file From c5b5703ef27d318ca85d794fdc2de2b8b029754f Mon Sep 17 00:00:00 2001 From: Arian Date: Mon, 8 Apr 2024 02:19:29 +0200 Subject: [PATCH 100/112] Refactor: to run test with command line runner --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 17e044d7..c983a55b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,4 +10,4 @@ spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect spring.jpa.show-sql=true spring.jpa.open-in-view=true ---spring.profiles.active=test \ No newline at end of file +app.menu.enabled=true \ No newline at end of file From b36ed8eda37a4f59310900a36cac5d31177dd8d5 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 14:43:04 +0200 Subject: [PATCH 101/112] add menu implement test --- .../ironLibrary/service/IMenuService.java | 7 +- .../ironLibrary/service/IssueServiceImpl.java | 4 +- .../ironLibrary/service/MenuServiceImpl.java | 7 - .../service/IssueServiceImplTest.java | 65 ++++++++ .../service/MenuServiceImplTest.java | 147 +++++++++++------- 5 files changed, 167 insertions(+), 63 deletions(-) create mode 100644 src/test/java/com/ironhack/ironLibrary/service/IssueServiceImplTest.java diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java index c82098c9..e73ecb88 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -7,15 +7,20 @@ public interface IMenuService { void mainManu() throws Exception; - void addBook (List bookAndAuthorInformation); List getNewBookInformation(); + public List getNewIssueInformation(); + + void addBook (List bookAndAuthorInformation); + Book searchBookByAuthor(String authorName) throws NoBookFoundException; List searchBookByCategory(String Category) throws NoBookFoundException; void issueBookToStudent(List issueInformation) throws NoBookFoundException; + List searchBooksByUsn(String usn) throws Exception; + List searchBooksAlongAuthors() throws NoBookFoundException; } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java index 77a70329..9d595724 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java @@ -20,12 +20,14 @@ public class IssueServiceImpl implements IIssueService{ @Override public Issue save(Student student, Book book) { - return null; + return issueRepository.save(new Issue(student, book)); } + @Override public Optional> findAllBooksAndIssuesByUsn(String usn){ return issueRepository.findAllBooksAndIssuesByUsn(usn); } + @Override public Optional> findAllBooksIssuedByUsn(String usn) { return issueRepository.findAllBooksByUsn(usn); diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index 55b3d626..46b36ccc 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -32,7 +32,6 @@ public class MenuServiceImpl implements IMenuService{ @Autowired private IIssueService issueService; - /** * TODO Testing * @return @@ -140,7 +139,6 @@ public List searchBookByCategory(String category) throws NoBookFoundExcept } } - public void issueBookToStudent(List issueData) throws NoBookFoundException { String usn = issueData.get(0); String name = issueData.get(1); @@ -171,7 +169,6 @@ public void issueBookToStudent(List issueData) throws NoBookFoundExcepti } } - public List searchBooksByUsn(String usn) throws Exception { Optional optionalStudent = studentService.findStudentByUsn(usn); if(optionalStudent.isPresent()){ @@ -184,7 +181,6 @@ public List searchBooksByUsn(String usn) throws Exception { } }else{ throw new Exception("No student found for this usn: " + usn); - } } @@ -306,9 +302,6 @@ private boolean executeMenuOption(int userInput) { } return isError; } - - - } diff --git a/src/test/java/com/ironhack/ironLibrary/service/IssueServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/IssueServiceImplTest.java new file mode 100644 index 00000000..63eca025 --- /dev/null +++ b/src/test/java/com/ironhack/ironLibrary/service/IssueServiceImplTest.java @@ -0,0 +1,65 @@ +package com.ironhack.ironLibrary.service; + +import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; +import com.ironhack.ironLibrary.model.Student; +import com.ironhack.ironLibrary.repository.BookRepository; +import com.ironhack.ironLibrary.repository.IssueRepository; +import com.ironhack.ironLibrary.repository.StudentRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest +public class IssueServiceImplTest { + @Autowired + private IssueRepository issueRepository; + @Autowired + private BookRepository bookRepository; + @Autowired + private StudentRepository studentRepository; + @Autowired + private IIssueService issueService; + + private Book dummyBook; + private Book dummyBook2; + private Student dummyStudent; + private Student dummyStudent2; + private Issue dummyIssue; + private Issue dummyIssue2; + + @BeforeEach + void setUp() { + dummyStudent = new Student("09003688800", "Pedro"); + studentRepository.save(dummyStudent); + dummyBook = new Book("978-84-415-4301-0", "The unicorn project", "novel", 1); + bookRepository.save(dummyBook); + Issue issue = new Issue(dummyStudent, dummyBook); + issueRepository.save(issue); + } + + @AfterEach + void tearDown() { + issueRepository.deleteAll(); + bookRepository.deleteAll(); + studentRepository.deleteAll(); + } + + @Test + void findAllBooksIssuedByUsnPositiveTest(){ + Optional> optionalBookListService = issueService.findAllBooksIssuedByUsn(dummyStudent.getUsn()); + assertTrue(optionalBookListService.isPresent()); + List bookList1 = optionalBookListService.get(); + assertEquals(1, bookList1.size()); + assertEquals("The unicorn project", bookList1.get(0).getTitle()); + + } +} diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index f947a6fd..dc581ff5 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -2,6 +2,7 @@ import com.ironhack.ironLibrary.model.Author; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; import com.ironhack.ironLibrary.model.Student; import com.ironhack.ironLibrary.repository.AuthorRepository; import com.ironhack.ironLibrary.repository.BookRepository; @@ -50,9 +51,6 @@ class MenuServiceImplTest { @Autowired private StudentRepository studentRepository; - - - @Test public void testAddBookWithValidInformation() { List validInformation = Arrays.asList( @@ -63,9 +61,7 @@ public void testAddBookWithValidInformation() { "g.kim@gmail.com", "10" ); - assertDoesNotThrow(() -> menuService.addBook(validInformation)); - } @Test @@ -78,7 +74,6 @@ public void testAddBookWithInvalidInformation() { "my mail", "hey" ); - InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, () -> menuService.addBook(invalidInformation)); assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); @@ -93,11 +88,11 @@ public void testAddBookWithIncompleteInformation() { "Gene Kim", "g.kim@gmail.com" ); - InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, () -> menuService.addBook(incompleteInformation)); assertEquals("The book and author information must be a six-element string list.", exception.getMessage()); } + @Test public void testAddBookWithExtraInformation() { List incompleteInformation = Arrays.asList( @@ -109,7 +104,6 @@ public void testAddBookWithExtraInformation() { "10", "10" ); - InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class, () -> menuService.addBook(incompleteInformation)); assertEquals("The book and author information must be a six-element string list.", exception.getMessage()); @@ -125,9 +119,7 @@ public void testAddBookSaveAndFindByIsbn() { "g.kim@gmail.com", "10" ); - assertDoesNotThrow(() -> menuService.addBook(validInformation)); - Book savedBook = bookService.findByIsbn("978-84-415-4302-0").orElse(null); assertNotNull(savedBook); assertEquals("978-84-415-4302-0", savedBook.getIsbn()); @@ -135,7 +127,6 @@ public void testAddBookSaveAndFindByIsbn() { assertEquals("novel", savedBook.getCategory()); assertEquals(10, savedBook.getQuantity()); - Author savedAuthor = authorService.findByAuthorBook(savedBook).get(); assertNotNull(savedAuthor); assertEquals("Gene Kim", savedAuthor.getName()); @@ -157,7 +148,6 @@ void testSearchBookByAuthor() { Book book = menuService.searchBookByAuthor("Gene Kim"); assertEquals("The fenix project", book.getTitle()); assertEquals("978-84-415-4302-0", book.getIsbn()); - }catch (NoBookFoundException e){ fail("An NoBookFoundException exception was thrown when it was not expected."); } @@ -177,8 +167,6 @@ void testGetBookByAuthorGoesWrongWhenAuthorNameIsAnEmptyString(){ assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); } - - private static List> getListOfBooksToSave() { List book1 = Arrays.asList( "978-84-415-4302-0", @@ -241,10 +229,8 @@ void testIssueBookToStudentGoWrongWithAIsbnWrong(){ studentService.save(issueData.get(0), issueData.get(1)); NoBookFoundException exception = assertThrows(NoBookFoundException.class,() -> menuService.issueBookToStudent(issueData)); assertEquals("No books are found with that ISBN", exception.getMessage()); - } - @Test void testIssueBookToStudentGoWrongWithAUsnWrong(){ List issueData = Arrays.asList( @@ -255,7 +241,6 @@ void testIssueBookToStudentGoWrongWithAUsnWrong(){ studentService.save(issueData.get(0), issueData.get(1)); InvalidBookInformationException exception = assertThrows(InvalidBookInformationException.class,() -> menuService.issueBookToStudent(issueData)); assertEquals("The provided information is invalid. Please check the format", exception.getMessage()); - } @Test @@ -265,7 +250,6 @@ void testIssueBookToStudentGoWrongWithUnavailableQuantity(){ "Pedro", "978-84-415-4302-1" ); - List bookData = Arrays.asList( "978-84-415-4302-1", "The fenix project", @@ -278,44 +262,36 @@ void testIssueBookToStudentGoWrongWithUnavailableQuantity(){ studentService.save(issueData.get(0), issueData.get(1)); NoBookFoundException exception = assertThrows(NoBookFoundException.class,() -> menuService.issueBookToStudent(issueData)); assertEquals("Quantity unavailable", exception.getMessage()); - } - - -// @Test -// void testIssueBookToStudent() { -// List issueData = Arrays.asList( -// "09003688800", -// "Pedro", -// "978-84-415-4302-1" -// ); -// -// List bookData = Arrays.asList( -// "978-84-415-4302-1", -// "The fenix project", -// "novel", -// "Gene Kim", -// "g.kim@gmail.com", -// "10" -// ); -// menuService.addBook(bookData); -// String usnStudent = issueData.get(0); -// String name = issueData.get(1); -// -// studentService.save(usnStudent,name); -// assertDoesNotThrow(() -> menuService.issueBookToStudent(issueData)); -// Optional> optionalBookList = issueService.findAllBooksIssuedByUsn(usnStudent); -// if(optionalBookList.isPresent()){ -// List bookList = optionalBookList.get(); -// assertEquals(1, bookList.size()); -// assertEquals(9, bookList.get(0).getQuantity()); -// } -// } - - - - + @Test + void testIssueBookToStudent() throws NoBookFoundException { + List issueData = Arrays.asList( + "09003688800", + "Pedro", + "978-84-415-4302-1" + ); + List bookData = Arrays.asList( + "978-84-415-4302-1", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + menuService.addBook(bookData); + String usnStudent = issueData.get(0); + String name = issueData.get(1); + + studentService.save(usnStudent,name); + assertDoesNotThrow(() -> menuService.issueBookToStudent(issueData)); + Optional> optionalBookList = issueService.findAllBooksIssuedByUsn(usnStudent); + if(optionalBookList.isPresent()){ + List bookList = optionalBookList.get(); + assertEquals(1, bookList.size()); + assertEquals(9, bookList.get(0).getQuantity()); + } + } @Test void searchBooksAlongAuthors() { @@ -356,6 +332,69 @@ void searchBooksAlongAuthors() { } } + @Test + void testSearchBooksByUsnProperFunction() throws Exception { + List bookData = Arrays.asList( + "978-84-415-4302-1", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + List issueData = Arrays.asList( + "09003688800", + "Pedro", + "978-84-415-4302-1" + ); + menuService.addBook(bookData); + String usnStudent = issueData.get(0); + String name = issueData.get(1); + studentService.save(usnStudent,name); + + try { + menuService.issueBookToStudent(issueData); + List objectList = menuService.searchBooksByUsn(usnStudent); + assertEquals(1, objectList.size()); + + Book book = (Book) objectList.get(0)[0]; + Issue issue = (Issue) objectList.get(0)[1]; + assertEquals("The fenix project", book.getTitle()); + assertEquals("Pedro", issue.getIssueStudent().getName()); + } catch (Exception e){ + fail(); + } + } + + @Test + void testSearchBooksByUsnWrongUsn() throws Exception { + List bookData = Arrays.asList( + "978-84-415-4302-1", + "The fenix project", + "novel", + "Gene Kim", + "g.kim@gmail.com", + "10" + ); + List issueData = Arrays.asList( + "09003688800", + "Pedro", + "978-84-415-4302-1" + ); + menuService.addBook(bookData); + String usnStudent = issueData.get(0); + String name = issueData.get(1); + studentService.save(usnStudent,name); + try { + menuService.issueBookToStudent(issueData); + assertThrows(Exception.class, () -> { + menuService.searchBooksByUsn("00001"); + }); + } catch (Exception e){ + fail(); + } + } + @AfterEach void tearDown() { issueRepository.deleteAll(); From 83afc63dd75cd25e0aff6b6a756a21f0e4760c0c Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 18:03:59 +0200 Subject: [PATCH 102/112] remove show sql --- src/main/resources/application.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c983a55b..8c2ad29d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,6 +8,6 @@ spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect ##spring.jpa.hibernate.ddl-auto=validate -spring.jpa.show-sql=true -spring.jpa.open-in-view=true +#spring.jpa.show-sql=true +#spring.jpa.open-in-view=true app.menu.enabled=true \ No newline at end of file From 6645803bd49e33618ca9354f9eb60d54b5d48517 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 18:30:51 +0200 Subject: [PATCH 103/112] solve some issue of menu --- .../java/com/ironhack/ironLibrary/service/MenuServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index 46b36ccc..2c56db85 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -250,6 +250,7 @@ private boolean executeMenuOption(int userInput) { System.out.println(DataOutput.listBookTable(books)); return isError; } catch (NoBookFoundException e) { + System.out.println(e.getMessage()); return true; } case 4: @@ -261,6 +262,7 @@ private boolean executeMenuOption(int userInput) { System.out.println(DataOutput.oneBookTable(book)); return isError; } catch (NoBookFoundException e) { + System.out.println(e.getMessage()); return true; } case 5: From adbeb9eeec0233210a181a14589fa1edce8f7ebf Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 19:21:14 +0200 Subject: [PATCH 104/112] update menu option 6 --- .../ironLibrary/service/MenuServiceImpl.java | 37 +++++++++---------- .../ironhack/ironLibrary/utils/Validator.java | 5 ++- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index 2c56db85..c9d564fa 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -64,8 +64,8 @@ public List getNewBookInformation(){ public List getNewIssueInformation(){ List issueDetails = new ArrayList<>(); - String usn = Validator.userInput("Enter usn: ", true, "validateInteger", - "The quantity only accepts numbers"); + String usn = Validator.userInput("Enter usn: ", true, "validateUsnFormat", + "USN must have 11 digits"); issueDetails.add(usn); String studentName = Validator.userInput("Enter name: ", true, "validateStringGeneralFormat", "The author name only accepts letters"); @@ -82,7 +82,6 @@ public void addBook(List bookAndAuthorInformation) { throw new InvalidBookInformationException( "The book and author information must be a six-element string list."); } - String isbn = bookAndAuthorInformation.get(0); String title = bookAndAuthorInformation.get(1); String category = bookAndAuthorInformation.get(2); @@ -143,29 +142,26 @@ public void issueBookToStudent(List issueData) throws NoBookFoundExcepti String usn = issueData.get(0); String name = issueData.get(1); String isbn = issueData.get(2); - if (!Validator.checkISBNFormat(isbn) || !Validator.validateStringGeneralFormat(name) || !Validator.checkUsnFormat(usn) ) { throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); } - Optional optionalStudent = studentService.findStudentByUsnAndName(usn,name); if(optionalStudent.isEmpty()){ studentService.save(usn, name); - }else{ - Student student = optionalStudent.get(); - Book book = bookService.findByIsbn(isbn).orElseThrow(() -> new NoBookFoundException("No books are found with that ISBN")); - if (book.getQuantity() < 1) { - throw new NoBookFoundException("Quantity unavailable"); - } else { - book.setQuantity(book.getQuantity() - 1); - bookService.save(book); - issueService.save(student, book); - // Update book quantity - - } + optionalStudent = studentService.findStudentByUsnAndName(usn,name); + } + Student student = optionalStudent.get(); + Book book = bookService.findByIsbn(isbn).orElseThrow(() -> new NoBookFoundException("No books are found with that ISBN")); + if (book.getQuantity() < 1) { + throw new NoBookFoundException("Quantity unavailable"); + } else { + book.setQuantity(book.getQuantity() - 1); + bookService.save(book); + issueService.save(student, book); + // Update book quantity } } @@ -272,6 +268,7 @@ private boolean executeMenuOption(int userInput) { System.out.println(DataOutput.listBookTableWithAuthor(objects)); return isError; } catch (NoBookFoundException e) { + System.out.println(e.getMessage()); return true; } case 6: @@ -280,11 +277,12 @@ private boolean executeMenuOption(int userInput) { issueBookToStudent(issueData); return isError; } catch (NoBookFoundException e) { + System.out.println(e.getMessage()); return true; } case 7: - String usn = Validator.userInput("Enter usn: ", true, "validateInteger", - "The quantity only accepts numbers"); + String usn = Validator.userInput("Enter usn: ", true, "validateUsnFormat", + "USN must have 11 digits"); try { List info = searchBooksByUsn(usn); Object[] firstElement = info.get(0); @@ -293,6 +291,7 @@ private boolean executeMenuOption(int userInput) { System.out.println(DataOutput.listBookTableByUsn(info, student)); return isError; } catch (Exception e) { + System.out.println(e.getMessage()); return true; } case 8: diff --git a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java index 1ff6b39d..b16c1ebc 100644 --- a/src/main/java/com/ironhack/ironLibrary/utils/Validator.java +++ b/src/main/java/com/ironhack/ironLibrary/utils/Validator.java @@ -18,8 +18,6 @@ public static boolean checkEmailFormat(String email){ return patternMatches(email, "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"); } - - private static boolean patternMatches(String inputString, String regexPattern) { return Pattern.compile(regexPattern) .matcher(inputString) @@ -79,6 +77,9 @@ public static String userInput(String printText, boolean validTheNextInput, Stri case "notBlankValidatorBooks": result = Validator.notBlankValidatorBooks(userInputText); break; + case "validateUsnFormat": + result = Validator.checkUsnFormat(userInputText); + break; } if(!result){ System.out.println("Sorry, but the input format it's incorrect. Please try again: "); From 37eeaa2ed42ee4c012fab6841befd7521f8d5560 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Mon, 8 Apr 2024 20:37:18 +0200 Subject: [PATCH 105/112] main menu mpv2 --- .../repository/BookRepository.java | 3 ++- .../ironLibrary/service/BookServiceImpl.java | 5 +++++ .../ironLibrary/service/IBookService.java | 1 + .../ironLibrary/service/MenuServiceImpl.java | 22 +++++++++++++++++-- src/main/resources/application.properties | 8 +++---- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java index c997a9d7..5de8ff57 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/BookRepository.java @@ -11,6 +11,7 @@ public interface BookRepository extends JpaRepository { Optional> findAllByCategory(String Category); Optional findOneByTitle(String Title); - Optional findByIsbn(String isbn); + Optional> findAllByTitle(String title); + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java index 87ecb72b..c70336e0 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/BookServiceImpl.java @@ -32,4 +32,9 @@ public Optional> findAllByCategory(String category) { public Optional findOneByTitle(String title) { return bookRepository.findOneByTitle(title); } + + @Override + public Optional> findAllByTitle(String title) { + return bookRepository.findAllByTitle(title); + } } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IBookService.java b/src/main/java/com/ironhack/ironLibrary/service/IBookService.java index 607c5c84..732b5890 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IBookService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IBookService.java @@ -8,5 +8,6 @@ public interface IBookService { Optional findByIsbn(String isbn); Optional> findAllByCategory(String Category); Optional findOneByTitle(String Title); + Optional> findAllByTitle(String title); } diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index c9d564fa..c942fa7e 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -138,6 +138,16 @@ public List searchBookByCategory(String category) throws NoBookFoundExcept } } + public List searchBookByTitle(String title) throws NoBookFoundException { + if(!Validator.validateStringGeneralFormat(title)) throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); + Optional> optionalBookList = bookService.findAllByTitle(title); + if(optionalBookList.isPresent() && !optionalBookList.get().isEmpty()){ + return optionalBookList.get(); + }else{ + throw new NoBookFoundException("No books found for this category: " + title); + } + } + public void issueBookToStudent(List issueData) throws NoBookFoundException { String usn = issueData.get(0); String name = issueData.get(1); @@ -235,8 +245,16 @@ private boolean executeMenuOption(int userInput) { addBook(bookAndAuthorInformation); return isError; case 2: - System.out.println("option 2"); - break; + String title = Validator.userInput("Enter title: ", false, "NULL", "NULL"); + List booksByTitle = null; + try { + booksByTitle = searchBookByTitle(title); + System.out.println(DataOutput.listBookTable(booksByTitle)); + return isError; + } catch (NoBookFoundException e) { + System.out.println(e.getMessage()); + return true; + } case 3: String category = Validator.userInput("Enter category: ", true, "validateStringGeneralFormat", "The category only accepts letters"); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8c2ad29d..0693bec7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,9 +1,9 @@ spring.application.name=ironLibrary -spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}?createDatabaseIfNotExist=TRUE -spring.datasource.username=${MYSQL_USERNAME} -spring.datasource.password=${MYSQL_PASSWORD} +spring.datasource.url=jdbc:mysql://localhost:3306/library_test?createDatabaseIfNotExist=TRUE +spring.datasource.username=root +spring.datasource.password=root -spring.jpa.properties.hibernate.hbm2ddl.auto=update +spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect ##spring.jpa.hibernate.ddl-auto=validate From d1e1f60e59e7205ccab1a501d5fb689aa7670795 Mon Sep 17 00:00:00 2001 From: esmartdie Date: Mon, 8 Apr 2024 20:41:30 +0200 Subject: [PATCH 106/112] adding real application.properties filecontent --- src/main/resources/application.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0693bec7..8c2ad29d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,9 +1,9 @@ spring.application.name=ironLibrary -spring.datasource.url=jdbc:mysql://localhost:3306/library_test?createDatabaseIfNotExist=TRUE -spring.datasource.username=root -spring.datasource.password=root +spring.datasource.url=jdbc:mysql://localhost:3306/${MYSQL_DATABASE}?createDatabaseIfNotExist=TRUE +spring.datasource.username=${MYSQL_USERNAME} +spring.datasource.password=${MYSQL_PASSWORD} -spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop +spring.jpa.properties.hibernate.hbm2ddl.auto=update spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect ##spring.jpa.hibernate.ddl-auto=validate From 502f24a7226783bff6c6eec937d6f8ddba59d021 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 21:28:29 +0200 Subject: [PATCH 107/112] solve menu errors --- .../repository/IssueRepository.java | 5 +- .../ironLibrary/service/IIssueService.java | 1 + .../ironLibrary/service/IMenuService.java | 3 +- .../ironLibrary/service/IssueServiceImpl.java | 6 ++ .../ironLibrary/service/MenuServiceImpl.java | 56 ++++++++++++------- .../service/StudentServiceImpl.java | 2 +- .../utils/BookWithActiveIssueException.java | 7 +++ .../utils/NoStudentFoundException.java | 7 +++ ...StudentExistsWithAnotherNameException.java | 7 +++ .../StudentWithActiveIssueException.java | 7 +++ 10 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/BookWithActiveIssueException.java create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/NoStudentFoundException.java create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java create mode 100644 src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java diff --git a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java index 4ac4eed0..523493db 100644 --- a/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java +++ b/src/main/java/com/ironhack/ironLibrary/repository/IssueRepository.java @@ -8,9 +8,12 @@ import java.util.Optional; public interface IssueRepository extends JpaRepository { - @Query("SELECT b from Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") + @Query("SELECT b FROM Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") Optional> findAllBooksByUsn(String usn); @Query("SELECT b, i FROM Issue i JOIN i.issueStudent c JOIN i.issueBook b WHERE c.usn = ?1") Optional> findAllBooksAndIssuesByUsn(String usn); + + @Query("SELECT i FROM Issue i WHERE i.issueBook.isbn = ?1") + Optional findIssueByIsbn(String isbn); } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java b/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java index d9cde4c8..03b822be 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IIssueService.java @@ -12,4 +12,5 @@ public interface IIssueService { Issue save(Student student, Book book); Optional> findAllBooksIssuedByUsn(String usn); public Optional> findAllBooksAndIssuesByUsn(String usn); + public Optional findIssueByIsbn(String isbn); } diff --git a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java index e73ecb88..903b24e9 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IMenuService.java @@ -1,5 +1,6 @@ package com.ironhack.ironLibrary.service; import com.ironhack.ironLibrary.model.Book; +import com.ironhack.ironLibrary.model.Issue; import com.ironhack.ironLibrary.utils.NoBookFoundException; import java.util.List; @@ -17,7 +18,7 @@ public interface IMenuService { List searchBookByCategory(String Category) throws NoBookFoundException; - void issueBookToStudent(List issueInformation) throws NoBookFoundException; + Issue issueBookToStudent(List issueInformation) throws NoBookFoundException; List searchBooksByUsn(String usn) throws Exception; diff --git a/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java index 9d595724..7e3024a3 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/IssueServiceImpl.java @@ -32,4 +32,10 @@ public Optional> findAllBooksAndIssuesByUsn(String usn){ public Optional> findAllBooksIssuedByUsn(String usn) { return issueRepository.findAllBooksByUsn(usn); } + + @Override + public Optional findIssueByIsbn(String isbn) { + return issueRepository.findIssueByIsbn(isbn); + } + } diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index c9d564fa..2e09a7d1 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -5,16 +5,13 @@ import com.ironhack.ironLibrary.model.Book; import com.ironhack.ironLibrary.model.Issue; import com.ironhack.ironLibrary.model.Student; -import com.ironhack.ironLibrary.utils.DataOutput; -import com.ironhack.ironLibrary.utils.InvalidBookInformationException; -import com.ironhack.ironLibrary.utils.NoBookFoundException; +import com.ironhack.ironLibrary.utils.*; import org.springframework.beans.factory.annotation.Autowired; import java.sql.SQLOutput; import java.util.*; -import com.ironhack.ironLibrary.utils.Validator; import org.springframework.stereotype.Service; @@ -116,7 +113,7 @@ public void addBook(List bookAndAuthorInformation) { } } - public Book searchBookByAuthor(String authorName) throws NoBookFoundException { + public Book searchBookByAuthor(String authorName) throws NoBookFoundException, InvalidBookInformationException { if (!Validator.validateStringGeneralFormat(authorName)) { throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); } @@ -128,17 +125,20 @@ public Book searchBookByAuthor(String authorName) throws NoBookFoundException { } } - public List searchBookByCategory(String category) throws NoBookFoundException { - if(!Validator.validateStringGeneralFormat(category)) throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); - Optional> optionalBookList = bookService.findAllByCategory(category); - if(optionalBookList.isPresent() && !optionalBookList.get().isEmpty()){ + public List searchBookByCategory(String category) throws NoBookFoundException, + InvalidBookInformationException { + if(!Validator.validateStringGeneralFormat(category)) + throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); + Optional> optionalBookList = bookService.findAllByCategory(category); + if(optionalBookList.isPresent() && !optionalBookList.get().isEmpty()){ return optionalBookList.get(); - }else{ + }else{ throw new NoBookFoundException("No books found for this category: " + category); - } + } } - public void issueBookToStudent(List issueData) throws NoBookFoundException { + public Issue issueBookToStudent(List issueData) throws InvalidBookInformationException, + NoBookFoundException, BookWithActiveIssueException, StudentExistsWithAnotherNameException { String usn = issueData.get(0); String name = issueData.get(1); String isbn = issueData.get(2); @@ -149,23 +149,39 @@ public void issueBookToStudent(List issueData) throws NoBookFoundExcepti throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); } Optional optionalStudent = studentService.findStudentByUsnAndName(usn,name); - if(optionalStudent.isEmpty()){ + Optional optionalStudentByUsn = studentService.findStudentByUsn(usn); + if(optionalStudent.isPresent()){ + Student student = optionalStudent.get(); + if (issueService.findAllBooksIssuedByUsn(student.getUsn()).isPresent()){ + throw new StudentWithActiveIssueException("Student has an active issue"); + } + } else if(optionalStudentByUsn.isPresent()){ + Student student = optionalStudentByUsn.get(); + if (issueService.findAllBooksIssuedByUsn(student.getUsn()).isPresent()){ + throw new StudentExistsWithAnotherNameException("Usn already exists with another student associated"); + } + } else{ studentService.save(usn, name); optionalStudent = studentService.findStudentByUsnAndName(usn,name); } Student student = optionalStudent.get(); + Book book = bookService.findByIsbn(isbn).orElseThrow(() -> new NoBookFoundException("No books are found with that ISBN")); + Issue issue; if (book.getQuantity() < 1) { throw new NoBookFoundException("Quantity unavailable"); + } else if (issueService.findIssueByIsbn(book.getIsbn()).isPresent()) { + throw new BookWithActiveIssueException("The book has an active issue"); } else { book.setQuantity(book.getQuantity() - 1); bookService.save(book); - issueService.save(student, book); + issue = issueService.save(student, book); // Update book quantity } + return issue; } - public List searchBooksByUsn(String usn) throws Exception { + public List searchBooksByUsn(String usn) throws NoBookFoundException, NoStudentFoundException { Optional optionalStudent = studentService.findStudentByUsn(usn); if(optionalStudent.isPresent()){ Student student = optionalStudent.get(); @@ -176,7 +192,7 @@ public List searchBooksByUsn(String usn) throws Exception { throw new NoBookFoundException("No books found for this usn: " + usn); } }else{ - throw new Exception("No student found for this usn: " + usn); + throw new NoStudentFoundException("No student found for this usn: " + usn); } } @@ -274,9 +290,11 @@ private boolean executeMenuOption(int userInput) { case 6: List issueData = getNewIssueInformation(); try { - issueBookToStudent(issueData); + Issue issue = issueBookToStudent(issueData); + System.out.println(DataOutput.bookIssuedDate(issue)); return isError; - } catch (NoBookFoundException e) { + } catch (NoBookFoundException | BookWithActiveIssueException | StudentWithActiveIssueException + | StudentExistsWithAnotherNameException e) { System.out.println(e.getMessage()); return true; } @@ -290,7 +308,7 @@ private boolean executeMenuOption(int userInput) { Student student = issue.getIssueStudent(); System.out.println(DataOutput.listBookTableByUsn(info, student)); return isError; - } catch (Exception e) { + } catch (NoBookFoundException | NoStudentFoundException e){ System.out.println(e.getMessage()); return true; } diff --git a/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java index e835f430..51613d3b 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/StudentServiceImpl.java @@ -24,6 +24,6 @@ public Student save(String usn, String name) { @Override public Optional findStudentByUsn(String usn) { return studentRepository.findByUsn(usn); - } + } diff --git a/src/main/java/com/ironhack/ironLibrary/utils/BookWithActiveIssueException.java b/src/main/java/com/ironhack/ironLibrary/utils/BookWithActiveIssueException.java new file mode 100644 index 00000000..3e83a6a6 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/BookWithActiveIssueException.java @@ -0,0 +1,7 @@ +package com.ironhack.ironLibrary.utils; + +public class BookWithActiveIssueException extends RuntimeException { + public BookWithActiveIssueException(String s) { + super(s); + } +} diff --git a/src/main/java/com/ironhack/ironLibrary/utils/NoStudentFoundException.java b/src/main/java/com/ironhack/ironLibrary/utils/NoStudentFoundException.java new file mode 100644 index 00000000..f9690dcb --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/NoStudentFoundException.java @@ -0,0 +1,7 @@ +package com.ironhack.ironLibrary.utils; + +public class NoStudentFoundException extends InstantiationException{ + public NoStudentFoundException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java b/src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java new file mode 100644 index 00000000..280e4367 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java @@ -0,0 +1,7 @@ +package com.ironhack.ironLibrary.utils; + +public class StudentExistsWithAnotherNameException extends RuntimeException{ + public StudentExistsWithAnotherNameException(String s) { + super(s); + } +} \ No newline at end of file diff --git a/src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java b/src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java new file mode 100644 index 00000000..eea8fcd3 --- /dev/null +++ b/src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java @@ -0,0 +1,7 @@ +package com.ironhack.ironLibrary.utils; + +public class StudentWithActiveIssueException extends RuntimeException { + public StudentWithActiveIssueException(String s) { + super(s); + } +} \ No newline at end of file From a2f2a0b161dbcd7bcee0b5aa1da11b3eb9320b91 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 22:27:10 +0200 Subject: [PATCH 108/112] solve menu issues --- .../ironLibrary/service/MenuServiceImpl.java | 64 ++++++++----------- ...StudentExistsWithAnotherNameException.java | 7 -- .../StudentWithActiveIssueException.java | 7 -- 3 files changed, 28 insertions(+), 50 deletions(-) delete mode 100644 src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java delete mode 100644 src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index 892314cb..a8062fad 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -6,6 +6,7 @@ import com.ironhack.ironLibrary.model.Issue; import com.ironhack.ironLibrary.model.Student; import com.ironhack.ironLibrary.utils.*; +import jakarta.persistence.criteria.CriteriaBuilder; import org.springframework.beans.factory.annotation.Autowired; @@ -73,7 +74,7 @@ public List getNewIssueInformation(){ return issueDetails; } - public void addBook(List bookAndAuthorInformation) { + public void addBook(List bookAndAuthorInformation) throws InvalidBookInformationException{ if (bookAndAuthorInformation.size() != 6) { throw new InvalidBookInformationException( @@ -137,7 +138,7 @@ public List searchBookByCategory(String category) throws NoBookFoundExcept } } - public List searchBookByTitle(String title) throws NoBookFoundException { + public List searchBookByTitle(String title) throws NoBookFoundException, InvalidBookInformationException { if(!Validator.validateStringGeneralFormat(title)) throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); Optional> optionalBookList = bookService.findAllByTitle(title); if(optionalBookList.isPresent() && !optionalBookList.get().isEmpty()){ @@ -148,8 +149,7 @@ public List searchBookByTitle(String title) throws NoBookFoundException { } public Issue issueBookToStudent(List issueData) throws InvalidBookInformationException, - NoBookFoundException, BookWithActiveIssueException, StudentExistsWithAnotherNameException { - + NoBookFoundException, BookWithActiveIssueException { String usn = issueData.get(0); String name = issueData.get(1); String isbn = issueData.get(2); @@ -160,37 +160,25 @@ public Issue issueBookToStudent(List issueData) throws InvalidBookInform throw new InvalidBookInformationException("The provided information is invalid. Please check the format"); } Optional optionalStudent = studentService.findStudentByUsnAndName(usn,name); - Optional optionalStudentByUsn = studentService.findStudentByUsn(usn); - if(optionalStudent.isPresent()){ - Student student = optionalStudent.get(); - if (issueService.findAllBooksIssuedByUsn(student.getUsn()).isPresent()){ - throw new StudentWithActiveIssueException("Student has an active issue"); - } - } else if(optionalStudentByUsn.isPresent()){ - Student student = optionalStudentByUsn.get(); - if (issueService.findAllBooksIssuedByUsn(student.getUsn()).isPresent()){ - throw new StudentExistsWithAnotherNameException("Usn already exists with another student associated"); - } - } else{ + if (optionalStudent.isEmpty()){ studentService.save(usn, name); optionalStudent = studentService.findStudentByUsnAndName(usn,name); - } - Student student = optionalStudent.get(); - - Book book = bookService.findByIsbn(isbn).orElseThrow(() -> new NoBookFoundException("No books are found with that ISBN")); - Issue issue; - if (book.getQuantity() < 1) { - throw new NoBookFoundException("Quantity unavailable"); - } else if (issueService.findIssueByIsbn(book.getIsbn()).isPresent()) { - throw new BookWithActiveIssueException("The book has an active issue"); - } else { + } + Student student = optionalStudent.get(); + Book book = bookService.findByIsbn(isbn).orElseThrow(() -> new NoBookFoundException("No books are found with that ISBN")); + Issue issue; + if (book.getQuantity() < 1) { + throw new NoBookFoundException("Quantity unavailable"); + } else if (issueService.findIssueByIsbn(book.getIsbn()).isPresent()) { + throw new BookWithActiveIssueException("The book has an active issue"); + } else { book.setQuantity(book.getQuantity() - 1); bookService.save(book); issue = issueService.save(student, book); // Update book quantity - } + } return issue; - } + } public List searchBooksByUsn(String usn) throws NoBookFoundException, NoStudentFoundException { Optional optionalStudent = studentService.findStudentByUsn(usn); @@ -258,9 +246,14 @@ private boolean executeMenuOption(int userInput) { boolean isError = false; switch (userInput){ case 1: - List bookAndAuthorInformation = getNewBookInformation(); - addBook(bookAndAuthorInformation); - return isError; + try { + List bookAndAuthorInformation = getNewBookInformation(); + addBook(bookAndAuthorInformation); + return isError; + } catch (InvalidBookInformationException e){ + System.out.println(e.getMessage()); + return true; + } case 2: String title = Validator.userInput("Enter title: ", false, "NULL", "NULL"); List booksByTitle = null; @@ -268,7 +261,7 @@ private boolean executeMenuOption(int userInput) { booksByTitle = searchBookByTitle(title); System.out.println(DataOutput.listBookTable(booksByTitle)); return isError; - } catch (NoBookFoundException e) { + } catch (NoBookFoundException | InvalidBookInformationException e) { System.out.println(e.getMessage()); return true; } @@ -280,7 +273,7 @@ private boolean executeMenuOption(int userInput) { books = searchBookByCategory(category); System.out.println(DataOutput.listBookTable(books)); return isError; - } catch (NoBookFoundException e) { + } catch (NoBookFoundException | InvalidBookInformationException e) { System.out.println(e.getMessage()); return true; } @@ -292,7 +285,7 @@ private boolean executeMenuOption(int userInput) { book = searchBookByAuthor(authorName); System.out.println(DataOutput.oneBookTable(book)); return isError; - } catch (NoBookFoundException e) { + } catch (NoBookFoundException | InvalidBookInformationException e) { System.out.println(e.getMessage()); return true; } @@ -312,8 +305,7 @@ private boolean executeMenuOption(int userInput) { Issue issue = issueBookToStudent(issueData); System.out.println(DataOutput.bookIssuedDate(issue)); return isError; - } catch (NoBookFoundException | BookWithActiveIssueException | StudentWithActiveIssueException - | StudentExistsWithAnotherNameException e) { + } catch (NoBookFoundException | BookWithActiveIssueException e) { System.out.println(e.getMessage()); return true; } diff --git a/src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java b/src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java deleted file mode 100644 index 280e4367..00000000 --- a/src/main/java/com/ironhack/ironLibrary/utils/StudentExistsWithAnotherNameException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.ironhack.ironLibrary.utils; - -public class StudentExistsWithAnotherNameException extends RuntimeException{ - public StudentExistsWithAnotherNameException(String s) { - super(s); - } -} \ No newline at end of file diff --git a/src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java b/src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java deleted file mode 100644 index eea8fcd3..00000000 --- a/src/main/java/com/ironhack/ironLibrary/utils/StudentWithActiveIssueException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.ironhack.ironLibrary.utils; - -public class StudentWithActiveIssueException extends RuntimeException { - public StudentWithActiveIssueException(String s) { - super(s); - } -} \ No newline at end of file From 0013c53460bc91de0b8387a89a483f6eeb165016 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 22:28:18 +0200 Subject: [PATCH 109/112] solve menu issues --- .../com/ironhack/ironLibrary/service/MenuServiceImplTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java index dc581ff5..a91bc009 100644 --- a/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java +++ b/src/test/java/com/ironhack/ironLibrary/service/MenuServiceImplTest.java @@ -222,7 +222,7 @@ void testSearchBookByCategoryGoesWrong(){ @Test void testIssueBookToStudentGoWrongWithAIsbnWrong(){ List issueData = Arrays.asList( - "09003688800", + "09003688801", "Pedro", "978-84-415-5302-1" ); @@ -246,7 +246,7 @@ void testIssueBookToStudentGoWrongWithAUsnWrong(){ @Test void testIssueBookToStudentGoWrongWithUnavailableQuantity(){ List issueData = Arrays.asList( - "09003688800", + "09003688802", "Pedro", "978-84-415-4302-1" ); From f1cedea953bee55d02efb81f0e13d5d80ddd1b93 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 22:34:19 +0200 Subject: [PATCH 110/112] solve menu issues --- .../java/com/ironhack/ironLibrary/service/MenuServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index a8062fad..bf773483 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -144,7 +144,7 @@ public List searchBookByTitle(String title) throws NoBookFoundException, I if(optionalBookList.isPresent() && !optionalBookList.get().isEmpty()){ return optionalBookList.get(); }else{ - throw new NoBookFoundException("No books found for this category: " + title); + throw new NoBookFoundException("No books found for this author: " + title); } } From 9c6ff80157c9260e0ad10a35f04d8de4ba6ca046 Mon Sep 17 00:00:00 2001 From: JuliaORS Date: Mon, 8 Apr 2024 22:35:13 +0200 Subject: [PATCH 111/112] solve menu issues --- .../java/com/ironhack/ironLibrary/service/MenuServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java index bf773483..dd7c92bd 100644 --- a/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java +++ b/src/main/java/com/ironhack/ironLibrary/service/MenuServiceImpl.java @@ -144,7 +144,7 @@ public List searchBookByTitle(String title) throws NoBookFoundException, I if(optionalBookList.isPresent() && !optionalBookList.get().isEmpty()){ return optionalBookList.get(); }else{ - throw new NoBookFoundException("No books found for this author: " + title); + throw new NoBookFoundException("No books found with this title: " + title); } } From f6d31e9a28028516d852bdd25451939b76bcbbde Mon Sep 17 00:00:00 2001 From: JuliaORS <128370372+JuliaORS@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:55:27 +0200 Subject: [PATCH 112/112] Create README_library.md --- README_library.md | 317 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 README_library.md diff --git a/README_library.md b/README_library.md new file mode 100644 index 00000000..11c918db --- /dev/null +++ b/README_library.md @@ -0,0 +1,317 @@ +# IronLibrary Application + +## Models + +#### Author Class +The Author class represents the details of an author associated with a book in the library. +Attributes: + - authorId: Integer - Unique identifier for the author (generated automatically). + - name: String - Name of the author. + - email: String - Email address of the author. + +#### Book Class +The Book class represents the details of a book in the library. +Attributes: + - isbn: String - Unique identifier for the book. + - title: String - Title of the book. + - category: String - Category of the book. + - quantity: Integer - Number of copies available in the library. + +#### Issue Class +The Issue class represents the details of a book issued to a student from the library. +Attributes: + - issueId: Integer - Unique identifier for the issue (generated automatically). + - issueDate: LocalDateTime - Date and time when the book was issued. + - returnDate: LocalDateTime - Date and time when the book is expected to be returned. + - issueStudent: Student - Student who issued the book. + - issueBook: Book - Book issued. + +#### Student Class +The Student class represents the details of a student. +Attributes: + - usn: String - Unique student number. + - name: String - Student's name. + + +## Repositories + +#### AuthorRepository +Custom methods: + - findBookByAuthor(String authorName): Find a book by author's name. + - findAllBooksWithAuthors(): Find all books with authors. + - findByAuthorBook(Book book): Find an author by a specific book. + +#### BookRepository +Custom methods: + - findAllByCategory(String Category): Find all books by category. + - findOneByTitle(String Title): Find a book by title. + - findByIsbn(String isbn): Find a book by ISBN. + +#### IssueRepository +Custom methods: + - findAllBooksByUsn(String Usn): Find all books issued by a student number. + - findAllBooksAndIssuesByUsn(String usn): Find all books and issues by a student number. + +#### StudentRepository +Custom methods: + - findByUsnAndName(String usn, String name): Find a student by number and name. + - findByUsn(String usn): Find a student by number. + + +## Services + +#### AuthorServiceImpl +Methods: + - save(Author author): Saves an author. + - findBookByAuthor(String authorName): Find a book by author's name. + - findAllBooksWithAuthors(): Find all books with authors. + - findByAuthorBook(Book book): Findsan author by a specific book. + +#### BookServiceImpl +The BookServiceImpl class implements the service for book-related operations. +Methods: + - save(Book book): Save a book. + - findByIsbn(String isbn): Find a book by its ISBN. + - findAllByCategory(String category): Find all books by category. + - findOneByTitle(String title): Find a book by title. + - findAllByTitle(String title): Find all books by title. + +#### StudentServiceImpl +The class StudentServiceImpl implements the service for operations related to students in the application. +Methods: + - findStudentByUsnAndName(String usn, String name): Finds a student by unique number and name. + - save(String usn, String name): Saves a new student with the specified number and name. + - findStudentByUsn(String usn): Finds a student by their unique number. + +#### IssueServiceImpl +The class IssueServiceImpl implements the service for operations related to book lending in the application. +These methods allow performing specific operations related to book lending in the IronLibrary application. +Methods: + - save(Student student, Book book): Saves a book lending for a student. + - findAllBooksAndIssuesByUsn(String usn): Finds all books and lendings by student number. + - findAllBooksIssuedByUsn(String usn): Finds all books lent by student number. + - findIssueByIsbn(String isbn): Finds a lending by the ISBN number of a book. + +#### MenuServiceImpl +The MenuServiceImpl class provides methods for managing the menu and related operations in the IronLibrary application. +Methods: + - getNewBookInformation(): Get the information necessary to add a new book. + - getNewIssueInformation(): Get the information necessary to perform a new book issuance. + - addBook(List bookAndAuthorInformation): Add a new book with the provided information. + - searchBookByAuthor(String authorName): Find all books by author. + - searchBookByCategory(String category): Find all books by category. + - searchBookByTitle(String title): Find all books by title. + - issueBookToStudent(List issueData): Create a new issue. + - searchBooksByUsn(String usn): Find all books that are issued by a student with specific usn. + - searchBooksAlongAuthors(): Find all books and their author. + - mainMenu(): Manage the menu of the application. + +#### IAuthorService +AuthorService interface defines the contract for author-related operations in the IronLibrary application. + +#### IBookService +BookService interface defines service operations related to books. + +#### IStudentService +StudentService interface defines service operations related to students. + +#### IIssueService +IssueService interface defines service operations related to book issuance. + +#### IMenuService +MenuService interface defines service operations related to menu management in the application. + + +## Utils +These classes and methods provide a way to handle exceptions and format dates properly in the IronLibrary application. + +#### DataOutput +The DataOutput class provides static methods for formatting and generating data outputs related to books, authors, and loans. +These methods provide a visually appealing way to present information related to books, authors, and loans in the IronLibrary application. +Methods: + - oneBookTable(Book book): Creates an ASCII table to display a single book with its information. + - listBookTable(List books): Creates an ASCII table to display a list of books with their information. + - listBookTableWithAuthor(List lstObjects): Creates an ASCII table to display a list of books along with their respective authors. + - bookIssuedDate(Issue issue): Gets the expected return date of a loaned book. + - listBookTableByUsn(List lstObjects, Student student): Creates an ASCII table to display a list of books loaned by a student with their return information. + +#### DateFormatter +The DateFormatter class provides static methods for formatting dates and times in different formats. +Methods: + - simpleDateFormat(LocalDateTime returnDate): Formats the date and time into a simple "yyyy-MM-dd HH:mm:ss" format. + - largeDateFormat(LocalDateTime returnDate): Formats the date and time into a more detailed format with time zone and day and month abbreviations. + +#### BookWithActiveIssueException +The BookWithActiveIssueException class is an exception used to represent the situation where a book has an active loan. +This could occur when attempting to loan a book that is already on loan. + +#### InvalidBookInformationException +The InvalidBookInformationException class is an exception used to represent the situation where incorrect or invalid information is provided when trying to perform operations with books. + +#### NoBookFoundException +The NoBookFoundException class is an exception used to represent the situation where a book is not found in the application. + +#### NoStudentFoundException +The NoStudentFoundException class is an exception used to represent the situation where a student is not found in the application. + + +### Validator +The Validator class provides various static methods for validating and securely obtaining user input, ensuring that the entered data complies with certain patterns and formats. +Methods: + - checkUsnFormat(String usn): Verifies if the format of the student number (USN) is correct. + - checkISBNFormat(String maybeISBN): Verifies if the format of the ISBN number is correct. + - checkEmailFormat(String email): Verifies if the format of the email address is correct. + - patternMatches(String inputString, String regexPattern): Checks if the regular expression pattern matches the given input. + - validateInteger(String input): Validates if the input is an integer number. + - notBlankValidatorBooks(String input): Verifies if the input is not blank. + - validateStringGeneralFormat(String input): Verifies if the string complies with a general string format, containing only letters and spaces. +Additionally, the userInput method handles obtaining user input and validating it according to a specific format, providing feedback and suggestions to the user. +These methods and the Validator class as a whole offer a secure and consistent mechanism for validating user input in the IronLibrary application. + +## Run +The IronLibraryApplication class is the main class of the IronLibrary application. +It implements the CommandLineRunner interface of Spring Boot to execute additional actions before the application starts completely. + +#### Attributes: + - isMenuEnabled: A boolean attribute indicating whether the application menu is enabled. + - menuService: An instance of the IMenuService service that will be used to interact with the application menu. + +#### Methods: +- main(String[] args): The main method that starts the Spring Boot application. +- run(String... args): The method that executes at the start of the application. If the menu is enabled, it calls the mainMenu() method of the IMenuService service. + +#### Annotations: +@SpringBootApplication: An annotation that combines several annotations, including @Configuration, to enable auto-configuration of the application and scan components, configurations, and services. + +#### Usage: +The IronLibraryApplication class starts the Spring Boot application and controls whether the menu should be displayed at startup, based on the value of the isMenuEnabled attribute. + +### Properties +The application.properties file contains the configuration of the IronLibrary application: + +#### Application Properties: + spring.application.name=ironLibrary: Defines the name of the Spring Boot application as "ironLibrary". + spring.datasource.url: Specifies the URL of the MySQL database that the application connects to. + spring.datasource.username: Provides the username for the database connection. + spring.datasource.password: Provides the password for the database connection. + +#### JPA Configuration: + spring.jpa.properties.hibernate.hbm2ddl.auto=update: Configures the automatic database schema update strategy to the JPA entity model. + spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver: Specifies the name of the MySQL database driver class. + spring.jpa.properties.hibernate.dialect: Defines the Hibernate dialect to interact with the database. + +#### Other Configurations: + app.menu.enabled=true: Enables or disables the application menu. + +## TEST + +### Model tests +These unit tests validate the behavior and functionality of the model classes in the IronLibrary application. + +#### AuthorTest + - createAuthor(): Verifies the creation of an author and its association with a book. + +#### BookTest +Various tests to ensure that the getters and setters of the Book class work correctly. + - Tests to validate the default constructor and proper property initialization. + - Tests to verify object equality and hash codes. + - Tests to update the quantity, category, and title of a book. + - Tests to validate the format of the ISBN and ensure that the title is not null. + - +#### IssueTest + - createIssue(): Tests the creation of a book loan and verifies its properties, such as the date, student, and associated book. + - +#### StudentTest + - createStudent(): Verifies the correct creation of a student and its initialization. + + +### Repository Tests +These unit tests validate that the repositories of the IronLibrary application interact correctly with the database layer and manage business logic effectively. + +#### AuthorRepositoryTest + - Tests to check the retrieval of a book by author. + - Tests to ensure that an empty list is received if the author has no books. + - Tests to retrieve all books with their authors. + - Tests to verify that the associations between books and authors are correct. + - +#### BookRepositoryTest + - Tests to ensure the retrieval of a book by its ISBN, checking that the expected book is retrieved correctly. + - Tests to validate the quantity of books of a certain category. + - Tests to retrieve a book by its title. + - Tests to validate that no book is found for an unregistered ISBN. + - +#### IssueRepositoryTest + - Tests to verify the retrieval of books loaned by student number. + - Tests to confirm the absence of books loaned by a student who has not made loans. + - Tests to retrieve all loaned books with their respective details. + - Tests to ensure the deletion of a loan. + +#### StudentRepositoryTest + - Test to confirm that students are saved correctly in the database. + - Test to check the retrieval of a student by their unique number and name. + + +### Services Tests +These unit tests validate that the services of the IronLibrary application meet their requirements and behave properly in different scenarios. + +#### AuthorServiceImplTest + - Test to validate that the behavior is the same using the repository directly and using the service, confirming that different results are obtained. + +#### BookServiceImplTest + - Test to validate that the behavior is the same using the repository directly and using the service, confirming that different results are obtained. + +#### IssueServiceImplTest +Unit tests to verify if: + - All books issued by a student number are returned correctly. + - The expected behavior is obtained when lending a book to a student. + - It behaves correctly when trying to lend a book to a student with unavailable quantity. + - It behaves properly when searching for books around a student. + +#### MenuServiceImplTest +Tests to validate that: + - Books are added with valid and invalid information, verifying that the appropriate exception is thrown. + - Book searches by author are performed, confirming that they are found and that the correct exception is thrown if they are not found. + - Book searches by category are performed, ensuring they work correctly and that exceptions are thrown in incorrect cases. + - Books are issued to students correctly and that the search for loaned books is correct. + +### Utils Tests +These unit tests validate that the utilities of the IronLibrary application work correctly and comply with the defined format and validation rules. + +#### DataOutputTest + - Tests to validate the generation of ASCII tables for data visualization. + - The tests verify that the expected table is obtained for a single book, a list of books, an empty list of books, a list of books with authors, the issuance of a book, and the return of a book by student number. + +#### DateFormatterTest + - Tests to validate the date formats used in the application. Simple and long date formats are verified. + +#### ValidatorTest +Tests to validate: + - The format of the ISBN. + - The format of the email. + - The format of the student number (USN). + +#### ValidatorTestInteger + - Tests to validate if input numbers are valid integers. + +#### ValidatorTestStrings +Tests to validate: + - The presence of non-empty strings. + - The general format of strings, such as names. + - It also verifies behavior with null or empty strings. + +#### ValidatorUserInputTest + - Tests to verify if user input complies with the defined validation rules. + It uses a console input simulator to test the validation of an ISBN input. + +### Resources +Configuration of resources for IronLibrary tests: + - spring.application.name=ironLibrary: Defines the name of the Spring Boot application. This name can be used in various parts of the application. + - spring.datasource.url=jdbc:mysql://localhost:3306/library_test?createDatabaseIfNotExist=TRUE: Defines the URL of the MySQL database that the application will connect to. It also indicates that if the database does not exist, it will be created. + - spring.datasource.username=root: Username of the MySQL database. + - spring.datasource.password=root: Password of the MySQL database. + - spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop: Configures the creation and deletion of the database schema each time the application starts. + - spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver: Class of the database driver for MySQL connection. + - spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect: Indicates the dialect of the MySQL database that the application will use to map JPA queries to specific SQL queries of the database. + - spring.jpa.show-sql=true: Enables the display of SQL statements generated by Hibernate in the console. Useful for debugging and understanding the queries sent to the database. + - spring.jpa.open-in-view=true: Configures whether to enable open session in view. This property is discouraged as it may cause unexpected database queries. + - app.menu.enabled=false: A specific property of the application that can enable or disable a menu in the application's user interface.