Skip to content
This repository was archived by the owner on Apr 27, 2023. It is now read-only.

Commit 0d7229e

Browse files
committed
Added usecase for delete user and test cases for userdao and delele
usecase
1 parent 272d73c commit 0d7229e

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

codebrag-dao/src/test/scala/com/softwaremill/codebrag/dao/user/UserDAOSpec.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,20 @@ class SQLUserDAOSpec extends FlatSpecWithSQL with ClearSQLDataAfterTest with Bef
370370
foundUser.get.notifications.commits.get.getMillis should equal(commitDate.getMillis)
371371
foundUser.get.notifications.followups.get.getMillis should equal(followupDate.getMillis)
372372
}
373+
it should "deleta a user " taggedAs RequiresDb in {
374+
// given
375+
val user = UserAssembler.randomUser.withBasicAuth("user", "pass").withAdmin(set = false).withActive(set = false).get
376+
userDAO.add(user)
377+
val newAuth = Authentication.basic(user.authentication.username, "newpass")
373378

379+
// when
380+
val modifiedUser = user.copy(authentication = newAuth, admin = true, active = true)
381+
userDAO.delete(modifiedUser.id)
382+
val deletedUser = userDAO.findById(user.id)
383+
384+
// then
385+
assert(deletedUser === None , "Deletion was attempted but found " + deletedUser)
386+
}
374387
"rememberNotifications" should "store dates properly" taggedAs RequiresDb in {
375388
// given
376389
val user = UserAssembler.randomUser.get
@@ -479,4 +492,5 @@ class SQLUserDAOSpec extends FlatSpecWithSQL with ClearSQLDataAfterTest with Bef
479492
partial should have size (2)
480493
partial.map(_.name).toSet should be (users.map(_.name).toSet)
481494
}
495+
482496
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.softwaremill.codebrag.usecases.user
2+
3+
import com.softwaremill.codebrag.dao.user.UserDAO
4+
import com.softwaremill.codebrag.usecases.assertions.UserAssertions
5+
import org.bson.types.ObjectId
6+
import com.softwaremill.codebrag.domain.{Authentication, User}
7+
import com.typesafe.scalalogging.slf4j.Logging
8+
import com.softwaremill.scalaval.Validation._
9+
10+
case class DeleteUserForm(userId: ObjectId, newPassword: Option[String], admin: Option[Boolean], active: Option[Boolean]) {
11+
12+
def applyTo(user: User) = {
13+
val modifiedAuth = newPassword.map { newPass =>
14+
buildNewAuth(user.authentication.username, newPass)
15+
} getOrElse user.authentication
16+
user.copy(
17+
admin = admin.getOrElse(user.admin),
18+
active = active.getOrElse(user.active),
19+
authentication = modifiedAuth
20+
)
21+
}
22+
23+
protected def buildNewAuth(username: String, password: String) = Authentication.basic(username, password)
24+
25+
}
26+
27+
class DeleteUserDetailsUseCase(protected val userDao: UserDAO) extends Logging {
28+
29+
import UserAssertions._
30+
31+
def execute(executorId: ObjectId, form: DeleteUserForm): Either[Errors, Unit] = {
32+
assertUserWithId(executorId, mustBeActive, mustBeAdmin)(userDao)
33+
val targetUser = loadUser(form.userId)
34+
validateUserDetails(executorId, targetUser, form).whenOk[Unit] {
35+
logger.debug(s"Validation passed, attempting to delete user $targetUser")
36+
userDao.delete(form.userId)
37+
}
38+
}
39+
40+
private def loadUser(userId: ObjectId) = userDao.findById(userId).getOrElse(throw new IllegalStateException(s"User $userId not found"))
41+
42+
private def validateUserDetails(executorId: ObjectId, user: User, form: DeleteUserForm) = {
43+
val changeOwnFlagsCheck = rule("userId") {
44+
val isDeleteFlags = form.admin.isDefined || form.active.isDefined
45+
(!isDeleteFlags || (isDeleteFlags && executorId != user.id), "Cannot delete own user")
46+
}
47+
validate(changeOwnFlagsCheck)
48+
}
49+
50+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.softwaremill.codebrag.usecases.user
2+
3+
import org.scalatest.{BeforeAndAfter, FlatSpec}
4+
import org.scalatest.matchers.ShouldMatchers
5+
import org.scalatest.mock.MockitoSugar
6+
import com.softwaremill.codebrag.dao.user.UserDAO
7+
import org.mockito.Matchers._
8+
import org.mockito.Mockito._
9+
import com.softwaremill.codebrag.domain.builder.UserAssembler
10+
import com.softwaremill.codebrag.domain.{Authentication, User}
11+
import com.softwaremill.codebrag.usecases.assertions.{ActiveUserStatusRequiredException, AdminRoleRequiredException}
12+
import org.bson.types.ObjectId
13+
14+
class DeleteUserUseCaseSpec extends FlatSpec with ShouldMatchers with BeforeAndAfter with MockitoSugar {
15+
16+
val userDao = mock[UserDAO]
17+
val useCase = new DeleteUserDetailsUseCase(userDao)
18+
19+
val InactiveUser = UserAssembler.randomUser.withActive(set = false).get
20+
val ActiveUser = UserAssembler.randomUser.withActive().get
21+
22+
val ValidExecutor = UserAssembler.randomUser.withAdmin().withActive().get
23+
val NonAdminExecutor = UserAssembler.randomUser.withActive().withAdmin(set = false).get
24+
val InactiveExecutor = UserAssembler.randomUser.withActive(set = false).withAdmin().get
25+
26+
after {
27+
reset(userDao)
28+
}
29+
30+
it should "not delete user when executing user is neither admin nor active" in {
31+
// given
32+
setupReturningUserFromDB(NonAdminExecutor, InactiveExecutor)
33+
val form = DeleteUserForm(ActiveUser.id, None, None, None)
34+
35+
// when
36+
intercept[AdminRoleRequiredException] {
37+
useCase.execute(NonAdminExecutor.id, form)
38+
}
39+
intercept[ActiveUserStatusRequiredException] {
40+
useCase.execute(InactiveExecutor.id, form)
41+
}
42+
43+
// then
44+
verify(userDao, never()).delete(any[ObjectId])
45+
}
46+
47+
it should "not allow to delete yourself" in {
48+
// given
49+
setupReturningUserFromDB(ValidExecutor)
50+
51+
// when
52+
val ownChangeForm = DeleteUserForm(ValidExecutor.id, None, admin = Some(false), active = Some(false))
53+
val Left(result) = useCase.execute(ValidExecutor.id, ownChangeForm)
54+
55+
// then
56+
result should be(Map("userId" -> List("Cannot delete own user")))
57+
verify(userDao, never()).delete(any[ObjectId])
58+
}
59+
60+
61+
it should "delete user when validation passes" in {
62+
// given
63+
stubCurrentlyActiveUsersCountTo(0)
64+
setupReturningUserFromDB(ValidExecutor, ActiveUser)
65+
66+
// when
67+
val newAuth = Authentication.basic(ActiveUser.authentication.username, "secret")
68+
val form = new DeleteUserForm(ActiveUser.id, newPassword = Some("secret"), admin = Some(true), active = None) {
69+
override def buildNewAuth(username: String, password: String) = newAuth
70+
}
71+
val result = useCase.execute(ValidExecutor.id, form)
72+
73+
// then
74+
result should be('right)
75+
val expectedUser = form.applyTo(ActiveUser)
76+
verify(userDao).delete(expectedUser.id)
77+
}
78+
79+
private def stubCurrentlyActiveUsersCountTo(activeUsersCount: Int) {
80+
when(userDao.countAllActive()).thenReturn(activeUsersCount)
81+
}
82+
83+
private def setupReturningUserFromDB(users: User*) {
84+
users.foreach { user =>
85+
when(userDao.findById(user.id)).thenReturn(Some(user))
86+
}
87+
}
88+
89+
}

0 commit comments

Comments
 (0)