Commit 1a3690532323c1c3d0a983a4cbd539ca62119322
Merge into master
Showing
10 changed files
with
191 additions
and
74 deletions
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
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> | ... | ... |