Commit 1a3690532323c1c3d0a983a4cbd539ca62119322

Authored by Thomas Ziemer
2 parents 27791b11 8cae1cc5

Merge into master

src/main/java/net/ziemers/swxercise/lg/user/dto/UserDto.java
1 1 package net.ziemers.swxercise.lg.user.dto;
2 2  
  3 +import net.ziemers.swxercise.lg.model.user.User;
  4 +
3 5 import javax.validation.constraints.NotNull;
4 6  
5 7 /**
... ... @@ -8,7 +10,7 @@ import javax.validation.constraints.NotNull;
8 10 */
9 11 public class UserDto {
10 12  
11   - private Long entityId;
  13 + private User user = null;
12 14  
13 15 @NotNull
14 16 private String username; // aus dem Profile
... ... @@ -22,12 +24,12 @@ public class UserDto {
22 24  
23 25 private String mailaddress; // aus dem Profile
24 26  
25   - public Long getEntityId() {
26   - return entityId;
  27 + public User getUser() {
  28 + return user;
27 29 }
28 30  
29   - public void setEntityId(Long entityId) {
30   - this.entityId = entityId;
  31 + public void setUser(User user) {
  32 + this.user = user;
31 33 }
32 34  
33 35 public String getUsername() {
... ...
src/main/java/net/ziemers/swxercise/lg/user/service/EntityToUserDtoMapper.java
... ... @@ -9,7 +9,7 @@ import net.ziemers.swxercise.lg.user.dto.UserDto;
9 9 public class EntityToUserDtoMapper {
10 10  
11 11 /**
12   - * Erzeugt ein DTO aus dem übergebenem Kontext.
  12 + * Erzeugt ein Data Transfer Object aus dem übergebenem Kontext.
13 13 *
14 14 * @param ctx der Kontext
15 15 * @return das erzeugte DTO.
... ... @@ -18,15 +18,15 @@ public class EntityToUserDtoMapper {
18 18 final UserDto dto = new UserDto();
19 19  
20 20 if (ctx.user != null) {
21   - mapEntityId(ctx, dto);
  21 + mapUser(ctx, dto);
22 22 mapFirstname(ctx, dto);
23 23 mapLastname(ctx, dto);
24 24 }
25 25 return dto;
26 26 }
27 27  
28   - private void mapEntityId(EntityToUserDtoContext ctx, UserDto dto) {
29   - dto.setEntityId(ctx.user.getId());
  28 + private void mapUser(EntityToUserDtoContext ctx, UserDto dto) {
  29 + dto.setUser(ctx.user);
30 30 }
31 31  
32 32 private void mapFirstname(EntityToUserDtoContext ctx, UserDto dto) {
... ...
src/main/java/net/ziemers/swxercise/lg/user/service/UserDtoToEntityContext.java
... ... @@ -13,6 +13,6 @@ public class UserDtoToEntityContext {
13 13  
14 14 public Profile profile;
15 15  
16   - public Address address;
  16 + public Address address = null;
17 17  
18 18 }
... ...
src/main/java/net/ziemers/swxercise/lg/user/service/UserDtoToEntityContextService.java
... ... @@ -22,20 +22,27 @@ public class UserDtoToEntityContextService {
22 22 */
23 23 public UserDtoToEntityContext createContext(final UserDto dto) {
24 24 final UserDtoToEntityContext ctx = new UserDtoToEntityContext();
  25 + final User existingUser = dto.getUser();
25 26  
26 27 // das übergebene UserDto in den Kontext füllen
27 28 ctx.dto = dto;
28 29  
29   - // einen neuen oder einen bereits existierenden Benutzer in den Kontext füllen
30   - ctx.user = dao.findByUsername(dto.getUsername());
31   - if (ctx.user == null) {
32   - // es soll niemals ein Profil ohne Benutzername und Kennwort geben
33   - ctx.profile = new Profile(dto.getUsername(), dto.getPassword());
  30 + // einen neuen Benutzer in den Kontext füllen
  31 + if (existingUser == null) {
  32 + // es darf nicht mehrere Benutzer mit dem selben Benutzernamen geben!
  33 + if (dao.findByUsername(dto.getUsername()) == null) {
  34 + // es soll niemals ein Profil ohne Benutzername und Kennwort geben
  35 + ctx.profile = new Profile(dto.getUsername(), dto.getPassword());
  36 +
  37 + // wir füllen das User-Objekt mit Method Chaining
  38 + ctx.user = new User(dto.getFirstname(), dto.getLastname())
  39 + .withProfile(ctx.profile);
  40 + }
  41 + }
34 42  
35   - // wir füllen das User-Objekt mit Method Chaining
36   - ctx.user = new User(dto.getFirstname(), dto.getLastname())
37   - .withProfile(ctx.profile);
38   - } else {
  43 + // einen bereits existierenden Benutzer in den Kontext füllen
  44 + else {
  45 + ctx.user = existingUser;
39 46 ctx.profile = ctx.user.getProfile();
40 47 ctx.address = ctx.user.getAddress();
41 48 }
... ...
src/main/java/net/ziemers/swxercise/lg/user/service/UserDtoToEntityMapper.java
... ... @@ -11,26 +11,30 @@ import javax.ejb.Stateless;
11 11 public class UserDtoToEntityMapper {
12 12  
13 13 /**
14   - * Überträgt die Eigenschaften aus dem UserDto sowie dem zusätzlichen Kontext in die Zielentität.
  14 + * Überträgt die Eigenschaften aus dem UserDto sowie dem zusätzlichen Kontext in die Zielentitäten.
  15 + * Anzumerken ist, dass der Benutzername einer existierenden Profile-Entität niemals aktualisiert
  16 + * wird.
15 17 *
16 18 * @param ctx der Kontext mit den Eigenschaften und der Zielentität
17 19 * @return den Kontext.
18 20 */
19 21 public UserDtoToEntityContext map(UserDtoToEntityContext ctx) {
20   - // User-Objekt mappen
  22 + // ins User-Objekt mappen
21 23 ctx.user.setFirstname(ctx.dto.getFirstname());
22 24 ctx.user.setLastname(ctx.dto.getLastname());
23 25  
24   - // Profile-Objekt mappen, falls gegeben
  26 + // ins Profile-Objekt mappen, falls gegeben
25 27 if (ctx.profile != null) {
26 28 ctx.user.setProfile(ctx.profile);
  29 +
  30 + // eventuell ein neues Kenntwort ins Profile-Objekt mappen
27 31 if(ctx.dto.getPassword().length() > 0) {
28 32 ctx.profile.setPassword(ctx.dto.getPassword());
29 33 }
30 34 ctx.profile.setMailaddress(ctx.dto.getMailaddress());
31 35 }
32 36  
33   - // Address-Objekt mappen, falls gegeben
  37 + // ins Address-Objekt mappen, falls gegeben
34 38 if (ctx.address != null) {
35 39 ctx.user.setAddress(ctx.address);
36 40 }
... ...
src/main/java/net/ziemers/swxercise/lg/user/service/UserService.java
... ... @@ -81,20 +81,17 @@ public class UserService {
81 81 * Zwischen der Groß- und Kleinschreibung wird nicht unterschieden.
82 82 *
83 83 * @param dto das {@link UserDto} enthält die Eigenschaften des zu erstellenden Benutzers
84   - * @return die Id des neuen Benutzers, wenn die Erstellung erfolgreich war.
  84 + * @return <code>true</code>, wenn das Aktualisieren des Benutzers erfolgreich war.
85 85 */
86   - public Long createUser(final UserDto dto) {
  86 + public boolean createUser(final UserDto dto) {
  87 + // Kontext für den zu erstellenden Benutzer erzeugen; falls bereits ein Benutzer
  88 + // mit dem selben Benutzernamen existiert, wird kein Benutzerobjekt zurückgeliefert
87 89 final UserDtoToEntityContext ctx = ctxService.createContext(dto);
88   - mapper.map(ctx);
89   - return persistUserIfNew(ctx);
90   - }
91   -
92   - private Long persistUserIfNew(final UserDtoToEntityContext ctx) {
93   - // nur ein neuer Benutzer hat noch keine Id
94   - if (ctx.user.getId() == null) {
95   - return dao.save(ctx.user);
  90 + if (ctx.user != null) {
  91 + mapper.map(ctx);
  92 + return dao.save(ctx.user) != null;
96 93 }
97   - return null;
  94 + return false;
98 95 }
99 96  
100 97 /**
... ... @@ -107,8 +104,12 @@ public class UserService {
107 104 public boolean updateUser(final Long id, final UserDto dto) {
108 105 final User user = dao.findById(id);
109 106 if (user != null) {
110   - // TODO noch zu implementieren
111   - return false;
  107 + // auf dieses Benutzerobjekt soll sich die Aktualisierung beziehen
  108 + dto.setUser(user);
  109 +
  110 + final UserDtoToEntityContext ctx = ctxService.createContext(dto);
  111 + mapper.map(ctx);
  112 + return dao.saveOrUpdate(ctx.user) != null;
112 113 }
113 114 return false;
114 115 }
... ... @@ -120,16 +121,8 @@ public class UserService {
120 121 * @return <code>true</code>, wenn das Aktualisieren des Benutzers erfolgreich war.
121 122 */
122 123 public boolean updateUser(final UserDto dto) {
123   - // ist zurzeit ein Benutzer angemeldet, können wir ihn aktualisieren
124 124 final User user = sessionContext.getUser();
125   - if (user != null) {
126   - // der Benutzername darf sich beim Aktualisieren nicht mehr ändern!
127   - dto.withUsername(user.getProfile().getUsername());
128   - final UserDtoToEntityContext ctx = ctxService.createContext(dto);
129   - mapper.map(ctx);
130   - return dao.saveOrUpdate(ctx.user) != null;
131   - }
132   - return false;
  125 + return updateUser(user.getId(), dto);
133 126 }
134 127  
135 128 /**
... ...
src/main/java/net/ziemers/swxercise/ui/UserViewController.java
... ... @@ -89,9 +89,8 @@ public class UserViewController {
89 89 @Produces(MediaType.APPLICATION_JSON)
90 90 @RolesAllowed(RightState.Constants.ADMIN)
91 91 public RestResponse createUser(UserDto dto) {
92   - final Long id = userService.createUser(dto);
93   - if (id != null) {
94   - return new RestResponse(ResponseState.SUCCESS, String.valueOf(id));
  92 + if (userService.createUser(dto)) {
  93 + return new RestResponse();
95 94 }
96 95 return new RestResponse(ResponseState.ALREADY_EXISTING);
97 96 }
... ...
src/test/java/net/ziemers/swxercise/lg/user/service/UserServiceTest.java
... ... @@ -29,12 +29,13 @@ public class UserServiceTest extends JpaTestUtils {
29 29  
30 30 private static String USERNAME_TEST = "username_test";
31 31 private static String EXISTING_USERNAME_TEST = "username_profile";
  32 + private static Long EXISTING_USER_ID = 2L;
32 33  
33 34 private static boolean dbInitialized;
34 35  
35 36 private UserDto userDto;
36 37  
37   - private Long userId;
  38 + private boolean actual;
38 39  
39 40 @Inject
40 41 private UserDao userDao;
... ... @@ -74,7 +75,20 @@ public class UserServiceTest extends JpaTestUtils {
74 75 .createUser();
75 76  
76 77 then()
77   - .assertCreateFail();
  78 + .assertCreateFailure();
  79 + }
  80 +
  81 + @Test
  82 + public void testUpdateUserDoesntUpdateUsername() {
  83 +
  84 + given()
  85 + .userDto(USERNAME_TEST);
  86 +
  87 + when()
  88 + .updateUser(EXISTING_USER_ID);
  89 +
  90 + then()
  91 + .assertUpdateSuccess();
78 92 }
79 93  
80 94 // given
... ... @@ -85,7 +99,7 @@ public class UserServiceTest extends JpaTestUtils {
85 99  
86 100 private UserServiceTest userDto(final String username) {
87 101 userDto = new UserDtoTestDataBuilder()
88   - .withUsername(USERNAME_TEST)
  102 + .withUsername(username)
89 103 .build();
90 104 return this;
91 105 }
... ... @@ -98,7 +112,15 @@ public class UserServiceTest extends JpaTestUtils {
98 112  
99 113 private UserServiceTest createUser() {
100 114 txBegin();
101   - userId = underTest.createUser(userDto);
  115 + actual = underTest.createUser(userDto);
  116 + txCommit();
  117 +
  118 + return this;
  119 + }
  120 +
  121 + private UserServiceTest updateUser(final Long id) {
  122 + txBegin();
  123 + actual = underTest.updateUser(id, userDto);
102 124 txCommit();
103 125  
104 126 return this;
... ... @@ -111,14 +133,20 @@ public class UserServiceTest extends JpaTestUtils {
111 133 }
112 134  
113 135 private void assertCreateSuccess() {
114   - // wir suchen den soeben erstellten Benutzer; wenn er existiert, is alles gut
  136 + // wir suchen den soeben erstellten Benutzer; wenn er existiert, ist alles gut
115 137 final User user = userDao.findByUsername(USERNAME_TEST);
116 138 assertNotNull(user);
117 139 }
118 140  
119   - private void assertCreateFail() {
120   - // es darf kein neuer Benutzer mit identischem "username" erstellt worden sein
121   - assertNull(userId);
  141 + private void assertCreateFailure() {
  142 + // es darf kein neuer Benutzer mit identischem Benutzernamen erstellt worden sein
  143 + assertFalse(actual);
  144 + }
  145 +
  146 + private void assertUpdateSuccess() {
  147 + // wir suchen den soeben aktualisierten Benutzer; wenn sein Benutzername unverändert ist, ist alles gut
  148 + final User user = userDao.findById(EXISTING_USER_ID);
  149 + assertEquals(EXISTING_USERNAME_TEST, user.getProfile().getUsername());
122 150 }
123 151  
124 152 }
... ...
src/test/java/net/ziemers/swxercise/ui/UserViewControllerTest.java
1 1 package net.ziemers.swxercise.ui;
2 2  
3   -import net.ziemers.swxercise.lg.model.user.User;
4 3 import net.ziemers.swxercise.lg.testdatabuilder.user.UserDtoTestDataBuilder;
5   -import net.ziemers.swxercise.lg.testdatabuilder.user.UserTestDataBuilder;
6 4 import net.ziemers.swxercise.lg.user.dto.UserDto;
7 5 import net.ziemers.swxercise.lg.user.service.UserService;
  6 +import net.ziemers.swxercise.ui.enums.ResponseState;
8 7 import org.junit.Test;
9 8 import org.junit.runner.RunWith;
10 9 import org.mockito.InjectMocks;
... ... @@ -33,8 +32,6 @@ public class UserViewControllerTest {
33 32  
34 33 private UserDto userDto;
35 34  
36   - private User user;
37   -
38 35 private RestResponse actual;
39 36  
40 37 @Test
... ... @@ -59,12 +56,54 @@ public class UserViewControllerTest {
59 56  
60 57 @Test
61 58 public void testCreateUserReturnsSuccess() {
62   - // TODO Test ist noch zu implementieren
  59 +
  60 + given()
  61 + .userDto();
  62 +
  63 + doing()
  64 + .createUser(true);
  65 +
  66 + then()
  67 + .assertCreateSuccess();
63 68 }
64 69  
65 70 @Test
66   - public void testUpdateUserReturnsSuccess() {
67   - // TODO Test ist noch zu implementieren
  71 + public void testCreateUserReturnsFailure() {
  72 +
  73 + given()
  74 + .userDto();
  75 +
  76 + doing()
  77 + .createUser(false);
  78 +
  79 + then()
  80 + .assertCreateFailure();
  81 + }
  82 +
  83 + @Test
  84 + public void testUpdateLoggedInUserReturnsSuccess() {
  85 +
  86 + given()
  87 + .userDto();
  88 +
  89 + doing()
  90 + .updateUser();
  91 +
  92 + then()
  93 + .assertUpdateSuccess();
  94 + }
  95 +
  96 + @Test
  97 + public void testUpdateSpecificUserReturnsSuccess() {
  98 +
  99 + given()
  100 + .userDto();
  101 +
  102 + doing()
  103 + .updateUser(1L);
  104 +
  105 + then()
  106 + .assertUpdateSuccess();
68 107 }
69 108  
70 109 @Test
... ... @@ -81,17 +120,29 @@ public class UserViewControllerTest {
81 120 public void testLoginUserReturnsSuccess() {
82 121  
83 122 given()
84   - .userDto()
85   - .user();
  123 + .userDto();
86 124  
87 125 doing()
88   - .loginUser();
  126 + .loginUser(true);
89 127  
90 128 then()
91 129 .assertLoginSuccess();
92 130 }
93 131  
94 132 @Test
  133 + public void testLoginNonExistingUserReturnsFailure() {
  134 +
  135 + given()
  136 + .userDto();
  137 +
  138 + doing()
  139 + .loginUser(false);
  140 +
  141 + then()
  142 + .assertLoginFailure();
  143 + }
  144 +
  145 + @Test
95 146 public void testLogoutUserReturnsSuccess() {
96 147  
97 148 doing()
... ... @@ -112,23 +163,36 @@ public class UserViewControllerTest {
112 163 return this;
113 164 }
114 165  
115   - private UserViewControllerTest user() {
116   - user = new UserTestDataBuilder().build();
117   - return this;
118   - }
119   -
120 166 // doing
121 167  
122 168 private UserViewControllerTest doing() {
123 169 return this;
124 170 }
125 171  
126   - private void loginUser() {
  172 + private void createUser(final boolean result) {
127 173 /*
128 174 * The when().thenReturn() method chain is used to specify
129 175 * a return value for a method call with pre-defined parameters.
130 176 */
131   - when(userService.loginUser(userDto)).thenReturn(true);
  177 + when(userService.createUser(userDto)).thenReturn(result);
  178 +
  179 + actual = underTest.createUser(userDto);
  180 + }
  181 +
  182 + private void updateUser() {
  183 + when(userService.updateUser(userDto)).thenReturn(true);
  184 +
  185 + actual = underTest.updateUser(userDto);
  186 + }
  187 +
  188 + private void updateUser(final Long id) {
  189 + when(userService.updateUser(id, userDto)).thenReturn(true);
  190 +
  191 + actual = underTest.updateUser(id, userDto);
  192 + }
  193 +
  194 + private void loginUser(final boolean result) {
  195 + when(userService.loginUser(userDto)).thenReturn(result);
132 196  
133 197 actual = underTest.loginUser(userDto);
134 198 }
... ... @@ -145,11 +209,31 @@ public class UserViewControllerTest {
145 209 return this;
146 210 }
147 211  
  212 + private void assertCreateSuccess() {
  213 + final RestResponse expected = new RestResponse();
  214 + assertEquals(expected, actual);
  215 + }
  216 +
  217 + private void assertCreateFailure() {
  218 + final RestResponse expected = new RestResponse(ResponseState.ALREADY_EXISTING);
  219 + assertEquals(expected, actual);
  220 + }
  221 +
  222 + private void assertUpdateSuccess() {
  223 + final RestResponse expected = new RestResponse();
  224 + assertEquals(expected, actual);
  225 + }
  226 +
148 227 private void assertLoginSuccess() {
149 228 final RestResponse expected = new RestResponse();
150 229 assertEquals(expected, actual);
151 230 }
152 231  
  232 + private void assertLoginFailure() {
  233 + final RestResponse expected = new RestResponse(ResponseState.FAILED);
  234 + assertEquals(expected, actual);
  235 + }
  236 +
153 237 private void assertLogoutSuccess() {
154 238 final RestResponse expected = new RestResponse();
155 239 assertEquals(expected, actual);
... ...
src/test/resources/net/ziemers/swxercise/testdata/UserServiceTestData.xml
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <dataset>
3 3 <!-- die Grosz-/Kleinschreibung scheint unter bestimmten Bedingungen von Bedeutung zu sein! -->
4   - <Profile id="1" username="username_profile" passwordHash="passwordHash_profile" hashAlgorithm="hashAlgorithm_profile" salt="salt_profile"/>
  4 + <Profile id="1" username="username_profile" passwordHash="passwordHash_profile" hashAlgorithm="SHA512" salt="salt_profile"/>
5 5 <User id="2" firstname="firstname_user" lastname="lastname_user" profile_id="1"/>
6 6 </dataset>
... ...