Merge branch 'tibor' into 'master'

ExercisePlan, ExercisePlanDetail - no OneToMany connection, Delete operation

See merge request bossanyit/aitrainer_server!16
This commit is contained in:
Bossányi Tibor 2020-09-10 05:16:35 +00:00
commit e5011f32ff
10 changed files with 99 additions and 29 deletions

View File

@ -11,7 +11,7 @@ plugins {
} }
group = "com.aitrainer" group = "com.aitrainer"
version = "1.0.7" version = "1.0.8"
java.sourceCompatibility = JavaVersion.VERSION_1_8 java.sourceCompatibility = JavaVersion.VERSION_1_8
repositories { repositories {

View File

@ -236,16 +236,17 @@ CREATE TABLE `exercise_plan` (
`description` TEXT(65535) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', `description` TEXT(65535) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`private` TINYINT(4) NULL DEFAULT '0', `private` TINYINT(4) NULL DEFAULT '0',
`date_add` DATETIME NOT NULL, `date_add` DATETIME NOT NULL,
`date_upd` DATETIME NOT NULL,
PRIMARY KEY (`exercise_plan_id`) USING BTREE PRIMARY KEY (`exercise_plan_id`) USING BTREE
) )
COLLATE='utf8mb4_general_ci' COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB ENGINE=InnoDB
; ;
INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`) VALUES (3, 90, 'Common', 'Common training plan', 0, '0000-00-00 00:00:00'); INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`, `date_upd`) VALUES (3, 90, 'Common', 'Common training plan', 0, NULL, NULL);
INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`) VALUES (4, 90, 'Chuck Norris Plan', '', 0, '0000-00-00 00:00:00'); INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`, `date_upd`) VALUES (4, 90, 'Chuck Norris Plan', '', 0, NULL, NULL);
INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`) VALUES (6, 90, 'Boss private', NULL, 1, '2020-09-05 18:00:00'); INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`, `date_upd`) VALUES (6, 90, 'Boss private', '', 1, '2020-09-08 00:06:26', NULL);
INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`) VALUES (7, 90, 'Boss private', NULL, 1, '2020-09-06 08:00:00'); INSERT INTO `exercise_plan` (`exercise_plan_id`, `customer_id`, `name`, `description`, `private`, `date_add`, `date_upd`) VALUES (20, 90, 'Boss private 2', NULL, 1, '2020-09-09 00:06:19', NULL);
CREATE TABLE `exercise_plan_detail` ( CREATE TABLE `exercise_plan_detail` (

View File

@ -1,8 +1,10 @@
package com.aitrainer.api.controller package com.aitrainer.api.controller
import com.aitrainer.api.model.ExercisePlan import com.aitrainer.api.model.ExercisePlan
import com.aitrainer.api.model.ExercisePlanDetail
import com.aitrainer.api.repository.ExercisePlanRepository import com.aitrainer.api.repository.ExercisePlanRepository
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.security.access.annotation.Secured import org.springframework.security.access.annotation.Secured
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
@ -33,7 +35,7 @@ class ExercisePlanController( private val exercisePlanRepository: ExercisePlanRe
@Secured @Secured
@PostMapping("/exercise_plan/{exercisePlanId}") @PostMapping("/exercise_plan/{exercisePlanId}")
fun updateExercisePlanById(@PathVariable(value = "exercisePlanId") exercisePlanId: Long, fun updateExercisePlanById(@PathVariable(value = "exercisePlanId") exercisePlanId: Int,
@Valid @RequestBody exercisePlan: ExercisePlan, @Valid @RequestBody exercisePlan: ExercisePlan,
@RequestHeader requestHeader: RequestHeader? @RequestHeader requestHeader: RequestHeader?
): ResponseEntity<ExercisePlan> { ): ResponseEntity<ExercisePlan> {
@ -49,4 +51,20 @@ class ExercisePlanController( private val exercisePlanRepository: ExercisePlanRe
logger.info("-- updateExercisePlanById id: $updatedPlan ") logger.info("-- updateExercisePlanById id: $updatedPlan ")
return ResponseEntity.ok().body(exercisePlanRepository.save(updatedPlan)) return ResponseEntity.ok().body(exercisePlanRepository.save(updatedPlan))
} }
@Secured
@PostMapping("/exercise_plan/delete/{exercisePlanId}")
fun deleteExercisePlanById(@PathVariable(value = "exercisePlanId") exercisePlanId: Int,
@Valid @RequestBody exercisePlan: ExercisePlan)
:ResponseEntity<HttpStatus> {
val returnPlan = exercisePlanRepository.findById(exercisePlanId).orElse(null)
?: return ResponseEntity.ok().body(HttpStatus.NOT_FOUND)
try {
exercisePlanRepository.delete(returnPlan)
} catch (e: IllegalArgumentException ) {
return ResponseEntity.ok().body(HttpStatus.BAD_REQUEST)
}
return ResponseEntity.ok().body(HttpStatus.OK)
}
} }

View File

@ -22,12 +22,21 @@ class ExercisePlanDetailController( private val exercisePlanDetailRepository: Ex
return ResponseEntity.ok().body(exercisePlanDetailRepository.save(exercisePlanDetail)) return ResponseEntity.ok().body(exercisePlanDetailRepository.save(exercisePlanDetail))
} }
@GetMapping("/exercise_plan_detail/last/{customerId}") /* @GetMapping("/exercise_plan_detail/last/{customerId}")
fun getExercisePlanByCustomerId(@PathVariable(value = "customerId") customerId: Long): ResponseEntity<List<ExercisePlanDetail>> { fun getExercisePlanByCustomerId(@PathVariable(value = "customerId") customerId: Long): ResponseEntity<List<ExercisePlanDetail>> {
val list: List<ExercisePlanDetail> = exercisePlanDetailRepository.getLastExercisePlanDetail(customerId) val list: List<ExercisePlanDetail> = exercisePlanDetailRepository.getLastExercisePlanDetail(customerId)
logger.info("-- getExercisePlanByCustomerId id: $customerId -- $list") logger.info("-- getExercisePlanByCustomerId id: $customerId -- $list")
return ResponseEntity.ok().body(list) return ResponseEntity.ok().body(list)
} }
*/
@GetMapping("/exercise_plan_detail/{exercisePlanId}")
fun getExercisePlanByExercisePlanId(@PathVariable(value = "exercisePlanId") exercisePlanId: Int): ResponseEntity<List<ExercisePlanDetail>> {
val list: List<ExercisePlanDetail> = exercisePlanDetailRepository.findByExercisePlanId(exercisePlanId)
logger.info("-- getExercisePlanByExercisePlanId id: $exercisePlanId -- $list")
return ResponseEntity.ok().body(list)
}
@Secured @Secured
@PostMapping("/exercise_plan_detail/{exercisePlanDetailId}") @PostMapping("/exercise_plan_detail/{exercisePlanDetailId}")
@ -39,7 +48,7 @@ class ExercisePlanDetailController( private val exercisePlanDetailRepository: Ex
?: return ResponseEntity.notFound().build() ?: return ResponseEntity.notFound().build()
val updatedPlanDetail = returnPlanDetail.copy( val updatedPlanDetail = returnPlanDetail.copy(
exercisePlan = exercisePlanDetail.exercisePlan, exercisePlanId = exercisePlanDetail.exercisePlanId,
exerciseTypeId = exercisePlanDetail.exerciseTypeId, exerciseTypeId = exercisePlanDetail.exerciseTypeId,
serie = exercisePlanDetail.serie, serie = exercisePlanDetail.serie,
repeats = exercisePlanDetail.repeats, repeats = exercisePlanDetail.repeats,
@ -56,9 +65,7 @@ class ExercisePlanDetailController( private val exercisePlanDetailRepository: Ex
@Valid @RequestBody exercisePlanDetail: ExercisePlanDetail) @Valid @RequestBody exercisePlanDetail: ExercisePlanDetail)
:ResponseEntity<HttpStatus> { :ResponseEntity<HttpStatus> {
val returnPlanDetail = exercisePlanDetailRepository.findById(exercisePlanDetailId).orElse(null) val returnPlanDetail = exercisePlanDetailRepository.findById(exercisePlanDetailId).orElse(null)
if (returnPlanDetail == null) { ?: return ResponseEntity.ok().body(HttpStatus.NOT_FOUND)
return ResponseEntity.ok().body(HttpStatus.NOT_FOUND)
}
try { try {
exercisePlanDetailRepository.delete(returnPlanDetail) exercisePlanDetailRepository.delete(returnPlanDetail)
} catch (e: IllegalArgumentException ) { } catch (e: IllegalArgumentException ) {

View File

@ -17,11 +17,13 @@ data class ExercisePlan(
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
var exercisePlanId: Long = 0 var exercisePlanId: Int = 0
@OneToMany(fetch = FetchType.EAGER, mappedBy = "exercisePlan") /* @OneToMany(fetch = FetchType.LAZY, mappedBy = "exercisePlan")
@Fetch(value = FetchMode.SUBSELECT) @Fetch(value = FetchMode.SUBSELECT)
val planDetailList: List<ExercisePlanDetail> = mutableListOf<ExercisePlanDetail>() val planDetailList: List<ExercisePlanDetail> = mutableListOf<ExercisePlanDetail>()
*/
} }

View File

@ -6,15 +6,18 @@ import javax.persistence.*
@Entity @Entity
data class ExercisePlanDetail ( data class ExercisePlanDetail (
@get: NonNull var exerciseTypeId: Long = 0, @get: NonNull var exercisePlanId: Int = 0,
@get: NonNull var exerciseTypeId: Int = 0,
@get: NonNull var serie: Int = 0, @get: NonNull var serie: Int = 0,
@get: NonNull var repeats: Int = 0, @get: NonNull var repeats: Int = 0,
@get: NonNull var weightEquation: String? = "", @get: NonNull var weightEquation: String? = ""
@ManyToOne(fetch = FetchType.EAGER, optional = false) /* @ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "exercisePlanId", nullable = false) @JoinColumn(name = "exercisePlanId", nullable = false)
@JsonIgnore @JsonIgnore
val exercisePlan: ExercisePlan? = null val exercisePlan: ExercisePlan? = null
*/
) { ) {
@Id @Id

View File

@ -1,17 +1,21 @@
package com.aitrainer.api.repository package com.aitrainer.api.repository
import com.aitrainer.api.model.ExercisePlan
import com.aitrainer.api.model.ExercisePlanDetail import com.aitrainer.api.model.ExercisePlanDetail
import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
@Repository @Repository
interface ExercisePlanDetailRepository: JpaRepository<ExercisePlanDetail, Long> { interface ExercisePlanDetailRepository: JpaRepository<ExercisePlanDetail, Long> {
@Query("FROM ExercisePlanDetail as d " + /* @Query("FROM ExercisePlanDetail as d " +
"INNER JOIN ExercisePlan as p ON p.exercisePlanId = d.exercisePlan " + "INNER JOIN ExercisePlan as p ON p.exercisePlanId = d.exercisePlan " +
"WHERE p.private = 1 " + "WHERE p.private = 1 " +
"AND p.customerId = :customerId " + "AND p.customerId = :customerId " +
"ORDER BY p.dateAdd DESC ") "ORDER BY p.dateAdd DESC ")
fun getLastExercisePlanDetail(customerId: Long): List<ExercisePlanDetail> fun getLastExercisePlanDetail(customerId: Long): List<ExercisePlanDetail>
*/
fun findByExercisePlanId(exercisePlanId: Int): List<ExercisePlanDetail>
} }

View File

@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
@Repository @Repository
interface ExercisePlanRepository: JpaRepository<ExercisePlan, Long> { interface ExercisePlanRepository: JpaRepository<ExercisePlan, Int> {
@Query(" FROM ExercisePlan" + @Query(" FROM ExercisePlan" +
" WHERE customerId = :customerId AND private = 1" + " WHERE customerId = :customerId AND private = 1" +
" AND dateAdd in (select Max(dateAdd) from ExercisePlan where customerId = :customerId and private = 1) "+ " AND dateAdd in (select Max(dateAdd) from ExercisePlan where customerId = :customerId and private = 1) "+

View File

@ -5,6 +5,7 @@ import com.aitrainer.api.controller.ExercisePlanDetailController
import com.aitrainer.api.model.ExercisePlan import com.aitrainer.api.model.ExercisePlan
import com.aitrainer.api.model.ExercisePlanDetail import com.aitrainer.api.model.ExercisePlanDetail
import com.aitrainer.api.repository.ExercisePlanDetailRepository import com.aitrainer.api.repository.ExercisePlanDetailRepository
import com.aitrainer.api.repository.ExercisePlanRepository
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -12,7 +13,6 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
@ -29,14 +29,14 @@ class ExercisePlanDetailTest {
val plan = ExercisePlan( val plan = ExercisePlan(
) )
plan.exercisePlanId = 6; plan.exercisePlanId = 6
val planDetail = ExercisePlanDetail( val planDetail = ExercisePlanDetail(
exerciseTypeId = 41, exerciseTypeId = 41,
serie = 3, serie = 3,
repeats = 12, repeats = 12,
weightEquation = "50", weightEquation = "50",
exercisePlan = plan exercisePlanId = 6
) )
val savedDetail: ExercisePlanDetail = exercisePlanDetailRepository.save(planDetail) val savedDetail: ExercisePlanDetail = exercisePlanDetailRepository.save(planDetail)
assertEquals(savedDetail.repeats, 12) assertEquals(savedDetail.repeats, 12)
@ -44,7 +44,7 @@ class ExercisePlanDetailTest {
exercisePlanDetailRepository.delete(savedDetail) exercisePlanDetailRepository.delete(savedDetail)
} }
@Test /* @Test
fun testGetLastExercisePlanDetail() { fun testGetLastExercisePlanDetail() {
val exercisePlanDetailList: List<ExercisePlanDetail> = exercisePlanDetailRepository.getLastExercisePlanDetail(90) val exercisePlanDetailList: List<ExercisePlanDetail> = exercisePlanDetailRepository.getLastExercisePlanDetail(90)
logger.info(" ****** list: $exercisePlanDetailList") logger.info(" ****** list: $exercisePlanDetailList")
@ -52,7 +52,7 @@ class ExercisePlanDetailTest {
val exercisePlanDetail: ExercisePlanDetail = exercisePlanDetailList[0] val exercisePlanDetail: ExercisePlanDetail = exercisePlanDetailList[0]
assertEquals(exercisePlanDetail.weightEquation, "40") assertEquals(exercisePlanDetail.weightEquation, "40")
} } */
@Test @Test
fun testUpdatePlanDetail() { fun testUpdatePlanDetail() {
@ -68,7 +68,7 @@ class ExercisePlanDetailTest {
val updatedPlanDetail = response.body as ExercisePlanDetail val updatedPlanDetail = response.body as ExercisePlanDetail
assertEquals(planDetail.weightEquation, "50%") assertEquals(planDetail.weightEquation, "50%")
assertEquals(planDetail.repeats, 30) assertEquals(planDetail.repeats, 30)
assertEquals(planDetail.exercisePlan?.exercisePlanId, 6) //assertEquals(planDetail.exercisePlan, )
assertEquals(planDetail.exercisePlanDetailId, 4) assertEquals(planDetail.exercisePlanDetailId, 4)
updatedPlanDetail.weightEquation = "40" updatedPlanDetail.weightEquation = "40"
@ -81,14 +81,14 @@ class ExercisePlanDetailTest {
val plan = ExercisePlan( val plan = ExercisePlan(
) )
plan.exercisePlanId = 6; plan.exercisePlanId = 6
val planDetail = ExercisePlanDetail( val planDetail = ExercisePlanDetail(
exerciseTypeId = 63, exerciseTypeId = 63,
serie = 3, serie = 3,
repeats = 120, repeats = 120,
weightEquation = "90", weightEquation = "90",
exercisePlan = plan exercisePlanId = 6
) )
val savedDetail: ExercisePlanDetail = exercisePlanDetailRepository.save(planDetail) val savedDetail: ExercisePlanDetail = exercisePlanDetailRepository.save(planDetail)
assertEquals(savedDetail.weightEquation, "90") assertEquals(savedDetail.weightEquation, "90")
@ -105,6 +105,17 @@ class ExercisePlanDetailTest {
val response2: ResponseEntity<*> = planDetailController.deleteExercisePlanDetailById(9999, planDetailToDelete) val response2: ResponseEntity<*> = planDetailController.deleteExercisePlanDetailById(9999, planDetailToDelete)
assertEquals(response2.body, HttpStatus.NOT_FOUND) assertEquals(response2.body, HttpStatus.NOT_FOUND)
}
@Test
fun testGetExercisePlanDetailByPlanId() {
val exercisePlanDetailList: List<ExercisePlanDetail> = exercisePlanDetailRepository.findByExercisePlanId(6)
logger.info(" ****** list: $exercisePlanDetailList")
assertEquals(exercisePlanDetailList.size, 2)
val exercisePlanDetail: ExercisePlanDetail = exercisePlanDetailList[0]
assertEquals(exercisePlanDetail.repeats, 1)
} }
} }

View File

@ -7,10 +7,12 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RequestHeader import org.springframework.web.bind.annotation.RequestHeader
import java.util.* import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNull
@SpringBootTest @SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ -40,8 +42,8 @@ class ExercisePlanTest {
@Test @Test
fun testGetLastPlan() { fun testGetLastPlan() {
val exercisePlan: ExercisePlan? = exercisePlanRepository.getLastExercisePlan(90) val exercisePlan: ExercisePlan? = exercisePlanRepository.getLastExercisePlan(90)
assertEquals(exercisePlan?.name, "Boss private") assertEquals(exercisePlan?.name, "Boss private 2")
assertEquals(exercisePlan?.dateAdd, "2020-09-06 08:00:00") assertEquals(exercisePlan?.dateAdd, "2020-09-09 00:06:19")
val exercisePlan2: ExercisePlan? = exercisePlanRepository.getLastExercisePlan(91) val exercisePlan2: ExercisePlan? = exercisePlanRepository.getLastExercisePlan(91)
assertEquals(exercisePlan2, null) assertEquals(exercisePlan2, null)
@ -66,4 +68,26 @@ class ExercisePlanTest {
updatedPlan.description = "" updatedPlan.description = ""
planController.updateExercisePlanById(6, updatedPlan, null) planController.updateExercisePlanById(6, updatedPlan, null)
} }
@Test
fun testDeletePlan() {
val exercisePlan = ExercisePlan (
name = "Bossanyi private 3",
description = "",
customerId = 92,
private = true,
dateAdd = "2020-09-10 17:00"
)
val savedPlan: ExercisePlan = exercisePlanRepository.save(exercisePlan)
assertEquals(savedPlan.customerId, 92)
val planController = ExercisePlanController(exercisePlanRepository)
val response3: ResponseEntity<*> = planController.deleteExercisePlanById(exercisePlan.exercisePlanId, exercisePlan)
assertEquals(response3.body, HttpStatus.OK)
val searchPlan = exercisePlanRepository.findById(exercisePlan.exercisePlanId)
assertEquals(searchPlan, Optional.empty())
}
} }