mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-22 23:45:02 +00:00

# Description of Changes Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
280 lines
9.5 KiB
Java
280 lines
9.5 KiB
Java
package stirling.software.SPDF.utils;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
import java.io.IOException;
|
|
import java.net.ServerSocket;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
import org.mockito.Mock;
|
|
import org.mockito.junit.jupiter.MockitoExtension;
|
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
|
|
@ExtendWith(MockitoExtension.class)
|
|
class UrlUtilsTest {
|
|
|
|
@Mock private HttpServletRequest request;
|
|
|
|
@Test
|
|
void testGetOrigin() {
|
|
// Arrange
|
|
when(request.getScheme()).thenReturn("http");
|
|
when(request.getServerName()).thenReturn("localhost");
|
|
when(request.getServerPort()).thenReturn(8080);
|
|
when(request.getContextPath()).thenReturn("/myapp");
|
|
|
|
// Act
|
|
String origin = UrlUtils.getOrigin(request);
|
|
|
|
// Assert
|
|
assertEquals(
|
|
"http://localhost:8080/myapp", origin, "Origin URL should be correctly formatted");
|
|
}
|
|
|
|
@Test
|
|
void testGetOriginWithHttps() {
|
|
// Arrange
|
|
when(request.getScheme()).thenReturn("https");
|
|
when(request.getServerName()).thenReturn("example.com");
|
|
when(request.getServerPort()).thenReturn(443);
|
|
when(request.getContextPath()).thenReturn("");
|
|
|
|
// Act
|
|
String origin = UrlUtils.getOrigin(request);
|
|
|
|
// Assert
|
|
assertEquals(
|
|
"https://example.com:443",
|
|
origin,
|
|
"HTTPS origin URL should be correctly formatted");
|
|
}
|
|
|
|
@Test
|
|
void testGetOriginWithEmptyContextPath() {
|
|
// Arrange
|
|
when(request.getScheme()).thenReturn("http");
|
|
when(request.getServerName()).thenReturn("localhost");
|
|
when(request.getServerPort()).thenReturn(8080);
|
|
when(request.getContextPath()).thenReturn("");
|
|
|
|
// Act
|
|
String origin = UrlUtils.getOrigin(request);
|
|
|
|
// Assert
|
|
assertEquals(
|
|
"http://localhost:8080",
|
|
origin,
|
|
"Origin URL with empty context path should be correct");
|
|
}
|
|
|
|
@Test
|
|
void testGetOriginWithSpecialCharacters() {
|
|
// Arrange - Test with server name containing special characters
|
|
when(request.getScheme()).thenReturn("https");
|
|
when(request.getServerName()).thenReturn("internal-server.example-domain.com");
|
|
when(request.getServerPort()).thenReturn(8443);
|
|
when(request.getContextPath()).thenReturn("/app-v1.2");
|
|
|
|
// Act
|
|
String origin = UrlUtils.getOrigin(request);
|
|
|
|
// Assert
|
|
assertEquals(
|
|
"https://internal-server.example-domain.com:8443/app-v1.2",
|
|
origin,
|
|
"Origin URL with special characters should be correctly formatted");
|
|
}
|
|
|
|
@Test
|
|
void testGetOriginWithIPv4Address() {
|
|
// Arrange
|
|
when(request.getScheme()).thenReturn("http");
|
|
when(request.getServerName()).thenReturn("192.168.1.100");
|
|
when(request.getServerPort()).thenReturn(8080);
|
|
when(request.getContextPath()).thenReturn("/app");
|
|
|
|
// Act
|
|
String origin = UrlUtils.getOrigin(request);
|
|
|
|
// Assert
|
|
assertEquals(
|
|
"http://192.168.1.100:8080/app",
|
|
origin,
|
|
"Origin URL with IPv4 address should be correctly formatted");
|
|
}
|
|
|
|
@Test
|
|
void testGetOriginWithNonStandardPort() {
|
|
// Arrange
|
|
when(request.getScheme()).thenReturn("https");
|
|
when(request.getServerName()).thenReturn("example.org");
|
|
when(request.getServerPort()).thenReturn(8443);
|
|
when(request.getContextPath()).thenReturn("/api");
|
|
|
|
// Act
|
|
String origin = UrlUtils.getOrigin(request);
|
|
|
|
// Assert
|
|
assertEquals(
|
|
"https://example.org:8443/api",
|
|
origin,
|
|
"Origin URL with non-standard port should be correctly formatted");
|
|
}
|
|
|
|
@Test
|
|
void testIsPortAvailable() {
|
|
// We'll use a real server socket for this test
|
|
ServerSocket socket = null;
|
|
int port = 12345; // Choose a port unlikely to be in use
|
|
|
|
try {
|
|
// First check the port is available
|
|
boolean initialAvailability = UrlUtils.isPortAvailable(port);
|
|
|
|
// Then occupy the port
|
|
socket = new ServerSocket(port);
|
|
|
|
// Now check the port is no longer available
|
|
boolean afterSocketCreation = UrlUtils.isPortAvailable(port);
|
|
|
|
// Assert
|
|
assertTrue(initialAvailability, "Port should be available initially");
|
|
assertFalse(
|
|
afterSocketCreation, "Port should not be available after socket is created");
|
|
|
|
} catch (IOException e) {
|
|
// This might happen if the port is already in use by another process
|
|
// We'll just verify the behavior of isPortAvailable matches what we expect
|
|
assertFalse(
|
|
UrlUtils.isPortAvailable(port),
|
|
"Port should not be available if exception is thrown");
|
|
} finally {
|
|
if (socket != null && !socket.isClosed()) {
|
|
try {
|
|
socket.close();
|
|
} catch (IOException e) {
|
|
// Ignore cleanup exceptions
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void testFindAvailablePort() {
|
|
// We'll create a socket on a port and ensure findAvailablePort returns a different port
|
|
ServerSocket socket = null;
|
|
int startPort = 12346; // Choose a port unlikely to be in use
|
|
|
|
try {
|
|
// Occupy the start port
|
|
socket = new ServerSocket(startPort);
|
|
|
|
// Find an available port
|
|
String availablePort = UrlUtils.findAvailablePort(startPort);
|
|
|
|
// Assert the returned port is not the occupied one
|
|
assertNotEquals(
|
|
String.valueOf(startPort),
|
|
availablePort,
|
|
"findAvailablePort should not return an occupied port");
|
|
|
|
// Verify the returned port is actually available
|
|
int portNumber = Integer.parseInt(availablePort);
|
|
|
|
// Close our test socket before checking the found port
|
|
socket.close();
|
|
socket = null;
|
|
|
|
// The port should now be available
|
|
assertTrue(
|
|
UrlUtils.isPortAvailable(portNumber),
|
|
"The port returned by findAvailablePort should be available");
|
|
|
|
} catch (IOException e) {
|
|
// If we can't create the socket, skip this assertion
|
|
} finally {
|
|
if (socket != null && !socket.isClosed()) {
|
|
try {
|
|
socket.close();
|
|
} catch (IOException e) {
|
|
// Ignore cleanup exceptions
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void testFindAvailablePortWithAvailableStartPort() {
|
|
// Find an available port without occupying any
|
|
int startPort = 23456; // Choose a different unlikely-to-be-used port
|
|
|
|
// Make sure the port is available first
|
|
if (UrlUtils.isPortAvailable(startPort)) {
|
|
// Find an available port
|
|
String availablePort = UrlUtils.findAvailablePort(startPort);
|
|
|
|
// Assert the returned port is the start port since it's available
|
|
assertEquals(
|
|
String.valueOf(startPort),
|
|
availablePort,
|
|
"findAvailablePort should return the start port if it's available");
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void testFindAvailablePortWithSequentialUsedPorts() {
|
|
// This test checks that findAvailablePort correctly skips multiple occupied ports
|
|
ServerSocket socket1 = null;
|
|
ServerSocket socket2 = null;
|
|
int startPort = 34567; // Another unlikely-to-be-used port
|
|
|
|
try {
|
|
// First verify the port is available
|
|
if (!UrlUtils.isPortAvailable(startPort)) {
|
|
return;
|
|
}
|
|
|
|
// Occupy two sequential ports
|
|
socket1 = new ServerSocket(startPort);
|
|
socket2 = new ServerSocket(startPort + 1);
|
|
|
|
// Find an available port starting from our occupied range
|
|
String availablePort = UrlUtils.findAvailablePort(startPort);
|
|
int foundPort = Integer.parseInt(availablePort);
|
|
|
|
// Should have skipped the two occupied ports
|
|
assertTrue(
|
|
foundPort >= startPort + 2,
|
|
"findAvailablePort should skip sequential occupied ports");
|
|
|
|
// Verify the found port is actually available
|
|
try (ServerSocket testSocket = new ServerSocket(foundPort)) {
|
|
assertTrue(testSocket.isBound(), "The found port should be bindable");
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
// Skip test if we encounter IO exceptions
|
|
} finally {
|
|
// Clean up resources
|
|
try {
|
|
if (socket1 != null && !socket1.isClosed()) socket1.close();
|
|
if (socket2 != null && !socket2.isClosed()) socket2.close();
|
|
} catch (IOException e) {
|
|
// Ignore cleanup exceptions
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void testIsPortAvailableWithPrivilegedPorts() {
|
|
// Skip tests for privileged ports as they typically require root access
|
|
// and results are environment-dependent
|
|
}
|
|
}
|