From 807f47c51645f16757a89115afee0333b08f41af Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 01:53:49 +0100 Subject: [PATCH 01/20] add rename method plus test --- Jenkinsfile | 14 ------ .../java/de/fd/fh/server/access/Access.java | 5 ++ .../de/fd/fh/server/access/AccessService.java | 7 +-- .../de/fd/fh/server/access/AccessTest.java | 48 +++++++++++++++++++ 4 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTest.java diff --git a/Jenkinsfile b/Jenkinsfile index fe465f2..bf1b355 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -60,20 +60,6 @@ pipeline { success { -// script { -// -// sh "'${env.BRANCH_NAME}'" -// if (${env.BRANCH_NAME}.startsWith('pr-')) { -// -//// git url: "git@gogs.informatik.hs-fulda.de:SteffenN/Multi-Chess.git", -//// credentialsId: 'jenkins_ssh_key', -//// branch: (env.BRANCH_NAME) -// -// sh "git merge '${env.BRANCH_NAME}'" -// sh "git commit -am 'Merged ${env.BRANCH_NAME} branch to master'" -// sh "git push origin master" -// } -// } office365ConnectorSend color: 'good', message: "Build ${currentBuild.fullDisplayName} completed *successfully* (<${BUILD_URL}>).\n\n\n${CUSTOM_SCM_INFO}", webhookUrl: "https://outlook.office.com/webhook/97618564-835e-438e-a2a7-a77b21331e1e@22877e52-e9fd-410d-91a3-817d8ab89d63/JenkinsCI/fa736de2175649a891c2957f00532027/87d23462-1d0c-4378-b4e0-05c7d5546a25" diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/Access.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/Access.java index d3ab03b..7fefde7 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/Access.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/Access.java @@ -43,4 +43,9 @@ public class Access { this.password = newPassword; } + + void rename(final String name) + { + this.name = name; + } } diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessService.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessService.java index 752d321..d0cf03e 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessService.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessService.java @@ -80,8 +80,6 @@ public class AccessService extends Observable { try { - System.out.println("logout " + header); - final Access access = accessRepository.findByToken(header.substring("Bearer ".length())); access.removeToken(); @@ -89,10 +87,9 @@ public class AccessService extends Observable accessRepository.save(access); return true; - } catch (Exception e) + } catch (final Exception e) { e.printStackTrace(); - return false; } } @@ -126,7 +123,7 @@ public class AccessService extends Observable } return null; - } catch (Exception e) + } catch (final Exception e) { e.printStackTrace(); return null; diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTest.java new file mode 100644 index 0000000..0339a18 --- /dev/null +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTest.java @@ -0,0 +1,48 @@ +package de.fd.fh.server.access; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class AccessTest +{ + @Test + void removeTokenTest() + { + final Access access = new Access(null, null, null, null, new AccessToken(), null); + + access.removeToken(); + + assertNull(access.getToken()); + } + + @Test + void setTokenTest() + { + final Access access = new Access(); + + access.setToken(new AccessToken()); + + assertNotNull(access.getToken()); + } + + @Test + void updatePasswordTest() + { + final Access access = new Access(null,null, "TestPassword", null, null, null); + + access.updatePassword("NewTestPassword"); + + assertEquals("NewTestPassword", access.getPassword(), "Should update password."); + } + + @Test + void renameTest() + { + final Access access = new Access(null, "TestName", null, null, null, null); + + access.rename("NewTestName"); + + assertEquals("NewTestName", access.getName(), "Should update name."); + } +} \ No newline at end of file From 4da6e021b7d6b3faa1b76b581d91dc2b5c08c4b7 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 02:22:34 +0100 Subject: [PATCH 02/20] add AccessServiceTest and AccessTokenTest --- .../fh/server/access/AccessServiceTest.java | 45 +++++++++++++++++++ .../fd/fh/server/access/AccessTokenTest.java | 18 ++++++++ 2 files changed, 63 insertions(+) diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessServiceTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessServiceTest.java index 073a84a..f3fa3df 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessServiceTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessServiceTest.java @@ -14,6 +14,7 @@ import java.util.Base64; import java.util.Observable; import java.util.Observer; +import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; import static org.junit.jupiter.api.Assertions.*; @@ -83,6 +84,28 @@ class AccessServiceTest implements Observer then(repository).shouldHaveNoMoreInteractions(); } + @Test + void testUnprotectedLoginPath() + { + final String path = "/accounts/login"; + + final AccessToken result = new AccessService(null) + .before(path, null); + + assertNull(result); + } + + @Test + void testUnprotectedRegistratePath() + { + final String path = "/accounts/registrate"; + + final AccessToken result = new AccessService(null) + .before(path, null); + + assertNull(result); + } + @Test void given_newUser_when_createUser_should_storeNewUser() { @@ -118,6 +141,28 @@ class AccessServiceTest implements Observer then(repository).shouldHaveNoMoreInteractions(); } + @Test + void given_newUser_when_userNameAlreadyExist_should_storeNewUser() + { + final RegistrateRequest request = + RegistrateRequest.of("testUser", "testPwd"); + + final AccessRepository repository = mock(AccessRepository.class); + when(repository.findByUserName(any())) + .thenReturn(new Access()); + + final AccessService service = new AccessService(repository); + service.addObserver(this); + + final boolean result = service.createPlayer(request); + + assertFalse(result); + assertThat("No event thrown", this.event, nullValue()); + + then(repository).should().findByUserName(any()); + then(repository).shouldHaveNoMoreInteractions(); + } + @Test void given_loggedInUser_when_logout_should_logoutUser() { diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTokenTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTokenTest.java index 1872e62..89e0609 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTokenTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTokenTest.java @@ -28,4 +28,22 @@ class AccessTokenTest assertEquals(result.getRole(), Role.USER); assertEquals(result.getUserId(), UserId.of("12345")); } + + @Test + void testPrePersist() + { + final Access access = new Access( + "testId", + "testName", + "testPwd", + UserId.of("12345"), + null, + Role.USER); + + final AccessToken accessToken = AccessToken.of(access); + + accessToken.prePersist(); + + assertNotNull(accessToken.getCreatedDate()); + } } \ No newline at end of file From 307cbd8a621da6a2874661d20471198a6b728153 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 02:32:43 +0100 Subject: [PATCH 03/20] add ChangeUserNameEvent and add UserServiceTest --- .../java/de/fd/fh/server/user/UserId.java | 1 - .../de/fd/fh/server/user/UserService.java | 19 +++++++--- .../user/events/ChangeUserNameEvent.java | 14 +++++++ .../fh/server/user/web/ChangeUserRequest.java | 10 +++-- .../de/fd/fh/server/user/UserServiceTest.java | 38 ++++++++++++++++--- 5 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 fh.fd.ci.server/src/main/java/de/fd/fh/server/user/events/ChangeUserNameEvent.java diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserId.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserId.java index d978069..e6599af 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserId.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserId.java @@ -6,7 +6,6 @@ import org.bson.types.ObjectId; @Getter @Embedded -@NoArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) @EqualsAndHashCode(of = {"identifier"}) public class UserId diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserService.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserService.java index 268e695..930a807 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserService.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserService.java @@ -1,6 +1,7 @@ package de.fd.fh.server.user; import de.fd.fh.server.user.events.ChangePasswordEvent; +import de.fd.fh.server.user.events.ChangeUserNameEvent; import de.fd.fh.server.user.web.ChangeUserRequest; import de.fd.fh.server.user.web.UserRequest; import lombok.RequiredArgsConstructor; @@ -14,8 +15,6 @@ public class UserService extends Observable public User changePlayer(final UserId userId, final ChangeUserRequest message) { - System.out.println("changePlayer: " + message); - User user = userRepository.findUserById(userId); if (message.getPassword() != null) @@ -24,9 +23,19 @@ public class UserService extends Observable notifyObservers(new ChangePasswordEvent(userId, message.getPassword())); } - userRepository.save(user); + if (message.getName() != null) + { + if (userRepository.findUserByName(message.getName()) == null) + { + user.rename(message.getName()); + userRepository.save(user); + + setChanged(); + notifyObservers(new ChangeUserNameEvent(userId, message.getName())); + } + } - return userRepository.findUserById(userId); + return user; } public User getPlayer(final UserId id) @@ -45,4 +54,4 @@ public class UserService extends Observable return new UserRequest(user.getId().getIdentifier(), user.getName()); } -} +} \ No newline at end of file diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/events/ChangeUserNameEvent.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/events/ChangeUserNameEvent.java new file mode 100644 index 0000000..e30a175 --- /dev/null +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/events/ChangeUserNameEvent.java @@ -0,0 +1,14 @@ +package de.fd.fh.server.user.events; + +import de.fd.fh.server.user.UserId; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public class ChangeUserNameEvent +{ + private final UserId userId; + + private final String newName; +} \ No newline at end of file diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/ChangeUserRequest.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/ChangeUserRequest.java index 82fbe76..a41e949 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/ChangeUserRequest.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/ChangeUserRequest.java @@ -1,13 +1,15 @@ package de.fd.fh.server.user.web; +import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.RequiredArgsConstructor; +import lombok.NoArgsConstructor; -@RequiredArgsConstructor +@NoArgsConstructor +@AllArgsConstructor @Getter public class ChangeUserRequest { - private final String name; + private String name; - private final String password; + private String password; } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserServiceTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserServiceTest.java index 1c3bcbf..357ef0e 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserServiceTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserServiceTest.java @@ -9,8 +9,10 @@ import org.mockito.ArgumentCaptor; import java.util.Observable; import java.util.Observer; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.*; class UserServiceTest implements Observer @@ -29,19 +31,45 @@ class UserServiceTest implements Observer final User user = User.of("testName"); final ChangeUserRequest request = - new ChangeUserRequest("testName", "newPassword"); + new ChangeUserRequest(null, "newPassword"); final UserRepository repository = mock(UserRepository.class); when(repository.findUserById(any(UserId.class))) .thenReturn(user); - final UserService service = new UserService(repository); + final de.fd.fh.server.user.UserService service = new de.fd.fh.server.user.UserService(repository); + service.addObserver(this); + + service.changePlayer(UserId.of("12345"), request); + + assertNotNull(event); + } + + @Test + void given_storedUser_when_changeUserName_should_renameAndFireEvent() + { + final User user = + User.of("testName"); + final ChangeUserRequest request = + new ChangeUserRequest("newTestName", null); + final UserRepository repository = mock(UserRepository.class); + when(repository.findUserById(any(UserId.class))) + .thenReturn(user); + when(repository.findUserByName(any())) + .thenReturn(null); + + final de.fd.fh.server.user.UserService service = new de.fd.fh.server.user.UserService(repository); service.addObserver(this); final ArgumentCaptor captor = ArgumentCaptor.forClass(User.class); service.changePlayer(UserId.of("12345"), request); - verify(repository).save(captor.capture()); + then(repository).should().findUserById(any(UserId.class)); + then(repository).should().findUserByName(any()); + verify(repository).save(captor.capture()); + then(repository).should().save(any()); + then(repository).shouldHaveNoMoreInteractions(); assertNotNull(captor.getValue(), "Should be saved"); + assertEquals(captor.getValue().getName(), "newTestName", "User should have new name"); assertNotNull(event); } @@ -68,7 +96,7 @@ class UserServiceTest implements Observer when(repository.findUserById(any(UserId.class))) .thenReturn(user); - final UserRequest result = new UserService(repository).getSmallPlayer(UserId.of("12345")); + final UserRequest result = new de.fd.fh.server.user.UserService(repository).getSmallPlayer(UserId.of("12345")); assertNotNull(result); assertEquals("12345", result.getId(), "Wrong UserId"); From d6b9ecd5bdd768c3fea9039a09c019c3d69bd88e Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 02:45:37 +0100 Subject: [PATCH 04/20] add missing UserTest and add changeUserName behavior --- .../access/AccessContextEventListener.java | 33 ++++++++++++++----- .../AccessContextEventListenerTest.java | 27 ++++++++++++--- .../java/de/fd/fh/server/user/UserTest.java | 28 ++++++++++++++++ 3 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserTest.java diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessContextEventListener.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessContextEventListener.java index 4920e07..216910e 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessContextEventListener.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessContextEventListener.java @@ -1,6 +1,7 @@ package de.fd.fh.server.access; import de.fd.fh.server.user.events.ChangePasswordEvent; +import de.fd.fh.server.user.events.ChangeUserNameEvent; import lombok.RequiredArgsConstructor; import java.util.Observable; @@ -12,17 +13,33 @@ public class AccessContextEventListener implements Observer private final AccessRepository accessRepository; @Override - public void update(Observable observable, Object o) + public void update(Observable observable, Object event) { - if(o instanceof ChangePasswordEvent) + if (event instanceof ChangePasswordEvent) { - final ChangePasswordEvent event = (ChangePasswordEvent) o; + handlePasswordChange((ChangePasswordEvent) event); + } + else if (event instanceof ChangeUserNameEvent) + { + handleRename((ChangeUserNameEvent) event); + } + } - final Access access = accessRepository.findByUserId(event.getUserId()); + public void handleRename(ChangeUserNameEvent event) + { + final Access access = accessRepository.findByUserId(event.getUserId()); - access.updatePassword(event.getNewPassword()); + access.rename(event.getNewName()); - accessRepository.save(access); - } + accessRepository.save(access); + } + + public void handlePasswordChange(ChangePasswordEvent event) + { + final Access access = accessRepository.findByUserId(event.getUserId()); + + access.updatePassword(event.getNewPassword()); + + accessRepository.save(access); } -} +} \ No newline at end of file diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessContextEventListenerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessContextEventListenerTest.java index e970141..84e5b4e 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessContextEventListenerTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessContextEventListenerTest.java @@ -1,13 +1,12 @@ package de.fd.fh.server.access; import de.fd.fh.server.user.UserId; -import de.fd.fh.server.user.UserRepository; -import de.fd.fh.server.user.UserService; import de.fd.fh.server.user.events.ChangePasswordEvent; +import de.fd.fh.server.user.events.ChangeUserNameEvent; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.*; @@ -25,7 +24,7 @@ class AccessContextEventListenerTest final ArgumentCaptor captor = ArgumentCaptor.forClass(Access.class); - new AccessContextEventListener(repository).update(null, event); + new de.fd.fh.server.access.AccessContextEventListener(repository).update(null, event); verify(repository).save(captor.capture()); assertEquals("newPwd", captor.getValue().getPassword(), "Have to be the new password"); @@ -33,4 +32,24 @@ class AccessContextEventListenerTest then(repository).should().save(any(Access.class)); then(repository).shouldHaveNoMoreInteractions(); } + + @Test + void given_changeNameEvent_when_nameChanged_should_renameAccess() + { + final ChangeUserNameEvent event = new ChangeUserNameEvent(UserId.of("12345"), "newName"); + + final AccessRepository repository = mock(AccessRepository.class); + when(repository.findByUserId(any(UserId.class))) + .thenReturn(new Access()); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Access.class); + + new de.fd.fh.server.access.AccessContextEventListener(repository).update(null, event); + verify(repository).save(captor.capture()); + + assertEquals("newName", captor.getValue().getName(), "Have to be the new name"); + then(repository).should().findByUserId(any(UserId.class)); + then(repository).should().save(any(Access.class)); + then(repository).shouldHaveNoMoreInteractions(); + } } \ No newline at end of file diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserTest.java new file mode 100644 index 0000000..50d2874 --- /dev/null +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserTest.java @@ -0,0 +1,28 @@ +package de.fd.fh.server.user; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class UserTest +{ + @Test + void testRename() + { + final User user = new User(UserId.random(), "TestName"); + + user.rename("NewTestName"); + + assertEquals("NewTestName", user.getName(), "Should rename user."); + } + + @Test + void failedRenameTest() + { + final User user = new User(UserId.random(), "TestName"); + + user.rename(null); + + assertEquals("TestName", user.getName(), "Should rename user."); + } +} \ No newline at end of file From a3edf01c742eb9a9e9694894642407e4d4606a4b Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 02:58:16 +0100 Subject: [PATCH 05/20] seperate delete method --- .../server/access/web/AccessController.java | 54 +++++-------- .../access/web/AccessControllerTest.java | 76 +++++++++++++++++++ 2 files changed, 97 insertions(+), 33 deletions(-) create mode 100644 fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index 3e32964..3d43c07 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -7,15 +7,35 @@ import de.fd.fh.server.user.UserId; import de.fd.fh.shared.Utils; import de.fd.fh.shared.network.messages.LoginRequest; import de.fd.fh.shared.network.messages.RegistrateRequest; +import spark.Request; +import spark.Response; import static spark.Spark.*; public class AccessController { private final ObjectMapper objectMapper = new ObjectMapper(); + private final AccessService service; + public Response deletePlayer(Request request, Response response) + { + final UserId userId = UserId.of(request.params(":player_id")); + final AccessToken token = request.session().attribute("userId"); + + if (service.deleteAccount(userId, token)) + { + response.status(200); + } + else + { + response.status(400); + } + + return response; + } public AccessController(final AccessService service) { + this.service = service; before("/*", (req, res) -> { @@ -66,39 +86,7 @@ public class AccessController return response; }); - post("/accounts/logout", - (request, response) -> - { - final String token = request.headers(Utils.AUTHENTICATION_HEADER); - - if (service.logout(token)) - { - response.status(200); - } - else - { - response.status(400); - } - - return response; - }); - - delete("/accounts/:player_id", - (request, response) -> - { - final UserId userId = UserId.of(request.params(":player_id")); - final AccessToken token = request.session().attribute("userId"); - - if (service.deleteAccount(userId, token)) - { - response.status(200); - } - else - { - response.status(400); - } + post("/accounts/logout", this::deletePlayer); - return response; - }); } } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java new file mode 100644 index 0000000..1046b8a --- /dev/null +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java @@ -0,0 +1,76 @@ +package de.fd.fh.server.access.web; + +import de.fd.fh.server.access.AccessService; +import de.fd.fh.server.access.AccessToken; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import spark.Request; +import spark.Response; +import spark.Session; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class AccessControllerTest +{ + @Mock + Request request; + @Mock + Response response; + @Mock + Session session; + @Mock + AccessService service; + + @BeforeEach + void before() + { + MockitoAnnotations.openMocks(this); + } + + @Test + void deletePlayerTest() + { + when(request.params(any())).thenReturn("12345"); + when(request.session()).thenReturn(session); + when(session.attribute(any())).thenReturn(new AccessToken()); + when(service.deleteAccount(any(), any())).thenReturn(true); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Integer.class); + + new AccessController(service).deletePlayer(request, response); + + verify(response).status(captor.capture()); + + then(service).should().deleteAccount(any(), any()); + then(service).shouldHaveNoMoreInteractions(); + + assertEquals(captor.getValue(), Integer.valueOf(200), "Should return Status code 200."); + } + + @Test + void failedDeletePlayerTest() + { + when(request.params(any())).thenReturn("12345"); + when(request.session()).thenReturn(session); + when(session.attribute(any())).thenReturn(new AccessToken()); + when(service.deleteAccount(any(), any())).thenReturn(false); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Integer.class); + + new AccessController(service).deletePlayer(request, response); + + verify(response).status(captor.capture()); + + then(service).should().deleteAccount(any(), any()); + then(service).shouldHaveNoMoreInteractions(); + + assertEquals(captor.getValue(), Integer.valueOf(400), "Should return Status code 400."); + } +} \ No newline at end of file From e1a3c968100ab6b0a68bb29bf7d1393e0effe44e Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:01:26 +0100 Subject: [PATCH 06/20] extract logout method --- .../server/access/web/AccessController.java | 20 ++++++++++- .../access/web/AccessControllerTest.java | 36 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index 3d43c07..ccef76e 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -33,6 +33,23 @@ public class AccessController return response; } + + public Object logout(Request request, Response response) + { + final String token = request.headers(Utils.AUTHENTICATION_HEADER); + + if (service.logout(token)) + { + response.status(200); + } + else + { + response.status(400); + } + + return response; + } + public AccessController(final AccessService service) { this.service = service; @@ -86,7 +103,8 @@ public class AccessController return response; }); - post("/accounts/logout", this::deletePlayer); + post("/accounts/logout",this::logout); + delete("/accounts/:player_id", this::deletePlayer); } } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java index 1046b8a..a99039f 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java @@ -73,4 +73,40 @@ class AccessControllerTest assertEquals(captor.getValue(), Integer.valueOf(400), "Should return Status code 400."); } + + @Test + void testLogout() + { + when(request.headers(any())).thenReturn("testHeader"); + when(service.logout(any())).thenReturn(true); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Integer.class); + + new AccessController(service).logout(request, response); + + verify(response).status(captor.capture()); + + then(service).should().logout(any()); + then(service).shouldHaveNoMoreInteractions(); + + assertEquals(captor.getValue(), Integer.valueOf(200), "Should return Status code 200."); + } + + @Test + void failedLogoutTest() + { + when(request.headers(any())).thenReturn("testHeader"); + when(service.logout(any())).thenReturn(false); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Integer.class); + + new AccessController(service).logout(request, response); + + verify(response).status(captor.capture()); + + then(service).should().logout(any()); + then(service).shouldHaveNoMoreInteractions(); + + assertEquals(captor.getValue(), Integer.valueOf(400), "Should return Status code 400."); + } } \ No newline at end of file From de04669bd132d6019f7df5afc68f95723607cfad Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:03:29 +0100 Subject: [PATCH 07/20] extract login method --- .../server/access/web/AccessController.java | 40 ++++++++------- .../access/web/AccessControllerTest.java | 50 +++++++++++++++++++ 2 files changed, 71 insertions(+), 19 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index ccef76e..6bd9676 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -1,5 +1,6 @@ package de.fd.fh.server.access.web; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import de.fd.fh.server.access.AccessService; import de.fd.fh.server.access.AccessToken; @@ -50,6 +51,25 @@ public class AccessController return response; } + public Object login(Request request, Response response) throws JsonProcessingException + { + final String header = request.headers(Utils.AUTHENTICATION_HEADER); + + final LoginRequest login = service.authorization(header); + + if (login == null) + { + response.status(401); + } + else + { + response.status(200); + response.type("application/json"); + response.body(objectMapper.writeValueAsString(login)); + } + return response; + } + public AccessController(final AccessService service) { this.service = service; @@ -83,25 +103,7 @@ public class AccessController } ); - post("/accounts/login", - (request, response) -> - { - final String header = request.headers(Utils.AUTHENTICATION_HEADER); - - final LoginRequest login = service.authorization(header); - - if (login == null) - { - response.status(401); - } - else - { - response.status(200); - response.type("application/json"); - response.body(objectMapper.writeValueAsString(login)); - } - return response; - }); + post("/accounts/login", this::login); post("/accounts/logout",this::logout); diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java index a99039f..ecd494d 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java @@ -1,7 +1,9 @@ package de.fd.fh.server.access.web; +import com.fasterxml.jackson.core.JsonProcessingException; import de.fd.fh.server.access.AccessService; import de.fd.fh.server.access.AccessToken; +import de.fd.fh.shared.network.messages.LoginRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -109,4 +111,52 @@ class AccessControllerTest assertEquals(captor.getValue(), Integer.valueOf(400), "Should return Status code 400."); } + + @Test + void loginTest() throws JsonProcessingException + { + final LoginRequest dummy = new LoginRequest(); + dummy.setName("TestName"); + dummy.setToken("TestToken"); + dummy.setUserId("12345"); + + when(request.headers(any())).thenReturn("testHeader"); + when(service.authorization(any())).thenReturn(dummy); + + final ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + final ArgumentCaptor typeCaptor = ArgumentCaptor.forClass(String.class); + final ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(String.class); + + new AccessController(service).login(request, response); + + verify(response).status(statusCaptor.capture()); + verify(response).type(typeCaptor.capture()); + verify(response).body(bodyCaptor.capture()); + + then(service).should().authorization(any()); + then(service).shouldHaveNoMoreInteractions(); + + assertEquals(Integer.valueOf(200), statusCaptor.getValue(), "Should return Status code 200."); + assertEquals("application/json", typeCaptor.getValue(), "Should have return type json."); + assertEquals("{\"name\":\"TestName\",\"userId\":\"12345\",\"token\":\"TestToken\"}", + bodyCaptor.getValue(), "Should return correct Body."); + } + + @Test + void failedLoginTest() throws JsonProcessingException + { + when(request.headers(any())).thenReturn("testHeader"); + when(service.authorization(any())).thenReturn(null); + + final ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + + new AccessController(service).login(request, response); + + verify(response).status(statusCaptor.capture()); + + then(service).should().authorization(any()); + then(service).shouldHaveNoMoreInteractions(); + + assertEquals(Integer.valueOf(401), statusCaptor.getValue(), "Should return Status code 401."); + } } \ No newline at end of file From ea211b5a7b9880c46c61839a93acf9a53fdc854f Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:05:14 +0100 Subject: [PATCH 08/20] extract registrate method --- .../server/access/web/AccessController.java | 34 ++++++++--------- .../access/web/AccessControllerTest.java | 38 +++++++++++++++++++ .../network/messages/RegistrateRequest.java | 2 + 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index 6bd9676..6594de0 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -70,6 +70,22 @@ public class AccessController return response; } + public Object registrate(Request request, Response response) throws java.io.IOException + { + final RegistrateRequest message = + objectMapper.readValue(request.body(), RegistrateRequest.class); + + if (service.createPlayer(message)) + { + response.status(201); + } + else + { + response.status(400); + } + return response; + } + public AccessController(final AccessService service) { this.service = service; @@ -85,23 +101,7 @@ public class AccessController accessToken); }); - post("/accounts/registrate", - (request, response) -> - { - final RegistrateRequest message = - objectMapper.readValue(request.body(), RegistrateRequest.class); - - if (service.createPlayer(message)) - { - response.status(201); - } - else - { - response.status(400); - } - return response; - } - ); + post("/accounts/registrate", this::registrate); post("/accounts/login", this::login); diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java index ecd494d..22d64e2 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java @@ -13,6 +13,8 @@ import spark.Request; import spark.Response; import spark.Session; +import java.io.IOException; + import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.then; @@ -159,4 +161,40 @@ class AccessControllerTest assertEquals(Integer.valueOf(401), statusCaptor.getValue(), "Should return Status code 401."); } + + @Test + void registrateTest() throws IOException + { + when(request.body()).thenReturn("{\"userName\":\"TestName\",\"password\":\"TestPassword\"}"); + + when(service.createPlayer(any())).thenReturn(true); + + final ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + + new AccessController(service).registrate(request, response); + + verify(response).status(statusCaptor.capture()); + + then(service).should().createPlayer(any()); + then(service).shouldHaveNoMoreInteractions(); + assertEquals(Integer.valueOf(201), statusCaptor.getValue(), "Should return Status code 201."); + } + + @Test + void failedRegistrateTest() throws IOException + { + when(request.body()).thenReturn("{\"userName\":\"TestName\",\"password\":\"TestPassword\"}"); + + when(service.createPlayer(any())).thenReturn(false); + + final ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + + new AccessController(service).registrate(request, response); + + verify(response).status(statusCaptor.capture()); + + then(service).should().createPlayer(any()); + then(service).shouldHaveNoMoreInteractions(); + assertEquals(Integer.valueOf(400), statusCaptor.getValue(), "Should return Status code 400."); + } } \ No newline at end of file diff --git a/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/RegistrateRequest.java b/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/RegistrateRequest.java index b3c08d4..1b37a02 100644 --- a/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/RegistrateRequest.java +++ b/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/RegistrateRequest.java @@ -2,9 +2,11 @@ package de.fd.fh.shared.network.messages; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; @Data @AllArgsConstructor(staticName = "of") +@NoArgsConstructor public class RegistrateRequest { private String userName; From ec303026ba1b1c287b5de98bb37600803b3b6943 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:19:46 +0100 Subject: [PATCH 09/20] extract before method --- .../server/access/web/AccessController.java | 24 ++++++++++-------- .../access/web/AccessControllerTest.java | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index 6594de0..c74fa87 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -10,6 +10,7 @@ import de.fd.fh.shared.network.messages.LoginRequest; import de.fd.fh.shared.network.messages.RegistrateRequest; import spark.Request; import spark.Response; +import spark.Spark; import static spark.Spark.*; @@ -86,20 +87,21 @@ public class AccessController return response; } - public AccessController(final AccessService service) + public void before(final Request req) { - this.service = service; - before("/*", - (req, res) -> - { - final String path = req.pathInfo(); - final String token = req.headers(Utils.AUTHENTICATION_HEADER); + final String path = req.pathInfo(); + final String token = req.headers(Utils.AUTHENTICATION_HEADER); - final AccessToken accessToken = service.before(path, token); + final AccessToken accessToken = service.before(path, token); + + req.session().attribute("userId", + accessToken); + } - req.session().attribute("userId", - accessToken); - }); + public AccessController(final AccessService service) + { + this.service = service; + Spark.before("/*", (req, res) -> before(req)); post("/accounts/registrate", this::registrate); diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java index 22d64e2..abeb4e9 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java @@ -3,6 +3,8 @@ package de.fd.fh.server.access.web; import com.fasterxml.jackson.core.JsonProcessingException; import de.fd.fh.server.access.AccessService; import de.fd.fh.server.access.AccessToken; +import de.fd.fh.server.access.Role; +import de.fd.fh.server.user.UserId; import de.fd.fh.shared.network.messages.LoginRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -14,6 +16,7 @@ import spark.Response; import spark.Session; import java.io.IOException; +import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; @@ -197,4 +200,26 @@ class AccessControllerTest then(service).shouldHaveNoMoreInteractions(); assertEquals(Integer.valueOf(400), statusCaptor.getValue(), "Should return Status code 400."); } + + @Test + void testBefore() + { + final AccessToken dummy = new AccessToken("TestToken", LocalDateTime.now(), Role.USER, UserId.random()); + + when(request.pathInfo()).thenReturn("/test/path"); + when(request.headers(any())).thenReturn("TestAuthHeader"); + when(request.session()).thenReturn(session); + when(service.before(any(), any())) + .thenReturn(dummy); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(AccessToken.class); + + new AccessController(service).before(request); + + verify(session).attribute(any(), captor.capture()); + + assertEquals(dummy, captor.getValue(), "Should store Token in Session"); + then(service).should().before(any(), any()); + then(service).shouldHaveNoMoreInteractions(); + } } \ No newline at end of file From 45766f907042512c042772e2f5a773346bf2b383 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:26:59 +0100 Subject: [PATCH 10/20] extract getUser method --- .../fd/fh/server/user/web/UserController.java | 34 +++++---- .../server/user/web/UserControllerTest.java | 70 +++++++++++++++++++ 2 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java index 67a932d..4f43bba 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java @@ -1,10 +1,13 @@ package de.fd.fh.server.user.web; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import de.fd.fh.server.access.AccessToken; import de.fd.fh.server.user.User; import de.fd.fh.server.user.UserId; import de.fd.fh.server.user.UserService; +import spark.Request; +import spark.Response; import static spark.Spark.get; import static spark.Spark.post; @@ -13,8 +16,25 @@ public class UserController { private ObjectMapper objectMapper = new ObjectMapper(); + private final UserService service; + + public Response getUser(Request request, Response response) throws JsonProcessingException + { + final UserId userId = UserId.of(request.params(":user_id")); + final UserRequest user = service.getSmallPlayer(userId); + + if (user == null) + { + response.status(404); + return response; + } + response.body(objectMapper.writeValueAsString(user)); + return response; + } + public UserController(final UserService service) { + this.service = service; post("/users", ((request, response) -> { @@ -72,18 +92,6 @@ public class UserController } ); - get("/users/:user_id", - (request, response) -> - { - final UserId userId = UserId.of(request.params(":user_id")); - final UserRequest user = service.getSmallPlayer(userId); - - if (user == null) - { - response.status(404); - } - response.body(objectMapper.writeValueAsString(user)); - return response; - }); + get("/users/:user_id", this::getUser); } } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java new file mode 100644 index 0000000..452814a --- /dev/null +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java @@ -0,0 +1,70 @@ +package de.fd.fh.server.user.web; + +import com.fasterxml.jackson.core.JsonProcessingException; +import de.fd.fh.server.user.UserService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import spark.Request; +import spark.Response; +import spark.Session; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class UserControllerTest +{ + @Mock + Request request; + @Mock + Response response; + @Mock + UserService service; + + @BeforeEach + void before() + { + MockitoAnnotations.openMocks(this); + } + + @Test + void getUserTest() throws JsonProcessingException + { + when(request.params(any())).thenReturn("12345"); + when(service.getSmallPlayer(any())).thenReturn(new UserRequest("12345", "TestName")); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); + + final Response result = new UserController(service).getUser(request, response); + + verify(response).body(captor.capture()); + + assertEquals(response, result, "Should return the incomming response."); + assertEquals("{\"id\":\"12345\",\"name\":\"TestName\"}", captor.getValue(), + "Should return UserRequest in Body."); + then(service).should().getSmallPlayer(any()); + } + + @Test + void failedGetUserTest() throws JsonProcessingException + { + when(request.params(any())).thenReturn("12345"); + when(service.getSmallPlayer(any())).thenReturn(null); + + final ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(Integer.class); + + final Response result = new UserController(service).getUser(request, response); + + verify(response).status(statusCaptor.capture()); + + assertEquals(response, result, "Should return the incomming response."); + assertEquals(Integer.valueOf(404), statusCaptor.getValue(), "Should return not found status code."); + then(service).should().getSmallPlayer(any()); + then(service).shouldHaveNoMoreInteractions(); + } +} \ No newline at end of file From 7821fb47e21cd01dece5415e4fa5e2c816d48352 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:31:19 +0100 Subject: [PATCH 11/20] extract getCompleteUser method --- .../fd/fh/server/user/web/UserController.java | 51 +++++++++--------- .../server/user/web/UserControllerTest.java | 53 +++++++++++++++++++ 2 files changed, 77 insertions(+), 27 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java index 4f43bba..8c225ba 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java @@ -32,39 +32,36 @@ public class UserController return response; } - public UserController(final UserService service) + public Response getCompleteUser(Request request, Response response) throws JsonProcessingException { - this.service = service; - post("/users", - ((request, response) -> - { - final UserId userId = - ((AccessToken) request.session() - .attribute("userId")) - .getUserId(); + final UserId userId = + ((AccessToken) request.session() + .attribute("userId")) + .getUserId(); - final ChangeUserRequest message = objectMapper.readValue(request.body(), - ChangeUserRequest.class); + final User user = service.getPlayer(userId); - final User user = service.changePlayer( - userId, - message); + if (user == null) + { + response.status(404); + } + else + { + response.status(200); + response.type("application/json"); - if (user == null) - { - response.status(400); - } - else - { - response.status(200); - response.type("application/json"); + response.body(objectMapper.writeValueAsString(user)); - return objectMapper.writeValueAsString(user); - } + return response; + } - return response; - } - )); + return response; + } + + public UserController(final UserService service) + { + this.service = service; + post("/users", this::getCompleteUser); get("/users", (request, response) -> diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java index 452814a..5ac91c7 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java @@ -1,6 +1,9 @@ package de.fd.fh.server.user.web; import com.fasterxml.jackson.core.JsonProcessingException; +import de.fd.fh.server.access.AccessToken; +import de.fd.fh.server.user.User; +import de.fd.fh.server.user.UserId; import de.fd.fh.server.user.UserService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -24,6 +27,8 @@ class UserControllerTest @Mock Response response; @Mock + Session session; + @Mock UserService service; @BeforeEach @@ -67,4 +72,52 @@ class UserControllerTest then(service).should().getSmallPlayer(any()); then(service).shouldHaveNoMoreInteractions(); } + + @Test + void getCompleteUserTest() throws JsonProcessingException + { + when(request.session()).thenReturn(session); + when(session.attribute(any())).thenReturn( + new AccessToken(null, null, null, UserId.of("12345"))); + when(service.getPlayer(any(UserId.class))).thenReturn(User.of("TestName")); + + final ArgumentCaptor statusCapture = ArgumentCaptor.forClass(Integer.class); + final ArgumentCaptor bodyCapture = ArgumentCaptor.forClass(String.class); + final ArgumentCaptor typeCapture = ArgumentCaptor.forClass(String.class); + + final Response result = new UserController(service).getCompleteUser(request, response); + + verify(response).status(statusCapture.capture()); + verify(response).type(typeCapture.capture()); + verify(response).body(bodyCapture.capture()); + + assertEquals(response, result, "Should return the incoming Response"); + assertEquals(Integer.valueOf(200), statusCapture.getValue(), "Should return status code 200."); + assertEquals("application/json", typeCapture.getValue(), "Should have content type json."); + assertEquals("{\"id\":null,\"name\":\"TestName\"}", bodyCapture.getValue(), "Should return user as json."); + + then(service).should().getPlayer(any()); + then(service).shouldHaveNoMoreInteractions(); + } + + @Test + void failedGetCompleteUserTest() throws JsonProcessingException + { + when(request.session()).thenReturn(session); + when(session.attribute(any())).thenReturn( + new AccessToken(null, null, null, UserId.of("12345"))); + when(service.getPlayer(any(UserId.class))).thenReturn(null); + + final ArgumentCaptor capture = ArgumentCaptor.forClass(Integer.class); + + final Response result = new UserController(service).getCompleteUser(request, response); + + verify(response).status(capture.capture()); + + assertEquals(response, result, "Should return the incoming Response"); + assertEquals(Integer.valueOf(404), capture.getValue(), "Should return status code 200."); + then(service).should().getPlayer(any()); + then(service).shouldHaveNoMoreInteractions(); + } + } \ No newline at end of file From 6d86dbdfa4fb18dbaa51ee15bcf48ea48a9d3289 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:33:16 +0100 Subject: [PATCH 12/20] extract updateUser method --- .../fd/fh/server/user/web/UserController.java | 57 +++++++++++-------- .../server/user/web/UserControllerTest.java | 51 +++++++++++++++++ 2 files changed, 83 insertions(+), 25 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java index 8c225ba..4ddeb91 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java @@ -58,36 +58,43 @@ public class UserController return response; } + public Response updateUser(Request request, Response response) throws java.io.IOException + { + final UserId userId = + ((AccessToken) request.session() + .attribute("userId")) + .getUserId(); + + final ChangeUserRequest message = objectMapper.readValue(request.body(), + ChangeUserRequest.class); + + final User user = service.changePlayer( + userId, + message); + + if (user == null) + { + response.status(400); + } + else + { + response.status(200); + response.type("application/json"); + + response.body(objectMapper.writeValueAsString(user)); + + return response; + } + + return response; + } + public UserController(final UserService service) { this.service = service; post("/users", this::getCompleteUser); - get("/users", - (request, response) -> - { - final UserId userId = - ((AccessToken) request.session() - .attribute("userId")) - .getUserId(); - - final User user = service.getPlayer(userId); - - if (user == null) - { - response.status(400); - } - else - { - response.status(200); - response.type("application/json"); - - return objectMapper.writeValueAsString(user); - } - - return response; - } - ); + get("/users", this::updateUser); get("/users/:user_id", this::getUser); } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java index 5ac91c7..65bf4ff 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java @@ -14,6 +14,8 @@ import spark.Request; import spark.Response; import spark.Session; +import java.io.IOException; + import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.then; @@ -120,4 +122,53 @@ class UserControllerTest then(service).shouldHaveNoMoreInteractions(); } + @Test + void updateUserTest() throws IOException + { + when(request.session()).thenReturn(session); + when(session.attribute(any())).thenReturn( + new AccessToken(null, null, null, UserId.of("12345"))); + when(request.body()).thenReturn("{\"name\":\"TestName\",\"password\":\"TestPassword\"}"); + when(service.changePlayer(any(), any())).thenReturn(new User(UserId.of("12345"), "TestName")); + + final ArgumentCaptor statusCapture = ArgumentCaptor.forClass(Integer.class); + final ArgumentCaptor bodyCapture = ArgumentCaptor.forClass(String.class); + final ArgumentCaptor typeCapture = ArgumentCaptor.forClass(String.class); + + final Response result = new UserController(service).updateUser(request, response); + + verify(response).status(statusCapture.capture()); + verify(response).type(typeCapture.capture()); + verify(response).body(bodyCapture.capture()); + + assertEquals(response, result, "Should return the incoming Response"); + assertEquals(Integer.valueOf(200), statusCapture.getValue(), "Should return status code 200."); + assertEquals("application/json", typeCapture.getValue(), "Should have content type json."); + assertEquals("{\"id\":{\"identifier\":\"12345\"},\"name\":\"TestName\"}", bodyCapture.getValue(), "Should return user as json."); + + then(service).should().changePlayer(any(), any()); + then(service).shouldHaveNoMoreInteractions(); + } + + @Test + void failedUpdateUserTest() throws IOException + { + when(request.session()).thenReturn(session); + when(session.attribute(any())).thenReturn( + new AccessToken(null, null, null, UserId.of("12345"))); + when(request.body()).thenReturn("{\"name\":\"TestName\",\"password\":\"TestPassword\"}"); + when(service.changePlayer(any(), any())).thenReturn(null); + + final ArgumentCaptor statusCapture = ArgumentCaptor.forClass(Integer.class); + + final Response result = new UserController(service).updateUser(request, response); + + verify(response).status(statusCapture.capture()); + + assertEquals(response, result, "Should return the incoming Response"); + assertEquals(Integer.valueOf(400), statusCapture.getValue(), "Should return status code 400."); + + then(service).should().changePlayer(any(), any()); + then(service).shouldHaveNoMoreInteractions(); + } } \ No newline at end of file From 3e23f6ff9c6013ae33c0ba714ed447d3ee3e43c4 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:46:37 +0100 Subject: [PATCH 13/20] extract before routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 29 +++++-- .../server/access/web/AccessController.java | 1 - .../src/test/java/de/fd/fh/ServerAppTest.java | 53 ++++++++++++ .../java/de/fd/fh/server/ApiTestUtils.java | 86 +++++++++++++++++++ 4 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java create mode 100644 fh.fd.ci.server/src/test/java/de/fd/fh/server/ApiTestUtils.java diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index d275c81..1c87d4d 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -22,21 +22,39 @@ public class ServerApp private static AccessRepository accessRepository; private static UserRepository userRepository; + private static AccessController accessController; + private static UserController userController; + private static final Set listeners = new HashSet<>(); public static void main(String[] args) { - initRepositories(); - initListeners(); - new AccessController((AccessService) addListeners(new AccessService(accessRepository))); - new UserController((UserService) addListeners(new UserService(userRepository))); + if (accessController == null && userController == null) + { + initRepositories(); + accessController = new AccessController((AccessService) + addListeners(new AccessService(accessRepository))); + userController = new UserController((UserService) + addListeners(new UserService(userRepository))); + } + + before("/*", (req, res) -> accessController.before(req)); get("/hello", (req, res) -> "Hello World"); } + public static void initController( + final AccessController accessController, + final UserController userController + ) + { + ServerApp.userController = userController; + ServerApp.accessController = accessController; + } + private static Object addListeners(Observable service) { listeners.forEach(service::addObserver); @@ -50,7 +68,8 @@ public class ServerApp listeners.add(new UserContextEventListener(userRepository)); } - private static void initRepositories() { + private static void initRepositories() + { accessRepository = new AccessRepository(); userRepository = new UserRepository(); } diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index c74fa87..390730f 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -101,7 +101,6 @@ public class AccessController public AccessController(final AccessService service) { this.service = service; - Spark.before("/*", (req, res) -> before(req)); post("/accounts/registrate", this::registrate); diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java new file mode 100644 index 0000000..e5fdb7e --- /dev/null +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -0,0 +1,53 @@ +package de.fd.fh; + +import de.fd.fh.server.ApiTestUtils; +import de.fd.fh.server.access.web.AccessController; +import de.fd.fh.server.user.web.UserController; +import de.fd.fh.shared.Utils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static spark.Spark.awaitInitialization; +import static spark.Spark.stop; + +class ServerAppTest +{ + private static UserController userController = mock(UserController.class); + private static AccessController accessController = mock(AccessController.class); + + @BeforeAll + static void before() + { + ServerApp.initController(accessController, userController); + ServerApp.main(null); + + awaitInitialization(); + } + + @AfterAll + static void after() + { + stop(); + } + + @Test + void testHalloWorld() + { + String url = "/hello"; + Map headers = new HashMap<>(); + headers.put(Utils.AUTHENTICATION_HEADER, "Bearer testToken"); + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("GET", url, null, headers, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + assertEquals("Hello World", res.getBody()); + } +} \ No newline at end of file diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/server/ApiTestUtils.java b/fh.fd.ci.server/src/test/java/de/fd/fh/server/ApiTestUtils.java new file mode 100644 index 0000000..fd8ff3b --- /dev/null +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/server/ApiTestUtils.java @@ -0,0 +1,86 @@ +package de.fd.fh.server; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Getter; +import lombok.Setter; +import spark.utils.IOUtils; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.fail; + +public class ApiTestUtils +{ + public TestResponse request( + final String method, + final String path, + final String requestBody, + final Map header, + final Class responseBodyType) + { + try + { + URL url = new URL("http://localhost:4567" + path); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(method); + connection.setDoOutput(true); + + if (requestBody != null) + { + final OutputStream outputStream = connection.getOutputStream(); + final OutputStreamWriter outputStreamWriter = + new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); + outputStreamWriter.write(requestBody); + outputStreamWriter.flush(); + outputStreamWriter.close(); + } + + if (header != null) + { + header.forEach(connection::addRequestProperty); + } + + connection.connect(); + + final String body = IOUtils.toString(connection.getInputStream()); + return new TestResponse(connection.getResponseCode(), body, responseBodyType); + } + catch (final IOException e) + { + e.printStackTrace(); + fail("Sending request failed: " + e.getMessage()); + return null; + } + } + + @Getter + @Setter + public static class TestResponse + { + + private final String body; + private final int status; + private final Class type; + + public TestResponse( + final int status, + final String body, + final Class type) + { + this.status = status; + this.body = body; + this.type = type; + } + + public T json() throws IOException + { + return new ObjectMapper().readValue(body, type); + } + } +} From 52b23adea26dde49f6b8b9deec9359b0c9157004 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:48:35 +0100 Subject: [PATCH 14/20] extract registrate routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 1 + .../server/access/web/AccessController.java | 2 -- .../src/test/java/de/fd/fh/ServerAppTest.java | 19 +++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index 1c87d4d..04d9fb6 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -41,6 +41,7 @@ public class ServerApp } before("/*", (req, res) -> accessController.before(req)); + post("/accounts/registrate", accessController::registrate); get("/hello", (req, res) -> "Hello World"); diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index 390730f..de3f26f 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -102,8 +102,6 @@ public class AccessController { this.service = service; - post("/accounts/registrate", this::registrate); - post("/accounts/login", this::login); post("/accounts/logout",this::logout); diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java index e5fdb7e..82a1cc1 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -8,11 +8,15 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static spark.Spark.awaitInitialization; import static spark.Spark.stop; @@ -50,4 +54,19 @@ class ServerAppTest assertEquals(200, res.getStatus()); assertEquals("Hello World", res.getBody()); } + + @Test + void testRegistrate() throws IOException + { + when(accessController.registrate(any(), any())).thenReturn("Test"); + + String url = "/accounts/registrate"; + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("POST", url, null, null, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + then(accessController).should().registrate(any(), any()); + } } \ No newline at end of file From 2624e63baa4bbdecbeebd5bbd92f65516ef0af30 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:50:18 +0100 Subject: [PATCH 15/20] extract login routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 1 + .../fh/server/access/web/AccessController.java | 2 -- .../src/test/java/de/fd/fh/ServerAppTest.java | 16 ++++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index 04d9fb6..dbef579 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -42,6 +42,7 @@ public class ServerApp before("/*", (req, res) -> accessController.before(req)); post("/accounts/registrate", accessController::registrate); + post("/accounts/login", accessController::login); get("/hello", (req, res) -> "Hello World"); diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index de3f26f..ab504ac 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -102,8 +102,6 @@ public class AccessController { this.service = service; - post("/accounts/login", this::login); - post("/accounts/logout",this::logout); delete("/accounts/:player_id", this::deletePlayer); diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java index 82a1cc1..0efea84 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -1,5 +1,6 @@ package de.fd.fh; +import com.fasterxml.jackson.core.JsonProcessingException; import de.fd.fh.server.ApiTestUtils; import de.fd.fh.server.access.web.AccessController; import de.fd.fh.server.user.web.UserController; @@ -69,4 +70,19 @@ class ServerAppTest assertEquals(200, res.getStatus()); then(accessController).should().registrate(any(), any()); } + + @Test + void testLogin() throws JsonProcessingException + { + when(accessController.login(any(), any())).thenReturn("Test"); + + String url = "/accounts/login"; + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("POST", url, null, null, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + then(accessController).should().login(any(), any()); + } } \ No newline at end of file From dae84ef1f629055cf3aad5a2ccc6776600e3c74f Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:51:29 +0100 Subject: [PATCH 16/20] extract logout routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 1 + .../fd/fh/server/access/web/AccessController.java | 2 -- .../src/test/java/de/fd/fh/ServerAppTest.java | 15 +++++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index dbef579..954ff09 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -43,6 +43,7 @@ public class ServerApp before("/*", (req, res) -> accessController.before(req)); post("/accounts/registrate", accessController::registrate); post("/accounts/login", accessController::login); + post("/accounts/logout", accessController::logout); get("/hello", (req, res) -> "Hello World"); diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index ab504ac..ce9c09e 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -102,8 +102,6 @@ public class AccessController { this.service = service; - post("/accounts/logout",this::logout); - delete("/accounts/:player_id", this::deletePlayer); } } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java index 0efea84..8f5dc24 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -85,4 +85,19 @@ class ServerAppTest assertEquals(200, res.getStatus()); then(accessController).should().login(any(), any()); } + + @Test + void testLogout() + { + when(accessController.logout(any(), any())).thenReturn("Test"); + + String url = "/accounts/logout"; + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("POST", url, null, null, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + then(accessController).should().logout(any(), any()); + } } \ No newline at end of file From fd05c6125bdb6f1b965706381895921d20350f76 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:54:02 +0100 Subject: [PATCH 17/20] extract delete player routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 2 ++ .../fh/server/access/web/AccessController.java | 12 ++---------- .../src/test/java/de/fd/fh/ServerAppTest.java | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index 954ff09..8ff3fbb 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -44,6 +44,8 @@ public class ServerApp post("/accounts/registrate", accessController::registrate); post("/accounts/login", accessController::login); post("/accounts/logout", accessController::logout); + delete("/accounts/:player_id", accessController::deletePlayer); + get("/hello", (req, res) -> "Hello World"); diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java index ce9c09e..ab3706a 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java @@ -8,12 +8,11 @@ import de.fd.fh.server.user.UserId; import de.fd.fh.shared.Utils; import de.fd.fh.shared.network.messages.LoginRequest; import de.fd.fh.shared.network.messages.RegistrateRequest; +import lombok.RequiredArgsConstructor; import spark.Request; import spark.Response; -import spark.Spark; - -import static spark.Spark.*; +@RequiredArgsConstructor public class AccessController { private final ObjectMapper objectMapper = new ObjectMapper(); @@ -97,11 +96,4 @@ public class AccessController req.session().attribute("userId", accessToken); } - - public AccessController(final AccessService service) - { - this.service = service; - - delete("/accounts/:player_id", this::deletePlayer); - } } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java index 8f5dc24..a848d18 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -8,6 +8,7 @@ import de.fd.fh.shared.Utils; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import spark.Response; import java.io.IOException; import java.util.HashMap; @@ -100,4 +101,21 @@ class ServerAppTest assertEquals(200, res.getStatus()); then(accessController).should().logout(any(), any()); } + + @Test + void testDeletePlayer() + { + final Response response = mock(Response.class); + + when(accessController.deletePlayer(any(), any())).thenReturn(response); + + String url = "/accounts/12345"; + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("DELETE", url, null, null, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + then(accessController).should().deletePlayer(any(), any()); + } } \ No newline at end of file From 3e507d3fe1efea94bb1548c7be9daa23c7487f17 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:57:50 +0100 Subject: [PATCH 18/20] extract update user routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 1 + .../de/fd/fh/server/user/web/UserController.java | 2 -- .../src/test/java/de/fd/fh/ServerAppTest.java | 15 +++++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index 8ff3fbb..62dfd47 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -46,6 +46,7 @@ public class ServerApp post("/accounts/logout", accessController::logout); delete("/accounts/:player_id", accessController::deletePlayer); + post("/users", userController::updateUser); get("/hello", (req, res) -> "Hello World"); diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java index 4ddeb91..016475b 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java @@ -94,8 +94,6 @@ public class UserController this.service = service; post("/users", this::getCompleteUser); - get("/users", this::updateUser); - get("/users/:user_id", this::getUser); } } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java index a848d18..962bf54 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -118,4 +118,19 @@ class ServerAppTest assertEquals(200, res.getStatus()); then(accessController).should().deletePlayer(any(), any()); } + + @Test + void updateUser() throws IOException + { + when(userController.updateUser(any(), any())).thenReturn(mock(Response.class)); + + String url = "/users"; + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("POST", url, null, null, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + then(userController).should().updateUser(any(), any()); + } } \ No newline at end of file From d586c064fcf0ffe184586bc11c15bc2c2d1ec90d Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 03:59:12 +0100 Subject: [PATCH 19/20] extract getCompleteUser routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 1 + .../de/fd/fh/server/user/web/UserController.java | 1 - .../src/test/java/de/fd/fh/ServerAppTest.java | 15 +++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index 62dfd47..bb152ed 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -47,6 +47,7 @@ public class ServerApp delete("/accounts/:player_id", accessController::deletePlayer); post("/users", userController::updateUser); + get("/users", userController::getCompleteUser); get("/hello", (req, res) -> "Hello World"); diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java index 016475b..5fffc37 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java @@ -92,7 +92,6 @@ public class UserController public UserController(final UserService service) { this.service = service; - post("/users", this::getCompleteUser); get("/users/:user_id", this::getUser); } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java index 962bf54..b41b23d 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -133,4 +133,19 @@ class ServerAppTest assertEquals(200, res.getStatus()); then(userController).should().updateUser(any(), any()); } + + @Test + void getPlayers() throws JsonProcessingException + { + when(userController.getCompleteUser(any(), any())).thenReturn(mock(Response.class)); + + String url = "/users"; + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("GET", url, null, null, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + then(userController).should().getCompleteUser(any(), any()); + } } \ No newline at end of file From d6046257e53dbe9273d31349fb28bd6ab0fa7970 Mon Sep 17 00:00:00 2001 From: Steffen Nitschke Date: Sun, 31 Jan 2021 04:00:46 +0100 Subject: [PATCH 20/20] extract getUser routing to ServerApp --- .../src/main/java/de/fd/fh/ServerApp.java | 1 + .../de/fd/fh/server/user/web/UserController.java | 12 ++---------- .../src/test/java/de/fd/fh/ServerAppTest.java | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java index bb152ed..809da76 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java @@ -48,6 +48,7 @@ public class ServerApp post("/users", userController::updateUser); get("/users", userController::getCompleteUser); + get("/users/:user_id", userController::getUser); get("/hello", (req, res) -> "Hello World"); diff --git a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java index 5fffc37..a264e6b 100644 --- a/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java +++ b/fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java @@ -6,12 +6,11 @@ import de.fd.fh.server.access.AccessToken; import de.fd.fh.server.user.User; import de.fd.fh.server.user.UserId; import de.fd.fh.server.user.UserService; +import lombok.RequiredArgsConstructor; import spark.Request; import spark.Response; -import static spark.Spark.get; -import static spark.Spark.post; - +@RequiredArgsConstructor public class UserController { private ObjectMapper objectMapper = new ObjectMapper(); @@ -88,11 +87,4 @@ public class UserController return response; } - - public UserController(final UserService service) - { - this.service = service; - - get("/users/:user_id", this::getUser); - } } diff --git a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java index b41b23d..c864f6b 100644 --- a/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java +++ b/fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java @@ -148,4 +148,19 @@ class ServerAppTest assertEquals(200, res.getStatus()); then(userController).should().getCompleteUser(any(), any()); } + + @Test + void getPlayer() throws JsonProcessingException + { + when(userController.getUser(any(), any())).thenReturn(mock(Response.class)); + + String url = "/users/12345"; + + ApiTestUtils.TestResponse res = new ApiTestUtils() + .request("GET", url, null, null, String.class); + + assertNotNull(res); + assertEquals(200, res.getStatus()); + then(userController).should().getUser(any(), any()); + } } \ No newline at end of file