Browse Source

Merge remote-tracking branch 'origin/chore-betterServerTestCoverage' into pr-betterServerTestCoverage

pr-betterServerTestCoverage
Steffen Nitschke 3 years ago
parent
commit
ce74e6b486
  1. 14
      Jenkinsfile
  2. 37
      fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java
  3. 5
      fh.fd.ci.server/src/main/java/de/fd/fh/server/access/Access.java
  4. 33
      fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessContextEventListener.java
  5. 7
      fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessService.java
  6. 169
      fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java
  7. 1
      fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserId.java
  8. 19
      fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserService.java
  9. 14
      fh.fd.ci.server/src/main/java/de/fd/fh/server/user/events/ChangeUserNameEvent.java
  10. 10
      fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/ChangeUserRequest.java
  11. 149
      fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java
  12. 166
      fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java
  13. 86
      fh.fd.ci.server/src/test/java/de/fd/fh/server/ApiTestUtils.java
  14. 27
      fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessContextEventListenerTest.java
  15. 45
      fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessServiceTest.java
  16. 48
      fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTest.java
  17. 18
      fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTokenTest.java
  18. 225
      fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java
  19. 38
      fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserServiceTest.java
  20. 28
      fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserTest.java
  21. 174
      fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java
  22. 2
      fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/RegistrateRequest.java

14
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"

37
fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java

@ -22,21 +22,47 @@ public class ServerApp
private static AccessRepository accessRepository;
private static UserRepository userRepository;
private static AccessController accessController;
private static UserController userController;
private static final Set<Observer> 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));
post("/accounts/registrate", accessController::registrate);
post("/accounts/login", accessController::login);
post("/accounts/logout", accessController::logout);
delete("/accounts/:player_id", accessController::deletePlayer);
post("/users", userController::updateUser);
get("/users", userController::getCompleteUser);
get("/users/:user_id", userController::getUser);
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 +76,8 @@ public class ServerApp
listeners.add(new UserContextEventListener(userRepository));
}
private static void initRepositories() {
private static void initRepositories()
{
accessRepository = new AccessRepository();
userRepository = new UserRepository();
}

5
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;
}
}

33
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);
}
}
}

7
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;

169
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;
@ -7,98 +8,92 @@ 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 static spark.Spark.*;
@RequiredArgsConstructor
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)
public Object logout(Request request, Response response)
{
before("/*",
(req, res) ->
{
final String path = req.pathInfo();
final String token = req.headers(Utils.AUTHENTICATION_HEADER);
final AccessToken accessToken = service.before(path, token);
req.session().attribute("userId",
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/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/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);
}
return response;
});
final String token = request.headers(Utils.AUTHENTICATION_HEADER);
if (service.logout(token))
{
response.status(200);
}
else
{
response.status(400);
}
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 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 void before(final Request req)
{
final String path = req.pathInfo();
final String token = req.headers(Utils.AUTHENTICATION_HEADER);
final AccessToken accessToken = service.before(path, token);
req.session().attribute("userId",
accessToken);
}
}

1
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

19
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());
}
}
}

14
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;
}

10
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;
}

149
fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java

@ -1,89 +1,90 @@
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 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();
public UserController(final UserService service)
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 Response getCompleteUser(Request request, Response response) throws JsonProcessingException
{
post("/users",
((request, response) ->
{
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");
return objectMapper.writeValueAsString(user);
}
return response;
}
));
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/: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;
});
final UserId userId =
((AccessToken) request.session()
.attribute("userId"))
.getUserId();
final User user = service.getPlayer(userId);
if (user == null)
{
response.status(404);
}
else
{
response.status(200);
response.type("application/json");
response.body(objectMapper.writeValueAsString(user));
return response;
}
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;
}
}

166
fh.fd.ci.server/src/test/java/de/fd/fh/ServerAppTest.java

