diff --git a/fh.fd.ci.client/build.gradle b/fh.fd.ci.client/build.gradle index 2e0dd87..2593e5e 100644 --- a/fh.fd.ci.client/build.gradle +++ b/fh.fd.ci.client/build.gradle @@ -7,6 +7,12 @@ mainClassName = 'de.fd.fh.ClientApp' dependencies { implementation project(':fh.fd.ci.shared') + + implementation 'io.github.openfeign:feign-okhttp:11.0' + implementation 'io.github.openfeign:feign-gson:11.0' + implementation 'io.github.openfeign:feign-slf4j:11.0' + + testImplementation 'io.github.openfeign:feign-mock:11.0' } javafx { diff --git a/fh.fd.ci.client/src/main/java/de/fd/fh/network/AccessClient.java b/fh.fd.ci.client/src/main/java/de/fd/fh/network/AccessClient.java new file mode 100644 index 0000000..fd69866 --- /dev/null +++ b/fh.fd.ci.client/src/main/java/de/fd/fh/network/AccessClient.java @@ -0,0 +1,26 @@ +package de.fd.fh.network; + +import de.fd.fh.shared.Utils; +import de.fd.fh.shared.network.messages.LoginResponse; +import de.fd.fh.shared.network.messages.RegistrateRequest; +import feign.Headers; +import feign.Param; +import feign.RequestLine; +import feign.Response; + +public interface AccessClient +{ + @RequestLine("POST /accounts/registrate") + Response registrate(RegistrateRequest request); + + @RequestLine("POST /accounts/login") + @Headers(Utils.AUTHENTICATION_HEADER + ":Basic {authToken}") + LoginResponse login(@Param("authToken") final String authenticationHeader); + + @RequestLine("POST /accounts/logout") + @Headers(Utils.AUTHENTICATION_HEADER + ":Bearer {authToken}") + Response logout(@Param("authToken") final String authenticationHeader); + + @RequestLine("DELETE /accounts/{playerId}") + Response deletePlayer(@Param("playerId") final String playerId); +} diff --git a/fh.fd.ci.client/src/main/java/de/fd/fh/network/FeignClients.java b/fh.fd.ci.client/src/main/java/de/fd/fh/network/FeignClients.java new file mode 100644 index 0000000..16ce86d --- /dev/null +++ b/fh.fd.ci.client/src/main/java/de/fd/fh/network/FeignClients.java @@ -0,0 +1,29 @@ +package de.fd.fh.network; + +import feign.Feign; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.okhttp.OkHttpClient; +import lombok.Getter; + +@Getter +public class FeignClients +{ + private static final String BASE_URL = "http://localhost:4567"; + + private AccessClient accessClient; + + public FeignClients() + { + accessClient = buildClient(AccessClient.class); + } + + T buildClient(final Class client) + { + return Feign.builder() + .client(new OkHttpClient()) + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .target(client, BASE_URL); + } +} diff --git a/fh.fd.ci.client/src/test/java/de/fd/fh/network/AccessClientTest.java b/fh.fd.ci.client/src/test/java/de/fd/fh/network/AccessClientTest.java new file mode 100644 index 0000000..c22bb79 --- /dev/null +++ b/fh.fd.ci.client/src/test/java/de/fd/fh/network/AccessClientTest.java @@ -0,0 +1,96 @@ +package de.fd.fh.network; + +import de.fd.fh.shared.Utils; +import de.fd.fh.shared.network.messages.LoginResponse; +import de.fd.fh.shared.network.messages.RegistrateRequest; +import feign.Feign; +import feign.Request; +import feign.Response; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.mock.HttpMethod; +import feign.mock.MockClient; +import feign.mock.MockTarget; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class AccessClientTest +{ + private AccessClient client; + private MockClient mockClient; + + @BeforeEach + void before() + { + mockClient = new MockClient(); + + client = Feign.builder() + .decoder(new GsonDecoder()) + .encoder(new GsonEncoder()) + .client(mockClient) + .target(new MockTarget<>(AccessClient.class)); + } + + @Test + void testRegistrate() + { + mockClient.ok(HttpMethod.POST, "/accounts/registrate"); + + final RegistrateRequest request = RegistrateRequest.of("TestName", "TestPassword"); + + final Response result = client.registrate(request); + + assertEquals(200, result.status(), "Should return status code 200."); + + mockClient.verifyStatus(); + } + + @Test + void testLogin() + { + mockClient + .ok(HttpMethod.POST, "/accounts/login", + "{\n" + + " \"name\":\"testName\",\n" + + " \"userId\": \"12345\",\n" + + " \"token\": \"testToken\"\n" + + "}" + ); + final LoginResponse result = client.login("testToken"); + + final Request request = mockClient.verifyOne(HttpMethod.POST, "/accounts/login"); + + assertNotNull(result); + assertEquals("testName", result.getName()); + assertEquals("12345", result.getUserId()); + assertEquals("testToken", result.getToken()); + + assertTrue(request.headers().get(Utils.AUTHENTICATION_HEADER).stream().findFirst().isPresent(), + "Should have auth header"); + final String authHeader = request.headers().get(Utils.AUTHENTICATION_HEADER).stream().findFirst().get(); + + assertEquals("Basic testToken", authHeader, "Should use given token."); + } + + @Test + void testLogout() + { + mockClient.ok(HttpMethod.POST, "/accounts/logout"); + + final Response result = client.logout("testToken"); + + assertEquals(200, result.status(), "Should return status code 200."); + } + + @Test + void testDeletePlayer() + { + mockClient.ok(HttpMethod.DELETE, "/accounts/12345"); + + final Response result = client.deletePlayer("12345"); + + assertEquals(200, result.status(), "Should return status code 200."); + } +} \ No newline at end of file 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 d0cf03e..1191d56 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 @@ -3,7 +3,7 @@ package de.fd.fh.server.access; import de.fd.fh.server.access.events.AccountCreatedEvent; import de.fd.fh.server.access.events.AccountDeletedEvent; import de.fd.fh.server.user.UserId; -import de.fd.fh.shared.network.messages.LoginRequest; +import de.fd.fh.shared.network.messages.LoginResponse; import de.fd.fh.shared.network.messages.RegistrateRequest; import lombok.RequiredArgsConstructor; import org.bson.types.ObjectId; @@ -94,7 +94,7 @@ public class AccessService extends Observable } } - public LoginRequest authorization(final String header) + public LoginResponse authorization(final String header) { System.out.println("authorization"); final String auth = header.substring("Basic ".length()); @@ -114,12 +114,12 @@ public class AccessService extends Observable access.setToken(AccessToken.of(access)); accessRepository.save(access); - final LoginRequest loginRequest = new LoginRequest(); - loginRequest.setUserId(access.getUserId().getIdentifier()); - loginRequest.setToken(access.getToken().getToken()); - loginRequest.setName(access.getName()); + final LoginResponse loginResponse = new LoginResponse(); + loginResponse.setUserId(access.getUserId().getIdentifier()); + loginResponse.setToken(access.getToken().getToken()); + loginResponse.setName(access.getName()); - return loginRequest; + return loginResponse; } return null; 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 ab3706a..59c32f4 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 @@ -6,7 +6,7 @@ import de.fd.fh.server.access.AccessService; import de.fd.fh.server.access.AccessToken; 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.LoginResponse; import de.fd.fh.shared.network.messages.RegistrateRequest; import lombok.RequiredArgsConstructor; import spark.Request; @@ -55,7 +55,7 @@ public class AccessController { final String header = request.headers(Utils.AUTHENTICATION_HEADER); - final LoginRequest login = service.authorization(header); + final LoginResponse login = service.authorization(header); if (login == null) { 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 f3fa3df..680e170 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 @@ -2,7 +2,7 @@ package de.fd.fh.server.access; import com.mongodb.WriteResult; import de.fd.fh.server.user.UserId; -import de.fd.fh.shared.network.messages.LoginRequest; +import de.fd.fh.shared.network.messages.LoginResponse; import de.fd.fh.shared.network.messages.RegistrateRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -221,7 +221,7 @@ class AccessServiceTest implements Observer when(repository.findByUserName(any())) .thenReturn(access); - final LoginRequest result = new AccessService(repository).authorization(header); + final LoginResponse result = new AccessService(repository).authorization(header); assertNotNull(result); assertEquals(result.getName(), "testName", "Wrong UserName"); @@ -236,7 +236,7 @@ class AccessServiceTest implements Observer final String header = "Basic " + new String(message); final AccessRepository repository = mock(AccessRepository.class); - final LoginRequest result = new AccessService(repository).authorization(header); + final LoginResponse result = new AccessService(repository).authorization(header); assertNull(result, "Return LoginRequest but wrong permissions"); } diff --git a/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/LoginRequest.java b/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/LoginResponse.java similarity index 84% rename from fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/LoginRequest.java rename to fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/LoginResponse.java index 4e1c38c..734cb52 100644 --- a/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/LoginRequest.java +++ b/fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/LoginResponse.java @@ -3,7 +3,7 @@ package de.fd.fh.shared.network.messages; import lombok.Data; @Data -public class LoginRequest +public class LoginResponse { private String name; private String userId;