Skip to content

Commit

Permalink
2557 [BE] delete autotest contributors
Browse files Browse the repository at this point in the history
  • Loading branch information
andrsam committed Aug 6, 2024
1 parent b18f286 commit cb4ccc6
Show file tree
Hide file tree
Showing 16 changed files with 390 additions and 19 deletions.
16 changes: 16 additions & 0 deletions api-contract/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,22 @@ annotationTypes:
description: Delete doctor from patient
responses:
200
/autotest/del
delete:
description: Delete autotest users by given prefix
responses:
200:
body:
application/json:
example: !include samples/user_deletion_result.json
/autotest/del/{email}
delete:
description: Delete autotest user by email
responses:
200:
body:
application/json:
example: !include samples/user_deletion_result.json

# CLOUD ----------------------
/cloud:
Expand Down
9 changes: 9 additions & 0 deletions api-contract/samples/user_deletion_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"data": [
{
"count": 1
}
],
"errors": [],
"meta": []
}
14 changes: 14 additions & 0 deletions src/main/kotlin/com/epam/brn/controller/UserDetailController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,18 @@ class UserDetailController(
@Operation(summary = "Delete doctor from patient")
fun deleteDoctorFromPatient(@PathVariable patientId: Long) =
doctorService.deleteDoctorFromPatientAsPatient(patientId)

@RolesAllowed(BrnRole.ADMIN)
@DeleteMapping("/autotest/del")
@Operation(summary = "Delete all auto test users")
@ResponseStatus(HttpStatus.OK)
fun deleteAutoTestUsers() = ResponseEntity.ok()
.body(BrnResponse(data = userAccountService.deleteAutoTestUsers()))

@DeleteMapping("/autotest/del/{email}")
@Operation(summary = "Delete auto test user by email")
@Throws(Exception::class)
@ResponseStatus(HttpStatus.OK)
fun deleteAutoTestUserByEmail(@PathVariable("email") email: String) =
ResponseEntity.ok().body(BrnResponse(data = userAccountService.deleteAutoTestUserByEmail(email)))
}
8 changes: 8 additions & 0 deletions src/main/kotlin/com/epam/brn/dto/UserDeletionResultDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.epam.brn.dto

