Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 63 additions & 0 deletions src/main/java/io/getstream/services/framework/StreamRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.getstream.exceptions.StreamException;
import io.getstream.models.UploadFileRequest;
import io.getstream.models.UploadImageRequest;
import io.getstream.models.framework.RateLimit;
import io.getstream.models.framework.StreamResponse;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
Expand Down Expand Up @@ -38,6 +41,10 @@ public StreamRequest(
RequestBody rawBody;
if (List.of("GET", "DELETE", "HEAD", "OPTIONS").contains(method) || jRequest == null) {
rawBody = null;
} else if (jRequest instanceof UploadFileRequest) {
rawBody = createMultipartBody((UploadFileRequest) jRequest);
} else if (jRequest instanceof UploadImageRequest) {
rawBody = createMultipartBody((UploadImageRequest) jRequest);
} else {
rawBody = RequestBody.create(objectMapper.writeValueAsBytes(jRequest));
}
Expand Down Expand Up @@ -103,6 +110,62 @@ public HttpUrl buildUrl(
return urlBuilder.build();
}

private RequestBody createMultipartBody(UploadFileRequest request) throws IOException {
if (request.getFile() == null || request.getFile().isEmpty()) {
throw new IllegalArgumentException("File path must be provided");
}

File file = new File(request.getFile());
if (!file.exists()) {
throw new IOException("File not found: " + request.getFile());
}

MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);

// Add file
RequestBody fileBody = RequestBody.create(file, MediaType.parse("application/octet-stream"));
builder.addFormDataPart("file", file.getName(), fileBody);

// Add user field if present
if (request.getUser() != null) {
String userJson = objectMapper.writeValueAsString(request.getUser());
builder.addFormDataPart("user", userJson);
}

return builder.build();
}

private RequestBody createMultipartBody(UploadImageRequest request) throws IOException {
if (request.getFile() == null || request.getFile().isEmpty()) {
throw new IllegalArgumentException("File path must be provided");
}

File file = new File(request.getFile());
if (!file.exists()) {
throw new IOException("File not found: " + request.getFile());
}

MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);

// Add file
RequestBody fileBody = RequestBody.create(file, MediaType.parse("image/*"));
builder.addFormDataPart("file", file.getName(), fileBody);

// Add upload_sizes field if present
if (request.getUploadSizes() != null && !request.getUploadSizes().isEmpty()) {
String uploadSizesJson = objectMapper.writeValueAsString(request.getUploadSizes());
builder.addFormDataPart("upload_sizes", uploadSizesJson);
}

// Add user field if present
if (request.getUser() != null) {
String userJson = objectMapper.writeValueAsString(request.getUser());
builder.addFormDataPart("user", userJson);
}

return builder.build();
}

public StreamResponse<T> execute() throws StreamException {
okhttp3.Call call = client.newCall(request);
Response response;
Expand Down
69 changes: 69 additions & 0 deletions src/test/java/io/getstream/FeedIntegrationTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,75 @@ void test32_RealWorldUsageDemo() throws Exception {
System.out.println("✅ Completed real-world usage scenario demonstration");
}

/** Test file upload functionality */
@Test
@Order(37)
void test37_UploadImage() throws Exception {
System.out.println("\n🖼️ Testing image upload...");

// snippet-start: UploadImage
UploadImageRequest imageUploadRequest =
UploadImageRequest.builder()
.file("img.png")
.user(OnlyUserID.builder().id(testUserId).build())
.uploadSizes(
List.of(
ImageSize.builder()
.width(100)
.height(100)
.resize("scale")
.crop("center")
.build()))
.build();

ImageUploadResponse imageResponse = common.uploadImage(imageUploadRequest).execute().getData();
// snippet-end: UploadImage

Assertions.assertNotNull(imageResponse, "Image upload response should not be null");
Assertions.assertNotNull(imageResponse.getFile(), "Uploaded image URL should not be null");
Assertions.assertTrue(
imageResponse.getFile().contains("http"), "Image URL should be a valid HTTP URL");

System.out.println("✅ Image uploaded successfully: " + imageResponse.getFile());
}

/** Test file upload functionality */
@Test
@Order(38)
void test38_UploadFile() throws Exception {
System.out.println("\n📄 Testing file upload...");

// Create a temporary test file
java.io.File tempFile = java.io.File.createTempFile("test-file-", ".txt");
java.nio.file.Files.writeString(
tempFile.toPath(),
"This is a test file for integration testing\nContains multiple lines\nWith various content");

try {
// snippet-start: UploadFile
UploadFileRequest fileUploadRequest =
UploadFileRequest.builder()
.file(tempFile.getAbsolutePath())
.user(OnlyUserID.builder().id(testUserId).build())
.build();

FileUploadResponse fileResponse = common.uploadFile(fileUploadRequest).execute().getData();
// snippet-end: UploadFile

Assertions.assertNotNull(fileResponse, "File upload response should not be null");
Assertions.assertNotNull(fileResponse.getFile(), "Uploaded file URL should not be null");
Assertions.assertTrue(
fileResponse.getFile().contains("http"), "File URL should be a valid HTTP URL");

System.out.println("✅ File uploaded successfully: " + fileResponse.getFile());
} finally {
// Clean up temp file
if (tempFile.exists()) {
tempFile.delete();
}
}
}

// =================================================================
// HELPER METHODS
// =================================================================
Expand Down