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

Commit 5411669

Browse files
committed
Enhanced error messages and unit test cases
1 parent 0d7229e commit 5411669

File tree

9 files changed

+37
-44
lines changed

9 files changed

+37
-44
lines changed

Diff for: codebrag-rest/src/main/scala/ScalatraBootstrap.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class ScalatraBootstrap extends LifeCycle with Logging {
6969
RepositoryUpdateScheduler.scheduleUpdates(actorSystem, repositories, commitImportService)
7070
context.mount(new RegistrationServlet(registerService, registerNewUserUseCase, listReposAfterRegistration, listRepoBranchesAfterRegistration, watchBranchAfterRegistration, unwatchBranchAfterRegistration), Prefix + RegistrationServlet.MappingPath)
7171
context.mount(new SessionServlet(authenticator, loginUserUseCase, userFinder), Prefix + SessionServlet.MappingPath)
72-
context.mount(new UsersServlet(authenticator, userFinder, modifyUserDetailsUseCase, config), Prefix + UsersServlet.MappingPath)
72+
context.mount(new UsersServlet(authenticator, userFinder, modifyUserDetailsUseCase, deleteUserUseCase, config), Prefix + UsersServlet.MappingPath)
7373
context.mount(new UserAliasesEndpoint(authenticator, addUserAliasUseCase, deleteUserAliasUseCase), Prefix + UserAliasesEndpoint.MappingPath)
7474
context.mount(new UsersSettingsServlet(authenticator, userDao, changeUserSettingsUseCase), Prefix + "users/settings")
7575
context.mount(new CommitsServlet(authenticator, toReviewCommitsFinder, allCommitsFinder, reactionFinder, addCommentUseCase,

Diff for: codebrag-rest/src/main/scala/com/softwaremill/codebrag/Beans.scala

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ trait Beans extends ActorSystemSupport with CommitsModule with Daos {
7979
lazy val generateInvitationCodeUseCase = new GenerateInvitationCodeUseCase(invitationsService, userDao)
8080
lazy val sendInvitationEmailUseCase = new SendInvitationEmailUseCase(invitationsService, userDao)
8181
lazy val modifyUserDetailsUseCase = new ModifyUserDetailsUseCase(userDao)
82+
lazy val deleteUserUseCase = new DeleteUserUseCase(userDao)
8283
lazy val updateUserBrowsingContextUseCase = new UpdateUserBrowsingContextUseCase(userRepoDetailsDao)
8384
lazy val addUserAliasUseCase = new AddUserAliasUseCase(userAliasDao, userDao)
8485
lazy val deleteUserAliasUseCase = new DeleteUserAliasUseCase(userAliasDao)

Diff for: codebrag-rest/src/main/scala/com/softwaremill/codebrag/rest/UsersServlet.scala

+9-4
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import org.bson.types.ObjectId
66
import org.scalatra
77
import com.softwaremill.codebrag.finders.user.UserFinder
88
import com.softwaremill.codebrag.finders.user.ManagedUsersListView
9-
import com.softwaremill.codebrag.usecases.user.{RegisterNewUserUseCase, ModifyUserDetailsUseCase, ModifyUserDetailsForm}
9+
import com.softwaremill.codebrag.usecases.user.{RegisterNewUserUseCase, ModifyUserDetailsUseCase, ModifyUserDetailsForm,DeleteUserUseCase,DeleteUserForm}
1010

1111
class UsersServlet(
1212
val authenticator: Authenticator,
1313
userFinder: UserFinder,
1414
modifyUserUseCase: ModifyUserDetailsUseCase,
15+
deleteUserUseCase: DeleteUserUseCase,
1516
config: CodebragConfig) extends JsonServletWithAuthentication {
1617

1718
get("/") {
@@ -34,9 +35,13 @@ class UsersServlet(
3435
case _ => scalatra.Ok()
3536
}
3637
}
37-
delete("/:id") {
38-
haltIfNotAuthenticated()
39-
modifyUserUseCase.delete(new ObjectId(params("id")))
38+
delete("/:userId") {
39+
haltIfNotAuthenticated()
40+
val targetUserId = new ObjectId(params("userId"))
41+
deleteUserUseCase.execute(user.id, DeleteUserForm(targetUserId)) match {
42+
case Left(errors) => scalatra.BadRequest(errors)
43+
case _ => scalatra.Ok()
44+
}
4045
}
4146
}
4247

Diff for: codebrag-rest/src/test/scala/com/softwaremill/codebrag/rest/UsersServletSpec.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import com.softwaremill.codebrag.finders.user.ManagedUserView
1313
import com.softwaremill.codebrag.finders.user.ManagedUsersListView
1414
import com.softwaremill.codebrag.domain.builder.UserAssembler
1515
import com.softwaremill.codebrag.domain.User
16-
import com.softwaremill.codebrag.usecases.user.ModifyUserDetailsUseCase
16+
import com.softwaremill.codebrag.usecases.user.{ModifyUserDetailsUseCase,DeleteUserUseCase}
1717

1818
class UsersServletSpec extends AuthenticatableServletSpec {
1919

2020
val modifyUserUseCase = mock[ModifyUserDetailsUseCase]
21+
val deleteUserUseCase = mock[DeleteUserUseCase]
2122
var userFinder: UserFinder = _
2223
var config: CodebragConfig = _
2324

@@ -60,7 +61,7 @@ class UsersServletSpec extends AuthenticatableServletSpec {
6061
}
6162

6263
class TestableUsersServlet(fakeAuthenticator: Authenticator, fakeScentry: Scentry[User])
63-
extends UsersServlet(fakeAuthenticator, userFinder, modifyUserUseCase, config) {
64+
extends UsersServlet(fakeAuthenticator, userFinder, modifyUserUseCase, deleteUserUseCase ,config) {
6465
override def scentry(implicit request: javax.servlet.http.HttpServletRequest) = fakeScentry
6566
}
6667

Diff for: codebrag-service/src/main/scala/com/softwaremill/codebrag/usecases/user/DeleteUserUseCase.scala

+3-16
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,11 @@ import com.softwaremill.codebrag.domain.{Authentication, User}
77
import com.typesafe.scalalogging.slf4j.Logging
88
import com.softwaremill.scalaval.Validation._
99

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)
10+
case class DeleteUserForm(userId: ObjectId) {
2411

2512
}
2613

27-
class DeleteUserDetailsUseCase(protected val userDao: UserDAO) extends Logging {
14+
class DeleteUserUseCase(protected val userDao: UserDAO) extends Logging {
2815

2916
import UserAssertions._
3017

@@ -41,7 +28,7 @@ class DeleteUserDetailsUseCase(protected val userDao: UserDAO) extends Logging {
4128

4229
private def validateUserDetails(executorId: ObjectId, user: User, form: DeleteUserForm) = {
4330
val changeOwnFlagsCheck = rule("userId") {
44-
val isDeleteFlags = form.admin.isDefined || form.active.isDefined
31+
val isDeleteFlags = user.admin || user.active
4532
(!isDeleteFlags || (isDeleteFlags && executorId != user.id), "Cannot delete own user")
4633
}
4734
validate(changeOwnFlagsCheck)

Diff for: codebrag-service/src/test/scala/com/softwaremill/codebrag/usecases/user/DeleteUserUseCaseSpec.scala

+7-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import org.bson.types.ObjectId
1414
class DeleteUserUseCaseSpec extends FlatSpec with ShouldMatchers with BeforeAndAfter with MockitoSugar {
1515

1616
val userDao = mock[UserDAO]
17-
val useCase = new DeleteUserDetailsUseCase(userDao)
17+
val useCase = new DeleteUserUseCase(userDao)
1818

1919
val InactiveUser = UserAssembler.randomUser.withActive(set = false).get
2020
val ActiveUser = UserAssembler.randomUser.withActive().get
@@ -30,7 +30,7 @@ class DeleteUserUseCaseSpec extends FlatSpec with ShouldMatchers with BeforeAndA
3030
it should "not delete user when executing user is neither admin nor active" in {
3131
// given
3232
setupReturningUserFromDB(NonAdminExecutor, InactiveExecutor)
33-
val form = DeleteUserForm(ActiveUser.id, None, None, None)
33+
val form = DeleteUserForm(ActiveUser.id)
3434

3535
// when
3636
intercept[AdminRoleRequiredException] {
@@ -49,7 +49,7 @@ class DeleteUserUseCaseSpec extends FlatSpec with ShouldMatchers with BeforeAndA
4949
setupReturningUserFromDB(ValidExecutor)
5050

5151
// when
52-
val ownChangeForm = DeleteUserForm(ValidExecutor.id, None, admin = Some(false), active = Some(false))
52+
val ownChangeForm = DeleteUserForm(ValidExecutor.id)
5353
val Left(result) = useCase.execute(ValidExecutor.id, ownChangeForm)
5454

5555
// then
@@ -65,15 +65,13 @@ class DeleteUserUseCaseSpec extends FlatSpec with ShouldMatchers with BeforeAndA
6565

6666
// when
6767
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-
}
68+
val form = new DeleteUserForm(ActiveUser.id)
7169
val result = useCase.execute(ValidExecutor.id, form)
7270

7371
// then
7472
result should be('right)
75-
val expectedUser = form.applyTo(ActiveUser)
76-
verify(userDao).delete(expectedUser.id)
73+
val expectedUser = form
74+
verify(userDao).delete(expectedUser.userId)
7775
}
7876

7977
private def stubCurrentlyActiveUsersCountTo(activeUsersCount: Int) {
@@ -87,3 +85,4 @@ class DeleteUserUseCaseSpec extends FlatSpec with ShouldMatchers with BeforeAndA
8785
}
8886

8987
}
88+

Diff for: codebrag-ui/app/scripts/users/manageUsersPopupCtrl.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,10 @@ angular.module('codebrag.userMgmt')
2626
});
2727
};
2828

29-
$scope.deleteUser = function(userId) {
29+
$scope.deleteUser = function(user) {
3030
$scope.flash.clear();
31-
var userData = { userId: userId };
32-
userMgmtService.deleteUser(userId).then(deleteSuccess, deleteFailed('active', userId))
33-
userMgmtService.loadUsers().then(function(users) {
34-
$scope.users = users;
35-
});
31+
var userData = { userId: user.userId };
32+
userMgmtService.deleteUser(userData).then(deleteSuccess(user), deleteFailed('active', user.userId))
3633
};
3734

3835
$scope.askForNewPassword = function(user) {
@@ -42,16 +39,19 @@ angular.module('codebrag.userMgmt')
4239
$scope.flash.add('info', 'User password changed');
4340
});
4441
};
45-
function deleteSuccess() {
46-
$scope.flash.add('error', 'User is removed');
42+
function deleteSuccess(user) {
43+
$scope.flash.add('error', 'User ' + user.email + ' is deleted');
44+
userMgmtService.loadUsers().then(function(users) {
45+
$scope.users = users;
46+
});
4747
}
4848

4949
function modifySuccess() {
5050
$scope.flash.add('info', 'User details changed');
5151
}
5252
function deleteFailed(flag, userId) {
5353
return function(errorsMap) {
54-
$scope.flash.add('error', 'Could not change user details');
54+
$scope.flash.add('error', ' Could not delete user ');
5555
flattenErrorsMap(errorsMap).forEach(function(error) {
5656
$scope.flash.add('error', error);
5757
});

Diff for: codebrag-ui/app/scripts/users/userMgmtService.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ angular.module('codebrag.userMgmt')
1919
return $http.put(modifyUserUrl, userData).then(null, modifyUserFailed);
2020
};
2121

22-
this.deleteUser = function(userId) {
23-
var modifyUserUrl = [usersApiUrl, '/', userId].join('');
24-
return $http.delete(modifyUserUrl).then(null, modifyUserFailed);
22+
this.deleteUser = function(userData) {
23+
var deleteUserUrl = [usersApiUrl, '/', userData.userId].join('');
24+
return $http.delete(deleteUserUrl).then(null, modifyUserFailed);
2525
};
2626

2727
function modifyUserFailed(response) {

Diff for: codebrag-ui/app/views/popups/manageUsers.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ <h1>Manage team members
3535
<td class="cell-centered"><input type="checkbox" ng-model="user.active" ng-click="modifyUser(user, 'active')" ng-disabled="user.locked"/></td>
3636
<td class="cell-centered"><input type="checkbox" ng-model="user.admin" ng-click="modifyUser(user, 'admin')" ng-disabled="user.locked"/></td>
3737
<td><button class="link" ng-disabled="!user.active" ng-click="askForNewPassword(user)">Set&nbsp;password</button></td>
38-
<td><i class="icon-remove" ng-hide="user.admin" ng-disabled="user.locked" ng-click="deleteUser(user.userId)"></i></td>
38+
<td><i class="icon-remove" ng-hide="user.admin" ng-disabled="user.locked" ng-click="deleteUser(user)"></i></td>
3939
</tr>
4040
</tbody>
4141
</table>

0 commit comments

Comments
 (0)