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
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.docling.ConversionStatus;
import org.apache.camel.component.docling.ConversionStatus.Status;
import org.apache.camel.component.docling.DoclingHeaders;
import org.apache.camel.component.docling.DoclingOperations;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import org.junit.jupiter.api.io.TempDir;

import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
Expand All @@ -45,156 +48,143 @@ class DoclingServeProducerIT extends DoclingITestSupport {
Path outputDir;

@Test
public void testMarkdownConversionWithDoclingServe() throws Exception {
void testMarkdownConversionWithDoclingServe() throws Exception {
Path testFile = createTestFile();

String result = template.requestBodyAndHeader("direct:convert-markdown-serve",
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), String.class);

assertNotNull(result);
assertTrue(result.length() > 0);
assertThat(result).containsIgnoringCase("Test Document");

LOG.info("Successfully converted document to Markdown");
}

@Test
public void testHtmlConversionWithDoclingServe() throws Exception {
void testHtmlConversionWithDoclingServe() throws Exception {
Path testFile = createTestFile();

String result = template.requestBodyAndHeader("direct:convert-html-serve",
testFile.toString(),
DoclingHeaders.OPERATION, DoclingOperations.CONVERT_TO_HTML, String.class);

assertNotNull(result);
assertTrue(result.length() > 0);
assertThat(result).containsIgnoringCase("<h1>Test Document</h1>");

LOG.info("Successfully converted document to HTML");
}

@Test
public void testUrlConversionWithDoclingServe() throws Exception {
void testUrlConversionWithDoclingServe() throws Exception {
// Test converting a document from a URL
String url = "https://arxiv.org/pdf/2501.17887";

String result = template.requestBody("direct:convert-url-serve", url, String.class);

assertNotNull(result);
assertTrue(result.length() > 0);
assertThat(result).containsIgnoringCase("An Efficient Open-Source Toolkit");

LOG.info("Successfully converted document from URL");
}

@Test
public void testJsonConversionWithDoclingServe() throws Exception {
void testJsonConversionWithDoclingServe() throws Exception {
Path testFile = createTestFile();

String result = template.requestBodyAndHeader("direct:convert-json-serve",
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), String.class);

assertNotNull(result);
assertTrue(result.length() > 0);
// JSON response should contain some structure
assertTrue(result.contains("{") || result.contains("["));
assertThatJson(result).node("schema_name").asString().isEqualTo("DoclingDocument");
assertThatJson(result).inPath("texts[*].text").isArray().contains("Test Document",
"This is a test document for Docling-Serve processing.");

LOG.info("Successfully converted document to JSON");
}

@Test
public void testConvertAndWriteToFile() throws Exception {
void testConvertAndWriteToFile() throws Exception {
Path testFile = createTestFile();

// Send the file path to the route that converts and writes to file
template.sendBodyAndHeader("direct:convert-and-write",
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString());

// Verify the output file was created
File outputFile = new File(outputDir.toFile(), "converted-output.md");
assertTrue(outputFile.exists(), "Output file should exist");
assertTrue(outputFile.length() > 0, "Output file should not be empty");

// Read and verify content
String content = Files.readString(outputFile.toPath());
assertNotNull(content);
assertTrue(content.length() > 0);
assertThat(outputFile.toPath())
.exists()
.content().containsIgnoringCase("Test Document");

LOG.info("Successfully converted document and wrote to file: {}", outputFile.getAbsolutePath());
LOG.info("Output file size: {} bytes", outputFile.length());
}

@Test
public void testAsyncMarkdownConversion() throws Exception {
void testAsyncMarkdownConversion() throws Exception {
Path testFile = createTestFile();

String result = template.requestBodyAndHeader("direct:convert-async-markdown",
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), String.class);

assertNotNull(result, "Async conversion result should not be null");
assertTrue(result.length() > 0, "Async conversion result should not be empty");
assertThat(result).containsIgnoringCase("Test Document");

LOG.info("Successfully converted document to Markdown using async mode");
}

@Test
public void testAsyncHtmlConversion() throws Exception {
void testAsyncHtmlConversion() throws Exception {
Path testFile = createTestFile();

String result = template.requestBodyAndHeader("direct:convert-async-html",
testFile.toString(),
DoclingHeaders.OPERATION, DoclingOperations.CONVERT_TO_HTML, String.class);

assertNotNull(result, "Async HTML conversion result should not be null");
assertTrue(result.length() > 0, "Async HTML conversion result should not be empty");
assertThat(result).containsIgnoringCase("<h1>Test Document</h1>");

LOG.info("Successfully converted document to HTML using async mode");
}

@Test
public void testAsyncJsonConversion() throws Exception {
void testAsyncJsonConversion() throws Exception {
Path testFile = createTestFile();

String result = template.requestBodyAndHeader("direct:convert-async-json",
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), String.class);

assertNotNull(result, "Async JSON conversion result should not be null");
assertTrue(result.length() > 0, "Async JSON conversion result should not be empty");
assertTrue(result.contains("{") || result.contains("["), "JSON result should contain JSON structure");
assertThatJson(result).node("schema_name").asString().isEqualTo("DoclingDocument");
assertThatJson(result).inPath("texts[*].text").isArray().contains("Test Document",
"This is a test document for Docling-Serve processing.");

LOG.info("Successfully converted document to JSON using async mode");
}

@Test
public void testAsyncUrlConversion() throws Exception {
void testAsyncUrlConversion() throws Exception {
String url = "https://arxiv.org/pdf/2501.17887";

String result = template.requestBody("direct:convert-async-url", url, String.class);

assertNotNull(result, "Async URL conversion result should not be null");
assertTrue(result.length() > 0, "Async URL conversion result should not be empty");
assertThat(result).containsIgnoringCase("An Efficient Open-Source Toolkit");

LOG.info("Successfully converted document from URL using async mode");
}

@Test
public void testAsyncConversionWithCustomTimeout() throws Exception {
void testAsyncConversionWithCustomTimeout() throws Exception {
Path testFile = createTestFile();

String result = template.requestBodyAndHeader("direct:convert-async-custom-timeout",
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), String.class);

assertNotNull(result, "Async conversion with custom timeout should not be null");
assertTrue(result.length() > 0, "Async conversion with custom timeout should not be empty");
assertThat(result).contains("This is a test document for Docling-Serve processing.");

LOG.info("Successfully converted document using async mode with custom timeout");
}

@Test
public void testAsyncConversionWithHeaderOverride() throws Exception {
void testAsyncConversionWithHeaderOverride() throws Exception {
Path testFile = createTestFile();

// Use sync endpoint but override with async header
Expand All @@ -209,29 +199,27 @@ public void testAsyncConversionWithHeaderOverride() throws Exception {
}
}, String.class);

assertNotNull(result, "Async conversion via header override should not be null");
assertTrue(result.length() > 0, "Async conversion via header override should not be empty");
assertThat(result).contains("This is a test document for Docling-Serve processing.");

LOG.info("Successfully converted document using async mode via header override");
}

@Test
public void testSubmitAsyncConversion() throws Exception {
void testSubmitAsyncConversion() throws Exception {
Path testFile = createTestFile();

// Submit async conversion and get task ID
String taskId = template.requestBodyAndHeader("direct:submit-async",
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), String.class);

assertNotNull(taskId, "Task ID should not be null");
assertTrue(taskId.length() > 0, "Task ID should not be empty");
assertThat(taskId).startsWith("task-");

LOG.info("Successfully submitted async conversion with task ID: {}", taskId);
}

@Test
public void testCheckConversionStatus() throws Exception {
void testCheckConversionStatus() throws Exception {
Path testFile = createTestFile();

// First, submit async conversion
Expand All @@ -249,13 +237,13 @@ public void testCheckConversionStatus() throws Exception {

assertNotNull(status, "Status should not be null");
assertNotNull(status.getTaskId(), "Status task ID should not be null");
assertNotNull(status.getStatus(), "Status state should not be null");
assertThat(status.getStatus()).isEqualTo(Status.COMPLETED);

LOG.info("Successfully checked status for task {}: {}", taskId, status.getStatus());
}

@Test
public void testCustomAsyncWorkflow() throws Exception {
void testCustomAsyncWorkflow() throws Exception {
Path testFile = createTestFile();

// Custom workflow: submit, poll until complete, get result
Expand Down Expand Up @@ -293,13 +281,14 @@ public void testCustomAsyncWorkflow() throws Exception {
}

if (status.getResult() != null) {
// TODO: this check can never happen as there is an if condition before. The status.getResult() is actually null, is it expected or a bug?
assertTrue(status.getResult().length() > 0, "Result should not be empty");
LOG.info("Successfully retrieved result: {} characters", status.getResult().length());
}
}

@Test
public void testCustomPollingWorkflowWithRoute() throws Exception {
void testCustomPollingWorkflowWithRoute() throws Exception {
Path testFile = createTestFile();

// This test demonstrates using the built-in async mode with a route
Expand All @@ -308,18 +297,27 @@ public void testCustomPollingWorkflowWithRoute() throws Exception {
testFile.toString(),
DoclingHeaders.INPUT_FILE_PATH, testFile.toString(), String.class);

assertNotNull(result, "Result should not be null");
assertTrue(result.length() > 0, "Result should not be empty");
assertThat(result).contains("This is a test document for Docling-Serve processing.");

LOG.info("Custom polling workflow (using built-in async mode) completed successfully with {} characters",
result.length());
}

private Path createTestFile() throws Exception {
Path tempFile = Files.createTempFile("docling-serve-test", ".md");
Files.write(tempFile,
"# Test Document\n\nThis is a test document for Docling-Serve processing.\n\n## Section 1\n\nSome content here.\n\n- List item 1\n- List item 2\n"
.getBytes());
Files.writeString(tempFile,
"""
# Test Document

This is a test document for Docling-Serve processing.

## Section 1

Some content here.

- List item 1
- List item 2
""");
return tempFile;
}

Expand Down
Loading