@ -0,0 +1,166 @@
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;
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;
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;
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<String, String> headers = new HashMap<>();
headers.put(Utils.AUTHENTICATION_HEADER, "Bearer testToken");
ApiTestUtils.TestResponse<String> res = new ApiTestUtils<String>()
.request("GET", url, null, headers, String.class);
assertNotNull(res);
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<String> res = new ApiTestUtils<String>()
.request("POST", url, null, null, String.class);
assertNotNull(res);
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<String> res = new ApiTestUtils<String>()
.request("POST", url, null, null, String.class);
assertNotNull(res);
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<String> res = new ApiTestUtils<String>()
.request("POST", url, null, null, String.class);
assertNotNull(res);
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<String> res = new ApiTestUtils<String>()
.request("DELETE", url, null, null, String.class);
assertNotNull(res);
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<String> res = new ApiTestUtils<String>()
.request("POST", url, null, null, String.class);
assertNotNull(res);
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<String> res = new ApiTestUtils<String>()
.request("GET", url, null, null, String.class);
assertNotNull(res);
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<String> res = new ApiTestUtils<String>()
.request("GET", url, null, null, String.class);
assertNotNull(res);
assertEquals(200, res.getStatus());
then(userController).should().getUser(any(), any());
}
}

86
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<T>
{
public TestResponse<T> request(
final String method,
final String path,
final String requestBody,
final Map<String, String> header,
final Class<T> 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<T>(connection.getResponseCode(), body, responseBodyType);
}
catch (final IOException e)
{
e.printStackTrace();
fail("Sending request failed: " + e.getMessage());
return null;
}
}
@Getter
@Setter
public static class TestResponse<T>
{
private final String body;
private final int status;
private final Class<T> type;
public TestResponse(
final int status,
final String body,
final Class<T> type)
{
this.status = status;
this.body = body;
this.type = type;
}
public T json() throws IOException
{
return new ObjectMapper().readValue(body, type);
}
}
}

27
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<Access> 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<Access> 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();
}
}

45
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()
{

48
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.");
}
}

18
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());
}
}

225
fh.fd.ci.server/src/test/java/de/fd/fh/server/access/web/AccessControllerTest.java

@ -0,0 +1,225 @@
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;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import spark.Request;
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;
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<Integer> 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<Integer> 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.");
}
@Test
void testLogout()
{
when(request.headers(any())).thenReturn("testHeader");
when(service.logout(any())).thenReturn(true);
final ArgumentCaptor<Integer> 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<Integer> 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.");
}
@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<Integer> statusCaptor = ArgumentCaptor.forClass(Integer.class);
final ArgumentCaptor<String> typeCaptor = ArgumentCaptor.forClass(String.class);
final ArgumentCaptor<String> 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<Integer> 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.");
}
@Test
void registrateTest() throws IOException
{
when(request.body()).thenReturn("{\"userName\":\"TestName\",\"password\":\"TestPassword\"}");
when(service.createPlayer(any())).thenReturn(true);
final ArgumentCaptor<Integer> 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<Integer> 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.");
}
@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<AccessToken> 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();
}
}

38
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<User> 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");

28
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.");
}
}

174
fh.fd.ci.server/src/test/java/de/fd/fh/server/user/web/UserControllerTest.java

@ -0,0 +1,174 @@
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;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
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;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class UserControllerTest
{
@Mock
Request request;
@Mock
Response response;
@Mock
Session session;
@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<String> 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<Integer> 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();
}
@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<Integer> statusCapture = ArgumentCaptor.forClass(Integer.class);
final ArgumentCaptor<String> bodyCapture = ArgumentCaptor.forClass(String.class);
final ArgumentCaptor<String> 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<Integer> 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();
}
@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<Integer> statusCapture = ArgumentCaptor.forClass(Integer.class);
final ArgumentCaptor<String> bodyCapture = ArgumentCaptor.forClass(String.class);
final ArgumentCaptor<String> 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<Integer> 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();
}
}

2
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;

Loading…
Cancel
Save