From c21f0ef463bcea27af436c407fe6af4291b9ba3d Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 2 Mar 2022 17:09:37 +0100 Subject: [PATCH] # WARNING: head commit changed in the meantime Merge remote-tracking branch 'origin/master' into dev-1.3 plus more unit tests plus CircuitBreaker fix --- pom.xml | 2 +- .../sebserver/gbl/async/CircuitBreaker.java | 18 ++-- .../servicelayer/dao/impl/ExamDAOImpl.java | 3 +- .../lms/impl/AbstractCourseAccess.java | 28 ++++-- .../mockup/MockLmsAPITemplateFactory.java | 14 ++- .../lms/impl/mockup/MockupLmsAPITemplate.java | 60 +++++++++++++ .../ClientHttpRequestFactoryServiceTest.java | 89 +++++++++++++++++++ .../gbl/async/CircuitBreakerTest.java | 2 +- .../async/MemoizingCircuitBreakerTest.java | 2 +- .../api/admin/WebserviceInfoTest.java | 69 ++++++++++++++ src/test/resources/data-test.sql | 2 +- 11 files changed, 269 insertions(+), 20 deletions(-) create mode 100644 src/test/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryServiceTest.java create mode 100644 src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/WebserviceInfoTest.java diff --git a/pom.xml b/pom.xml index 4e37aa0d..d7a50792 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ jar - 1.3-rc2 + 1.3-rc3 ${sebserver-version} ${sebserver-version} UTF-8 diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreaker.java b/src/main/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreaker.java index 3f13ea72..2493bb23 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreaker.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreaker.java @@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory; import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.gbl.util.Utils; /** A circuit breaker with three states (CLOSED, HALF_OPEN, OPEN) *

