Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta: Stripe.rawRequest -> StripeClient.rawRequest #1728

Merged
merged 14 commits into from
Jan 18, 2024
7 changes: 7 additions & 0 deletions src/main/java/com/stripe/Stripe.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,10 @@ public static Map<String, String> getAppInfo() {
* @param relativeUrl the relative URL of the request, e.g. "/v1/charges"
* @param content the body of the request as a string
* @return the JSON response as a string
* @deprecated Use {@link com.stripe.StripeClient#rawRequest(ApiResource.RequestMethod, String,
* String)} instead.
*/
@Deprecated
public static StripeResponse rawRequest(
final ApiResource.RequestMethod method, final String relativeUrl, final String content)
throws StripeException {
Expand All @@ -239,7 +242,10 @@ public static StripeResponse rawRequest(
* @param content the body of the request as a string
* @param options the special modifiers of the request
* @return the JSON response as a string
* @deprecated Use {@link com.stripe.StripeClient#rawRequest(ApiResource.RequestMethod, String,
* String, RawRequestOptions)} instead.
*/
@Deprecated
public static StripeResponse rawRequest(
final ApiResource.RequestMethod method,
final String relativeUrl,
Expand All @@ -254,6 +260,7 @@ public static StripeResponse rawRequest(
}

/** Deserializes StripeResponse returned by rawRequest into a similar class. */
@Deprecated
public static StripeObject deserialize(String rawJson) throws StripeException {
if (rawJson == null) {
throw new IllegalArgumentException("rawJson cannot be null");
Expand Down
57 changes: 57 additions & 0 deletions src/main/java/com/stripe/StripeClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.stripe;

import com.google.gson.JsonObject;
import com.stripe.exception.StripeException;
import com.stripe.model.StripeObject;
import com.stripe.net.*;
import java.net.PasswordAuthentication;
import java.net.Proxy;
Expand Down Expand Up @@ -570,4 +573,58 @@ StripeResponseGetterOptions buildOptions() {
connectBase);
}
}

/**
* Send raw request to Stripe API. This is the lowest level method for interacting with the Stripe
* API. This method is useful for interacting with endpoints that are not covered yet in
* stripe-java.
*
* @param method the HTTP method
* @param relativeUrl the relative URL of the request, e.g. "/v1/charges"
* @param content the body of the request as a string
* @return the JSON response as a string
*/
public StripeResponse rawRequest(
final ApiResource.RequestMethod method, final String relativeUrl, final String content)
throws StripeException {
RawRequestOptions options = RawRequestOptions.builder().build();
return rawRequest(method, relativeUrl, content, options);
}

/**
* Send raw request to Stripe API. This is the lowest level method for interacting with the Stripe
* API. This method is useful for interacting with endpoints that are not covered yet in
* stripe-java.
*
* @param method the HTTP method
* @param relativeUrl the relative URL of the request, e.g. "/v1/charges"
* @param content the body of the request as a string
* @param options the special modifiers of the request
* @return the JSON response as a string
*/
public StripeResponse rawRequest(
final ApiResource.RequestMethod method,
final String relativeUrl,
final String content,
final RawRequestOptions options)
throws StripeException {
if (method != ApiResource.RequestMethod.POST && content != null && !content.equals("")) {
throw new IllegalArgumentException(
"content is not allowed for non-POST requests. Please pass null and add request parameters to the query string of the URL.");
}
return this.getResponseGetter()
.rawRequest(
new RawApiRequest(
BaseAddress.API, method, relativeUrl, content, options, options.getApiMode()));
}

/** Deserializes StripeResponse returned by rawRequest into a similar class. */
public StripeObject deserialize(String rawJson) throws StripeException {
if (rawJson == null) {
throw new IllegalArgumentException("rawJson cannot be null");
}

return StripeObject.deserializeStripeObject(
ApiResource.GSON.fromJson(rawJson, JsonObject.class));
}
}
1 change: 1 addition & 0 deletions src/main/java/com/stripe/net/ApiResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public static String urlEncodeId(String id) throws InvalidRequestException {
return urlEncode(id);
}

@Deprecated
public static StripeResponse rawRequest(
ApiResource.RequestMethod method, String url, String content, RawRequestOptions options)
throws StripeException {
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/com/stripe/BaseStripeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class BaseStripeTest {
private String origClientId;
private String origUploadBase;
private String origStripeVersion;
protected static final String TEST_API_KEY = "sk_test_123";

static {
// To only stop stripe-mock process after all the test classes.
Expand Down Expand Up @@ -121,7 +122,7 @@ public void setUpStripeMockUsage() {

Stripe.overrideApiBase("http://localhost:" + port);
Stripe.overrideUploadBase("http://localhost:" + port);
Stripe.apiKey = "sk_test_123";
Stripe.apiKey = TEST_API_KEY;
Stripe.clientId = "ca_123";
Stripe.enableTelemetry = false;

Expand Down
165 changes: 159 additions & 6 deletions src/test/java/com/stripe/net/RawRequestOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import com.stripe.BaseStripeTest;
import com.stripe.Stripe;
import com.stripe.StripeClient;
import com.stripe.exception.StripeException;
import com.stripe.model.Customer;
import java.io.IOException;
Expand All @@ -21,12 +22,18 @@

public class RawRequestOptionsTest extends BaseStripeTest {
public static MockWebServer server;
public static StripeClient client;

@BeforeEach
void setUp() throws IOException {
server = new MockWebServer();
server.start();
Stripe.overrideApiBase(server.url("").toString());
client =
StripeClient.builder()
.setApiKey(TEST_API_KEY)
.setApiBase(server.url("").toString())
.build();
}

@AfterEach
Expand All @@ -35,7 +42,7 @@ void tearDown() throws IOException {
}

@Test
public void testStandardRequest() throws StripeException, InterruptedException {
public void testStandardRequestGlobal() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody(
Expand Down Expand Up @@ -64,7 +71,7 @@ public void testStandardRequest() throws StripeException, InterruptedException {
}

@Test
public void testPreviewPostRequest() throws StripeException, InterruptedException {
public void testPreviewPostRequestGlobal() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody("{\"id\": \"sub_sched_123\",\n \"object\": \"subscription_schedule\"}"));
Expand Down Expand Up @@ -94,7 +101,7 @@ public void testPreviewPostRequest() throws StripeException, InterruptedExceptio
}

@Test
public void testPreviewGetRequest() throws StripeException, InterruptedException {
public void testPreviewGetRequestGlobal() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody("{\"id\": \"sub_sched_123\",\n \"object\": \"subscription_schedule\"}"));
Expand All @@ -118,7 +125,7 @@ public void testPreviewGetRequest() throws StripeException, InterruptedException
}

@Test
public void testAdditionalHeaders() throws StripeException, InterruptedException {
public void testAdditionalHeadersGlobal() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody(
Expand All @@ -144,7 +151,7 @@ public void testAdditionalHeaders() throws StripeException, InterruptedException
}

@Test
public void testDeserialize() throws StripeException, InterruptedException {
public void testDeserializeGlobal() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody(
Expand All @@ -171,12 +178,158 @@ public void testDeserialize() throws StripeException, InterruptedException {
}

@Test
public void testRaisesErrorWhenGetRequestAndContentIsNonNull() throws StripeException {
public void testRaisesErrorWhenGetRequestAndContentIsNonNullGlobal() throws StripeException {
try {
Stripe.rawRequest(ApiResource.RequestMethod.GET, "/v1/customers", "key=value!", null);
fail("Expected illegal argument exception.");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("content is not allowed for non-POST requests."));
}
}

@Test
public void testStandardRequestClient() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody(
"{\"id\": \"cus_123\",\n \"object\": \"customer\",\n \"description\": \"test customer\"}"));

final ApiMode apiMode = ApiMode.V1;

final RawRequestOptions options =
RawRequestOptions.builder().setApiMode(apiMode).setApiKey("sk_123").build();

assertEquals(apiMode, options.getApiMode());

final StripeResponse response =
client.rawRequest(
ApiResource.RequestMethod.POST, "/v1/customers", "description=test+customer", options);

assertNotNull(response);
assertEquals(200, response.code());
assertTrue(response.body().length() > 0);

RecordedRequest request = server.takeRequest();
assertEquals(
"application/x-www-form-urlencoded;charset=UTF-8", request.getHeader("Content-Type"));
assertEquals(Stripe.API_VERSION, request.getHeader("Stripe-Version"));
assertEquals("description=test+customer", request.getBody().readUtf8());
}

@Test
public void testPreviewPostRequestClient() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody("{\"id\": \"sub_sched_123\",\n \"object\": \"subscription_schedule\"}"));
final ApiMode apiMode = ApiMode.PREVIEW;
final RawRequestOptions options =
RawRequestOptions.builder().setApiMode(apiMode).setApiKey("sk_123").build();

assertEquals(apiMode, options.getApiMode());

final StripeResponse response =
client.rawRequest(
ApiResource.RequestMethod.POST,
"/v1/subscription_schedules",
"{\"end_behavior\":\"release\",\"phases\":[{\"items\":[{\"quantity\":1,\"price\":\"price_123\"}],\"iterations\":12}],\"customer\":\"cus_123\",\"start_date\":1683338558}",
options);

RecordedRequest request = server.takeRequest();
assertEquals("application/json", request.getHeader("Content-Type"));
assertEquals(Stripe.PREVIEW_API_VERSION, request.getHeader("Stripe-Version"));
assertEquals(
"{\"end_behavior\":\"release\",\"phases\":[{\"items\":[{\"quantity\":1,\"price\":\"price_123\"}],\"iterations\":12}],\"customer\":\"cus_123\",\"start_date\":1683338558}",
request.getBody().readUtf8());

assertNotNull(response);
assertEquals(200, response.code());
assertTrue(response.body().length() > 0);
}

@Test
public void testPreviewGetRequestClient() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody("{\"id\": \"sub_sched_123\",\n \"object\": \"subscription_schedule\"}"));
final ApiMode apiMode = ApiMode.PREVIEW;
final RawRequestOptions options =
RawRequestOptions.builder().setApiMode(apiMode).setApiKey("sk_123").build();

assertEquals(apiMode, options.getApiMode());

final StripeResponse response =
client.rawRequest(ApiResource.RequestMethod.GET, "/v1/subscription_schedules", "", options);

RecordedRequest request = server.takeRequest();
assertEquals(null, request.getHeader("Content-Type"));
assertEquals(Stripe.PREVIEW_API_VERSION, request.getHeader("Stripe-Version"));
assertEquals("", request.getBody().readUtf8());

assertNotNull(response);
assertEquals(200, response.code());
assertTrue(response.body().length() > 0);
}

@Test
public void testAdditionalHeadersClient() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody(
"{\"id\": \"cus_123\",\n \"object\": \"customer\",\n \"description\": \"test customer\"}"));

Map<String, String> additionalHeaders = new HashMap<>();

additionalHeaders.put("foo", "bar");
final RawRequestOptions options =
RawRequestOptions.builder().setAdditionalHeaders(additionalHeaders).build();

assertEquals(additionalHeaders, options.getAdditionalHeaders());

final StripeResponse response =
client.rawRequest(ApiResource.RequestMethod.GET, "/v1/customers", null, options);

RecordedRequest request = server.takeRequest();
assertEquals("bar", request.getHeader("foo"));

assertNotNull(response);
assertEquals(200, response.code());
assertTrue(response.body().length() > 0);
}

@Test
public void testDeserializeClient() throws StripeException, InterruptedException {
server.enqueue(
new MockResponse()
.setBody(
"{\"id\": \"cus_123\",\n \"object\": \"customer\",\n \"description\": \"test customer\"}"));

final ApiMode apiMode = ApiMode.V1;

final RawRequestOptions options =
RawRequestOptions.builder().setApiMode(apiMode).setApiKey("sk_123").build();

assertEquals(apiMode, options.getApiMode());

final StripeResponse response =
client.rawRequest(
ApiResource.RequestMethod.POST, "/v1/customers", "description=test+customer", options);

assertNotNull(response);
assertEquals(200, response.code());
assertTrue(response.body().length() > 0);

Customer customer = (Customer) Stripe.deserialize(response.body());
assertTrue(customer.getId().startsWith("cus_"));
assertEquals("test customer", customer.getDescription());
}

@Test
public void testRaisesErrorWhenGetRequestAndContentIsNonNullClient() throws StripeException {
try {
client.rawRequest(ApiResource.RequestMethod.GET, "/v1/customers", "key=value!", null);
fail("Expected illegal argument exception.");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("content is not allowed for non-POST requests."));
}
}
}
Loading