Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2557 [BE] delete autotest users #2596

Merged
merged 2 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
ElenaSpb marked this conversation as resolved.
Show resolved Hide resolved
delete:
description: Delete autotest users by given prefix
responses:
200:
body:
application/json:
example: !include samples/user_deletion_result.json
/autotest/del/{email}
andrsam marked this conversation as resolved.
Show resolved Hide resolved
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)))
}
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
}
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,8 +106,7 @@ 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 {
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;
ElenaSpb marked this conversation as resolved.
Show resolved Hide resolved

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
Loading