diff --git a/src/main/java/com/google/firebase/ErrorCode.java b/src/main/java/com/google/firebase/ErrorCode.java new file mode 100644 index 000000000..217903c35 --- /dev/null +++ b/src/main/java/com/google/firebase/ErrorCode.java @@ -0,0 +1,109 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase; + +/** + * Platform-wide error codes that can be raised by Admin SDK APIs. + */ +public enum ErrorCode { + + /** + * Client specified an invalid argument. + */ + INVALID_ARGUMENT, + + /** + * Request can not be executed in the current system state, such as deleting a non-empty + * directory. + */ + FAILED_PRECONDITION, + + /** + * Client specified an invalid range. + */ + OUT_OF_RANGE, + + /** + * Request not authenticated due to missing, invalid, or expired OAuth token. + */ + UNAUTHENTICATED, + + /** + * Client does not have sufficient permission. This can happen because the OAuth token does + * not have the right scopes, the client doesn't have permission, or the API has not been + * enabled for the client project. + */ + PERMISSION_DENIED, + + /** + * A specified resource is not found, or the request is rejected by undisclosed reasons, + * such as whitelisting. + */ + NOT_FOUND, + + /** + * Concurrency conflict, such as read-modify-write conflict. + */ + CONFLICT, + + /** + * Concurrency conflict, such as read-modify-write conflict. + */ + ABORTED, + + /** + * The resource that a client tried to create already exists. + */ + ALREADY_EXISTS, + + /** + * Either out of resource quota or reaching rate limiting. + */ + RESOURCE_EXHAUSTED, + + /** + * Request cancelled by the client. + */ + CANCELLED, + + /** + * Unrecoverable data loss or data corruption. The client should report the error to the user. + */ + DATA_LOSS, + + /** + * Unknown server error. Typically a server bug. + */ + UNKNOWN, + + /** + * Internal server error. Typically a server bug. + */ + INTERNAL, + + /** + * Service unavailable. Typically the server is down. + */ + UNAVAILABLE, + + /** + * Request deadline exceeded. This will happen only if the caller sets a deadline that is + * shorter than the method's default deadline (i.e. requested deadline is not enough for the + * server to process the request) and the request did not finish within the deadline. + */ + DEADLINE_EXCEEDED, +} diff --git a/src/main/java/com/google/firebase/FirebaseException.java b/src/main/java/com/google/firebase/FirebaseException.java index f78b3fb98..f15c042ba 100644 --- a/src/main/java/com/google/firebase/FirebaseException.java +++ b/src/main/java/com/google/firebase/FirebaseException.java @@ -17,24 +17,59 @@ package com.google.firebase; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Strings; import com.google.firebase.internal.NonNull; +import com.google.firebase.internal.Nullable; -/** Base class for all Firebase exceptions. */ +/** + * Base class for all Firebase exceptions. + */ public class FirebaseException extends Exception { - // TODO(b/27677218): Exceptions should have non-empty messages. - @Deprecated - protected FirebaseException() {} + private final ErrorCode errorCode; + private final IncomingHttpResponse httpResponse; + @Deprecated public FirebaseException(@NonNull String detailMessage) { - super(detailMessage); - checkArgument(!Strings.isNullOrEmpty(detailMessage), "Detail message must not be empty"); + this(detailMessage, null); } + @Deprecated public FirebaseException(@NonNull String detailMessage, Throwable cause) { - super(detailMessage, cause); - checkArgument(!Strings.isNullOrEmpty(detailMessage), "Detail message must not be empty"); + this(ErrorCode.UNKNOWN, detailMessage, null, cause); + } + + public FirebaseException( + @NonNull ErrorCode errorCode, + @NonNull String message, + @Nullable IncomingHttpResponse httpResponse, + @Nullable Throwable cause) { + super(message, cause); + checkArgument(!Strings.isNullOrEmpty(message), "Message must not be null or empty"); + this.errorCode = checkNotNull(errorCode, "ErrorCode must not be null"); + this.httpResponse = httpResponse; + } + + /** + * Returns the platform-wide error code associated with this exception. + * + * @return A Firebase error code. + */ + // TODO: Expose this method publicly + ErrorCode getErrorCode() { + return errorCode; + } + + /** + * Returns the HTTP response that resulted in this exception. If the exception was not caused by + * an HTTP error response, returns null. + * + * @return An HTTP response or null. + */ + @Nullable + public IncomingHttpResponse getHttpResponse() { + return httpResponse; } } diff --git a/src/main/java/com/google/firebase/IncomingHttpResponse.java b/src/main/java/com/google/firebase/IncomingHttpResponse.java new file mode 100644 index 000000000..02bdcb7a2 --- /dev/null +++ b/src/main/java/com/google/firebase/IncomingHttpResponse.java @@ -0,0 +1,94 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpResponse; +import com.google.api.client.http.HttpResponseException; +import com.google.common.collect.ImmutableMap; +import com.google.firebase.database.annotations.Nullable; +import java.util.Map; + +/** + * Contains the information that describe an HTTP response received by the SDK. + */ +public final class IncomingHttpResponse { + + private final int statusCode; + private final String content; + private final Map headers; + private final OutgoingHttpRequest request; + + IncomingHttpResponse(HttpResponse response, @Nullable String content) { + checkNotNull(response, "response must not be null"); + this.statusCode = response.getStatusCode(); + this.content = content; + this.headers = ImmutableMap.copyOf(response.getHeaders()); + this.request = new OutgoingHttpRequest(response.getRequest()); + } + + IncomingHttpResponse(HttpResponseException e, HttpRequest request) { + this(e, new OutgoingHttpRequest(request)); + } + + IncomingHttpResponse(HttpResponseException e, OutgoingHttpRequest request) { + checkNotNull(e, "exception must not be null"); + this.statusCode = e.getStatusCode(); + this.content = e.getContent(); + this.headers = ImmutableMap.copyOf(e.getHeaders()); + this.request = checkNotNull(request, "request must not be null"); + } + + /** + * Returns the status code of the response. + * + * @return An HTTP status code (e.g. 500). + */ + public int getStatusCode() { + return this.statusCode; + } + + /** + * Returns the content of the response as a string. + * + * @return HTTP content or null. + */ + @Nullable + public String getContent() { + return this.content; + } + + /** + * Returns the headers set on the response. + * + * @return An immutable map of headers (possibly empty). + */ + public Map getHeaders() { + return this.headers; + } + + /** + * Returns the request that resulted in this response. + * + * @return An HTTP request. + */ + public OutgoingHttpRequest getRequest() { + return request; + } +} diff --git a/src/main/java/com/google/firebase/OutgoingHttpRequest.java b/src/main/java/com/google/firebase/OutgoingHttpRequest.java new file mode 100644 index 000000000..09a64b0a2 --- /dev/null +++ b/src/main/java/com/google/firebase/OutgoingHttpRequest.java @@ -0,0 +1,92 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.client.http.HttpContent; +import com.google.api.client.http.HttpRequest; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; +import com.google.firebase.internal.Nullable; +import java.util.Map; + +/** + * Contains the information that describe an HTTP request made by the SDK. + */ +public final class OutgoingHttpRequest { + + private final String method; + private final String url; + private final HttpContent content; + private final Map headers; + + OutgoingHttpRequest(String method, String url) { + checkArgument(!Strings.isNullOrEmpty(method), "method must not be null or empty"); + checkArgument(!Strings.isNullOrEmpty(url), "url must not be empty"); + this.method = method; + this.url = url; + this.content = null; + this.headers = ImmutableMap.of(); + } + + OutgoingHttpRequest(HttpRequest request) { + checkNotNull(request, "request must not be null"); + this.method = request.getRequestMethod(); + this.url = request.getUrl().toString(); + this.content = request.getContent(); + this.headers = ImmutableMap.copyOf(request.getHeaders()); + } + + /** + * Returns the HTTP method of the request. + * + * @return An HTTP method string (e.g. GET). + */ + public String getMethod() { + return method; + } + + /** + * Returns the URL of the request. + * + * @return An absolute HTTP URL. + */ + public String getUrl() { + return url; + } + + /** + * Returns any content that was sent with the request. + * + * @return HTTP content or null. + */ + @Nullable + public HttpContent getContent() { + return content; + } + + /** + * Returns the headers set on the request. + * + * @return An immutable map of headers (possibly empty). + */ + public Map getHeaders() { + return headers; + } +} diff --git a/src/test/java/com/google/firebase/FirebaseAppTest.java b/src/test/java/com/google/firebase/FirebaseAppTest.java index eee9efdb8..77191fa4c 100644 --- a/src/test/java/com/google/firebase/FirebaseAppTest.java +++ b/src/test/java/com/google/firebase/FirebaseAppTest.java @@ -579,16 +579,6 @@ public void testFirebaseConfigStringIgnoresInvalidKey() { assertEquals("hipster-chat-mock", firebaseApp.getOptions().getProjectId()); } - @Test(expected = IllegalArgumentException.class) - public void testFirebaseExceptionNullDetail() { - new FirebaseException(null); - } - - @Test(expected = IllegalArgumentException.class) - public void testFirebaseExceptionEmptyDetail() { - new FirebaseException(""); - } - @Test public void testFirebaseAppCreationWithEmptySupplier() { FirebaseApp.initializeApp(FirebaseOptions.builder() diff --git a/src/test/java/com/google/firebase/FirebaseExceptionTest.java b/src/test/java/com/google/firebase/FirebaseExceptionTest.java new file mode 100644 index 000000000..46d3cf018 --- /dev/null +++ b/src/test/java/com/google/firebase/FirebaseExceptionTest.java @@ -0,0 +1,145 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpResponseException; +import com.google.api.client.http.HttpStatusCodes; +import com.google.api.client.testing.http.MockLowLevelHttpRequest; +import com.google.api.client.testing.http.MockLowLevelHttpResponse; +import com.google.firebase.testing.TestUtils; +import java.io.IOException; +import org.junit.Test; + +@SuppressWarnings("ThrowableNotThrown") +public class FirebaseExceptionTest { + + @Test(expected = NullPointerException.class) + public void testFirebaseExceptionWithoutErrorCode() { + new FirebaseException( + null, + "Test error", + null, + null); + } + + @Test(expected = IllegalArgumentException.class) + public void testFirebaseExceptionWithNullMessage() { + new FirebaseException( + ErrorCode.INTERNAL, + null, + null, + null); + } + + @Test(expected = IllegalArgumentException.class) + public void testFirebaseExceptionWithEmptyMessage() { + new FirebaseException( + ErrorCode.INTERNAL, + "", + null, + null); + } + + @Test + public void testFirebaseExceptionWithoutResponseAndCause() { + FirebaseException exception = new FirebaseException( + ErrorCode.INTERNAL, + "Test error", + null, + null); + + assertEquals(ErrorCode.INTERNAL, exception.getErrorCode()); + assertEquals("Test error", exception.getMessage()); + assertNull(exception.getHttpResponse()); + assertNull(exception.getCause()); + } + + @Test + public void testFirebaseExceptionWithResponse() throws IOException { + HttpResponseException httpError = createHttpResponseException(); + OutgoingHttpRequest request = new OutgoingHttpRequest( + "GET", "https://firebase.google.com"); + IncomingHttpResponse response = new IncomingHttpResponse(httpError, request); + + FirebaseException exception = new FirebaseException( + ErrorCode.INTERNAL, + "Test error", + response, + null); + + assertEquals(ErrorCode.INTERNAL, exception.getErrorCode()); + assertEquals("Test error", exception.getMessage()); + assertSame(response, exception.getHttpResponse()); + assertNull(exception.getCause()); + } + + @Test + public void testFirebaseExceptionWithCause() { + Exception cause = new Exception("root cause"); + + FirebaseException exception = new FirebaseException( + ErrorCode.INTERNAL, + "Test error", + null, + cause); + + assertEquals(ErrorCode.INTERNAL, exception.getErrorCode()); + assertEquals("Test error", exception.getMessage()); + assertNull(exception.getHttpResponse()); + assertSame(cause, exception.getCause()); + } + + @Test + public void testFirebaseExceptionLegacyConstructor() { + FirebaseException exception = new FirebaseException("Test error"); + + assertEquals(ErrorCode.UNKNOWN, exception.getErrorCode()); + assertEquals("Test error", exception.getMessage()); + assertNull(exception.getHttpResponse()); + assertNull(exception.getCause()); + } + + @Test(expected = IllegalArgumentException.class) + public void testFirebaseExceptionNullDetail() { + new FirebaseException(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testFirebaseExceptionEmptyDetail() { + new FirebaseException(""); + } + + private HttpResponseException createHttpResponseException() throws IOException { + MockLowLevelHttpResponse lowLevelResponse = new MockLowLevelHttpResponse() + .setStatusCode(HttpStatusCodes.STATUS_CODE_SERVER_ERROR) + .setContent("{}"); + MockLowLevelHttpRequest lowLevelRequest = new MockLowLevelHttpRequest() + .setResponse(lowLevelResponse); + HttpRequest request = TestUtils.createRequest(lowLevelRequest); + try { + request.execute(); + throw new IOException("HttpResponseException not thrown"); + } catch (HttpResponseException e) { + return e; + } + } +} diff --git a/src/test/java/com/google/firebase/IncomingHttpResponseTest.java b/src/test/java/com/google/firebase/IncomingHttpResponseTest.java new file mode 100644 index 000000000..4da63d12b --- /dev/null +++ b/src/test/java/com/google/firebase/IncomingHttpResponseTest.java @@ -0,0 +1,141 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.HttpMethods; +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpResponse; +import com.google.api.client.http.HttpResponseException; +import com.google.api.client.http.HttpStatusCodes; +import com.google.api.client.testing.http.MockLowLevelHttpRequest; +import com.google.api.client.testing.http.MockLowLevelHttpResponse; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.firebase.testing.TestUtils; +import java.io.IOException; +import java.util.Map; +import org.junit.Test; + +public class IncomingHttpResponseTest { + + private static final String TEST_URL = "https://firebase.google.com/response"; + private static final OutgoingHttpRequest REQUEST = new OutgoingHttpRequest("GET", TEST_URL); + private static final Map RESPONSE_HEADERS = + ImmutableMap.of("x-firebase-client", ImmutableList.of("test-version")); + private static final String RESPONSE_BODY = "test response"; + + @Test(expected = NullPointerException.class) + public void testNullHttpResponse() { + new IncomingHttpResponse(null, "content"); + } + + @Test + public void testNullHttpResponseException() throws IOException { + try { + new IncomingHttpResponse(null, REQUEST); + fail("No exception thrown for null HttpResponseException"); + } catch (NullPointerException ignore) { + // expected + } + + HttpRequest request = createHttpRequest(); + try { + new IncomingHttpResponse(null, request); + fail("No exception thrown for null HttpResponseException"); + } catch (NullPointerException ignore) { + // expected + } + } + + @Test + public void testIncomingHttpResponse() throws IOException { + HttpResponseException httpError = createHttpResponseException(); + + IncomingHttpResponse response = new IncomingHttpResponse(httpError, REQUEST); + + assertEquals(HttpStatusCodes.STATUS_CODE_SERVER_ERROR, response.getStatusCode()); + assertEquals(RESPONSE_BODY, response.getContent()); + assertEquals(RESPONSE_HEADERS, response.getHeaders()); + assertFalse(response.getHeaders().isEmpty()); + assertSame(REQUEST, response.getRequest()); + } + + @Test + public void testIncomingHttpResponseWithRequest() throws IOException { + HttpResponseException httpError = createHttpResponseException(); + HttpRequest httpRequest = createHttpRequest(); + + IncomingHttpResponse response = new IncomingHttpResponse(httpError, httpRequest); + + assertEquals(HttpStatusCodes.STATUS_CODE_SERVER_ERROR, response.getStatusCode()); + assertEquals(RESPONSE_BODY, response.getContent()); + assertEquals(RESPONSE_HEADERS, response.getHeaders()); + OutgoingHttpRequest request = response.getRequest(); + assertEquals(HttpMethods.POST, request.getMethod()); + assertEquals(TEST_URL, request.getUrl()); + } + + @Test + public void testIncomingHttpResponseWithResponse() throws IOException { + HttpResponse httpResponse = createHttpResponse(); + + IncomingHttpResponse response = new IncomingHttpResponse(httpResponse, RESPONSE_BODY); + + assertEquals(HttpStatusCodes.STATUS_CODE_OK, response.getStatusCode()); + assertEquals(RESPONSE_BODY, response.getContent()); + assertTrue(response.getHeaders().isEmpty()); + OutgoingHttpRequest request = response.getRequest(); + assertEquals(HttpMethods.POST, request.getMethod()); + assertEquals(TEST_URL, request.getUrl()); + } + + private HttpResponseException createHttpResponseException() throws IOException { + MockLowLevelHttpResponse lowLevelResponse = new MockLowLevelHttpResponse() + .setStatusCode(HttpStatusCodes.STATUS_CODE_SERVER_ERROR) + .addHeader("X-Firebase-Client", "test-version") + .setContent(RESPONSE_BODY); + MockLowLevelHttpRequest lowLevelRequest = new MockLowLevelHttpRequest() + .setResponse(lowLevelResponse); + HttpRequest request = TestUtils.createRequest(lowLevelRequest, new GenericUrl(TEST_URL)); + try { + request.execute(); + throw new IOException("HttpResponseException not thrown"); + } catch (HttpResponseException e) { + return e; + } + } + + private HttpRequest createHttpRequest() throws IOException { + MockLowLevelHttpResponse lowLevelResponse = new MockLowLevelHttpResponse() + .setContent("{}"); + MockLowLevelHttpRequest lowLevelRequest = new MockLowLevelHttpRequest() + .setResponse(lowLevelResponse); + return TestUtils.createRequest(lowLevelRequest, new GenericUrl(TEST_URL)); + } + + private HttpResponse createHttpResponse() throws IOException { + HttpRequest request = createHttpRequest(); + return request.execute(); + } +} diff --git a/src/test/java/com/google/firebase/OutgoingHttpRequestTest.java b/src/test/java/com/google/firebase/OutgoingHttpRequestTest.java new file mode 100644 index 000000000..792d621f5 --- /dev/null +++ b/src/test/java/com/google/firebase/OutgoingHttpRequestTest.java @@ -0,0 +1,89 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.api.client.googleapis.util.Utils; +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.HttpMethods; +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.json.JsonHttpContent; +import com.google.api.client.testing.http.MockHttpTransport; +import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import org.junit.Test; + +public class OutgoingHttpRequestTest { + + private static final String TEST_URL = "https://firebase.google.com/request"; + + @Test(expected = NullPointerException.class) + public void testNullHttpRequest() { + new OutgoingHttpRequest(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testNullMethod() { + new OutgoingHttpRequest(null, TEST_URL); + } + + @Test(expected = IllegalArgumentException.class) + public void testEmptyMethod() { + new OutgoingHttpRequest("", TEST_URL); + } + + @Test(expected = IllegalArgumentException.class) + public void testNullUrl() { + new OutgoingHttpRequest(HttpMethods.GET, null); + } + + @Test(expected = IllegalArgumentException.class) + public void testEmptyUrl() { + new OutgoingHttpRequest(HttpMethods.GET, ""); + } + + @Test + public void testOutgoingHttpRequest() { + OutgoingHttpRequest request = new OutgoingHttpRequest(HttpMethods.GET, TEST_URL); + + assertEquals(HttpMethods.GET, request.getMethod()); + assertEquals(TEST_URL, request.getUrl()); + assertNull(request.getContent()); + assertTrue(request.getHeaders().isEmpty()); + } + + @Test + public void testOutgoingHttpRequestWithContent() throws IOException { + JsonHttpContent streamingContent = new JsonHttpContent( + Utils.getDefaultJsonFactory(), + ImmutableMap.of("key", "value")); + HttpRequest httpRequest = new MockHttpTransport().createRequestFactory() + .buildPostRequest(new GenericUrl(TEST_URL), streamingContent); + httpRequest.getHeaders().set("X-Firebase-Client", "test-version"); + + OutgoingHttpRequest request = new OutgoingHttpRequest(httpRequest); + + assertEquals(HttpMethods.POST, request.getMethod()); + assertEquals(TEST_URL, request.getUrl()); + assertSame(streamingContent, request.getContent()); + assertEquals("test-version", request.getHeaders().get("x-firebase-client")); + } +} diff --git a/src/test/java/com/google/firebase/testing/TestUtils.java b/src/test/java/com/google/firebase/testing/TestUtils.java index a63aa8d10..e44ca2be8 100644 --- a/src/test/java/com/google/firebase/testing/TestUtils.java +++ b/src/test/java/com/google/firebase/testing/TestUtils.java @@ -162,11 +162,19 @@ public static HttpRequest createRequest() throws IOException { } public static HttpRequest createRequest(MockLowLevelHttpRequest request) throws IOException { + return createRequest(request, TEST_URL); + } + + /** + * Creates a test HTTP POST request for the given target URL. + */ + public static HttpRequest createRequest( + MockLowLevelHttpRequest request, GenericUrl url) throws IOException { HttpTransport transport = new MockHttpTransport.Builder() .setLowLevelHttpRequest(request) .build(); HttpRequestFactory requestFactory = transport.createRequestFactory(); - return requestFactory.buildPostRequest(TEST_URL, new EmptyContent()); + return requestFactory.buildPostRequest(url, new EmptyContent()); } public static HttpTransport createFaultyHttpTransport() {