@@ -70,6 +71,7 @@ public final class CircuitBreaker { private State state = State.CLOSED; private final AtomicInteger failingCount = new AtomicInteger(0); private long lastSuccessTime; + private long lastOpenTime; /** Create new CircuitBreakerSupplier. * @@ -99,6 +101,8 @@ public final class CircuitBreaker { this.maxFailingAttempts = maxFailingAttempts; this.maxBlockingTime = maxBlockingTime; this.timeToRecover = timeToRecover; + // Initialize with creation time to get expected cool-down phase time if never was successful since + this.lastOpenTime = Utils.getMillisecondsNow(); } public int getMaxFailingAttempts() { @@ -122,7 +126,7 @@ public final class CircuitBreaker { } public synchronized Result protectedRun(final Supplier supplier) { - final long currentTime = System.currentTimeMillis(); + final long currentTime = Utils.getMillisecondsNow(); if (log.isDebugEnabled()) { log.debug("Called on: {} current state is: {} failing count: {}", @@ -163,7 +167,7 @@ public final class CircuitBreaker { log.debug("Attempt failed. failing count: {}", this.failingCount); } - final long currentBlockingTime = System.currentTimeMillis() - startTime; + final long currentBlockingTime = Utils.getMillisecondsNow() - startTime; final int failing = this.failingCount.incrementAndGet(); if (failing > this.maxFailingAttempts || currentBlockingTime > this.maxBlockingTime) { // brake thought to HALF_OPEN state and return error @@ -174,14 +178,14 @@ public final class CircuitBreaker { this.state = State.HALF_OPEN; this.failingCount.set(0); return Result.ofError(new RuntimeException( - "Set CircuitBeaker to half-open state. Cause: " + result.getError().getMessage(), + "Set CircuitBeaker to half-open state. Cause: " + result.getError(), result.getError())); } else { // try again return protectedRun(supplier); } } else { - this.lastSuccessTime = System.currentTimeMillis(); + this.lastSuccessTime = Utils.getMillisecondsNow(); return result; } } @@ -202,9 +206,10 @@ public final class CircuitBreaker { log.debug("Changing state from Half Open to Open and return cached value"); } + this.lastOpenTime = Utils.getMillisecondsNow(); this.state = State.OPEN; return Result.ofError(new RuntimeException( - "Set CircuitBeaker to open state. Cause: " + result.getError().getMessage(), + "Set CircuitBeaker to open state. Cause: " + result.getError(), result.getError())); } else { // on success go to CLOSED state @@ -228,7 +233,7 @@ public final class CircuitBreaker { log.debug("Handle Open on: {}", startTime); } - if (startTime - this.lastSuccessTime >= this.timeToRecover) { + if (startTime - this.lastOpenTime >= this.timeToRecover) { // if cool-down period is over, go back to HALF_OPEN state and try again if (log.isDebugEnabled()) { log.debug("Time to recover reached. Changing state from Open to Half Open"); @@ -247,6 +252,7 @@ public final class CircuitBreaker { return Result.of(future.get(this.maxBlockingTime, TimeUnit.MILLISECONDS)); } catch (final Exception e) { future.cancel(false); + log.warn("Max blocking timeout exceeded: {}, {}", this.maxBlockingTime, this.state); return Result.ofError(e); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java index f03910fb..f9f1d6bb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java @@ -818,7 +818,8 @@ public class ExamDAOImpl implements ExamDAO { log.debug("Using short-name: {} for recovering", shortname); - final QuizData recoveredQuizData = this.lmsAPIService.getLmsAPITemplate(lmsSetup.id) + final QuizData recoveredQuizData = this.lmsAPIService + .getLmsAPITemplate(lmsSetup.id) .map(template -> template.getQuizzes(new FilterMap()) .getOrThrow() .stream() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCourseAccess.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCourseAccess.java index c1bc7ffe..5a5f3a3c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCourseAccess.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCourseAccess.java @@ -80,7 +80,7 @@ public abstract class AbstractCourseAccess { environment.getProperty( "sebserver.webservice.circuitbreaker.quizzesRequest.blockingTime", Long.class, - Constants.MINUTE_IN_MILLIS), + Constants.SECOND_IN_MILLIS * 10), environment.getProperty( "sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover", Long.class, @@ -94,7 +94,7 @@ public abstract class AbstractCourseAccess { environment.getProperty( "sebserver.webservice.circuitbreaker.quizzesRequest.blockingTime", Long.class, - Constants.MINUTE_IN_MILLIS), + Constants.SECOND_IN_MILLIS * 10), environment.getProperty( "sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover", Long.class, @@ -112,7 +112,7 @@ public abstract class AbstractCourseAccess { environment.getProperty( "sebserver.webservice.circuitbreaker.chaptersRequest.timeToRecover", Long.class, - Constants.MINUTE_IN_MILLIS)); + Constants.SECOND_IN_MILLIS * 30)); this.accountDetailRequest = asyncService.createCircuitBreaker( environment.getProperty( @@ -126,19 +126,28 @@ public abstract class AbstractCourseAccess { environment.getProperty( "sebserver.webservice.circuitbreaker.accountDetailRequest.timeToRecover", Long.class, - Constants.SECOND_IN_MILLIS * 10)); + Constants.SECOND_IN_MILLIS * 30)); } public Result> protectedQuizzesRequest(final FilterMap filterMap) { - return this.allQuizzesRequest.protectedRun(allQuizzesSupplier(filterMap)); + return this.allQuizzesRequest.protectedRun(allQuizzesSupplier(filterMap)) + .onError(error -> log.error( + "Failed to run protectedQuizzesRequest: {}", + error.getMessage())); } public Result> protectedQuizzesRequest(final Set ids) { - return this.quizzesRequest.protectedRun(quizzesSupplier(ids)); + return this.quizzesRequest.protectedRun(quizzesSupplier(ids)) + .onError(error -> log.error( + "Failed to run protectedQuizzesRequest: {}", + error.getMessage())); } public Result protectedQuizRequest(final String id) { - return this.quizRequest.protectedRun(quizSupplier(id)); + return this.quizRequest.protectedRun(quizSupplier(id)) + .onError(error -> log.error( + "Failed to run protectedQuizRequest: {}", + error.getMessage())); } public Result getExamineeAccountDetails(final String examineeSessionId) { @@ -165,7 +174,10 @@ public abstract class AbstractCourseAccess { } public Result getCourseChapters(final String courseId) { - return this.chaptersRequest.protectedRun(getCourseChaptersSupplier(courseId)); + return this.chaptersRequest.protectedRun(getCourseChaptersSupplier(courseId)) + .onError(error -> log.error( + "Failed to run getCourseChapters: {}", + error.getMessage())); } protected abstract Supplier accountDetailsSupplier(final String examineeSessionId); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockLmsAPITemplateFactory.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockLmsAPITemplateFactory.java index 2cf628c5..032e7d6a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockLmsAPITemplateFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockLmsAPITemplateFactory.java @@ -9,8 +9,10 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.mockup; import org.springframework.context.annotation.Lazy; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; +import ch.ethz.seb.sebserver.gbl.async.AsyncService; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; @@ -24,9 +26,17 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory; @WebServiceProfile public class MockLmsAPITemplateFactory implements LmsAPITemplateFactory { + private final AsyncService asyncService; private final WebserviceInfo webserviceInfo; + private final Environment environment; - public MockLmsAPITemplateFactory(final WebserviceInfo webserviceInfo) { + public MockLmsAPITemplateFactory( + final AsyncService asyncService, + final Environment environment, + final WebserviceInfo webserviceInfo) { + + this.environment = environment; + this.asyncService = asyncService; this.webserviceInfo = webserviceInfo; } @@ -38,6 +48,8 @@ public class MockLmsAPITemplateFactory implements LmsAPITemplateFactory { @Override public Result create(final APITemplateDataSupplier apiTemplateDataSupplier) { return Result.tryCatch(() -> new MockupLmsAPITemplate( + this.asyncService, + this.environment, apiTemplateDataSupplier, this.webserviceInfo)); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java index fd039f43..cb369e82 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockupLmsAPITemplate.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -19,9 +20,11 @@ import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.APIMessage; +import ch.ethz.seb.sebserver.gbl.async.AsyncService; import ch.ethz.seb.sebserver.gbl.client.ClientCredentials; import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP; import ch.ethz.seb.sebserver.gbl.model.exam.Chapters; @@ -38,6 +41,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate; +import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCourseAccess; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.NoSEBRestrictionException; public class MockupLmsAPITemplate implements LmsAPITemplate { @@ -48,7 +52,11 @@ public class MockupLmsAPITemplate implements LmsAPITemplate { private final WebserviceInfo webserviceInfo; private final APITemplateDataSupplier apiTemplateDataSupplier; + private final AbstractCourseAccess abstractCourseAccess; + MockupLmsAPITemplate( + final AsyncService asyncService, + final Environment environment, final APITemplateDataSupplier apiTemplateDataSupplier, final WebserviceInfo webserviceInfo) { @@ -56,6 +64,37 @@ public class MockupLmsAPITemplate implements LmsAPITemplate { this.webserviceInfo = webserviceInfo; this.mockups = new ArrayList<>(); + this.abstractCourseAccess = new AbstractCourseAccess(asyncService, environment) { + + @Override + protected Supplier accountDetailsSupplier(final String examineeSessionId) { + return () -> MockupLmsAPITemplate.this + .getExamineeAccountDetails_protected(examineeSessionId) + .getOrThrow(); + } + + @Override + protected Supplier> allQuizzesSupplier(final FilterMap filterMap) { + return () -> MockupLmsAPITemplate.this.getQuizzes_protected(filterMap).getOrThrow(); + } + + @Override + protected Supplier> quizzesSupplier(final Set ids) { + return () -> MockupLmsAPITemplate.this.getQuizzes_protected(ids).getOrThrow(); + } + + @Override + protected Supplier quizSupplier(final String id) { + return () -> MockupLmsAPITemplate.this.getQuiz_protected(id).getOrThrow(); + } + + @Override + protected Supplier getCourseChaptersSupplier(final String courseId) { + return () -> MockupLmsAPITemplate.this.getCourseChapters_protected(courseId).getOrThrow(); + } + + }; + final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup(); final Long lmsSetupId = lmsSetup.id; final Long institutionId = lmsSetup.getInstitutionId(); @@ -149,6 +188,10 @@ public class MockupLmsAPITemplate implements LmsAPITemplate { @Override public Result> getQuizzes(final FilterMap filterMap) { + return this.abstractCourseAccess.protectedQuizzesRequest(filterMap); + } + + private Result> getQuizzes_protected(final FilterMap filterMap) { return Result.tryCatch(() -> { if (!authenticate()) { throw new IllegalArgumentException("Wrong clientId or secret"); @@ -164,6 +207,10 @@ public class MockupLmsAPITemplate implements LmsAPITemplate { @Override public Result getQuiz(final String id) { + return this.abstractCourseAccess.protectedQuizRequest(id); + } + + private Result getQuiz_protected(final String id) { return Result.of(this.mockups .stream() .filter(q -> id.equals(q.id)) @@ -173,6 +220,11 @@ public class MockupLmsAPITemplate implements LmsAPITemplate { @Override public Result> getQuizzes(final Set ids) { + return this.abstractCourseAccess.protectedQuizzesRequest(ids); + } + + private Result> getQuizzes_protected(final Set ids) { + return Result.tryCatch(() -> { if (!authenticate()) { throw new IllegalArgumentException("Wrong clientId or secret"); @@ -193,11 +245,19 @@ public class MockupLmsAPITemplate implements LmsAPITemplate { @Override public Result getCourseChapters(final String courseId) { + return this.abstractCourseAccess.getCourseChapters(courseId); + } + + private Result getCourseChapters_protected(final String courseId) { return Result.ofError(new UnsupportedOperationException()); } @Override public Result getExamineeAccountDetails(final String examineeSessionId) { + return this.abstractCourseAccess.getExamineeAccountDetails(examineeSessionId); + } + + private Result getExamineeAccountDetails_protected(final String examineeSessionId) { return Result.ofError(new UnsupportedOperationException()); } diff --git a/src/test/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryServiceTest.java b/src/test/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryServiceTest.java new file mode 100644 index 00000000..d6a7bab2 --- /dev/null +++ b/src/test/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryServiceTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022 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; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.core.env.Environment; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; + +import ch.ethz.seb.sebserver.gbl.client.ClientCredentialService; +import ch.ethz.seb.sebserver.gbl.client.ClientCredentials; +import ch.ethz.seb.sebserver.gbl.client.ProxyData; +import ch.ethz.seb.sebserver.gbl.util.Result; + +public class ClientHttpRequestFactoryServiceTest { + + @Mock + Environment environment; + @Mock + ClientCredentialService clientCredentialService; + + @Before + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testGetClientHttpRequestFactory() { + + final ClientHttpRequestFactoryService clientHttpRequestFactoryService = new ClientHttpRequestFactoryService( + this.environment, + this.clientCredentialService, + 1, 1, 1); + + final ProxyData proxyData = new ProxyData("testPoxy", 8000, new ClientCredentials("test", "test")); + + Mockito.when(this.environment.getActiveProfiles()).thenReturn(new String[] { "dev-gui", "test" }); + Mockito.when(this.clientCredentialService.getPlainClientSecret(Mockito.any())).thenReturn(Result.of("test")); + + Result clientHttpRequestFactory = clientHttpRequestFactoryService + .getClientHttpRequestFactory(); + + assertNotNull(clientHttpRequestFactory); + assertFalse(clientHttpRequestFactory.hasError()); + ClientHttpRequestFactory instance = clientHttpRequestFactory.get(); + assertTrue(instance instanceof HttpComponentsClientHttpRequestFactory); + + clientHttpRequestFactory = clientHttpRequestFactoryService + .getClientHttpRequestFactory(proxyData); + + assertNotNull(clientHttpRequestFactory); + assertFalse(clientHttpRequestFactory.hasError()); + instance = clientHttpRequestFactory.get(); + assertTrue(instance instanceof HttpComponentsClientHttpRequestFactory); + + Mockito.when(this.environment.getActiveProfiles()).thenReturn(new String[] { "prod-gui", "prod-ws" }); + + clientHttpRequestFactory = clientHttpRequestFactoryService + .getClientHttpRequestFactory(); + + assertNotNull(clientHttpRequestFactory); + assertFalse(clientHttpRequestFactory.hasError()); + instance = clientHttpRequestFactory.get(); + assertTrue(instance instanceof HttpComponentsClientHttpRequestFactory); + + clientHttpRequestFactory = clientHttpRequestFactoryService + .getClientHttpRequestFactory(proxyData); + + assertNotNull(clientHttpRequestFactory); + assertFalse(clientHttpRequestFactory.hasError()); + instance = clientHttpRequestFactory.get(); + assertTrue(instance instanceof HttpComponentsClientHttpRequestFactory); + } + +} diff --git a/src/test/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreakerTest.java b/src/test/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreakerTest.java index f3a00e40..ee69e441 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreakerTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/gbl/async/CircuitBreakerTest.java @@ -76,7 +76,7 @@ public class CircuitBreakerTest { assertEquals(CircuitBreaker.OPEN_STATE_EXCEPTION, result.getError()); // wait time to recover - Thread.sleep(500); + Thread.sleep(1000); result = circuitBreaker.protectedRun(tester); // 11. call... assertEquals(State.CLOSED, circuitBreaker.getState()); assertEquals("Hello back again", result.get()); diff --git a/src/test/java/ch/ethz/seb/sebserver/gbl/async/MemoizingCircuitBreakerTest.java b/src/test/java/ch/ethz/seb/sebserver/gbl/async/MemoizingCircuitBreakerTest.java index ab239a23..6b96f907 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gbl/async/MemoizingCircuitBreakerTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/gbl/async/MemoizingCircuitBreakerTest.java @@ -77,7 +77,7 @@ public class MemoizingCircuitBreakerTest { assertEquals(State.OPEN, circuitBreaker.getState()); // wait time to recover - Thread.sleep(500); + Thread.sleep(1000); result = circuitBreaker.get(); // 11. call... assertEquals(State.CLOSED, circuitBreaker.getState()); assertEquals("Hello back again", result.get()); diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/WebserviceInfoTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/WebserviceInfoTest.java new file mode 100644 index 00000000..72974be5 --- /dev/null +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/WebserviceInfoTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022 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.webservice.integration.api.admin; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Collection; + +import org.junit.Test; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.jdbc.Sql; + +import com.fasterxml.jackson.core.type.TypeReference; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.model.EntityName; + +@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql" }) +public class WebserviceInfoTest extends AdministrationAPIIntegrationTester { + + @Test + public void testGetLogo() throws Exception { + String result = new RestAPITestHelper() + .withAccessToken(getAdminInstitution1Access()) + .withPath(API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT) + .withPath("/inst1") + .withMethod(HttpMethod.GET) + .withExpectedStatus(HttpStatus.OK) + .getAsString(); + + assertEquals("", result); + + result = new RestAPITestHelper() + .withAccessToken(getAdminInstitution1Access()) + .withPath(API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT) + .withPath("/inst2") + .withMethod(HttpMethod.GET) + .withExpectedStatus(HttpStatus.OK) + .getAsString(); + + assertEquals("AAA", result); + } + + @Test + public void test_getInstitutionInfo() throws Exception { + + final Collection result = new RestAPITestHelper() + .withAccessToken(getAdminInstitution1Access()) + .withPath(API.INFO_ENDPOINT + API.INFO_INST_PATH_SEGMENT) + .withMethod(HttpMethod.GET) + .withExpectedStatus(HttpStatus.OK) + .getAsObject(new TypeReference>() { + }); + + assertNotNull(result); + assertTrue(result.stream().filter(en -> "Institution1".equals(en.name)).findFirst().isPresent()); + assertTrue(result.stream().filter(en -> "Institution2".equals(en.name)).findFirst().isPresent()); + assertFalse(result.stream().filter(en -> "Institution3".equals(en.name)).findFirst().isPresent()); + + } + +} diff --git a/src/test/resources/data-test.sql b/src/test/resources/data-test.sql index 93a9b3aa..27e07aed 100644 --- a/src/test/resources/data-test.sql +++ b/src/test/resources/data-test.sql @@ -1,6 +1,6 @@ INSERT INTO institution VALUES (1, 'Institution1', 'inst1', null, null, 1), - (2, 'Institution2', 'inst2', null, null, 1), + (2, 'Institution2', 'inst2', 'AAA', null, 1), (3, 'Institution3', 'inst3', null, null, 0) ;