From 985e1ae38690f3c93f2bbe700d5853d76279fbe9 Mon Sep 17 00:00:00 2001 From: anhefti Date: Fri, 31 May 2019 14:16:41 +0200 Subject: [PATCH] added more tests --- .../seb/sebserver/gbl/api/POSTMapper.java | 17 ++- .../remote/webservice/api/RestCall.java | 13 ++ .../gui/integration/GuiIntegrationTest.java | 15 ++ .../api/institution/GetInstitutionTest.java | 47 ++++++ .../seb/clientconfig/ClientConfigTest.java | 144 ++++++++++++++++++ 5 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/institution/GetInstitutionTest.java create mode 100644 src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ClientConfigTest.java diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/POSTMapper.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/POSTMapper.java index ba18da6c..a47896e0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/POSTMapper.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/POSTMapper.java @@ -8,6 +8,8 @@ package ch.ethz.seb.sebserver.gbl.api; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.nio.CharBuffer; import java.util.Arrays; import java.util.Collections; @@ -20,6 +22,8 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -30,6 +34,8 @@ import ch.ethz.seb.sebserver.gbl.util.Utils; public class POSTMapper { + private static final Logger log = LoggerFactory.getLogger(POSTMapper.class); + public static final POSTMapper EMPTY_MAP = new POSTMapper(null); protected final MultiValueMap params; @@ -42,7 +48,16 @@ public class POSTMapper { } public String getString(final String name) { - return this.params.getFirst(name); + final String first = this.params.getFirst(name); + if (StringUtils.isNoneBlank(first)) { + try { + return URLDecoder.decode(first, "UTF-8"); + } catch (final UnsupportedEncodingException e) { + log.warn("Failed to decode form URL formatted string value: ", e); + return first; + } + } + return first; } public char[] getCharArray(final String name) { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java index a354d4fd..c14354b2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.function.Function; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; @@ -32,6 +33,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; +import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.JSONMapper; @@ -238,6 +240,17 @@ public abstract class RestCall { return this; } + public RestCallBuilder withFormParam(final String name, final String value) { + if (StringUtils.isBlank(this.body)) { + this.body = name + Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR + value; + } else { + this.body = this.body + Constants.FORM_URL_ENCODED_SEPARATOR + name + + Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR + value; + } + + return this; + } + public RestCallBuilder withPaging(final int pageNumber, final int pageSize) { this.queryParams.put(Page.ATTR_PAGE_NUMBER, Arrays.asList(String.valueOf(pageNumber))); this.queryParams.put(Page.ATTR_PAGE_SIZE, Arrays.asList(String.valueOf(pageSize))); diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/integration/GuiIntegrationTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/integration/GuiIntegrationTest.java index bf3482d0..a7152219 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gui/integration/GuiIntegrationTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/gui/integration/GuiIntegrationTest.java @@ -32,6 +32,8 @@ import org.springframework.web.context.WebApplicationContext; import ch.ethz.seb.sebserver.SEBServer; import ch.ethz.seb.sebserver.gbl.api.JSONMapper; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestServiceImpl; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.OAuth2AuthorizationContextHolder; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService; @@ -118,4 +120,17 @@ public abstract class GuiIntegrationTest { return authorizationContextHolder; } + protected RestServiceImpl createRestServiceForUser( + final String username, + final String password, + final RestCall... calls) { + + final OAuth2AuthorizationContextHolder authorizationContextHolder = login(username, password); + final RestServiceImpl restService = new RestServiceImpl( + authorizationContextHolder, + new JSONMapper(), + java.util.Arrays.asList(calls)); + return restService; + } + } diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/institution/GetInstitutionTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/institution/GetInstitutionTest.java new file mode 100644 index 00000000..c02d4e74 --- /dev/null +++ b/src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/institution/GetInstitutionTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Test; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.api.JSONMapper; +import ch.ethz.seb.sebserver.gbl.model.institution.Institution; +import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.gui.integration.GuiIntegrationTest; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestServiceImpl; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.OAuth2AuthorizationContextHolder; + +public class GetInstitutionTest extends GuiIntegrationTest { + + @Test + public void testRestServiceInit() { + final OAuth2AuthorizationContextHolder authorizationContextHolder = login("admin", "admin"); + final Collection> calls = new ArrayList<>(); + calls.add(new GetInstitution()); + + final RestServiceImpl restService = new RestServiceImpl(authorizationContextHolder, new JSONMapper(), calls); + + final Result call = restService.getBuilder(GetInstitution.class) + .withURIVariable(API.PARAM_MODEL_ID, "2") + .call(); + + assertNotNull(call); + assertFalse(call.hasError()); + final Institution institution = call.get(); + assertEquals("Institution2", institution.name); + } + +} diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ClientConfigTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ClientConfigTest.java new file mode 100644 index 00000000..c177e1bb --- /dev/null +++ b/src/test/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ClientConfigTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springframework.test.context.jdbc.Sql; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.model.Domain; +import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig; +import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.gui.integration.GuiIntegrationTest; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestServiceImpl; + +@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql" }) +public class ClientConfigTest extends GuiIntegrationTest { + + @Test + public void testNewClientConfigWithQueryParam() { + final RestServiceImpl restService = createRestServiceForUser("admin", "admin", new NewClientConfig()); + + final Result call = restService.getBuilder(NewClientConfig.class) + .withQueryParam(Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME, "new client config") + .call(); + + assertNotNull(call); + assertFalse(call.hasError()); + final SebClientConfig createdConfig = call.get(); + assertEquals(Long.valueOf(1), createdConfig.id); + assertEquals("new client config", createdConfig.name); + assertFalse(createdConfig.active); + } + + @Test + public void testNewClientConfigWithURLEncodedForm() { + final RestServiceImpl restService = createRestServiceForUser("admin", "admin", new NewClientConfig()); + + final Result call = restService.getBuilder(NewClientConfig.class) + .withFormParam(Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME, "new client config") + .call(); + + assertNotNull(call); + assertFalse(call.hasError()); + final SebClientConfig createdConfig = call.get(); + assertEquals(Long.valueOf(1), createdConfig.id); + assertEquals("new client config", createdConfig.name); + assertFalse(createdConfig.active); + } + + @Test + public void testCreate_Get_Activate_Save_Deactivate_ClientConfig() { + final RestServiceImpl restService = createRestServiceForUser("admin", "admin", + new NewClientConfig(), + new GetClientConfig(), + new ActivateClientConfig(), + new SaveClientConfig(), + new DeactivateClientConfig()); + + // create one + final SebClientConfig config = restService.getBuilder(NewClientConfig.class) + .withQueryParam(Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME, "new client config") + .call() + .getOrThrow(); + + // get + final Result call = restService.getBuilder(GetClientConfig.class) + .withURIVariable(API.PARAM_MODEL_ID, config.getModelId()) + .call(); + + assertNotNull(call); + assertFalse(call.hasError()); + final SebClientConfig createdConfig = call.get(); + assertEquals(config.id, createdConfig.id); + assertEquals("new client config", createdConfig.name); + assertFalse(createdConfig.active); + + // activate + final EntityProcessingReport activationReport = restService.getBuilder(ActivateClientConfig.class) + .withURIVariable(API.PARAM_MODEL_ID, config.getModelId()) + .call() + .getOrThrow(); + + assertTrue(activationReport.errors.isEmpty()); + assertEquals( + "EntityKey [modelId=1, entityType=SEB_CLIENT_CONFIGURATION]", + activationReport.getSingleSource().toString()); + + // save with password (no confirm) expecting validation error + final Result valError = restService.getBuilder(SaveClientConfig.class) + .withBody(new SebClientConfig( + config.id, + config.institutionId, + "new client config", + null, + "password", + null, + null)) + .call(); + + assertTrue(valError.hasError()); + final Throwable error = valError.getError(); + assertTrue(error.getMessage().contains("confirm_encrypt_secret")); + assertTrue(error.getMessage().contains("password.mismatch")); + + // save with new password + final SebClientConfig newConfig = restService.getBuilder(SaveClientConfig.class) + .withBody(new SebClientConfig( + config.id, + config.institutionId, + "new client config", + null, + "password", + "password", + null)) + .call() + .getOrThrow(); + + assertEquals(config.id, newConfig.id); + assertEquals("new client config", newConfig.name); + assertTrue(newConfig.active); + assertNull(newConfig.getEncryptSecret()); + + // deactivate + final EntityProcessingReport deactivationReport = restService.getBuilder(DeactivateClientConfig.class) + .withURIVariable(API.PARAM_MODEL_ID, config.getModelId()) + .call() + .getOrThrow(); + + assertTrue(deactivationReport.errors.isEmpty()); + assertEquals( + "EntityKey [modelId=1, entityType=SEB_CLIENT_CONFIGURATION]", + deactivationReport.getSingleSource().toString()); + } + +}