/**
* UserDeletionDto.
*
* @author Andrey Samoylov
*/
data class UserDeletionResultDto(val count: Long)
2 changes: 1 addition & 1 deletion src/main/kotlin/com/epam/brn/model/StudyHistory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ data class StudyHistory(
val id: Long? = null,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
@JoinColumn(name = "user_id", insertable = true, updatable = false)
var userAccount: UserAccount,

@ManyToOne(fetch = FetchType.LAZY)
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/com/epam/brn/repo/UserAccountRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,10 @@ interface UserAccountRepository : JpaRepository<UserAccount, Long> {
where u.email = :email"""
)
fun updateLastVisitByEmail(email: String, lastVisit: LocalDateTime)

@Transactional
fun deleteUserAccountsByEmailStartsWith(prefix: String): Long

@Transactional
fun deleteUserAccountByEmailIs(email: String): Long
}
4 changes: 3 additions & 1 deletion src/main/kotlin/com/epam/brn/service/UserAccountService.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.epam.brn.service

import com.epam.brn.dto.HeadphonesDto
import com.epam.brn.dto.request.UserAccountChangeRequest
import com.epam.brn.dto.UserAccountDto
import com.epam.brn.dto.request.UserAccountChangeRequest
import com.epam.brn.model.UserAccount
import com.google.firebase.auth.UserRecord
import org.springframework.data.domain.Pageable
Expand Down Expand Up @@ -36,4 +36,6 @@ interface UserAccountService {
fun getPatientsForDoctor(doctorId: Long): List<UserAccountDto>

fun markVisitForCurrentUser()
fun deleteAutoTestUsers(): Long
fun deleteAutoTestUserByEmail(email: String): Long
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.epam.brn.service.RoleService
import com.epam.brn.service.TimeService
import com.epam.brn.service.UserAccountService
import com.google.firebase.auth.UserRecord
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.domain.Pageable
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
Expand All @@ -26,8 +27,10 @@ class UserAccountServiceImpl(
private val userAccountRepository: UserAccountRepository,
private val roleService: RoleService,
private val headphonesService: HeadphonesService,
private val timeService: TimeService
private val timeService: TimeService,
) : UserAccountService {
@Value("\${users.delete.prefix}")
private lateinit var prefix: String

override fun findUserByEmail(email: String): UserAccountDto =
userAccountRepository.findUserAccountByEmail(email)
Expand Down Expand Up @@ -172,4 +175,11 @@ class UserAccountServiceImpl(

private fun getDefaultRoleSet(): MutableSet<Role> =
setOf(BrnRole.USER).mapTo(mutableSetOf()) { roleService.findByName(it) }

override fun deleteAutoTestUsers(): Long = userAccountRepository.deleteUserAccountsByEmailStartsWith(prefix)
override fun deleteAutoTestUserByEmail(email: String): Long =
if (email.startsWith(prefix))
userAccountRepository.deleteUserAccountByEmailIs(email)
else
throw IllegalArgumentException("email = [$email] must start with prefix = [$prefix]")
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ class InitialDataLoader(
val firstUser = createUser("Name1", "default@default.ru", setOf(userRole))
val secondUser = createUser("Name2", "default2@default.ru", setOf(userRole, specialistRole))
val autoTestUser = createUser("autoTestUser", AUTO_TEST_USER_EMAIL, setOf(userRole))
val autoTestSpecialist =
createUser("autoTestSpecialist", AUTO_TEST_SPECIALIST_EMAIL, setOf(userRole, specialistRole))
val autoTestSpecialist = createUser("autoTestSpecialist", AUTO_TEST_SPECIALIST_EMAIL, setOf(userRole, specialistRole))
val listOfUsers = listOf(admin, firstUser, secondUser, autoTestUser, autoTestSpecialist)

userAccountRepository.saveAll(listOfUsers)
} else {
try {
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ github.api.url.base=https://api.github.com
github.api.url.path.contributors=/repos/{OWNER}/{REPO}/contributors
github.api.url.path.users=/users/{username}

users.delete.prefix=autotest

# Swagger
springdoc.swagger-ui.tagsSorter=alpha
springdoc.writer-with-order-by-keys=true
15 changes: 15 additions & 0 deletions src/main/resources/db/migration/V220240729_2557.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
alter table user_roles
drop constraint fk6teafluo1xt1re7vbgr16w8iy;

alter table user_roles
add constraint user_roles_to_user_account
foreign key (user_id) references user_account
on delete cascade;

alter table study_history
drop constraint fk5gkcspvt7bmyc80jv8vfbfpqt;

alter table study_history
add constraint study_history_to_user_account
foreign key (user_id) references user_account
on delete cascade;
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.epam.brn.controller

import com.epam.brn.dto.HeadphonesDto
import com.epam.brn.dto.UserAccountDto
import com.epam.brn.dto.request.UserAccountChangeRequest
import com.epam.brn.dto.request.UserAccountCreateRequest
import com.epam.brn.dto.response.BrnResponse
import com.epam.brn.dto.UserAccountDto
import com.epam.brn.dto.response.UserWithAnalyticsResponse
import com.epam.brn.enums.BrnGender
import com.epam.brn.enums.BrnRole
import com.epam.brn.enums.HeadphonesType
import com.epam.brn.enums.BrnGender
import com.epam.brn.service.DoctorService
import com.epam.brn.service.UserAccountService
import com.epam.brn.service.UserAnalyticsService
Expand Down Expand Up @@ -314,4 +314,35 @@ internal class UserDetailControllerTest {
users.statusCodeValue shouldBe HttpStatus.SC_OK
(users.body as BrnResponse<*>).data shouldBe listOf(userAccountDto)
}

@Test
fun `deleteAutoTestUsers should return count of deleted users`() {
// GIVEN
val usersCount = 2L
every { userAccountService.deleteAutoTestUsers() } returns usersCount

// WHEN
val result = userDetailController.deleteAutoTestUsers()

// THEN
verify { userAccountService.deleteAutoTestUsers() }
result.statusCodeValue shouldBe HttpStatus.SC_OK
(result.body as BrnResponse<*>).data shouldBe usersCount
}

@Test
fun `deleteAutoTestUserByEmail should return count of deleted users`() {
// GIVEN
val email = "autotest_n@170472339.1784415.com"
val usersCount = 1L
every { userAccountService.deleteAutoTestUserByEmail(email) } returns usersCount

// WHEN
val result = userDetailController.deleteAutoTestUserByEmail(email)

// THEN
verify { userAccountService.deleteAutoTestUserByEmail(email) }
result.statusCodeValue shouldBe HttpStatus.SC_OK
(result.body as BrnResponse<*>).data shouldBe usersCount
}
}
118 changes: 117 additions & 1 deletion src/test/kotlin/com/epam/brn/integration/StudyHistoryIT.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package com.epam.brn.integration

import com.epam.brn.enums.BrnGender
import com.epam.brn.enums.BrnRole
import com.epam.brn.model.Exercise
import com.epam.brn.model.ExerciseGroup
import com.epam.brn.enums.BrnGender
import com.epam.brn.model.Role
import com.epam.brn.model.Series
import com.epam.brn.model.StudyHistory
import com.epam.brn.model.SubGroup
import com.epam.brn.model.UserAccount
import com.epam.brn.repo.ExerciseGroupRepository
import com.epam.brn.repo.ExerciseRepository
import com.epam.brn.repo.RoleRepository
import com.epam.brn.repo.SeriesRepository
import com.epam.brn.repo.StudyHistoryRepository
import com.epam.brn.repo.SubGroupRepository
import com.epam.brn.repo.UserAccountRepository
import com.epam.brn.service.UserAccountService
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
Expand Down Expand Up @@ -54,6 +57,12 @@ class StudyHistoryIT : BaseIT() {
@Autowired
lateinit var exerciseGroupRepository: ExerciseGroupRepository

@Autowired
lateinit var roleRepository: RoleRepository

@Autowired
lateinit var userAccountService: UserAccountService

@AfterEach
fun deleteAfterTest() {
studyHistoryRepository.deleteAll()
Expand All @@ -62,6 +71,7 @@ class StudyHistoryIT : BaseIT() {
seriesRepository.deleteAll()
exerciseGroupRepository.deleteAll()
userAccountRepository.deleteAll()
roleRepository.deleteAll()
}

@Test
Expand Down Expand Up @@ -226,6 +236,110 @@ class StudyHistoryIT : BaseIT() {
assertEquals(0, result)
}

@Test
fun `test delete study history when delete autotest users`() {
// GIVEN
val roleUser = insertRole(BrnRole.USER)

val user1 = UserAccount(
fullName = "autotest_n1",
email = "autotest_n@1704819771.8820736.com",
gender = BrnGender.MALE.toString(),
bornYear = 2000,
active = true,
)
user1.roleSet = mutableSetOf(roleUser)

val user2 = UserAccount(
fullName = "autotest_n1",
email = "autotest_n@170472339.1784415.com",
gender = BrnGender.MALE.toString(),
bornYear = 2000,
active = true,
)
user2.roleSet = mutableSetOf(roleUser)

userAccountRepository.saveAll(listOf(user1, user2))

val existingSeries = insertSeries()
val subGroup = insertSubGroup(existingSeries)
val existingExerciseFirst = insertExercise("FirstName", subGroup)
val existingExerciseSecond = insertExercise("SecondName", subGroup)
val now = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS)
val historyFirstExerciseOne = insertStudyHistory(user1, existingExerciseFirst, now)
val historySecondExerciseOne = insertStudyHistory(user2, existingExerciseSecond, now)

studyHistoryRepository
.saveAll(
listOf(
historyFirstExerciseOne,
historySecondExerciseOne,
)
)

// WHEN
val count = userAccountService.deleteAutoTestUsers()

val result1 = user1.id?.let {
studyHistoryRepository.findLastByUserAccountIdAndExercises(
it,
listOf(existingExerciseFirst.id!!)
)
}

val result2 = user1.id?.let {
studyHistoryRepository.findLastByUserAccountIdAndExercises(
it,
listOf(existingExerciseFirst.id!!)
)
}

// THEN
assertEquals(2, count)
assertEquals(0, result1?.size)
assertEquals(0, result2?.size)
}

@Test
fun `test delete study history when delete single autotest user`() {
// GIVEN
val roleUser = insertRole(BrnRole.USER)
val email = "autotest_n@1704819771.8820736.com"

val user1 = UserAccount(
fullName = "autotest_n1",
email = email,
gender = BrnGender.MALE.toString(),
bornYear = 2000,
active = true,
)
user1.roleSet = mutableSetOf(roleUser)
userAccountRepository.save(user1)

val exerciseFirstName = "FirstName"
val existingSeries = insertSeries()
val subGroup = insertSubGroup(existingSeries)
val existingExerciseFirst = insertExercise(exerciseFirstName, subGroup)
val now = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS)
val historyFirstExerciseTwo = insertStudyHistory(user1, existingExerciseFirst, now)

studyHistoryRepository.save(historyFirstExerciseTwo)

// WHEN
val count = userAccountService.deleteAutoTestUserByEmail(email)

val result1 = user1.id?.let {
studyHistoryRepository.findLastByUserAccountIdAndExercises(
it,
listOf(existingExerciseFirst.id!!)
)
}

// THEN
assertEquals(1, count)
assertEquals(0, result1?.size)
}

private fun insertStudyHistory(
existingUser: UserAccount,
existingExercise: Exercise,
Expand Down Expand Up @@ -289,4 +403,6 @@ class StudyHistoryIT : BaseIT() {
)
)
}

private fun insertRole(roleName: String): Role = roleRepository.save(Role(name = roleName))
}
Loading

0 comments on commit cb4ccc6

Please sign in to comment.