Skip to content

Commit 23067a4

Browse files
committed
Add tests for the Proxy
1 parent d8a9748 commit 23067a4

File tree

1 file changed

+294
-0
lines changed

1 file changed

+294
-0
lines changed
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
package com.pipedream.api;
2+
3+
import com.pipedream.api.resources.proxy.requests.ProxyGetRequest;
4+
import com.pipedream.api.resources.proxy.types.ProxyResponse;
5+
import okhttp3.mockwebserver.MockResponse;
6+
import okhttp3.mockwebserver.MockWebServer;
7+
import okhttp3.mockwebserver.RecordedRequest;
8+
import okio.Buffer;
9+
import org.junit.jupiter.api.AfterEach;
10+
import org.junit.jupiter.api.BeforeEach;
11+
import org.junit.jupiter.api.Test;
12+
13+
import java.io.ByteArrayOutputStream;
14+
import java.io.IOException;
15+
import java.io.InputStream;
16+
import java.util.Map;
17+
import java.util.concurrent.CompletableFuture;
18+
import java.util.concurrent.TimeUnit;
19+
20+
import static org.junit.jupiter.api.Assertions.*;
21+
22+
public class ProxyClientWireTest {
23+
private MockWebServer server;
24+
private BaseClient client;
25+
private AsyncBaseClient asyncClient;
26+
27+
private static final String TEST_EXTERNAL_USER_ID = "test-user-123";
28+
private static final String TEST_ACCOUNT_ID = "test-account-456";
29+
private static final String TEST_URL = "https://api.example.com/data";
30+
31+
@BeforeEach
32+
public void setup() throws Exception {
33+
server = new MockWebServer();
34+
server.start();
35+
String baseUrl = server.url("/").toString();
36+
// Explicitly set credentials to null to avoid OAuth token fetching
37+
// (environment variables might be set, which would trigger network calls)
38+
client = BaseClient.builder()
39+
.url(baseUrl)
40+
.projectId("test-project")
41+
.clientId(null)
42+
.clientSecret(null)
43+
.build();
44+
asyncClient = AsyncBaseClient.builder()
45+
.url(baseUrl)
46+
.projectId("test-project")
47+
.clientId(null)
48+
.clientSecret(null)
49+
.build();
50+
}
51+
52+
@AfterEach
53+
public void teardown() throws Exception {
54+
server.shutdown();
55+
}
56+
57+
private ProxyGetRequest createGetRequest() {
58+
return ProxyGetRequest.builder()
59+
.externalUserId(TEST_EXTERNAL_USER_ID)
60+
.accountId(TEST_ACCOUNT_ID)
61+
.build();
62+
}
63+
64+
/**
65+
* Java 8-compatible replacement for InputStream.readAllBytes() (Java 9+).
66+
*/
67+
private byte[] readAllBytes(InputStream is) throws IOException {
68+
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
69+
byte[] data = new byte[1024];
70+
int bytesRead;
71+
while ((bytesRead = is.read(data, 0, data.length)) != -1) {
72+
buffer.write(data, 0, bytesRead);
73+
}
74+
return buffer.toByteArray();
75+
}
76+
77+
// ==================== Sync Client Tests ====================
78+
79+
@Test
80+
public void testGetJsonResponse() throws Exception {
81+
String jsonBody = "{\"key\":\"value\",\"number\":42}";
82+
server.enqueue(new MockResponse()
83+
.setResponseCode(200)
84+
.setHeader("Content-Type", "application/json")
85+
.setBody(jsonBody));
86+
87+
ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest());
88+
89+
// Verify response type
90+
assertTrue(response.isJson(), "Response should be JSON");
91+
assertFalse(response.isStream(), "Response should not be a stream");
92+
93+
// Verify parsed JSON content
94+
Object json = response.json();
95+
assertNotNull(json, "JSON body should not be null");
96+
assertInstanceOf(Map.class, json, "JSON body should be a Map");
97+
98+
@SuppressWarnings("unchecked")
99+
Map<String, Object> jsonMap = (Map<String, Object>) json;
100+
assertEquals("value", jsonMap.get("key"));
101+
assertEquals(42, jsonMap.get("number"));
102+
103+
// Verify content type is preserved
104+
assertTrue(response.getContentType().isPresent());
105+
assertEquals("application/json", response.getContentType().get());
106+
107+
// Verify request was made correctly
108+
RecordedRequest request = server.takeRequest();
109+
assertNotNull(request);
110+
assertEquals("GET", request.getMethod());
111+
}
112+
113+
@Test
114+
public void testGetJsonResponseWithCharset() {
115+
String jsonBody = "{\"message\":\"hello\"}";
116+
server.enqueue(new MockResponse()
117+
.setResponseCode(200)
118+
.setHeader("Content-Type", "application/json; charset=utf-8")
119+
.setBody(jsonBody));
120+
121+
ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest());
122+
123+
// Should still be detected as JSON even with charset parameter
124+
assertTrue(response.isJson(), "Response should be JSON even with charset");
125+
126+
@SuppressWarnings("unchecked")
127+
Map<String, Object> jsonMap = (Map<String, Object>) response.json();
128+
assertEquals("hello", jsonMap.get("message"));
129+
}
130+
131+
@Test
132+
public void testGetOctetStreamResponse() throws Exception {
133+
byte[] binaryData = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
134+
Buffer buffer = new Buffer();
135+
buffer.write(binaryData);
136+
137+
server.enqueue(new MockResponse()
138+
.setResponseCode(200)
139+
.setHeader("Content-Type", "application/octet-stream")
140+
.setBody(buffer));
141+
142+
ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest());
143+
144+
// Verify response type
145+
assertTrue(response.isStream(), "Response should be a stream");
146+
assertFalse(response.isJson(), "Response should not be JSON");
147+
148+
// Verify binary content
149+
byte[] actualData = readAllBytes(response.stream());
150+
assertArrayEquals(binaryData, actualData, "Binary data should match");
151+
152+
// Verify content type is preserved
153+
assertTrue(response.getContentType().isPresent());
154+
assertEquals("application/octet-stream", response.getContentType().get());
155+
156+
// Clean up
157+
response.close();
158+
159+
// Verify request was made correctly
160+
RecordedRequest request = server.takeRequest();
161+
assertNotNull(request);
162+
assertEquals("GET", request.getMethod());
163+
}
164+
165+
@Test
166+
public void testGetRedirectFollowed() throws Exception {
167+
// First response: 302 redirect
168+
server.enqueue(new MockResponse()
169+
.setResponseCode(302)
170+
.setHeader("Location", server.url("/redirected").toString()));
171+
172+
// Second response: 200 OK with JSON
173+
String jsonBody = "{\"redirected\":true,\"status\":\"success\"}";
174+
server.enqueue(new MockResponse()
175+
.setResponseCode(200)
176+
.setHeader("Content-Type", "application/json")
177+
.setBody(jsonBody));
178+
179+
ProxyResponse response = client.proxy().get(TEST_URL, createGetRequest());
180+
181+
// Verify we got the final response (redirect was followed)
182+
assertTrue(response.isJson(), "Response should be JSON after redirect");
183+
184+
@SuppressWarnings("unchecked")
185+
Map<String, Object> jsonMap = (Map<String, Object>) response.json();
186+
assertEquals(true, jsonMap.get("redirected"));
187+
assertEquals("success", jsonMap.get("status"));
188+
189+
// Verify both requests were made (original + redirect)
190+
RecordedRequest firstRequest = server.takeRequest();
191+
assertNotNull(firstRequest);
192+
assertEquals("GET", firstRequest.getMethod());
193+
194+
RecordedRequest secondRequest = server.takeRequest();
195+
assertNotNull(secondRequest);
196+
assertEquals("GET", secondRequest.getMethod());
197+
assertNotNull(secondRequest.getPath());
198+
assertTrue(secondRequest.getPath().contains("redirected"));
199+
}
200+
201+
// ==================== Async Client Tests ====================
202+
203+
@Test
204+
public void testAsyncGetJsonResponse() throws Exception {
205+
String jsonBody = "{\"async\":true,\"data\":\"test\"}";
206+
server.enqueue(new MockResponse()
207+
.setResponseCode(200)
208+
.setHeader("Content-Type", "application/json")
209+
.setBody(jsonBody));
210+
211+
CompletableFuture<ProxyResponse> future = asyncClient.proxy().get(TEST_URL, createGetRequest());
212+
ProxyResponse response = future.get(10, TimeUnit.SECONDS);
213+
214+
// Verify response type
215+
assertTrue(response.isJson(), "Response should be JSON");
216+
assertFalse(response.isStream(), "Response should not be a stream");
217+
218+
// Verify parsed JSON content
219+
@SuppressWarnings("unchecked")
220+
Map<String, Object> jsonMap = (Map<String, Object>) response.json();
221+
assertEquals(true, jsonMap.get("async"));
222+
assertEquals("test", jsonMap.get("data"));
223+
224+
// Verify request was made correctly
225+
RecordedRequest request = server.takeRequest();
226+
assertNotNull(request);
227+
assertEquals("GET", request.getMethod());
228+
}
229+
230+
@Test
231+
public void testAsyncGetOctetStreamResponse() throws Exception {
232+
byte[] binaryData = new byte[]{(byte) 0xFF, (byte) 0xFE, (byte) 0xFD};
233+
Buffer buffer = new Buffer();
234+
buffer.write(binaryData);
235+
236+
server.enqueue(new MockResponse()
237+
.setResponseCode(200)
238+
.setHeader("Content-Type", "application/octet-stream")
239+
.setBody(buffer));
240+
241+
CompletableFuture<ProxyResponse> future = asyncClient.proxy().get(TEST_URL, createGetRequest());
242+
ProxyResponse response = future.get(10, TimeUnit.SECONDS);
243+
244+
// Verify response type
245+
assertTrue(response.isStream(), "Response should be a stream");
246+
assertFalse(response.isJson(), "Response should not be JSON");
247+
248+
// Verify binary content
249+
byte[] actualData = readAllBytes(response.stream());
250+
assertArrayEquals(binaryData, actualData, "Binary data should match");
251+
252+
// Clean up
253+
response.close();
254+
255+
// Verify request was made correctly
256+
RecordedRequest request = server.takeRequest();
257+
assertNotNull(request);
258+
assertEquals("GET", request.getMethod());
259+
}
260+
261+
@Test
262+
public void testAsyncGetRedirectFollowed() throws Exception {
263+
// First response: 302 redirect
264+
server.enqueue(new MockResponse()
265+
.setResponseCode(302)
266+
.setHeader("Location", server.url("/async-redirected").toString()));
267+
268+
// Second response: 200 OK with JSON
269+
String jsonBody = "{\"asyncRedirected\":true}";
270+
server.enqueue(new MockResponse()
271+
.setResponseCode(200)
272+
.setHeader("Content-Type", "application/json")
273+
.setBody(jsonBody));
274+
275+
CompletableFuture<ProxyResponse> future = asyncClient.proxy().get(TEST_URL, createGetRequest());
276+
ProxyResponse response = future.get(10, TimeUnit.SECONDS);
277+
278+
// Verify we got the final response (redirect was followed)
279+
assertTrue(response.isJson(), "Response should be JSON after redirect");
280+
281+
@SuppressWarnings("unchecked")
282+
Map<String, Object> jsonMap = (Map<String, Object>) response.json();
283+
assertEquals(true, jsonMap.get("asyncRedirected"));
284+
285+
// Verify both requests were made (original + redirect)
286+
RecordedRequest firstRequest = server.takeRequest();
287+
assertNotNull(firstRequest);
288+
289+
RecordedRequest secondRequest = server.takeRequest();
290+
assertNotNull(secondRequest);
291+
assertNotNull(secondRequest.getPath());
292+
assertTrue(secondRequest.getPath().contains("async-redirected"));
293+
}
294+
}

0 commit comments

Comments
 (0)