> entries = underlyingJson.entrySet();
+ assertThat(entries)
+ .hasSize(1);
+
+ String valueString = Iterators
+ .getOnlyElement(entries.iterator())
+ .getValue()
+ .getAsString();
+ assertThat(valueString)
+ .isEqualTo(childValue.value());
}
private static void
@@ -87,6 +91,7 @@ private static void assertSingleChild(NodeValue value, StoredJson childValue) {
assertTrue(underlyingJson.has(childKey));
String actual = underlyingJson.get(childKey)
.getAsString();
- assertEquals(childValue.value(), actual);
+ assertThat(actual)
+ .isEqualTo(childValue.value());
}
}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/given/FirebaseResultTestEnv.java b/firebase-web/src/test/java/io/spine/web/firebase/given/FirebaseResultTestEnv.java
deleted file mode 100644
index a88f3cc6c..000000000
--- a/firebase-web/src/test/java/io/spine/web/firebase/given/FirebaseResultTestEnv.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2020, TeamDev. All rights reserved.
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.web.firebase.given;
-
-import io.spine.core.Response;
-
-import javax.servlet.ServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import static io.spine.core.Responses.statusOk;
-import static org.mockito.Mockito.when;
-
-public final class FirebaseResultTestEnv {
-
- /**
- * Prevents instantiation of this test environment.
- */
- private FirebaseResultTestEnv() {
- }
-
- public static StringWriter mockWriter(ServletResponse response) throws IOException {
- StringWriter stringWriter = new StringWriter();
- PrintWriter writer = new PrintWriter(stringWriter);
- when(response.getWriter()).thenReturn(writer);
- return stringWriter;
- }
-
- public static Response okCancelSubscriptionResult() {
- Response response = Response
- .newBuilder()
- .setStatus(statusOk())
- .vBuild();
- return response;
- }
-}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/given/FirebaseSubscriptionBridgeTestEnv.java b/firebase-web/src/test/java/io/spine/web/firebase/given/FirebaseSubscriptionBridgeTestEnv.java
index 39705ac40..c322af6e7 100644
--- a/firebase-web/src/test/java/io/spine/web/firebase/given/FirebaseSubscriptionBridgeTestEnv.java
+++ b/firebase-web/src/test/java/io/spine/web/firebase/given/FirebaseSubscriptionBridgeTestEnv.java
@@ -36,17 +36,12 @@
import io.spine.web.firebase.NodePath;
import io.spine.web.firebase.subscription.FirebaseSubscriptionBridge;
-import javax.servlet.ServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.util.Collection;
import java.util.regex.Pattern;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.truth.Truth.assertThat;
import static io.spine.core.Responses.statusOk;
-import static org.mockito.Mockito.when;
@SuppressWarnings("DuplicateStringLiteralInspection") // Duplicate strings for testing.
public final class FirebaseSubscriptionBridgeTestEnv {
@@ -69,7 +64,8 @@ public static void assertSubscriptionPointsToFirebase(NodePath path, Topic topic
DEFAULT_TENANT, escaped(actor), topic.getId().getValue()
);
String expectedPath = PATH_JOINER.join(pathElements);
- assertThat(path.getValue()).isEqualTo(expectedPath);
+ assertThat(path.getValue())
+ .isEqualTo(expectedPath);
}
private static String actorAsString(Topic topic) {
@@ -90,13 +86,6 @@ public static Response newResponse() {
.vBuild();
}
- public static StringWriter mockWriter(ServletResponse response) throws IOException {
- StringWriter stringWriter = new StringWriter();
- PrintWriter writer = new PrintWriter(stringWriter);
- when(response.getWriter()).thenReturn(writer);
- return stringWriter;
- }
-
public static Subscription newSubscription(Topic topic) {
return Subscription
.newBuilder()
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/given/TestFirebaseClient.java b/firebase-web/src/test/java/io/spine/web/firebase/given/MemoizingFirebase.java
similarity index 54%
rename from firebase-web/src/test/java/io/spine/web/firebase/given/TestFirebaseClient.java
rename to firebase-web/src/test/java/io/spine/web/firebase/given/MemoizingFirebase.java
index 0086b0d9a..68544e256 100644
--- a/firebase-web/src/test/java/io/spine/web/firebase/given/TestFirebaseClient.java
+++ b/firebase-web/src/test/java/io/spine/web/firebase/given/MemoizingFirebase.java
@@ -21,39 +21,59 @@
package io.spine.web.firebase.given;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.firebase.database.ChildEventListener;
import io.spine.web.firebase.FirebaseClient;
import io.spine.web.firebase.NodePath;
import io.spine.web.firebase.NodeValue;
import java.time.Duration;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly;
+import static io.spine.util.Exceptions.newIllegalStateException;
-public final class TestFirebaseClient implements FirebaseClient {
+/**
+ * A Firebase client that memoizes read and write operations.
+ *
+ * Supports having a custom write latency through {@linkplain #withSimulatedLatency(Duration)
+ * setting} a particular write operations duration.
+ */
+public final class MemoizingFirebase implements FirebaseClient {
- private final List reads = newArrayList();
- private final List writes = newArrayList();
+ private final Map writes = new HashMap<>();
+ private final Collection reads = new ArrayList<>();
private final Duration writeLatency;
- private TestFirebaseClient(Duration latency) {
+ private MemoizingFirebase(Duration latency) {
this.writeLatency = latency;
}
- public static TestFirebaseClient withSimulatedLatency(Duration latency) {
+ /**
+ * Creates a new instance with zero latency.
+ */
+ public static MemoizingFirebase withNoLatency() {
+ return withSimulatedLatency(Duration.ZERO);
+ }
+
+ /**
+ * Creates a new instance with simulated {@code latency}.
+ */
+ public static MemoizingFirebase withSimulatedLatency(Duration latency) {
checkNotNull(latency);
- return new TestFirebaseClient(latency);
+ return new MemoizingFirebase(latency);
}
@Override
public Optional fetchNode(NodePath nodePath) {
reads.add(nodePath);
- return Optional.empty();
+ return Optional.ofNullable(writes.get(nodePath));
}
@Override
@@ -64,26 +84,48 @@ public void subscribeTo(NodePath nodePath, ChildEventListener listener) {
@Override
public void create(NodePath nodePath, NodeValue value) {
sleepUninterruptibly(writeLatency);
- writes.add(nodePath);
+ writes.put(nodePath, value);
}
@Override
public void update(NodePath nodePath, NodeValue value) {
sleepUninterruptibly(writeLatency);
- writes.add(nodePath);
+ writes.put(nodePath, value);
}
@Override
public void delete(NodePath nodePath) {
sleepUninterruptibly(writeLatency);
- writes.add(nodePath);
+ writes.remove(nodePath);
}
+ /**
+ * Returns a copy of all made read operations.
+ */
public ImmutableList reads() {
return ImmutableList.copyOf(reads);
}
- public ImmutableList writes() {
- return ImmutableList.copyOf(writes);
+ /**
+ * Returns a copy of all made write operation.
+ */
+ public ImmutableMap writes() {
+ return ImmutableMap.copyOf(writes);
+ }
+
+ /**
+ * Returns a {@code NodeValue} written to a specific {@code path}.
+ *
+ * @throws IllegalStateException
+ * if no value is present for the {@code path}
+ */
+ public NodeValue valueFor(NodePath path) {
+ NodeValue result = writes.get(path);
+ if (result == null) {
+ throw newIllegalStateException(
+ "A value is expected to be present at path `%s`.", path.getValue()
+ );
+ }
+ return result;
}
}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/query/FirebaseQueryBridgeTest.java b/firebase-web/src/test/java/io/spine/web/firebase/query/FirebaseQueryBridgeTest.java
index 18e63eccf..8b483b165 100644
--- a/firebase-web/src/test/java/io/spine/web/firebase/query/FirebaseQueryBridgeTest.java
+++ b/firebase-web/src/test/java/io/spine/web/firebase/query/FirebaseQueryBridgeTest.java
@@ -20,46 +20,46 @@
package io.spine.web.firebase.query;
+import com.google.common.collect.Iterators;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.protobuf.Message;
import io.spine.client.Query;
import io.spine.client.QueryFactory;
import io.spine.core.Event;
+import io.spine.json.Json;
import io.spine.server.BoundedContextBuilder;
import io.spine.server.QueryService;
import io.spine.testing.client.TestActorRequestFactory;
-import io.spine.web.firebase.FirebaseClient;
+import io.spine.web.firebase.NodePaths;
+import io.spine.web.firebase.NodeValue;
+import io.spine.web.firebase.StoredJson;
import io.spine.web.firebase.given.Book;
import io.spine.web.firebase.given.BookId;
-import io.spine.web.given.TestQueryService;
-import io.spine.web.firebase.subscription.given.HasChildren;
+import io.spine.web.firebase.given.MemoizingFirebase;
import io.spine.web.given.TestQueryService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
-import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static io.spine.base.Identifier.newUuid;
-import static com.google.common.truth.Truth.assertThat;
-import static io.spine.json.Json.toCompactJson;
-import static io.spine.web.firebase.subscription.given.HasChildren.anyKey;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-@DisplayName("FirebaseQueryBridge should")
+@DisplayName("`FirebaseQueryBridge` should")
class FirebaseQueryBridgeTest {
private static final QueryFactory queryFactory =
new TestActorRequestFactory(FirebaseQueryBridgeTest.class).query();
- private FirebaseClient firebaseClient;
+ private MemoizingFirebase firebaseClient;
@BeforeEach
- void setUp() {
- firebaseClient = mock(FirebaseClient.class);
+ void initClient() {
+ firebaseClient = MemoizingFirebase.withNoLatency();
}
@SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Method called to throw.
@@ -68,13 +68,13 @@ void setUp() {
void requireQueryService() {
FirebaseQueryBridge.Builder builder = FirebaseQueryBridge
.newBuilder()
- .setFirebaseClient(mock(FirebaseClient.class));
+ .setFirebaseClient(firebaseClient);
assertThrows(IllegalStateException.class, builder::build);
}
- @SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Method called to throw.
@Test
@DisplayName("require Firebase Client set in class Builder")
+ @SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Method called to throw.
void requireFirebaseClient() {
QueryService queryService = QueryService
.newBuilder()
@@ -90,13 +90,15 @@ void requireFirebaseClient() {
@DisplayName("produce a database path for the given query results")
void testMediate() {
TestQueryService queryService = new TestQueryService();
- FirebaseQueryBridge bridge = FirebaseQueryBridge.newBuilder()
- .setQueryService(queryService)
- .setFirebaseClient(firebaseClient)
- .build();
+ FirebaseQueryBridge bridge = FirebaseQueryBridge
+ .newBuilder()
+ .setQueryService(queryService)
+ .setFirebaseClient(firebaseClient)
+ .build();
Query query = queryFactory.all(Event.class);
FirebaseQueryResponse response = bridge.send(query);
- assertThat(response).isNotNull();
+ assertThat(response)
+ .isNotNull();
}
@Test
@@ -112,15 +114,39 @@ void testWriteData() {
.setName(newUuid())
.build();
TestQueryService queryService = new TestQueryService(book);
- FirebaseQueryBridge bridge = FirebaseQueryBridge.newBuilder()
- .setQueryService(queryService)
- .setFirebaseClient(firebaseClient)
- .build();
+ FirebaseQueryBridge bridge = FirebaseQueryBridge
+ .newBuilder()
+ .setQueryService(queryService)
+ .setFirebaseClient(firebaseClient)
+ .build();
Query query = queryFactory.all(Book.class);
- bridge.send(query);
+ FirebaseQueryResponse response = bridge.send(query);
+ NodeValue nodeValue = firebaseClient.valueFor(NodePaths.of(response.getPath()));
+ Book actual = firstFieldOf(nodeValue, Book.class);
+ assertThat(actual)
+ .isEqualTo(book);
+ }
- Map expected = new HashMap<>();
- expected.put(anyKey(), toCompactJson(book));
- verify(firebaseClient).create(any(), argThat(new HasChildren(expected)));
+ /**
+ * Returns the {@code message} stored in the first JSON element of the {@code nodeValue}.
+ *
+ * The node has a single randomized field with the field value being a serialized
+ * processed message.
+ *
+ * @implNote The {@code nodeValue} holds data as a JSON primitive string (i.e. an
+ * escaped string that actually holds a JSON object), thus we're forced to parse
+ * the string into a JSON object first and then convert it back to a string.
+ */
+ private static T firstFieldOf(NodeValue nodeValue, Class message) {
+ JsonObject json = nodeValue.underlyingJson();
+ Set> entries = json.entrySet();
+ JsonElement value = Iterators
+ .getOnlyElement(entries.iterator())
+ .getValue();
+ String messageJson = StoredJson
+ .from(value.getAsString())
+ .asJsonObject()
+ .toString();
+ return Json.fromJson(messageJson, message);
}
}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/rest/HttpClientMockFactory.java b/firebase-web/src/test/java/io/spine/web/firebase/rest/HttpClientMockFactory.java
new file mode 100644
index 000000000..6be691f83
--- /dev/null
+++ b/firebase-web/src/test/java/io/spine/web/firebase/rest/HttpClientMockFactory.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.web.firebase.rest;
+
+import com.google.api.client.http.HttpRequestFactory;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.http.LowLevelHttpRequest;
+import com.google.api.client.testing.http.MockHttpTransport;
+import com.google.api.client.testing.http.MockLowLevelHttpRequest;
+import com.google.api.client.testing.http.MockLowLevelHttpResponse;
+
+import java.io.IOException;
+
+/**
+ * Creates mocked {@link HttpClient}s.
+ */
+final class HttpClientMockFactory {
+
+ /**
+ * Prevents instantiation of this utility class.
+ */
+ private HttpClientMockFactory() {
+ }
+
+ /**
+ * Creates a new no-operation {@code HttpClient}.
+ */
+ static HttpClient noOpClient() {
+ MockHttpTransport transport = new MockHttpTransport.Builder().build();
+ return HttpClient.using(transport.createRequestFactory());
+ }
+
+ /**
+ * Creates an {@code HttpClient} mock which returns the specified {@code content}
+ * on every request.
+ */
+ static HttpClient mockHttpClient(String content) {
+ return mockHttpClient(content, HttpClientMockFactory::noOpObserver);
+ }
+
+ /**
+ * Creates an {@code HttpClient} mock which returns the specified {@code content}
+ * on every request and uses supplied {@code observer} while building requests.
+ *
+ * The observer is called by the underlying {@code HttpRequestFactory} whenever a new
+ * HTTP request is being built.
+ */
+ static HttpClient mockHttpClient(String content, HttpRequestObserver observer) {
+ return HttpClient.using(mockRequestFactory(content, observer));
+ }
+
+ private static HttpRequestFactory
+ mockRequestFactory(String content, HttpRequestObserver observer) {
+ HttpTransport transportMock = mockHttpTransport(content, observer);
+ HttpRequestFactory requestFactoryMock = transportMock.createRequestFactory();
+ return requestFactoryMock;
+ }
+
+ private static HttpTransport
+ mockHttpTransport(String content, HttpRequestObserver observer) {
+ final MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
+ response.setContent(content);
+ return new MockHttpTransport() {
+ @Override
+ public LowLevelHttpRequest
+ buildRequest(String method, String url) {
+ MockLowLevelHttpRequest request = new MockLowLevelHttpRequest(url);
+ request.setResponse(response);
+ observer.onRequest(method, url);
+ return request;
+ }
+ };
+ }
+
+ /**
+ * Creates an {@code HttpClient} mock which throws {@link java.io.IOException} on every
+ * request.
+ */
+ static HttpClient throwingClient() {
+ return HttpClient.using(throwingRequestFactory());
+ }
+
+ private static HttpRequestFactory throwingRequestFactory() {
+ HttpRequestFactory result = throwingHttpTransport().createRequestFactory();
+ return result;
+ }
+
+ private static MockHttpTransport throwingHttpTransport() {
+ return new MockHttpTransport() {
+ @Override
+ public LowLevelHttpRequest
+ buildRequest(String method, String url) throws IOException {
+ throw new IOException("Intended exception");
+ }
+ };
+ }
+
+ private static void noOpObserver(String method, String url) {
+ }
+
+ /**
+ * An observer that is called by the underlying
+ * {@linkplain #mockHttpTransport(String, HttpRequestObserver) transport} whenever a request
+ * is being built.
+ *
+ * @implNote The observer allows the caller to sneak-peak into the request creation
+ * process and verify that a particular request is being built.
+ */
+ interface HttpRequestObserver {
+
+ /**
+ * A callback that is executed whenever an HTTP request is built.
+ *
+ * @param method
+ * the HTTP method being used to build a request
+ * @param url
+ * the request URL
+ */
+ void onRequest(String method, String url);
+ }
+}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/rest/HttpClientTest.java b/firebase-web/src/test/java/io/spine/web/firebase/rest/HttpClientTest.java
index 1c5b56ad9..efe9ac117 100644
--- a/firebase-web/src/test/java/io/spine/web/firebase/rest/HttpClientTest.java
+++ b/firebase-web/src/test/java/io/spine/web/firebase/rest/HttpClientTest.java
@@ -22,25 +22,18 @@
import com.google.api.client.http.ByteArrayContent;
import com.google.api.client.http.GenericUrl;
-import com.google.api.client.http.HttpRequestFactory;
-import com.google.api.client.http.HttpTransport;
-import com.google.api.client.http.LowLevelHttpRequest;
-import com.google.api.client.http.LowLevelHttpResponse;
-import com.google.api.client.testing.http.MockHttpTransport;
-import com.google.api.client.testing.http.MockLowLevelHttpRequest;
-import com.google.api.client.testing.http.MockLowLevelHttpResponse;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
-import java.io.IOException;
-
import static com.google.api.client.http.ByteArrayContent.fromString;
import static com.google.common.net.MediaType.JSON_UTF_8;
+import static io.spine.web.firebase.rest.HttpClientMockFactory.mockHttpClient;
+import static io.spine.web.firebase.rest.HttpClientMockFactory.throwingClient;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+@DisplayName("`HttpClient` should")
@SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Calling methods to throw.
-@DisplayName("HttpClient should")
class HttpClientTest {
private static final GenericUrl URL = new GenericUrl("https://localhost:8080");
@@ -50,8 +43,7 @@ class HttpClientTest {
@Test
@DisplayName("execute GET request")
void executeGetRequest() {
- HttpRequestFactory transport = mockRequestFactory(RESPONSE);
- HttpClient requestExecutor = HttpClient.using(transport);
+ HttpClient requestExecutor = mockHttpClient(RESPONSE);
String content = requestExecutor.get(URL);
assertEquals(RESPONSE, content);
}
@@ -59,16 +51,14 @@ void executeGetRequest() {
@Test
@DisplayName("throw RequestToFirebaseFailedException if an error occurs on GET request")
void throwIfErrorOnGet() {
- HttpRequestFactory transport = throwingRequestFactory();
- HttpClient requestExecutor = HttpClient.using(transport);
+ HttpClient requestExecutor = throwingClient();
assertThrows(RequestToFirebaseFailedException.class, () -> requestExecutor.get(URL));
}
@Test
@DisplayName("execute PUT request")
void executePutRequest() {
- HttpRequestFactory transport = mockRequestFactory(RESPONSE);
- HttpClient requestExecutor = HttpClient.using(transport);
+ HttpClient requestExecutor = mockHttpClient(RESPONSE);
String content = requestExecutor.put(URL, CONTENT);
assertEquals(RESPONSE, content);
}
@@ -76,8 +66,7 @@ void executePutRequest() {
@Test
@DisplayName("throw RequestToFirebaseFailedException if an error occurs on PUT request")
void throwIfErrorOnPut() {
- HttpRequestFactory transport = throwingRequestFactory();
- HttpClient requestExecutor = HttpClient.using(transport);
+ HttpClient requestExecutor = throwingClient();
assertThrows(RequestToFirebaseFailedException.class,
() -> requestExecutor.put(URL, CONTENT));
}
@@ -85,8 +74,7 @@ void throwIfErrorOnPut() {
@Test
@DisplayName("execute PATCH request")
void executePatchRequest() {
- HttpRequestFactory transport = mockRequestFactory(RESPONSE);
- HttpClient requestExecutor = HttpClient.using(transport);
+ HttpClient requestExecutor = mockHttpClient(RESPONSE);
String content = requestExecutor.patch(URL, CONTENT);
assertEquals(RESPONSE, content);
}
@@ -94,55 +82,8 @@ void executePatchRequest() {
@Test
@DisplayName("throw RequestToFirebaseFailedException if an error occurs on PATCH request")
void throwIfErrorOnPatch() {
- HttpRequestFactory transport = throwingRequestFactory();
- HttpClient requestExecutor = HttpClient.using(transport);
+ HttpClient requestExecutor = throwingClient();
assertThrows(RequestToFirebaseFailedException.class,
() -> requestExecutor.patch(URL, CONTENT));
}
-
- /**
- * Returns an {@code HttpRequestFactory} mock which returns the specified content on every
- * request.
- */
- private static HttpRequestFactory mockRequestFactory(String content) {
- HttpTransport transportMock = mockHttpTransport(content);
- HttpRequestFactory requestFactoryMock = transportMock.createRequestFactory();
- return requestFactoryMock;
- }
-
- /**
- * Returns an {@code HttpRequestFactory} mock which throws {@link java.io.IOException} on every
- * request.
- */
- private static HttpRequestFactory throwingRequestFactory() {
- HttpRequestFactory result = throwingHttpTransport().createRequestFactory();
- return result;
- }
-
- private static HttpTransport mockHttpTransport(String content) {
- return new MockHttpTransport() {
- @Override
- public LowLevelHttpRequest
- buildRequest(String method, String url) {
- return new MockLowLevelHttpRequest() {
- @Override
- public LowLevelHttpResponse execute() {
- MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
- response.setContent(content);
- return response;
- }
- };
- }
- };
- }
-
- private static MockHttpTransport throwingHttpTransport() {
- return new MockHttpTransport() {
- @Override
- public LowLevelHttpRequest
- buildRequest(String method, String url) throws IOException {
- throw new IOException("Intended exception");
- }
- };
- }
}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/rest/RemoteDatabaseClientTest.java b/firebase-web/src/test/java/io/spine/web/firebase/rest/RemoteDatabaseClientTest.java
index 0b56f2b2e..d0d74946e 100644
--- a/firebase-web/src/test/java/io/spine/web/firebase/rest/RemoteDatabaseClientTest.java
+++ b/firebase-web/src/test/java/io/spine/web/firebase/rest/RemoteDatabaseClientTest.java
@@ -20,8 +20,8 @@
package io.spine.web.firebase.rest;
-import com.google.api.client.http.ByteArrayContent;
import com.google.api.client.http.GenericUrl;
+import com.google.api.client.http.HttpMethods;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.testing.http.MockHttpTransport;
import com.google.auth.oauth2.AccessToken;
@@ -32,6 +32,7 @@
import com.google.firebase.database.FirebaseDatabase;
import io.spine.web.firebase.DatabaseUrl;
import io.spine.web.firebase.DatabaseUrls;
+import io.spine.web.firebase.FirebaseClient;
import io.spine.web.firebase.NodePath;
import io.spine.web.firebase.NodePaths;
import io.spine.web.firebase.NodeValue;
@@ -45,17 +46,14 @@
import java.util.Date;
import java.util.Optional;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
import static io.spine.testing.DisplayNames.NOT_ACCEPT_NULLS;
+import static io.spine.web.firebase.rest.HttpClientMockFactory.mockHttpClient;
+import static io.spine.web.firebase.rest.HttpClientMockFactory.noOpClient;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
@DisplayName("`RemoteDatabaseClient` should")
class RemoteDatabaseClientTest {
@@ -71,8 +69,7 @@ class RemoteDatabaseClientTest {
private static final GenericUrl EXPECTED_NODE_URL =
new GenericUrl(DATABASE_URL_STRING + '/' + PATH + ".json");
- private HttpClient httpClient;
- private RemoteDatabaseClient client;
+ private FirebaseDatabase database;
private NodePath path;
private NodeValue value;
@@ -91,9 +88,9 @@ static void initFirebase() {
@BeforeEach
void setUp() {
- httpClient = mock(HttpClient.class);
- FirebaseDatabase mockFirebase = mock(FirebaseDatabase.class);
- client = new RemoteDatabaseClient(mockFirebase, NODE_FACTORY, httpClient);
+ database = FirebaseDatabase.getInstance(
+ FirebaseApp.getInstance(FIREBASE_APP_NAME)
+ );
path = NodePaths.of(PATH);
value = DATA.asNodeValue();
}
@@ -101,6 +98,7 @@ void setUp() {
@Test
@DisplayName(NOT_ACCEPT_NULLS)
void passNullToleranceCheck() {
+ FirebaseClient client = new RemoteDatabaseClient(database, NODE_FACTORY, noOpClient());
new NullPointerTester()
.setDefault(NodePath.class, path)
.setDefault(NodeValue.class, value)
@@ -110,10 +108,12 @@ void passNullToleranceCheck() {
@Test
@DisplayName("retrieve data from given database path")
void getData() {
- when(httpClient.get(any())).thenReturn(DATA.value());
+ HttpClient httpClient = mockHttpClient(DATA.value());
+ FirebaseClient client = new RemoteDatabaseClient(database, NODE_FACTORY, httpClient);
Optional result = client.fetchNode(path);
- assertTrue(result.isPresent());
+ assertThat(result)
+ .isPresent();
NodeValue value = result.get();
String contentString = value.underlyingJson()
.toString();
@@ -123,28 +123,40 @@ void getData() {
@Test
@DisplayName("return empty Optional in case of null data")
void getNullData() {
- when(httpClient.get(any())).thenReturn(NULL_ENTRY);
+ HttpClient httpClient = mockHttpClient(NULL_ENTRY);
+ FirebaseClient client = new RemoteDatabaseClient(database, NODE_FACTORY, httpClient);
Optional result = client.fetchNode(path);
- assertFalse(result.isPresent());
+ assertThat(result)
+ .isEmpty();
}
@Test
@DisplayName("store data via PUT method when node is not present")
void storeNewViaPut() {
- when(httpClient.get(any())).thenReturn(NULL_ENTRY);
+ HttpClient httpClient = mockHttpClient(NULL_ENTRY, (method, url) -> {
+ assertThat(method)
+ .isEqualTo(HttpMethods.PUT);
+ assertThat(url)
+ .isEqualTo(EXPECTED_NODE_URL.build());
+ });
+ FirebaseClient client = new RemoteDatabaseClient(database, NODE_FACTORY, httpClient);
client.create(path, value);
- verify(httpClient).put(eq(EXPECTED_NODE_URL), any(ByteArrayContent.class));
}
@Test
@DisplayName("store data via PATCH method when node already exists")
void updateExistingViaPatch() {
- when(httpClient.get(any())).thenReturn(DATA.value());
+ HttpClient httpClient = mockHttpClient(NULL_ENTRY, (method, url) -> {
+ assertThat(method)
+ .isEqualTo(HttpMethods.PATCH);
+ assertThat(url)
+ .isEqualTo(EXPECTED_NODE_URL.build());
+ });
+ FirebaseClient client = new RemoteDatabaseClient(database, NODE_FACTORY, httpClient);
client.update(path, value);
- verify(httpClient).patch(eq(EXPECTED_NODE_URL), any(ByteArrayContent.class));
}
@Nested
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/subscription/FirebaseSubscriptionBridgeTest.java b/firebase-web/src/test/java/io/spine/web/firebase/subscription/FirebaseSubscriptionBridgeTest.java
index 7ea2af628..f4b770f36 100644
--- a/firebase-web/src/test/java/io/spine/web/firebase/subscription/FirebaseSubscriptionBridgeTest.java
+++ b/firebase-web/src/test/java/io/spine/web/firebase/subscription/FirebaseSubscriptionBridgeTest.java
@@ -27,8 +27,7 @@
import io.spine.core.Response;
import io.spine.server.BoundedContextBuilder;
import io.spine.server.SubscriptionService;
-import io.spine.web.firebase.FirebaseClient;
-import io.spine.web.firebase.subscription.given.InMemFirebaseClient;
+import io.spine.web.firebase.given.MemoizingFirebase;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -43,9 +42,8 @@
import static io.spine.web.firebase.given.FirebaseSubscriptionBridgeTestEnv.newTarget;
import static io.spine.web.firebase.given.FirebaseSubscriptionBridgeTestEnv.topicFactory;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.mock;
-@DisplayName("FirebaseSubscriptionBridge should")
+@DisplayName("`FirebaseSubscriptionBridge` should")
class FirebaseSubscriptionBridgeTest {
private FirebaseSubscriptionBridge bridge;
@@ -54,24 +52,23 @@ class FirebaseSubscriptionBridgeTest {
@BeforeEach
void setUp() {
SubscriptionServiceImplBase subscriptionService = new TestSubscriptionService();
- FirebaseClient firebaseClient = new InMemFirebaseClient();
- bridge = newBridge(firebaseClient, subscriptionService);
+ bridge = newBridge(MemoizingFirebase.withNoLatency(), subscriptionService);
topicFactory = topicFactory();
}
- @SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Method called to throw.
@Test
@DisplayName("require Query Service set in Builder")
+ @SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Method called to throw.
void requireQueryService() {
FirebaseSubscriptionBridge.Builder builder = FirebaseSubscriptionBridge
.newBuilder()
- .setFirebaseClient(mock(FirebaseClient.class));
+ .setFirebaseClient(MemoizingFirebase.withNoLatency());
assertThrows(IllegalStateException.class, builder::build);
}
- @SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Method called to throw.
@Test
@DisplayName("require Firebase Client set in Builder")
+ @SuppressWarnings({"ResultOfMethodCallIgnored", "CheckReturnValue"}) // Method called to throw.
void requireFirebaseClient() {
SubscriptionService subscriptionService = SubscriptionService
.newBuilder()
@@ -90,7 +87,8 @@ void keepUpSubscription() {
FirebaseSubscription subscription = bridge.subscribe(topic);
Response keptUp = bridge.keepUp(subscription.getSubscription());
Response responseMessage = newResponse();
- assertThat(keptUp).isEqualTo(responseMessage);
+ assertThat(keptUp)
+ .isEqualTo(responseMessage);
}
@Test
@@ -99,7 +97,8 @@ void failKeepUp() {
Topic topic = topicFactory.forTarget(newTarget());
Subscription subscription = newSubscription(topic);
Response keptUp = bridge.keepUp(subscription);
- assertThat(keptUp.getStatus().getStatusCase()).isEqualTo(ERROR);
+ assertThat(keptUp.getStatus().getStatusCase())
+ .isEqualTo(ERROR);
}
@Test
@@ -113,7 +112,8 @@ void cancelSubscription() {
Response canceled = bridge.cancel(subscription);
Response responseMessage = newResponse();
- assertThat(canceled).isEqualTo(responseMessage);
+ assertThat(canceled)
+ .isEqualTo(responseMessage);
}
@Test
@@ -122,7 +122,8 @@ void failCancellation() {
Topic topic = topicFactory.forTarget(newTarget());
Subscription subscription = newSubscription(topic);
Response canceled = bridge.cancel(subscription);
- assertThat(canceled.getStatus().getStatusCase()).isEqualTo(ERROR);
+ assertThat(canceled.getStatus().getStatusCase())
+ .isEqualTo(ERROR);
}
@Test
@@ -130,11 +131,16 @@ void failCancellation() {
void failDoubleCancellation() {
Topic topic = topicFactory.forTarget(newTarget());
FirebaseSubscription subscriptionResult = bridge.subscribe(topic);
- assertThat(subscriptionResult).isNotNull();
+ assertThat(subscriptionResult)
+ .isNotNull();
+
Response canceled = bridge.cancel(subscriptionResult.getSubscription());
- assertThat(canceled.getStatus().getStatusCase()).isEqualTo(OK);
+ assertThat(canceled.getStatus().getStatusCase())
+ .isEqualTo(OK);
+
Response canceledAgain = bridge.cancel(subscriptionResult.getSubscription());
- assertThat(canceledAgain.getStatus().getStatusCase()).isEqualTo(ERROR);
+ assertThat(canceledAgain.getStatus().getStatusCase())
+ .isEqualTo(ERROR);
}
@Test
@@ -144,7 +150,8 @@ void subscribe() {
FirebaseSubscription firebaseSubscription = bridge.subscribe(topic);
Subscription subscription = firebaseSubscription.getSubscription();
- assertThat(subscription.getTopic()).isEqualTo(topic);
+ assertThat(subscription.getTopic())
+ .isEqualTo(topic);
assertSubscriptionPointsToFirebase(firebaseSubscription.getNodePath(), topic);
}
}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/HasChildren.java b/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/HasChildren.java
deleted file mode 100644
index 8f7b42123..000000000
--- a/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/HasChildren.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2020, TeamDev. All rights reserved.
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.web.firebase.subscription.given;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import io.spine.web.firebase.NodeValue;
-import org.mockito.ArgumentMatcher;
-
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.stream.Collectors.toList;
-
-/**
- * A checker of {@code NodeValue} instances used in Firebase requests.
- *
- * By default checks that the value contains all the {@linkplain #expected expected} entries
- * under the specified keys.
- *
- *
If {@link #ANY_KEY} is specified as entry key then the checker verifies that corresponding
- * value is present under any of the keys in the tested object.
- */
-public class HasChildren implements ArgumentMatcher {
-
- private static final String ANY_KEY = "any_key";
- public static final String JSON_NULL = "json_null";
-
- private final ImmutableMap expected;
-
- /**
- * Creates a new matcher for the specified expected entries.
- *
- * @param expected
- * the expected entries in "nodeKey-nodeValue" format
- */
- public HasChildren(Map expected) {
- this.expected = ImmutableMap.copyOf(expected);
- }
-
- @Override
- public boolean matches(NodeValue nodeValue) {
- JsonObject actual = nodeValue.underlyingJson();
- for (Map.Entry entry : expected.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- if (!hasKeyAndValue(actual, key, value)) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean hasKeyAndValue(JsonObject json, String key, String value) {
- checkNotNull(json);
- checkNotNull(key);
- if (key.startsWith(ANY_KEY)) {
- List> containingValue = json
- .entrySet()
- .stream()
- .filter(e -> equalsOrNull(e.getValue(), value))
- .collect(toList());
- boolean result = !containingValue.isEmpty();
- return result;
- } else {
- boolean result = json.has(key) && equalsOrNull(json.get(key), value);
- return result;
- }
- }
-
- public static String anyKey() {
- return ANY_KEY + UUID.randomUUID().toString();
- }
-
- private static boolean equalsOrNull(JsonElement element, String value) {
- if (element.isJsonNull()) {
- return value.equals(JSON_NULL);
- }
-
- return element.getAsString().equals(value);
- }
-}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/InMemFirebaseClient.java b/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/InMemFirebaseClient.java
deleted file mode 100644
index 99b5b603c..000000000
--- a/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/InMemFirebaseClient.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2020, TeamDev. All rights reserved.
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package io.spine.web.firebase.subscription.given;
-
-import com.google.firebase.database.ChildEventListener;
-import io.spine.web.firebase.FirebaseClient;
-import io.spine.web.firebase.NodePath;
-import io.spine.web.firebase.NodeValue;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-public class InMemFirebaseClient implements FirebaseClient {
-
- private final Map values = new HashMap<>();
-
- @Override
- public Optional fetchNode(NodePath nodePath) {
- return Optional.ofNullable(values.get(nodePath));
- }
-
- @Override
- public void subscribeTo(NodePath nodePath, ChildEventListener listener) {
- // Method `subscribeTo` is not supported. OK for test purposes.
- }
-
- @Override
- public void create(NodePath nodePath, NodeValue value) {
- values.put(nodePath,value);
- }
-
- @Override
- public void update(NodePath nodePath, NodeValue value) {
- values.put(nodePath,value);
- }
-
- @Override
- public void delete(NodePath nodePath) {
- values.remove(nodePath);
- }
-}
diff --git a/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/package-info.java b/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/package-info.java
deleted file mode 100644
index b76e86f10..000000000
--- a/firebase-web/src/test/java/io/spine/web/firebase/subscription/given/package-info.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2020, TeamDev. All rights reserved.
- *
- * Redistribution and use in source and/or binary forms, with or without
- * modification, must retain the above copyright notice and the following
- * disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-@CheckReturnValue
-@ParametersAreNonnullByDefault
-package io.spine.web.firebase.subscription.given;
-
-import com.google.errorprone.annotations.CheckReturnValue;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/integration-tests/js-tests/package.json b/integration-tests/js-tests/package.json
index ff5b0a466..b2551caf6 100644
--- a/integration-tests/js-tests/package.json
+++ b/integration-tests/js-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "client-js-tests",
- "version": "1.6.15",
+ "version": "1.6.16",
"license": "Apache-2.0",
"description": "Tests of a `spine-web` JS library against the Spine-based application.",
"scripts": {
diff --git a/license-report.md b/license-report.md
index 1661bff8f..900b84bef 100644
--- a/license-report.md
+++ b/license-report.md
@@ -1,6 +1,6 @@
-# Dependencies of `io.spine:spine-client-js:1.6.15`
+# Dependencies of `io.spine:spine-client-js:1.6.16`
## Runtime
1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -10,9 +10,6 @@
1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.4.0
* **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.4.0
- * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** com.google.guava **Name:** failureaccess **Version:** 1.0.1
* **Manifest Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -220,12 +217,6 @@
* **POM Project URL:** [http://junit.org](http://junit.org)
* **POM License: Eclipse Public License 1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html)
-1. **Group:** net.bytebuddy **Name:** byte-buddy **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-1. **Group:** net.bytebuddy **Name:** byte-buddy-agent **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** net.java.dev.javacc **Name:** javacc **Version:** 5.0
* **POM Project URL:** [https://javacc.dev.java.net/](https://javacc.dev.java.net/)
* **POM License: Berkeley Software Distribution (BSD) License** - [http://www.opensource.org/licenses/bsd-license.html](http://www.opensource.org/licenses/bsd-license.html)
@@ -280,9 +271,6 @@
* **POM License: MIT license** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** org.hamcrest **Name:** hamcrest-all **Version:** 1.3
- * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
-
1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3
* **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
@@ -319,14 +307,6 @@
* **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/)
* **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html)
-1. **Group:** org.mockito **Name:** mockito-core **Version:** 2.12.0
- * **POM Project URL:** [https://github.com/mockito/mockito](https://github.com/mockito/mockito)
- * **POM License: The MIT License** - [https://github.com/mockito/mockito/blob/master/LICENSE](https://github.com/mockito/mockito/blob/master/LICENSE)
-
-1. **Group:** org.objenesis **Name:** objenesis **Version:** 2.6
- * **POM Project URL:** [http://objenesis.org](http://objenesis.org)
- * **POM License: Apache 2** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0
* **Manifest License:** The Apache License, Version 2.0 (Not packaged)
* **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j)
@@ -388,17 +368,17 @@
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Mon Dec 07 12:28:03 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
-#NPM dependencies of `spine-web@1.6.15`
+#NPM dependencies of `spine-web@1.6.16`
## `Production` dependencies:
1. **base64-js@1.3.1**
* Licenses: MIT
* Repository: [https://github.com/beatgammit/base64-js](https://github.com/beatgammit/base64-js)
-1. **google-protobuf@3.14.0**
+1. **google-protobuf@3.13.0**
* Licenses: BSD-3-Clause
* Repository: [https://github.com/protocolbuffers/protobuf/tree/master/js](https://github.com/protocolbuffers/protobuf/tree/master/js)
1. **isomorphic-fetch@3.0.0**
@@ -410,7 +390,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **rxjs@6.5.5**
* Licenses: Apache-2.0
* Repository: [https://github.com/reactivex/rxjs](https://github.com/reactivex/rxjs)
-1. **spine-web@1.6.15**
+1. **spine-web@1.6.16**
* Licenses: Apache-2.0
* Repository: [https://github.com/SpineEventEngine/web](https://github.com/SpineEventEngine/web)
1. **tslib@1.14.1**
@@ -419,7 +399,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **uuid@8.3.1**
* Licenses: MIT
* Repository: [https://github.com/uuidjs/uuid](https://github.com/uuidjs/uuid)
-1. **whatwg-fetch@3.5.0**
+1. **whatwg-fetch@3.4.1**
* Licenses: MIT
* Repository: [https://github.com/github/fetch](https://github.com/github/fetch)
@@ -427,16 +407,16 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
## `Development` dependencies:
-1. **@babel/cli@7.12.7**
+1. **@babel/cli@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/code-frame@7.10.4**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/compat-data@7.12.7**
+1. **@babel/compat-data@7.12.5**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/core@7.12.7**
+1. **@babel/core@7.12.3**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/generator@7.12.5**
@@ -454,7 +434,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/helper-create-class-features-plugin@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/helper-create-regexp-features-plugin@7.12.7**
+1. **@babel/helper-create-regexp-features-plugin@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/helper-define-map@7.10.5**
@@ -472,7 +452,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/helper-hoist-variables@7.10.4**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/helper-member-expression-to-functions@7.12.7**
+1. **@babel/helper-member-expression-to-functions@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/helper-module-imports@7.12.5**
@@ -481,12 +461,15 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/helper-module-transforms@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/helper-optimise-call-expression@7.12.7**
+1. **@babel/helper-optimise-call-expression@7.10.4**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/helper-plugin-utils@7.10.4**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
+1. **@babel/helper-regex@7.10.5**
+ * Licenses: MIT
+ * Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/helper-remap-async-to-generator@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
@@ -517,7 +500,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/highlight@7.10.4**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/parser@7.12.7**
+1. **@babel/parser@7.12.5**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/plugin-proposal-async-generator-functions@7.12.1**
@@ -541,7 +524,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/plugin-proposal-nullish-coalescing-operator@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/plugin-proposal-numeric-separator@7.12.7**
+1. **@babel/plugin-proposal-numeric-separator@7.12.5**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/plugin-proposal-object-rest-spread@7.12.1**
@@ -550,7 +533,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/plugin-proposal-optional-catch-binding@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/plugin-proposal-optional-chaining@7.12.7**
+1. **@babel/plugin-proposal-optional-chaining@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/plugin-proposal-private-methods@7.12.1**
@@ -676,7 +659,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/plugin-transform-spread@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/plugin-transform-sticky-regex@7.12.7**
+1. **@babel/plugin-transform-sticky-regex@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/plugin-transform-template-literals@7.12.1**
@@ -691,7 +674,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/plugin-transform-unicode-regex@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/preset-env@7.12.7**
+1. **@babel/preset-env@7.12.1**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@babel/preset-modules@0.1.4**
@@ -703,13 +686,13 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@babel/runtime@7.12.5**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/template@7.12.7**
+1. **@babel/template@7.10.4**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/traverse@7.12.7**
+1. **@babel/traverse@7.12.5**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
-1. **@babel/types@7.12.7**
+1. **@babel/types@7.12.6**
* Licenses: MIT
* Repository: [https://github.com/babel/babel](https://github.com/babel/babel)
1. **@firebase/analytics-types@0.4.0**
@@ -796,19 +779,22 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@firebase/webchannel-wrapper@0.4.0**
* Licenses: Apache-2.0
* Repository: [https://github.com/firebase/firebase-js-sdk](https://github.com/firebase/firebase-js-sdk)
-1. **@grpc/grpc-js@1.2.1**
+1. **@grpc/grpc-js@1.1.8**
* Licenses: Apache-2.0
* Repository: [https://github.com/grpc/grpc-node/tree/master/packages/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js)
1. **@grpc/proto-loader@0.5.5**
* Licenses: Apache-2.0
* Repository: [https://github.com/grpc/grpc-node](https://github.com/grpc/grpc-node)
+1. **@grpc/proto-loader@0.6.0-pre9**
+ * Licenses: Apache-2.0
+ * Repository: [https://github.com/grpc/grpc-node](https://github.com/grpc/grpc-node)
1. **@istanbuljs/load-nyc-config@1.1.0**
* Licenses: ISC
* Repository: [https://github.com/istanbuljs/load-nyc-config](https://github.com/istanbuljs/load-nyc-config)
1. **@istanbuljs/schema@0.1.2**
* Licenses: MIT
* Repository: [https://github.com/istanbuljs/schema](https://github.com/istanbuljs/schema)
-1. **@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents**
+1. **@nicolo-ribaudo/chokidar-2@2.1.8**
* Licenses: MIT
* Repository: [https://github.com/nicolo-ribaudo/chokidar-2](https://github.com/nicolo-ribaudo/chokidar-2)
1. **@protobufjs/aspromise@1.1.2**
@@ -850,7 +836,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@sinonjs/formatio@5.0.1**
* Licenses: BSD-3-Clause
* Repository: [https://github.com/sinonjs/formatio](https://github.com/sinonjs/formatio)
-1. **@sinonjs/samsam@5.3.0**
+1. **@sinonjs/samsam@5.2.0**
* Licenses: BSD-3-Clause
* Repository: [https://github.com/sinonjs/samsam](https://github.com/sinonjs/samsam)
1. **@sinonjs/text-encoding@0.7.1**
@@ -859,19 +845,16 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **@tootallnate/once@1.1.2**
* Licenses: MIT
* Repository: [https://github.com/TooTallNate/once](https://github.com/TooTallNate/once)
-1. **@types/color-name@1.1.1**
- * Licenses: MIT
- * Repository: [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
1. **@types/json-schema@7.0.6**
* Licenses: MIT
* Repository: [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
1. **@types/long@4.0.1**
* Licenses: MIT
* Repository: [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
-1. **@types/node@12.19.6**
+1. **@types/node@12.19.3**
* Licenses: MIT
* Repository: [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
-1. **@types/node@13.13.32**
+1. **@types/node@13.13.30**
* Licenses: MIT
* Repository: [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
1. **@ungap/promise-all-settled@1.1.2**
@@ -958,7 +941,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **agent-base@6.0.2**
* Licenses: MIT
* Repository: [https://github.com/TooTallNate/node-agent-base](https://github.com/TooTallNate/node-agent-base)
-1. **aggregate-error@3.0.1**
+1. **aggregate-error@3.1.0**
* Licenses: MIT
* Repository: [https://github.com/sindresorhus/aggregate-error](https://github.com/sindresorhus/aggregate-error)
1. **ajv-errors@1.0.1**
@@ -991,9 +974,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **ansi-styles@3.2.1**
* Licenses: MIT
* Repository: [https://github.com/chalk/ansi-styles](https://github.com/chalk/ansi-styles)
-1. **ansi-styles@4.2.1**
- * Licenses: MIT
- * Repository: [https://github.com/chalk/ansi-styles](https://github.com/chalk/ansi-styles)
1. **ansi-styles@4.3.0**
* Licenses: MIT
* Repository: [https://github.com/chalk/ansi-styles](https://github.com/chalk/ansi-styles)
@@ -1060,7 +1040,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **babel-code-frame@6.26.0**
* Licenses: MIT
* Repository: [https://github.com/babel/babel/tree/master/packages/babel-code-frame](https://github.com/babel/babel/tree/master/packages/babel-code-frame)
-1. **babel-loader@8.2.1**
+1. **babel-loader@8.1.0**
* Licenses: MIT
* Repository: [https://github.com/babel/babel-loader](https://github.com/babel/babel-loader)
1. **babel-messages@6.23.0**
@@ -1108,9 +1088,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **binary-extensions@2.1.0**
* Licenses: MIT
* Repository: [https://github.com/sindresorhus/binary-extensions](https://github.com/sindresorhus/binary-extensions)
-1. **bindings@1.5.0**
- * Licenses: MIT
- * Repository: [https://github.com/TooTallNate/node-bindings](https://github.com/TooTallNate/node-bindings)
1. **bluebird@3.7.2**
* Licenses: MIT
* Repository: [https://github.com/petkaantonov/bluebird](https://github.com/petkaantonov/bluebird)
@@ -1144,7 +1121,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **browserify-des@1.0.2**
* Licenses: MIT
* Repository: [https://github.com/crypto-browserify/browserify-des](https://github.com/crypto-browserify/browserify-des)
-1. **browserify-rsa@4.1.0**
+1. **browserify-rsa@4.0.1**
* Licenses: MIT
* Repository: [https://github.com/crypto-browserify/browserify-rsa](https://github.com/crypto-browserify/browserify-rsa)
1. **browserify-sign@4.2.1**
@@ -1153,7 +1130,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **browserify-zlib@0.2.0**
* Licenses: MIT
* Repository: [https://github.com/devongovett/browserify-zlib](https://github.com/devongovett/browserify-zlib)
-1. **browserslist@4.14.7**
+1. **browserslist@4.14.6**
* Licenses: MIT
* Repository: [https://github.com/browserslist/browserslist](https://github.com/browserslist/browserslist)
1. **buffer-equal-constant-time@1.0.1**
@@ -1189,7 +1166,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **camelcase@6.2.0**
* Licenses: MIT
* Repository: [https://github.com/sindresorhus/camelcase](https://github.com/sindresorhus/camelcase)
-1. **caniuse-lite@1.0.30001159**
+1. **caniuse-lite@1.0.30001156**
* Licenses: CC-BY-4.0
* Repository: [https://github.com/ben-eb/caniuse-lite](https://github.com/ben-eb/caniuse-lite)
1. **catharsis@0.8.11**
@@ -1252,7 +1229,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **colorette@1.2.1**
* Licenses: MIT
* Repository: [https://github.com/jorgebucaran/colorette](https://github.com/jorgebucaran/colorette)
-1. **command-line-usage@6.1.1**
+1. **command-line-usage@6.1.0**
* Licenses: MIT
* Repository: [https://github.com/75lb/command-line-usage](https://github.com/75lb/command-line-usage)
1. **commander@2.20.3**
@@ -1291,7 +1268,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **copy-descriptor@0.1.1**
* Licenses: MIT
* Repository: [https://github.com/jonschlinkert/copy-descriptor](https://github.com/jonschlinkert/copy-descriptor)
-1. **core-js-compat@3.7.0**
+1. **core-js-compat@3.6.5**
* Licenses: MIT
* Repository: [https://github.com/zloirock/core-js](https://github.com/zloirock/core-js)
1. **core-js@2.6.11**
@@ -1327,15 +1304,9 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **debug@3.2.6**
* Licenses: MIT
* Repository: [https://github.com/visionmedia/debug](https://github.com/visionmedia/debug)
-1. **debug@4.1.1**
- * Licenses: MIT
- * Repository: [https://github.com/visionmedia/debug](https://github.com/visionmedia/debug)
1. **debug@4.2.0**
* Licenses: MIT
* Repository: [https://github.com/visionmedia/debug](https://github.com/visionmedia/debug)
-1. **debug@4.3.1**
- * Licenses: MIT
- * Repository: [https://github.com/visionmedia/debug](https://github.com/visionmedia/debug)
1. **debuglog@1.0.1**
* Licenses: MIT
* Repository: [https://github.com/sam-github/node-debuglog](https://github.com/sam-github/node-debuglog)
@@ -1390,7 +1361,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **ecdsa-sig-formatter@1.0.11**
* Licenses: Apache-2.0
* Repository: [https://github.com/Brightspace/node-ecdsa-sig-formatter](https://github.com/Brightspace/node-ecdsa-sig-formatter)
-1. **electron-to-chromium@1.3.603**
+1. **electron-to-chromium@1.3.588**
* Licenses: ISC
* Repository: [https://github.com/kilian/electron-to-chromium](https://github.com/kilian/electron-to-chromium)
1. **elliptic@6.5.3**
@@ -1498,9 +1469,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **figgy-pudding@3.5.2**
* Licenses: ISC
* Repository: [https://github.com/npm/figgy-pudding](https://github.com/npm/figgy-pudding)
-1. **file-uri-to-path@1.0.0**
- * Licenses: MIT
- * Repository: [https://github.com/TooTallNate/file-uri-to-path](https://github.com/TooTallNate/file-uri-to-path)
1. **fill-range@4.0.0**
* Licenses: MIT
* Repository: [https://github.com/jonschlinkert/fill-range](https://github.com/jonschlinkert/fill-range)
@@ -1546,7 +1514,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **from2@2.3.0**
* Licenses: MIT
* Repository: [https://github.com/hughsk/from2](https://github.com/hughsk/from2)
-1. **fromentries@1.2.0**
+1. **fromentries@1.3.2**
* Licenses: MIT
* Repository: [https://github.com/feross/fromentries](https://github.com/feross/fromentries)
1. **fs-readdir-recursive@1.1.0**
@@ -1558,12 +1526,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **fs.realpath@1.0.0**
* Licenses: ISC
* Repository: [https://github.com/isaacs/fs.realpath](https://github.com/isaacs/fs.realpath)
-1. **fsevents@1.2.13**
- * Licenses: MIT
- * Repository: [https://github.com/strongloop/fsevents](https://github.com/strongloop/fsevents)
-1. **fsevents@2.1.3**
- * Licenses: MIT
- * Repository: [https://github.com/fsevents/fsevents](https://github.com/fsevents/fsevents)
1. **function-bind@1.1.1**
* Licenses: MIT
* Repository: [https://github.com/Raynos/function-bind](https://github.com/Raynos/function-bind)
@@ -1612,13 +1574,13 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **google-p12-pem@3.0.3**
* Licenses: MIT
* Repository: [https://github.com/google/google-p12-pem](https://github.com/google/google-p12-pem)
-1. **graceful-fs@4.2.3**
+1. **graceful-fs@4.2.4**
* Licenses: ISC
* Repository: [https://github.com/isaacs/node-graceful-fs](https://github.com/isaacs/node-graceful-fs)
1. **growl@1.10.5**
* Licenses: MIT
* Repository: [https://github.com/tj/node-growl](https://github.com/tj/node-growl)
-1. **gtoken@5.1.0**
+1. **gtoken@5.0.5**
* Licenses: MIT
* Repository: [https://github.com/google/node-gtoken](https://github.com/google/node-gtoken)
1. **has-ansi@2.0.0**
@@ -1654,7 +1616,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **hash.js@1.1.7**
* Licenses: MIT
* Repository: [https://github.com/indutny/hash.js](https://github.com/indutny/hash.js)
-1. **hasha@5.2.0**
+1. **hasha@5.2.2**
* Licenses: MIT
* Repository: [https://github.com/sindresorhus/hasha](https://github.com/sindresorhus/hasha)
1. **he@1.2.0**
@@ -1744,6 +1706,9 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **is-buffer@1.1.6**
* Licenses: MIT
* Repository: [https://github.com/feross/is-buffer](https://github.com/feross/is-buffer)
+1. **is-core-module@2.1.0**
+ * Licenses: MIT
+ * Repository: [https://github.com/inspect-js/is-core-module](https://github.com/inspect-js/is-core-module)
1. **is-data-descriptor@0.1.4**
* Licenses: MIT
* Repository: [https://github.com/jonschlinkert/is-data-descriptor](https://github.com/jonschlinkert/is-data-descriptor)
@@ -1843,9 +1808,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **js-tokens@4.0.0**
* Licenses: MIT
* Repository: [https://github.com/lydell/js-tokens](https://github.com/lydell/js-tokens)
-1. **js-yaml@3.13.1**
- * Licenses: MIT
- * Repository: [https://github.com/nodeca/js-yaml](https://github.com/nodeca/js-yaml)
1. **js-yaml@3.14.0**
* Licenses: MIT
* Repository: [https://github.com/nodeca/js-yaml](https://github.com/nodeca/js-yaml)
@@ -1867,6 +1829,9 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **json-parse-better-errors@1.0.2**
* Licenses: MIT
* Repository: [https://github.com/zkat/json-parse-better-errors](https://github.com/zkat/json-parse-better-errors)
+1. **json-parse-even-better-errors@2.3.1**
+ * Licenses: MIT
+ * Repository: [https://github.com/npm/json-parse-even-better-errors](https://github.com/npm/json-parse-even-better-errors)
1. **json-schema-traverse@0.4.1**
* Licenses: MIT
* Repository: [https://github.com/epoberezkin/json-schema-traverse](https://github.com/epoberezkin/json-schema-traverse)
@@ -1936,9 +1901,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **lodash.get@4.4.2**
* Licenses: MIT
* Repository: [https://github.com/lodash/lodash](https://github.com/lodash/lodash)
-1. **lodash@4.17.15**
- * Licenses: MIT
- * Repository: [https://github.com/lodash/lodash](https://github.com/lodash/lodash)
1. **lodash@4.17.20**
* Licenses: MIT
* Repository: [https://github.com/lodash/lodash](https://github.com/lodash/lodash)
@@ -2014,9 +1976,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **minimatch@3.0.4**
* Licenses: ISC
* Repository: [https://github.com/isaacs/minimatch](https://github.com/isaacs/minimatch)
-1. **minimist@0.0.8**
- * Licenses: MIT
- * Repository: [https://github.com/substack/minimist](https://github.com/substack/minimist)
1. **minimist@1.2.5**
* Licenses: MIT
* Repository: [https://github.com/substack/minimist](https://github.com/substack/minimist)
@@ -2026,9 +1985,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **mixin-deep@1.3.2**
* Licenses: MIT
* Repository: [https://github.com/jonschlinkert/mixin-deep](https://github.com/jonschlinkert/mixin-deep)
-1. **mkdirp@0.5.1**
- * Licenses: MIT
- * Repository: [https://github.com/substack/node-mkdirp](https://github.com/substack/node-mkdirp)
1. **mkdirp@0.5.5**
* Licenses: MIT
* Repository: [https://github.com/substack/node-mkdirp](https://github.com/substack/node-mkdirp)
@@ -2047,9 +2003,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **ms@2.1.2**
* Licenses: MIT
* Repository: [https://github.com/zeit/ms](https://github.com/zeit/ms)
-1. **nan@2.14.2**
- * Licenses: MIT
- * Repository: [https://github.com/nodejs/nan](https://github.com/nodejs/nan)
1. **nanoid@3.1.12**
* Licenses: MIT
* Repository: [https://github.com/ai/nanoid](https://github.com/ai/nanoid)
@@ -2062,6 +2015,9 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **nise@4.0.4**
* Licenses: BSD-3-Clause
* Repository: [https://github.com/sinonjs/nise](https://github.com/sinonjs/nise)
+1. **node-fetch@2.6.1**
+ * Licenses: MIT
+ * Repository: [https://github.com/bitinn/node-fetch](https://github.com/bitinn/node-fetch)
1. **node-forge@0.10.0**
* Licenses: (BSD-3-Clause OR GPL-2.0)
* Repository: [https://github.com/digitalbazaar/forge](https://github.com/digitalbazaar/forge)
@@ -2074,7 +2030,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **node-preload@0.2.1**
* Licenses: MIT
* Repository: [https://github.com/cfware/node-preload](https://github.com/cfware/node-preload)
-1. **node-releases@1.1.67**
+1. **node-releases@1.1.65**
* Licenses: MIT
* Repository: [https://github.com/chicoxyzzy/node-releases](https://github.com/chicoxyzzy/node-releases)
1. **nopt@4.0.3**
@@ -2134,7 +2090,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **osenv@0.1.5**
* Licenses: ISC
* Repository: [https://github.com/npm/osenv](https://github.com/npm/osenv)
-1. **p-limit@2.2.2**
+1. **p-limit@2.3.0**
* Licenses: MIT
* Repository: [https://github.com/sindresorhus/p-limit](https://github.com/sindresorhus/p-limit)
1. **p-limit@3.0.2**
@@ -2233,7 +2189,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **promise-polyfill@8.1.3**
* Licenses: MIT
* Repository: [https://github.com/taylorhakes/promise-polyfill](https://github.com/taylorhakes/promise-polyfill)
-1. **protobufjs@6.10.2**
+1. **protobufjs@6.10.1**
* Licenses: BSD-3-Clause
* Repository: [https://github.com/protobufjs/protobuf.js](https://github.com/protobufjs/protobuf.js)
1. **prr@1.0.1**
@@ -2275,7 +2231,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **read-installed@4.0.3**
* Licenses: ISC
* Repository: [https://github.com/isaacs/read-installed](https://github.com/isaacs/read-installed)
-1. **read-package-json@2.1.1**
+1. **read-package-json@2.1.2**
* Licenses: ISC
* Repository: [https://github.com/npm/read-package-json](https://github.com/npm/read-package-json)
1. **readable-stream@2.3.7**
@@ -2359,7 +2315,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **resolve-url@0.2.1**
* Licenses: MIT
* Repository: [https://github.com/lydell/resolve-url](https://github.com/lydell/resolve-url)
-1. **resolve@1.15.1**
+1. **resolve@1.18.1**
* Licenses: MIT
* Repository: [https://github.com/browserify/resolve](https://github.com/browserify/resolve)
1. **ret@0.1.15**
@@ -2428,7 +2384,7 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **shebang-regex@3.0.0**
* Licenses: MIT
* Repository: [https://github.com/sindresorhus/shebang-regex](https://github.com/sindresorhus/shebang-regex)
-1. **signal-exit@3.0.2**
+1. **signal-exit@3.0.3**
* Licenses: ISC
* Repository: [https://github.com/tapjs/signal-exit](https://github.com/tapjs/signal-exit)
1. **sinon@9.2.1**
@@ -2473,25 +2429,25 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **spdx-compare@1.0.0**
* Licenses: MIT
* Repository: [https://github.com/kemitchell/spdx-compare.js](https://github.com/kemitchell/spdx-compare.js)
-1. **spdx-correct@3.1.0**
+1. **spdx-correct@3.1.1**
* Licenses: Apache-2.0
* Repository: [https://github.com/jslicense/spdx-correct.js](https://github.com/jslicense/spdx-correct.js)
-1. **spdx-exceptions@2.2.0**
+1. **spdx-exceptions@2.3.0**
* Licenses: CC-BY-3.0
* Repository: [https://github.com/kemitchell/spdx-exceptions.json](https://github.com/kemitchell/spdx-exceptions.json)
-1. **spdx-expression-parse@3.0.0**
+1. **spdx-expression-parse@3.0.1**
* Licenses: MIT
* Repository: [https://github.com/jslicense/spdx-expression-parse.js](https://github.com/jslicense/spdx-expression-parse.js)
-1. **spdx-license-ids@3.0.5**
+1. **spdx-license-ids@3.0.6**
* Licenses: CC0-1.0
- * Repository: [https://github.com/shinnn/spdx-license-ids](https://github.com/shinnn/spdx-license-ids)
+ * Repository: [https://github.com/jslicense/spdx-license-ids](https://github.com/jslicense/spdx-license-ids)
1. **spdx-ranges@2.1.1**
* Licenses: (MIT AND CC-BY-3.0)
* Repository: [https://github.com/kemitchell/spdx-ranges.js](https://github.com/kemitchell/spdx-ranges.js)
1. **spdx-satisfies@4.0.1**
* Licenses: MIT
* Repository: [https://github.com/kemitchell/spdx-satisfies.js](https://github.com/kemitchell/spdx-satisfies.js)
-1. **spine-web@1.6.15**
+1. **spine-web@1.6.16**
* Licenses: Apache-2.0
* Repository: [https://github.com/SpineEventEngine/web](https://github.com/SpineEventEngine/web)
1. **split-string@3.1.0**
@@ -2563,9 +2519,6 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **supports-color@5.5.0**
* Licenses: MIT
* Repository: [https://github.com/chalk/supports-color](https://github.com/chalk/supports-color)
-1. **supports-color@7.1.0**
- * Licenses: MIT
- * Repository: [https://github.com/chalk/supports-color](https://github.com/chalk/supports-color)
1. **supports-color@7.2.0**
* Licenses: MIT
* Repository: [https://github.com/chalk/supports-color](https://github.com/chalk/supports-color)
@@ -2710,10 +2663,10 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **vm-browserify@1.1.2**
* Licenses: MIT
* Repository: [https://github.com/substack/vm-browserify](https://github.com/substack/vm-browserify)
-1. **watchpack-chokidar2@2.0.1**
+1. **watchpack-chokidar2@2.0.0**
* Licenses: MIT
* Repository: [https://github.com/webpack/watchpack](https://github.com/webpack/watchpack)
-1. **watchpack@1.7.5**
+1. **watchpack@1.7.4**
* Licenses: MIT
* Repository: [https://github.com/webpack/watchpack](https://github.com/webpack/watchpack)
1. **webpack-cli@4.2.0**
@@ -2797,17 +2750,17 @@ This report was generated on **Mon Nov 23 17:08:56 EET 2020** using [Gradle-Lice
1. **yargs@13.3.2**
* Licenses: MIT
* Repository: [https://github.com/yargs/yargs](https://github.com/yargs/yargs)
-1. **yargs@15.3.1**
+1. **yargs@15.4.1**
* Licenses: MIT
* Repository: [https://github.com/yargs/yargs](https://github.com/yargs/yargs)
-This report was generated on **Mon Nov 23 2020 17:08:57 GMT+0200 (Eastern European Standard Time)** using [NPM License Checker](https://github.com/davglass/license-checker) library.
+This report was generated on **Mon Dec 07 2020 12:28:06 GMT+0200 (Eastern European Standard Time)** using [NPM License Checker](https://github.com/davglass/license-checker) library.
-# Dependencies of `io.spine.gcloud:spine-firebase-web:1.6.15`
+# Dependencies of `io.spine.gcloud:spine-firebase-web:1.6.16`
## Runtime
1. **Group:** com.fasterxml.jackson.core **Name:** jackson-annotations **Version:** 2.9.10
@@ -2908,9 +2861,6 @@ This report was generated on **Mon Nov 23 2020 17:08:57 GMT+0200 (Eastern Europe
1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.4.0
* **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.4.0
- * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** com.google.firebase **Name:** firebase-admin **Version:** 6.12.2
* **POM Project URL:** [https://firebase.google.com/](https://firebase.google.com/)
* **POM License: Apache License, Version 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -3433,12 +3383,6 @@ This report was generated on **Mon Nov 23 2020 17:08:57 GMT+0200 (Eastern Europe
* **POM Project URL:** [https://github.com/trustin/os-maven-plugin/](https://github.com/trustin/os-maven-plugin/)
* **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
-1. **Group:** net.bytebuddy **Name:** byte-buddy **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-1. **Group:** net.bytebuddy **Name:** byte-buddy-agent **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** net.java.dev.javacc **Name:** javacc **Version:** 5.0
* **POM Project URL:** [https://javacc.dev.java.net/](https://javacc.dev.java.net/)
* **POM License: Berkeley Software Distribution (BSD) License** - [http://www.opensource.org/licenses/bsd-license.html](http://www.opensource.org/licenses/bsd-license.html)
@@ -3493,9 +3437,6 @@ This report was generated on **Mon Nov 23 2020 17:08:57 GMT+0200 (Eastern Europe
* **POM License: MIT license** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** org.hamcrest **Name:** hamcrest-all **Version:** 1.3
- * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
-
1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3
* **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
@@ -3532,14 +3473,6 @@ This report was generated on **Mon Nov 23 2020 17:08:57 GMT+0200 (Eastern Europe
* **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/)
* **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html)
-1. **Group:** org.mockito **Name:** mockito-core **Version:** 2.12.0
- * **POM Project URL:** [https://github.com/mockito/mockito](https://github.com/mockito/mockito)
- * **POM License: The MIT License** - [https://github.com/mockito/mockito/blob/master/LICENSE](https://github.com/mockito/mockito/blob/master/LICENSE)
-
-1. **Group:** org.objenesis **Name:** objenesis **Version:** 2.6
- * **POM Project URL:** [http://objenesis.org](http://objenesis.org)
- * **POM License: Apache 2** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0
* **Manifest License:** The Apache License, Version 2.0 (Not packaged)
* **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j)
@@ -3614,12 +3547,12 @@ This report was generated on **Mon Nov 23 2020 17:08:57 GMT+0200 (Eastern Europe
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Mon Nov 23 17:09:07 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Mon Dec 07 12:13:51 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
-# Dependencies of `io.spine:spine-js-tests:1.6.15`
+# Dependencies of `io.spine:spine-js-tests:1.6.16`
## Runtime
1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -3629,9 +3562,6 @@ This report was generated on **Mon Nov 23 17:09:07 EET 2020** using [Gradle-Lice
1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.4.0
* **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.4.0
- * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** com.google.guava **Name:** failureaccess **Version:** 1.0.1
* **Manifest Project URL:** [https://github.com/google/guava/](https://github.com/google/guava/)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -3853,12 +3783,6 @@ This report was generated on **Mon Nov 23 17:09:07 EET 2020** using [Gradle-Lice
* **POM Project URL:** [http://junit.org](http://junit.org)
* **POM License: Eclipse Public License 1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html)
-1. **Group:** net.bytebuddy **Name:** byte-buddy **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-1. **Group:** net.bytebuddy **Name:** byte-buddy-agent **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** net.java.dev.javacc **Name:** javacc **Version:** 5.0
* **POM Project URL:** [https://javacc.dev.java.net/](https://javacc.dev.java.net/)
* **POM License: Berkeley Software Distribution (BSD) License** - [http://www.opensource.org/licenses/bsd-license.html](http://www.opensource.org/licenses/bsd-license.html)
@@ -3913,9 +3837,6 @@ This report was generated on **Mon Nov 23 17:09:07 EET 2020** using [Gradle-Lice
* **POM License: MIT license** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** org.hamcrest **Name:** hamcrest-all **Version:** 1.3
- * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
-
1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3
* **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
@@ -3952,14 +3873,6 @@ This report was generated on **Mon Nov 23 17:09:07 EET 2020** using [Gradle-Lice
* **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/)
* **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html)
-1. **Group:** org.mockito **Name:** mockito-core **Version:** 2.12.0
- * **POM Project URL:** [https://github.com/mockito/mockito](https://github.com/mockito/mockito)
- * **POM License: The MIT License** - [https://github.com/mockito/mockito/blob/master/LICENSE](https://github.com/mockito/mockito/blob/master/LICENSE)
-
-1. **Group:** org.objenesis **Name:** objenesis **Version:** 2.6
- * **POM Project URL:** [http://objenesis.org](http://objenesis.org)
- * **POM License: Apache 2** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0
* **Manifest License:** The Apache License, Version 2.0 (Not packaged)
* **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j)
@@ -4029,12 +3942,12 @@ This report was generated on **Mon Nov 23 17:09:07 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Mon Nov 23 17:09:22 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Mon Dec 07 12:14:00 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
-# Dependencies of `io.spine:spine-test-app:1.6.15`
+# Dependencies of `io.spine:spine-test-app:1.6.16`
## Runtime
1. **Group:** com.fasterxml.jackson.core **Name:** jackson-annotations **Version:** 2.9.10
@@ -4135,9 +4048,6 @@ This report was generated on **Mon Nov 23 17:09:22 EET 2020** using [Gradle-Lice
1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.4.0
* **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.4.0
- * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** com.google.firebase **Name:** firebase-admin **Version:** 6.12.2
* **POM Project URL:** [https://firebase.google.com/](https://firebase.google.com/)
* **POM License: Apache License, Version 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -4724,12 +4634,6 @@ This report was generated on **Mon Nov 23 17:09:22 EET 2020** using [Gradle-Lice
* **POM Project URL:** [https://github.com/trustin/os-maven-plugin/](https://github.com/trustin/os-maven-plugin/)
* **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
-1. **Group:** net.bytebuddy **Name:** byte-buddy **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-1. **Group:** net.bytebuddy **Name:** byte-buddy-agent **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** net.java.dev.javacc **Name:** javacc **Version:** 5.0
* **POM Project URL:** [https://javacc.dev.java.net/](https://javacc.dev.java.net/)
* **POM License: Berkeley Software Distribution (BSD) License** - [http://www.opensource.org/licenses/bsd-license.html](http://www.opensource.org/licenses/bsd-license.html)
@@ -5416,9 +5320,6 @@ This report was generated on **Mon Nov 23 17:09:22 EET 2020** using [Gradle-Lice
* **POM Project URL:** [https://github.com/gretty-gradle-plugin/gretty](https://github.com/gretty-gradle-plugin/gretty)
* **POM License: MIT** - [https://raw.github.com/gretty-gradle-plugin/gretty/master/LICENSE](https://raw.github.com/gretty-gradle-plugin/gretty/master/LICENSE)
-1. **Group:** org.hamcrest **Name:** hamcrest-all **Version:** 1.3
- * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
-
1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3
* **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
@@ -5455,10 +5356,6 @@ This report was generated on **Mon Nov 23 17:09:22 EET 2020** using [Gradle-Lice
* **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/)
* **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html)
-1. **Group:** org.mockito **Name:** mockito-core **Version:** 2.12.0
- * **POM Project URL:** [https://github.com/mockito/mockito](https://github.com/mockito/mockito)
- * **POM License: The MIT License** - [https://github.com/mockito/mockito/blob/master/LICENSE](https://github.com/mockito/mockito/blob/master/LICENSE)
-
1. **Group:** org.mortbay.jasper **Name:** apache-el **Version:** 8.0.33
* **Manifest Project URL:** [http://webtide.com](http://webtide.com)
* **POM License: Apache License Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
@@ -5477,10 +5374,6 @@ This report was generated on **Mon Nov 23 17:09:22 EET 2020** using [Gradle-Lice
1. **Group:** org.mortbay.jasper **Name:** apache-jsp **Version:** 8.5.40
* **POM License: Apache License Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
-1. **Group:** org.objenesis **Name:** objenesis **Version:** 2.6
- * **POM Project URL:** [http://objenesis.org](http://objenesis.org)
- * **POM License: Apache 2** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0
* **Manifest License:** The Apache License, Version 2.0 (Not packaged)
* **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j)
@@ -5628,12 +5521,12 @@ This report was generated on **Mon Nov 23 17:09:22 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Mon Dec 07 12:14:05 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
-# Dependencies of `io.spine:spine-testutil-web:1.6.15`
+# Dependencies of `io.spine:spine-testutil-web:1.6.16`
## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -5654,9 +5547,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.4.0
* **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.4.0
- * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** com.google.flogger **Name:** flogger **Version:** 0.5.1
* **POM Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger)
* **POM License: Apache 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -5944,12 +5834,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
* **POM Project URL:** [http://junit.org](http://junit.org)
* **POM License: Eclipse Public License 1.0** - [http://www.eclipse.org/legal/epl-v10.html](http://www.eclipse.org/legal/epl-v10.html)
-1. **Group:** net.bytebuddy **Name:** byte-buddy **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-1. **Group:** net.bytebuddy **Name:** byte-buddy-agent **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** net.java.dev.javacc **Name:** javacc **Version:** 5.0
* **POM Project URL:** [https://javacc.dev.java.net/](https://javacc.dev.java.net/)
* **POM License: Berkeley Software Distribution (BSD) License** - [http://www.opensource.org/licenses/bsd-license.html](http://www.opensource.org/licenses/bsd-license.html)
@@ -6004,9 +5888,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
* **POM License: MIT license** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** org.hamcrest **Name:** hamcrest-all **Version:** 1.3
- * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
-
1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3
* **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
@@ -6043,14 +5924,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
* **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/)
* **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html)
-1. **Group:** org.mockito **Name:** mockito-core **Version:** 2.12.0
- * **POM Project URL:** [https://github.com/mockito/mockito](https://github.com/mockito/mockito)
- * **POM License: The MIT License** - [https://github.com/mockito/mockito/blob/master/LICENSE](https://github.com/mockito/mockito/blob/master/LICENSE)
-
-1. **Group:** org.objenesis **Name:** objenesis **Version:** 2.6
- * **POM Project URL:** [http://objenesis.org](http://objenesis.org)
- * **POM License: Apache 2** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0
* **Manifest License:** The Apache License, Version 2.0 (Not packaged)
* **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j)
@@ -6112,12 +5985,12 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
+This report was generated on **Mon Dec 07 12:14:05 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
-# Dependencies of `io.spine:spine-web:1.6.15`
+# Dependencies of `io.spine:spine-web:1.6.16`
## Runtime
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -6138,9 +6011,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
1. **Group:** com.google.errorprone **Name:** error_prone_annotations **Version:** 2.4.0
* **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** com.google.errorprone **Name:** error_prone_type_annotations **Version:** 2.4.0
- * **POM License: Apache 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** com.google.flogger **Name:** flogger **Version:** 0.5.1
* **POM Project URL:** [https://github.com/google/flogger](https://github.com/google/flogger)
* **POM License: Apache 2.0** - [https://www.apache.org/licenses/LICENSE-2.0.txt](https://www.apache.org/licenses/LICENSE-2.0.txt)
@@ -6467,12 +6337,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
* **POM Project URL:** [https://github.com/trustin/os-maven-plugin/](https://github.com/trustin/os-maven-plugin/)
* **POM License: Apache License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
-1. **Group:** net.bytebuddy **Name:** byte-buddy **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
-1. **Group:** net.bytebuddy **Name:** byte-buddy-agent **Version:** 1.7.9
- * **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** net.java.dev.javacc **Name:** javacc **Version:** 5.0
* **POM Project URL:** [https://javacc.dev.java.net/](https://javacc.dev.java.net/)
* **POM License: Berkeley Software Distribution (BSD) License** - [http://www.opensource.org/licenses/bsd-license.html](http://www.opensource.org/licenses/bsd-license.html)
@@ -6527,9 +6391,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
* **POM License: MIT license** - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php)
* **POM License: The Apache Software License, Version 2.0** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-1. **Group:** org.hamcrest **Name:** hamcrest-all **Version:** 1.3
- * **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
-
1. **Group:** org.hamcrest **Name:** hamcrest-core **Version:** 1.3
* **POM License: New BSD License** - [http://www.opensource.org/licenses/bsd-license.php](http://www.opensource.org/licenses/bsd-license.php)
@@ -6566,14 +6427,6 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
* **POM Project URL:** [https://junit.org/junit5/](https://junit.org/junit5/)
* **POM License: Eclipse Public License v2.0** - [https://www.eclipse.org/legal/epl-v20.html](https://www.eclipse.org/legal/epl-v20.html)
-1. **Group:** org.mockito **Name:** mockito-core **Version:** 2.12.0
- * **POM Project URL:** [https://github.com/mockito/mockito](https://github.com/mockito/mockito)
- * **POM License: The MIT License** - [https://github.com/mockito/mockito/blob/master/LICENSE](https://github.com/mockito/mockito/blob/master/LICENSE)
-
-1. **Group:** org.objenesis **Name:** objenesis **Version:** 2.6
- * **POM Project URL:** [http://objenesis.org](http://objenesis.org)
- * **POM License: Apache 2** - [http://www.apache.org/licenses/LICENSE-2.0.txt](http://www.apache.org/licenses/LICENSE-2.0.txt)
-
1. **Group:** org.opentest4j **Name:** opentest4j **Version:** 1.2.0
* **Manifest License:** The Apache License, Version 2.0 (Not packaged)
* **POM Project URL:** [https://github.com/ota4j-team/opentest4j](https://github.com/ota4j-team/opentest4j)
@@ -6635,4 +6488,4 @@ This report was generated on **Mon Nov 23 17:10:40 EET 2020** using [Gradle-Lice
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
-This report was generated on **Mon Nov 23 17:10:42 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
+This report was generated on **Mon Dec 07 12:14:08 EET 2020** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 46524fd98..3236299c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject.
io.spine
spine-web
-1.6.15
+1.6.16
2015
@@ -31,18 +31,6 @@ all modules and does not describe the project structure per-subproject.
2.9.10.5
compile
-
- com.google.errorprone
- error_prone_annotations
- 2.4.0
- compile
-
-
- com.google.errorprone
- error_prone_type_annotations
- 2.4.0
- compile
-
com.google.firebase
firebase-admin
@@ -70,13 +58,7 @@ all modules and does not describe the project structure per-subproject.
io.spine
spine-server
- 1.6.15
- compile
-
-
- org.checkerframework
- checker-qual
- 3.7.1
+ 1.6.18
compile
@@ -91,16 +73,34 @@ all modules and does not describe the project structure per-subproject.
30.0-jre
test
+
+ com.google.truth
+ truth
+ 1.1
+ test
+
+
+ com.google.truth.extensions
+ truth-java8-extension
+ 1.1
+ test
+
+
+ com.google.truth.extensions
+ truth-proto-extension
+ 1.1
+ test
+
io.spine
spine-testutil-client
- 1.6.15
+ 1.6.18
test
io.spine.tools
spine-mute-logging
- 1.6.13
+ 1.6.16
test
@@ -109,12 +109,6 @@ all modules and does not describe the project structure per-subproject.
1.1.0
test
-
- org.hamcrest
- hamcrest-all
- 1.3
- test
-
org.junit.jupiter
junit-jupiter-api
@@ -133,12 +127,6 @@ all modules and does not describe the project structure per-subproject.
5.7.0
test
-
- org.mockito
- mockito-core
- 2.12.0
- test
-
com.google.errorprone
error_prone_core
@@ -162,22 +150,17 @@ all modules and does not describe the project structure per-subproject.
io.spine
spine-client
- 1.6.15
-
-
- io.spine.tools
- spine-errorprone-checks
- 1.6.13
+ 1.6.18
io.spine.tools
spine-javadoc-filter
- 1.6.13
+ 1.6.16
io.spine.tools
spine-protoc-plugin
- 1.6.13
+ 1.6.16
javax.servlet
diff --git a/testutil-web/build.gradle.kts b/testutil-web/build.gradle.kts
index 3cd25f3ee..bb03c2b26 100644
--- a/testutil-web/build.gradle.kts
+++ b/testutil-web/build.gradle.kts
@@ -19,5 +19,5 @@
*/
dependencies {
- implementation(project(":web"))
+ api(project(":web"))
}
diff --git a/testutil-web/src/main/java/io/spine/web/given/KnownRequest.java b/testutil-web/src/main/java/io/spine/web/given/KnownRequest.java
new file mode 100644
index 000000000..a42182c77
--- /dev/null
+++ b/testutil-web/src/main/java/io/spine/web/given/KnownRequest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.web.given;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.net.MediaType;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterators.asEnumeration;
+import static com.google.common.collect.Iterators.singletonIterator;
+import static java.util.Collections.emptyIterator;
+
+/**
+ * A mocked servlet request with pre-defined {@code content}, {@code type} and {@code headers}.
+ *
+ * @implNote The request is effectively immutable and does not pay attention to any
+ * modification attempts. Such a mocked implementation may be used for tests where
+ * one do not care if anything may be adjusted in the request while the request
+ * is being processed.
+ */
+@SuppressWarnings("UnstableApiUsage") // we're OK using Guava's beta APIs
+public final class KnownRequest implements MockedRequest {
+
+ private static final String CONTENT_TYPE = "Content-Type";
+
+ private final ImmutableMap headers;
+ private final byte[] content;
+ private final MediaType type;
+
+ private KnownRequest(ImmutableMap headers, byte[] content, MediaType type) {
+ this.headers = headers;
+ this.content = content;
+ this.type = type;
+ }
+
+ /**
+ * Creates a new mocked request with specified {@code content} and default
+ * {@linkplain MediaType#ANY_TYPE any} type.
+ */
+ public static KnownRequest create(String content) {
+ checkNotNull(content);
+ return create(content, MediaType.ANY_TYPE);
+ }
+
+ /**
+ * Creates a new mocked request with specified {@code content} and {@code type}.
+ */
+ public static KnownRequest create(String content, MediaType type) {
+ checkNotNull(content);
+ checkNotNull(type);
+ return create(content, type, contentTypeHeader(type));
+ }
+
+ /**
+ * Creates a new mocked request with specified {@code content}, {@code type}
+ * and {@code headers}.
+ */
+ public static KnownRequest create(String content,
+ MediaType type,
+ ImmutableMap headers) {
+ checkNotNull(content);
+ checkNotNull(type);
+ checkNotNull(headers);
+ return create(content.getBytes(StandardCharsets.UTF_8), type, headers);
+ }
+
+ /**
+ * Creates a new mocked request with specified {@code content}, {@code type}
+ * and {@code headers}.
+ */
+ public static KnownRequest create(byte[] content,
+ MediaType type,
+ ImmutableMap headers) {
+ checkNotNull(content);
+ checkNotNull(type);
+ checkNotNull(headers);
+ return new KnownRequest(headers, content, type);
+ }
+
+ private static ImmutableMap contentTypeHeader(MediaType type) {
+ return ImmutableMap.of(CONTENT_TYPE, type.toString());
+ }
+
+ @Override
+ public @Nullable String getHeader(String name) {
+ return headers.get(name);
+ }
+
+ @Override
+ public Enumeration getHeaders(String name) {
+ String result = headers.get(name);
+ if (result == null) {
+ return asEnumeration(emptyIterator());
+ }
+ return asEnumeration(singletonIterator(result));
+ }
+
+ @Override
+ public Enumeration getHeaderNames() {
+ ImmutableSet names = headers.keySet();
+ return asEnumeration(names.iterator());
+ }
+
+ @Override
+ public int getContentLength() {
+ return content.length;
+ }
+
+ @Override
+ public long getContentLengthLong() {
+ return content.length;
+ }
+
+ @Override
+ public @Nullable String getContentType() {
+ return type.toString();
+ }
+
+ @Override
+ public BufferedReader getReader() {
+ return new BufferedReader(
+ new InputStreamReader(
+ new ByteArrayInputStream(content), StandardCharsets.UTF_8
+ )
+ );
+ }
+}
diff --git a/testutil-web/src/main/java/io/spine/web/given/KnownResponse.java b/testutil-web/src/main/java/io/spine/web/given/KnownResponse.java
new file mode 100644
index 000000000..1d2b56126
--- /dev/null
+++ b/testutil-web/src/main/java/io/spine/web/given/KnownResponse.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.web.given;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.io.PrintWriter;
+import java.io.Writer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A mocked servlet response with pre-defined {@code writer}, {@code status} and {@code headers}.
+ *
+ * @implNote The response is effectively immutable and does not pay attention to any
+ * modification attempts. Such a mocked implementation may be used for tests where
+ * one do not care if anything may be adjusted in the response while the response
+ * is being created.
+ * See {@linkplain MemoizingResponse memoizing response} if mutability is required.
+ */
+public final class KnownResponse implements MockedResponse {
+
+ private final ImmutableMap headers;
+ private final int status;
+ private final Writer writer;
+
+ private KnownResponse(ImmutableMap headers, Writer writer, int status) {
+ this.headers = headers;
+ this.writer = writer;
+ this.status = status;
+ }
+
+ /**
+ * Creates a new mocked response with specified {@code writer} and default
+ * {@linkplain #SC_OK OK} status.
+ */
+ public static KnownResponse create(Writer writer) {
+ checkNotNull(writer);
+ return create(writer, SC_OK);
+ }
+
+ /**
+ * Creates a new mocked response with specified {@code writer} and {@code status}.
+ */
+ public static KnownResponse create(Writer writer, int status) {
+ checkNotNull(writer);
+ return create(writer, status, ImmutableMap.of());
+ }
+
+ /**
+ * Creates a new mocked response with specified {@code writer}, {@code status}
+ * and {@code headers}.
+ */
+ public static KnownResponse create(Writer writer,
+ int status,
+ ImmutableMap headers) {
+ checkNotNull(writer);
+ checkNotNull(headers);
+ return new KnownResponse(headers, writer, status);
+ }
+
+ @Override
+ public int getStatus() {
+ return status;
+ }
+
+ @Override
+ public @Nullable String getHeader(String name) {
+ return headers.get(name);
+ }
+
+ @Override
+ public ImmutableSet getHeaders(String name) {
+ String result = headers.get(name);
+ if (result == null) {
+ return ImmutableSet.of();
+ }
+ return ImmutableSet.of(result);
+ }
+
+ @Override
+ public ImmutableSet getHeaderNames() {
+ return headers.keySet();
+ }
+
+ @Override
+ public PrintWriter getWriter() {
+ return new PrintWriter(writer);
+ }
+}
diff --git a/testutil-web/src/main/java/io/spine/web/given/MemoizingResponse.java b/testutil-web/src/main/java/io/spine/web/given/MemoizingResponse.java
new file mode 100644
index 000000000..0372dcdcb
--- /dev/null
+++ b/testutil-web/src/main/java/io/spine/web/given/MemoizingResponse.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.web.given;
+
+import com.google.common.collect.ImmutableSet;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A mocked response that attempts to save all the actions done to it.
+ *
+ * @implNote The response mutates its state and holds the latest changes. Such an
+ * implementation may be useful to verify that e.g. a particular error code was set
+ * to the response or a particular content was written.
+ * See {@linkplain KnownResponse known response} if an immutable implementation is required.
+ */
+public final class MemoizingResponse implements MockedResponse {
+
+ private final StringWriter writer = new StringWriter();
+ private final Map headers = new HashMap<>();
+ private String contentType = "";
+ private int status = -1;
+
+ @Override
+ public int getStatus() {
+ return status;
+ }
+
+ @Override
+ public @Nullable String getHeader(String name) {
+ return headers.get(name);
+ }
+
+ @Override
+ public void addHeader(String name, String value) {
+ headers.put(name, value);
+ }
+
+ @Override
+ public void sendError(int sc) {
+ status = sc;
+ }
+
+ @Override
+ public void sendError(int sc, String msg) {
+ sendError(sc);
+ }
+
+ @Override
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ @Override
+ public @Nullable String getContentType() {
+ return contentType;
+ }
+
+ @Override
+ public ImmutableSet getHeaders(String name) {
+ String result = headers.get(name);
+ if (result == null) {
+ return ImmutableSet.of();
+ }
+ return ImmutableSet.of(result);
+ }
+
+ @Override
+ public Set getHeaderNames() {
+ return headers.keySet();
+ }
+
+ @Override
+ public PrintWriter getWriter() {
+ return new PrintWriter(writer);
+ }
+
+ /**
+ * Returns the content of the associated response writer.
+ */
+ public String writerContent() {
+ return writer.toString();
+ }
+}
diff --git a/testutil-web/src/main/java/io/spine/web/given/MockedRequest.java b/testutil-web/src/main/java/io/spine/web/given/MockedRequest.java
new file mode 100644
index 000000000..333e46ee2
--- /dev/null
+++ b/testutil-web/src/main/java/io/spine/web/given/MockedRequest.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2000-2020 TeamDev Ltd. All rights reserved.
+ * TeamDev PROPRIETARY and CONFIDENTIAL.
+ * Use is subject to license terms.
+ */
+
+package io.spine.web.given;
+
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpUpgradeHandler;
+import javax.servlet.http.Part;
+import java.io.BufferedReader;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * A mocked no-op servlet request.
+ *
+ * @apiNote Some of the methods are marked as {@linkplain Deprecated deprecated} to avoid
+ * the deprecation warnings, as their {@code super} methods are marked as such.
+ */
+@SuppressWarnings("PMD.UncommentedEmptyMethodBody") // default implementations are empty on purpose.
+public interface MockedRequest extends HttpServletRequest {
+
+ @Override
+ default @Nullable String getRequestURI() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getAuthType() {
+ return null;
+ }
+
+ @Override
+ @SuppressWarnings("ReturnOfNull") // we're explicitly returning `null`.
+ default @Nullable Cookie[] getCookies() {
+ return null;
+ }
+
+ @Override
+ default long getDateHeader(String name) {
+ return 0;
+ }
+
+ @Override
+ default @Nullable String getHeader(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Enumeration getHeaders(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Enumeration getHeaderNames() {
+ return null;
+ }
+
+ @Override
+ default int getIntHeader(String name) {
+ return 0;
+ }
+
+ @Override
+ default @Nullable String getMethod() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getPathInfo() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getPathTranslated() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getContextPath() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getQueryString() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getRemoteUser() {
+ return null;
+ }
+
+ @Override
+ default boolean isUserInRole(String role) {
+ return false;
+ }
+
+ @Override
+ default @Nullable Principal getUserPrincipal() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getRequestedSessionId() {
+ return null;
+ }
+
+ @Override
+ default @Nullable StringBuffer getRequestURL() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getServletPath() {
+ return null;
+ }
+
+ @Override
+ default @Nullable HttpSession getSession(boolean create) {
+ return null;
+ }
+
+ @Override
+ default @Nullable HttpSession getSession() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String changeSessionId() {
+ return null;
+ }
+
+ @Override
+ default boolean isRequestedSessionIdValid() {
+ return false;
+ }
+
+ @Override
+ default boolean isRequestedSessionIdFromCookie() {
+ return false;
+ }
+
+ @Override
+ default boolean isRequestedSessionIdFromURL() {
+ return false;
+ }
+
+ @Deprecated
+ @Override
+ default boolean isRequestedSessionIdFromUrl() {
+ return false;
+ }
+
+ @Override
+ default boolean authenticate(HttpServletResponse response) {
+ return false;
+ }
+
+ @Override
+ default void login(String username, String password) {
+ }
+
+ @Override
+ default void logout() {
+ }
+
+ @Override
+ default @Nullable Collection getParts() {
+ return null;
+ }
+
+ @Override
+ default @Nullable Part getPart(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable T upgrade(Class handlerClass) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Object getAttribute(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Enumeration getAttributeNames() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getCharacterEncoding() {
+ return null;
+ }
+
+ @Override
+ default void setCharacterEncoding(String env) {
+ }
+
+ @Override
+ default int getContentLength() {
+ return 0;
+ }
+
+ @Override
+ default long getContentLengthLong() {
+ return 0;
+ }
+
+ @Override
+ default @Nullable String getContentType() {
+ return null;
+ }
+
+ @Override
+ default @Nullable ServletInputStream getInputStream() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getParameter(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Enumeration getParameterNames() {
+ return null;
+ }
+
+ @Override
+ @SuppressWarnings("ReturnOfNull") // we're explicitly returning `null`.
+ default @Nullable String[] getParameterValues(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Map getParameterMap() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getProtocol() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getScheme() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getServerName() {
+ return null;
+ }
+
+ @Override
+ default int getServerPort() {
+ return 0;
+ }
+
+ @Override
+ default @Nullable BufferedReader getReader() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getRemoteAddr() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getRemoteHost() {
+ return null;
+ }
+
+ @Override
+ default void setAttribute(String name, Object o) {
+ }
+
+ @Override
+ default void removeAttribute(String name) {
+ }
+
+ @Override
+ default @Nullable Locale getLocale() {
+ return null;
+ }
+
+ @Override
+ default @Nullable Enumeration getLocales() {
+ return null;
+ }
+
+ @Override
+ default boolean isSecure() {
+ return false;
+ }
+
+ @Override
+ default @Nullable RequestDispatcher getRequestDispatcher(String path) {
+ return null;
+ }
+
+ @Deprecated
+ @Override
+ default @Nullable String getRealPath(String path) {
+ return null;
+ }
+
+ @Override
+ default int getRemotePort() {
+ return 0;
+ }
+
+ @Override
+ default @Nullable String getLocalName() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getLocalAddr() {
+ return null;
+ }
+
+ @Override
+ default int getLocalPort() {
+ return 0;
+ }
+
+ @Override
+ default @Nullable ServletContext getServletContext() {
+ return null;
+ }
+
+ @Override
+ default @Nullable AsyncContext startAsync() throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ default @Nullable AsyncContext
+ startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
+ throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ default boolean isAsyncStarted() {
+ return false;
+ }
+
+ @Override
+ default boolean isAsyncSupported() {
+ return false;
+ }
+
+ @Override
+ default @Nullable AsyncContext getAsyncContext() {
+ return null;
+ }
+
+ @Override
+ default @Nullable DispatcherType getDispatcherType() {
+ return null;
+ }
+}
diff --git a/testutil-web/src/main/java/io/spine/web/given/MockedResponse.java b/testutil-web/src/main/java/io/spine/web/given/MockedResponse.java
new file mode 100644
index 000000000..c09e6c8c4
--- /dev/null
+++ b/testutil-web/src/main/java/io/spine/web/given/MockedResponse.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2000-2020 TeamDev Ltd. All rights reserved.
+ * TeamDev PROPRIETARY and CONFIDENTIAL.
+ * Use is subject to license terms.
+ */
+
+package io.spine.web.given;
+
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Locale;
+
+/**
+ * A mocked no-op servlet response.
+ *
+ * @apiNote Some of the methods are marked as {@linkplain Deprecated deprecated} to avoid
+ * the deprecation warnings, as their {@code super} methods are marked as such.
+ */
+@SuppressWarnings("PMD.UncommentedEmptyMethodBody") // default implementations are empty on purpose.
+public interface MockedResponse extends HttpServletResponse {
+
+ @Override
+ default int getStatus() {
+ return 0;
+ }
+
+ @Override
+ default void addCookie(Cookie cookie) {
+ }
+
+ @Override
+ default boolean containsHeader(String name) {
+ return false;
+ }
+
+ @Override
+ default @Nullable String encodeURL(String url) {
+ return null;
+ }
+
+ @Override
+ default @Nullable String encodeRedirectURL(String url) {
+ return null;
+ }
+
+ @Deprecated
+ @Override
+ default @Nullable String encodeUrl(String url) {
+ return null;
+ }
+
+ @Deprecated
+ @Override
+ default @Nullable String encodeRedirectUrl(String url) {
+ return null;
+ }
+
+ @Override
+ default void sendError(int sc, String msg) {
+ }
+
+ @Override
+ default void sendError(int sc) {
+ }
+
+ @Override
+ default void sendRedirect(String location) {
+ }
+
+ @Override
+ default void setDateHeader(String name, long date) {
+ }
+
+ @Override
+ default void addDateHeader(String name, long date) {
+ }
+
+ @Override
+ default void setHeader(String name, String value) {
+ }
+
+ @Override
+ default void addHeader(String name, String value) {
+ }
+
+ @Override
+ default void setIntHeader(String name, int value) {
+ }
+
+ @Override
+ default void addIntHeader(String name, int value) {
+ }
+
+ @Override
+ default void setStatus(int sc) {
+ }
+
+ @Deprecated
+ @Override
+ default void setStatus(int sc, String sm) {
+ }
+
+ @Override
+ default @Nullable String getHeader(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Collection getHeaders(String name) {
+ return null;
+ }
+
+ @Override
+ default @Nullable Collection getHeaderNames() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getCharacterEncoding() {
+ return null;
+ }
+
+ @Override
+ default @Nullable String getContentType() {
+ return null;
+ }
+
+ @Override
+ default @Nullable ServletOutputStream getOutputStream() {
+ return null;
+ }
+
+ @Override
+ default @Nullable PrintWriter getWriter() {
+ return null;
+ }
+
+ @Override
+ default void setCharacterEncoding(String charset) {
+ }
+
+ @Override
+ default void setContentLength(int len) {
+ }
+
+ @Override
+ default void setContentLengthLong(long len) {
+ }
+
+ @Override
+ default void setContentType(String type) {
+ }
+
+ @Override
+ default void setBufferSize(int size) {
+ }
+
+ @Override
+ default int getBufferSize() {
+ return 0;
+ }
+
+ @Override
+ default void flushBuffer() {
+ }
+
+ @Override
+ default void resetBuffer() {
+ }
+
+ @Override
+ default boolean isCommitted() {
+ return false;
+ }
+
+ @Override
+ default void reset() {
+ }
+
+ @Override
+ default void setLocale(Locale loc) {
+ }
+
+ @Override
+ default @Nullable Locale getLocale() {
+ return null;
+ }
+}
diff --git a/testutil-web/src/test/java/io/spine/web/given/KnownRequestTest.java b/testutil-web/src/test/java/io/spine/web/given/KnownRequestTest.java
new file mode 100644
index 000000000..fea3f3316
--- /dev/null
+++ b/testutil-web/src/test/java/io/spine/web/given/KnownRequestTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.web.given;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.net.MediaType;
+import com.google.common.testing.NullPointerTester;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@DisplayName("`KnownRequest` should")
+class KnownRequestTest {
+
+ @Test
+ @DisplayName("not tolerate `null`s")
+ void notTolerateNull() {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicStaticMethods(KnownRequest.class);
+ }
+
+ @Test
+ @DisplayName("return set values")
+ @SuppressWarnings("JdkObsolete") // we're force to follow the contract
+ void returnSetValues() throws IOException {
+ String text = "some text";
+ MediaType type = MediaType.PLAIN_TEXT_UTF_8;
+ String headerName = "custom";
+ String headerValue = "header";
+ ImmutableMap headers = ImmutableMap.of(headerName, headerValue);
+ KnownRequest request = KnownRequest.create(text, type, headers);
+ assertThat(request.getContentLength())
+ .isEqualTo(text.length());
+ assertThat(request.getContentLengthLong())
+ .isEqualTo(text.length());
+ assertThat(request.getHeader(headerName))
+ .isEqualTo(headerValue);
+ assertThat(request.getHeaders(headerName)
+ .nextElement())
+ .isEqualTo(headerValue);
+ assertThat(request.getHeaders("non-existing")
+ .hasMoreElements())
+ .isFalse();
+ assertThat(request.getContentType())
+ .isEqualTo(type.toString());
+ assertThat(request.getReader()
+ .readLine())
+ .isEqualTo(text);
+ }
+}
diff --git a/testutil-web/src/test/java/io/spine/web/given/KnownResponseTest.java b/testutil-web/src/test/java/io/spine/web/given/KnownResponseTest.java
new file mode 100644
index 000000000..58f4c4f7b
--- /dev/null
+++ b/testutil-web/src/test/java/io/spine/web/given/KnownResponseTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.web.given;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.NullPointerTester;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static javax.servlet.http.HttpServletResponse.SC_ACCEPTED;
+
+@DisplayName("`KnownResponse` should")
+class KnownResponseTest {
+
+ @Test
+ @DisplayName("not tolerate `null`s")
+ void notTolerateNull() {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicStaticMethods(KnownResponse.class);
+ }
+
+ @Test
+ @DisplayName("return set values")
+ @SuppressWarnings("JdkObsolete") // we're force to follow the contract
+ void returnSetValues() {
+ String headerName = "custom";
+ String headerValue = "header";
+ ImmutableMap headers = ImmutableMap.of(headerName, headerValue);
+ StringWriter writer = new StringWriter();
+ KnownResponse response = KnownResponse.create(writer, SC_ACCEPTED, headers);
+ assertThat(response.getStatus())
+ .isEqualTo(SC_ACCEPTED);
+ assertThat(response.getHeader(headerName))
+ .isEqualTo(headerValue);
+ assertThat(response.getHeaders(headerName))
+ .isEqualTo(ImmutableSet.of(headerValue));
+ assertThat(response.getHeaderNames())
+ .isEqualTo(ImmutableSet.of(headerName));
+ PrintWriter printWriter = response.getWriter();
+ printWriter.print("Unbelievable string!");
+ assertThat(writer.toString())
+ .isEqualTo("Unbelievable string!");
+ }
+}
diff --git a/testutil-web/src/test/java/io/spine/web/given/MemoizingResponseTest.java b/testutil-web/src/test/java/io/spine/web/given/MemoizingResponseTest.java
new file mode 100644
index 000000000..8478a5369
--- /dev/null
+++ b/testutil-web/src/test/java/io/spine/web/given/MemoizingResponseTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020, TeamDev. All rights reserved.
+ *
+ * Redistribution and use in source and/or binary forms, with or without
+ * modification, must retain the above copyright notice and the following
+ * disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.spine.web.given;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.io.PrintWriter;
+
+import static com.google.common.truth.Truth.assertThat;
+import static javax.servlet.http.HttpServletResponse.SC_BAD_GATEWAY;
+
+@DisplayName("`MemoizingResponse` should")
+class MemoizingResponseTest {
+
+ @Test
+ @DisplayName("return set values")
+ @SuppressWarnings("JdkObsolete") // we're force to follow the contract
+ void returnSetValues() {
+ String headerName = "custom";
+ String headerValue = "header";
+ MemoizingResponse response = new MemoizingResponse();
+ response.sendError(SC_BAD_GATEWAY);
+ assertThat(response.getStatus())
+ .isEqualTo(SC_BAD_GATEWAY);
+ response.addHeader(headerName, headerValue);
+ assertThat(response.getHeader(headerName))
+ .isEqualTo(headerValue);
+ PrintWriter printWriter = response.getWriter();
+ printWriter.print("I'm writing you!");
+ assertThat(response.writerContent())
+ .isEqualTo("I'm writing you!");
+ }
+}
diff --git a/version.gradle.kts b/version.gradle.kts
index 1edf3707d..a2cc7aafa 100644
--- a/version.gradle.kts
+++ b/version.gradle.kts
@@ -18,10 +18,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-val spineBaseVersion: String by extra("1.6.13")
-val spineTimeVersion: String by extra("1.6.13")
-val spineCoreVersion: String by extra("1.6.15")
+val spineBaseVersion: String by extra("1.6.16")
+val spineTimeVersion: String by extra("1.6.16")
+val spineCoreVersion: String by extra("1.6.18")
val spineVersion: String by extra(spineCoreVersion)
-val versionToPublish: String by extra("1.6.15")
-val versionToPublishJs: String by extra("1.6.15")
+val versionToPublish: String by extra("1.6.16")
+val versionToPublishJs: String by extra("1.6.16")
diff --git a/web/build.gradle.kts b/web/build.gradle.kts
index ecba8937f..343a7cb2c 100644
--- a/web/build.gradle.kts
+++ b/web/build.gradle.kts
@@ -18,7 +18,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import com.google.protobuf.gradle.*
+import com.google.protobuf.gradle.builtins
+import com.google.protobuf.gradle.generateProtoTasks
+import com.google.protobuf.gradle.id
+import com.google.protobuf.gradle.protobuf
+import com.google.protobuf.gradle.protoc
import io.spine.gradle.internal.DependencyResolution
import io.spine.gradle.internal.Deps
import io.spine.gradle.internal.IncrementGuard
diff --git a/web/src/test/java/io/spine/web/command/CommandServletTest.java b/web/src/test/java/io/spine/web/command/CommandServletTest.java
index 35b3f79af..6381b5d1f 100644
--- a/web/src/test/java/io/spine/web/command/CommandServletTest.java
+++ b/web/src/test/java/io/spine/web/command/CommandServletTest.java
@@ -30,24 +30,25 @@
import io.spine.testing.client.command.TestCommandMessage;
import io.spine.testing.logging.MuteLogging;
import io.spine.web.command.given.DetachedCommandServlet;
+import io.spine.web.given.MemoizingResponse;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
-import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static io.spine.base.Identifier.newUuid;
import static io.spine.web.given.Servlets.request;
import static io.spine.web.given.Servlets.response;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.verify;
-@DisplayName("CommandServlet should")
+@DisplayName("`CommandServlet` should")
class CommandServletTest {
private static final CommandFactory commandFactory =
@@ -74,7 +75,8 @@ void testHandle() throws IOException {
Command command = commandFactory.create(createTask);
servlet.doPost(request(command), response(response));
Ack ack = Json.fromJson(response.toString(), Ack.class);
- assertEquals(command.getId(), AnyPacker.unpack(ack.getMessageId()));
+ assertThat(command.getId())
+ .isEqualTo(AnyPacker.unpack(ack.getMessageId()));
}
@MuteLogging
@@ -82,8 +84,9 @@ void testHandle() throws IOException {
@DisplayName("respond 400 to an invalid command")
void testInvalidCommand() throws IOException {
CommandServlet servlet = new DetachedCommandServlet();
- HttpServletResponse response = response(new StringWriter());
+ MemoizingResponse response = new MemoizingResponse();
servlet.doPost(request(Time.currentTime()), response);
- verify(response).sendError(400);
+ assertThat(response.getStatus())
+ .isEqualTo(SC_BAD_REQUEST);
}
}
diff --git a/web/src/test/java/io/spine/web/future/FutureObserverTest.java b/web/src/test/java/io/spine/web/future/FutureObserverTest.java
index 9b13c3ace..d784c0849 100644
--- a/web/src/test/java/io/spine/web/future/FutureObserverTest.java
+++ b/web/src/test/java/io/spine/web/future/FutureObserverTest.java
@@ -20,19 +20,19 @@
package io.spine.web.future;
+import com.google.common.truth.StringSubject;
+import com.google.errorprone.annotations.CanIgnoreReturnValue;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.concurrent.CompletionException;
import static com.google.common.base.Throwables.getRootCause;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
-@DisplayName("FutureObserver should")
+@DisplayName("`FutureObserver` should")
class FutureObserverTest {
@Test
@@ -41,9 +41,11 @@ void testCreateDefault() {
FutureObserver observer = FutureObserver.create();
String value = "hello";
observer.onNext(value);
- assertEquals(value, observer.toFuture().join());
+ assertResult(observer)
+ .isEqualTo(value);
observer.onCompleted();
- assertEquals(value, observer.toFuture().join());
+ assertResult(observer)
+ .isEqualTo(value);
}
@Test
@@ -51,7 +53,8 @@ void testCreateDefault() {
void testDefaultNull() {
FutureObserver observer = FutureObserver.create();
observer.onCompleted();
- assertNull(observer.toFuture().join());
+ assertResult(observer)
+ .isNull();
}
@Test
@@ -60,7 +63,8 @@ void testDefaultValue() {
String defaultValue = "Aquaman";
FutureObserver observer = FutureObserver.withDefault(defaultValue);
observer.onCompleted();
- assertEquals(defaultValue, observer.toFuture().join());
+ assertResult(observer)
+ .isEqualTo(defaultValue);
}
@Test
@@ -77,13 +81,28 @@ void testOverrideWithError() {
FutureObserver observer = FutureObserver.create();
String value = "Titanic";
observer.onNext(value);
- assertEquals(value, observer.toFuture().join());
+ assertResult(observer)
+ .isEqualTo(value);
+
observer.onError(new IcebergCollisionException());
- Throwable thrown = assertThrows(CompletionException.class,
- () -> observer.toFuture()
- .join());
+ Throwable thrown = assertThrows(
+ CompletionException.class,
+ () -> observerResult(observer)
+ );
Throwable rootCause = getRootCause(thrown);
- assertThat(rootCause, instanceOf(IcebergCollisionException.class));
+ assertThat(rootCause)
+ .isInstanceOf(IcebergCollisionException.class);
+ }
+
+ private static StringSubject assertResult(FutureObserver observer) {
+ return assertThat(observerResult(observer));
+ }
+
+ @CanIgnoreReturnValue
+ private static T observerResult(FutureObserver observer) {
+ return observer
+ .toFuture()
+ .join();
}
/**
@@ -92,6 +111,7 @@ void testOverrideWithError() {
* This exception type exists in order to uniquely flag an error origin.
*/
private static final class IcebergCollisionException extends Exception {
+
private static final long serialVersionUID = 0L;
}
}
diff --git a/web/src/test/java/io/spine/web/given/Servlets.java b/web/src/test/java/io/spine/web/given/Servlets.java
index 745101a13..00888e5ce 100644
--- a/web/src/test/java/io/spine/web/given/Servlets.java
+++ b/web/src/test/java/io/spine/web/given/Servlets.java
@@ -20,20 +20,13 @@
package io.spine.web.given;
+import com.google.common.net.MediaType;
import com.google.protobuf.Message;
import io.spine.json.Json;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringReader;
import java.io.StringWriter;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
/**
* The factory of mock servlet API objects, such as requests and responses.
*/
@@ -45,16 +38,18 @@ public final class Servlets {
private Servlets() {
}
- public static HttpServletRequest request(Message contents) throws IOException {
- HttpServletRequest request = mock(HttpServletRequest.class);
- String content = Json.toJson(contents);
- when(request.getReader()).thenReturn(new BufferedReader(new StringReader(content)));
- return request;
+ /**
+ * Creates a new request with the supplied {@code content}.
+ */
+ public static KnownRequest request(Message content) {
+ String json = Json.toJson(content);
+ return KnownRequest.create(json, MediaType.JSON_UTF_8);
}
- public static HttpServletResponse response(StringWriter writer) throws IOException {
- HttpServletResponse response = mock(HttpServletResponse.class);
- when(response.getWriter()).thenReturn(new PrintWriter(writer));
- return response;
+ /**
+ * Creates a new response with the supplied {@code writer}.
+ */
+ public static HttpServletResponse response(StringWriter writer) {
+ return KnownResponse.create(writer);
}
}
diff --git a/web/src/test/java/io/spine/web/query/QueryServletTest.java b/web/src/test/java/io/spine/web/query/QueryServletTest.java
index ad0568498..ae1e08852 100644
--- a/web/src/test/java/io/spine/web/query/QueryServletTest.java
+++ b/web/src/test/java/io/spine/web/query/QueryServletTest.java
@@ -20,11 +20,13 @@
package io.spine.web.query;
+import com.google.protobuf.Message;
import io.spine.client.Query;
import io.spine.client.QueryFactory;
import io.spine.json.Json;
import io.spine.testing.client.TestActorRequestFactory;
import io.spine.testing.logging.MuteLogging;
+import io.spine.web.given.MemoizingResponse;
import io.spine.web.query.given.QueryServletTestEnv.TestQueryServlet;
import io.spine.web.test.Task;
import io.spine.web.test.TaskId;
@@ -32,20 +34,20 @@
import org.junit.jupiter.api.Test;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static io.spine.base.Time.currentTime;
import static io.spine.web.given.Servlets.request;
import static io.spine.web.given.Servlets.response;
+import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.verify;
-@DisplayName("QueryServlet should")
+@DisplayName("`QueryServlet` should")
class QueryServletTest {
private static final QueryFactory queryFactory =
@@ -54,7 +56,7 @@ class QueryServletTest {
@Test
@DisplayName("throw UnsupportedOperationException when trying to serialize")
void testFailToSerialize() throws IOException {
- QueryServlet servlet = new TestQueryServlet();
+ QueryServlet servlet = new TestQueryServlet();
ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream());
assertThrows(UnsupportedOperationException.class, () -> stream.writeObject(servlet));
stream.close();
@@ -68,7 +70,7 @@ void testHandle() throws IOException {
.setId(TaskId.generate())
.setDescription("some-task-description")
.build();
- QueryServlet servlet = new TestQueryServlet(task);
+ QueryServlet servlet = new TestQueryServlet(task);
StringWriter response = new StringWriter();
Query query = queryFactory.all(Task.class);
HttpServletRequest request = request(query);
@@ -81,9 +83,10 @@ void testHandle() throws IOException {
@Test
@DisplayName("respond 400 to an invalid query")
void testInvalidQuery() throws IOException {
- QueryServlet servlet = new TestQueryServlet();
- HttpServletResponse response = response(new StringWriter());
+ QueryServlet servlet = new TestQueryServlet();
+ MemoizingResponse response = new MemoizingResponse();
servlet.doPost(request(currentTime()), response);
- verify(response).sendError(400);
+ assertThat(response.getStatus())
+ .isEqualTo(SC_BAD_REQUEST);
}
}