Skip to content

Commit

Permalink
Brain-up#2406 update lastVisit time for current user
Browse files Browse the repository at this point in the history
  • Loading branch information
naXa777 committed Oct 20, 2023
1 parent 2b27a7f commit 64b21d0
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 28 deletions.
11 changes: 11 additions & 0 deletions src/main/kotlin/com/epam/brn/repo/UserAccountRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import com.epam.brn.model.UserAccount
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
import java.util.Optional

@Repository
Expand Down Expand Up @@ -50,4 +53,12 @@ interface UserAccountRepository : JpaRepository<UserAccount, Long> {
left JOIN FETCH u.headphones where roles.name = :roleName"""
)
fun findUsersAccountsByRole(roleName: String): List<UserAccount>

@Transactional
@Modifying
@Query(
"""update UserAccount u SET u.lastVisit = :lastVisit
where u.email = :email"""
)
fun updateLastVisitByEmail(email: String, lastVisit: LocalDateTime)
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,15 @@ class UserAccountServiceImpl(
.toSet()

override fun getCurrentUser(): UserAccount {
val authentication = SecurityContextHolder.getContext().authentication
val email = authentication.name ?: getNameFromPrincipals(authentication)
val email = getCurrentUserEmail()
return userAccountRepository.findUserAccountByEmail(email)
.orElseThrow { EntityNotFoundException("No user was found for email=$email") }
}

override fun markVisitForCurrentUser() {
getCurrentUser().let {
it.lastVisit = timeService.now()
userAccountRepository.save(it)
}
val email = getCurrentUserEmail()
val lastVisit = timeService.now()
return userAccountRepository.updateLastVisitByEmail(email, lastVisit)
}

override fun getCurrentUserDto(): UserAccountDto =
Expand Down Expand Up @@ -158,6 +156,11 @@ class UserAccountServiceImpl(
return this
}

private fun getCurrentUserEmail(): String {
val authentication = SecurityContextHolder.getContext().authentication
return authentication.name ?: getNameFromPrincipals(authentication)
}

private fun getNameFromPrincipals(authentication: Authentication): String {
val principal = authentication.principal
if (principal is UserDetails)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.epam.brn.integration.repo

import com.epam.brn.model.UserAccount
import com.epam.brn.repo.UserAccountRepository
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertDoesNotThrow
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit

@DataJpaTest
@Tag("integration-test")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@DisplayName("UserAccountRepository tests")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class UserAccountRepositoryTest {

@Autowired
private lateinit var repository: UserAccountRepository

@Autowired
private lateinit var testEntityManager: TestEntityManager

@Test
fun `should update lastVisit date of user`() {
// GIVEN
val yesterday = LocalDateTime.now().minusDays(1).truncatedTo(ChronoUnit.MILLIS)
val today = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS)

val email = "[email protected]"
val user = UserAccount(
email = email,
fullName = "John Doe",
lastVisit = yesterday
)
val savedUser = testEntityManager.persistAndFlush(user)

// WHEN
repository.updateLastVisitByEmail(email, today)

testEntityManager.flush()
testEntityManager.clear()

// THEN
val retrievedUser = testEntityManager.find(UserAccount::class.java, savedUser.id)
assertThat(retrievedUser).isNotNull
val actualLastVisit = retrievedUser.lastVisit?.truncatedTo(ChronoUnit.MILLIS)
assertThat(actualLastVisit).isEqualTo(today)
}

@Test
fun `should not throw error when user doesn't exist`() {
// GIVEN
val today = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS)
val email = "[email protected]"

// WHEN & THEN
assertDoesNotThrow {
repository.updateLastVisitByEmail(email, today)
}
}
}
29 changes: 7 additions & 22 deletions src/test/kotlin/com/epam/brn/service/UserAccountServiceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import com.epam.brn.service.impl.UserAccountServiceImpl
import com.google.firebase.auth.UserRecord
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.matchers.shouldBe
import io.mockk.Runs
import io.mockk.every
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.mockkClass
import io.mockk.just
import io.mockk.slot
import io.mockk.verify
import org.apache.commons.lang3.math.NumberUtils
Expand Down Expand Up @@ -301,39 +303,22 @@ internal class UserAccountServiceTest {
}

@Test
fun `should mark visit current session user`() {
fun `should mark visit for current session user`() {
// GIVEN
val email = "[email protected]"
val userAccount = UserAccount(
id = 1L,
fullName = "testUserFirstName",
email = email,
gender = BrnGender.MALE.toString(),
bornYear = 2000,
changed = LocalDateTime.now().minusMinutes(5),
avatar = null
)
val userAccountUpdated = userAccount.copy()
val now = LocalDateTime.now(ZoneOffset.UTC)
userAccountUpdated.lastVisit = now
val userArgumentCaptor = slot<UserAccount>()

SecurityContextHolder.setContext(securityContext)
every { securityContext.authentication } returns authentication
every { authentication.name } returns email
every { userAccountRepository.findUserAccountByEmail(email) } returns Optional.of(userAccount)
every { userAccountRepository.save(ofType(UserAccount::class)) } returns userAccountUpdated
every { userAccountRepository.save(capture(userArgumentCaptor)) } returns userAccount
every { timeService.now() } returns now
every { userAccountRepository.updateLastVisitByEmail(email, now) } just Runs

// WHEN
userAccountService.markVisitForCurrentUser()

// THEN
verify { userAccountRepository.findUserAccountByEmail(email) }
verify { userAccountRepository.save(userArgumentCaptor.captured) }
val userForSave = userArgumentCaptor.captured
assertThat(userForSave.lastVisit).isEqualTo(now)
assertThat(userForSave.id).isEqualTo(userAccount.id)
assertThat(userForSave.fullName).isEqualTo(userAccount.fullName)
verify { userAccountRepository.updateLastVisitByEmail(email, now) }
}
}

Expand Down

0 comments on commit 64b21d0

Please sign in to comment.