Skip to content

Commit 536d6c0

Browse files
committed
Test it with http request to HttpServer.
1 parent d0ab476 commit 536d6c0

File tree

1 file changed

+134
-90
lines changed

1 file changed

+134
-90
lines changed

src/test/java/org/tinystruct/system/HttpServerHttpModeTest.java

Lines changed: 134 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,92 @@
11
package org.tinystruct.system;
22

3-
import org.junit.jupiter.api.BeforeEach;
4-
import org.junit.jupiter.api.Test;
3+
import org.junit.jupiter.api.*;
54
import org.tinystruct.AbstractApplication;
65
import org.tinystruct.ApplicationContext;
7-
import org.tinystruct.ApplicationException;
86
import org.tinystruct.application.Action;
9-
import org.tinystruct.application.ActionRegistry;
107
import org.tinystruct.http.Method;
8+
import org.tinystruct.http.Response;
9+
import org.tinystruct.net.URLRequest;
10+
import org.tinystruct.net.URLResponse;
11+
import org.tinystruct.net.handlers.HTTPHandler;
12+
import org.tinystruct.system.Dispatcher;
13+
14+
import java.io.BufferedReader;
15+
import java.io.InputStreamReader;
16+
import java.io.OutputStream;
17+
import java.net.HttpURLConnection;
18+
import java.net.Socket;
19+
import java.net.URI;
20+
import java.net.URL;
21+
import java.nio.charset.StandardCharsets;
1122

1223
import static org.junit.jupiter.api.Assertions.*;
1324

25+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
1426
public class HttpServerHttpModeTest {
1527

28+
private static final int TEST_PORT = 18080;
29+
private static final String BASE_URL = "http://localhost:" + TEST_PORT;
30+
private HttpServer httpServer;
31+
private Thread serverThread;
1632
private TestWebApp app;
17-
private ActionRegistry registry;
1833

19-
@BeforeEach
20-
public void setup() throws ApplicationException {
34+
@BeforeAll
35+
public void setUp() throws Exception {
36+
// Initialize settings
37+
Settings settings = new Settings();
38+
settings.set("default.base_url", "/?q=");
39+
settings.set("default.language", "en_US");
40+
settings.set("charset", "utf-8");
41+
42+
// Create and install test app
2143
this.app = new TestWebApp();
44+
ApplicationManager.install(this.app, settings);
45+
46+
// Install required applications
47+
ApplicationManager.install(new Dispatcher());
48+
this.httpServer = new HttpServer();
49+
ApplicationManager.install(this.httpServer, settings);
50+
51+
// Start server in a separate thread
52+
serverThread = new Thread(() -> {
53+
try {
54+
ApplicationContext context = new ApplicationContext();
55+
context.setAttribute("--server-port", String.valueOf(TEST_PORT));
56+
ApplicationManager.call("start", context, Action.Mode.CLI);
57+
} catch (Exception e) {
58+
e.printStackTrace();
59+
}
60+
});
61+
serverThread.setDaemon(true);
62+
serverThread.start();
63+
64+
// Wait for server to be ready
65+
boolean started = false;
66+
for (int i = 0; i < 30; i++) {
67+
try (Socket socket = new Socket("localhost", TEST_PORT)) {
68+
started = true;
69+
break;
70+
} catch (Exception e) {
71+
Thread.sleep(1000);
72+
}
73+
}
74+
if (!started) {
75+
throw new RuntimeException("Server failed to start within 30 seconds");
76+
}
77+
78+
// Give server a moment to fully initialize
79+
Thread.sleep(500);
80+
}
2281

23-
this.registry = ActionRegistry.getInstance();
24-
// Initialize configuration to trigger annotation processing
25-
this.app.setConfiguration(new Settings());
26-
// Ensure annotations are processed
27-
new AnnotationProcessor(this.app).processActionAnnotations();
82+
@AfterAll
83+
public void tearDown() {
84+
if (httpServer != null) {
85+
httpServer.stop();
86+
}
87+
if (serverThread != null && serverThread.isAlive()) {
88+
serverThread.interrupt();
89+
}
2890
}
2991

3092
@Test
@@ -48,109 +110,91 @@ public void testActionModeFromName() {
48110
}
49111

50112
@Test
51-
public void testHttpGetRouting() throws ApplicationException {
52-
// Test that GET requests match HTTP_GET mode actions
53-
Action action = registry.getAction("api/users", Action.Mode.HTTP_GET);
54-
assertNotNull(action, "GET action should be found");
55-
assertEquals(Action.Mode.HTTP_GET, action.getMode());
56-
57-
Object result = action.execute();
58-
assertEquals("GET users", String.valueOf(result));
113+
public void testHttpGetRequest() throws Exception {
114+
// Make actual HTTP GET request
115+
String response = sendHttpRequest("GET", BASE_URL + "/?q=api/users", null);
116+
assertTrue(response.contains("GET users"), "GET request should return 'GET users'");
59117
}
60118

61119
@Test
62-
public void testHttpPostRouting() throws ApplicationException {
63-
// Test that POST requests match HTTP_POST mode actions
64-
Action action = registry.getAction("api/users", Action.Mode.HTTP_POST);
65-
assertNotNull(action, "POST action should be found");
66-
assertEquals(Action.Mode.HTTP_POST, action.getMode());
67-
68-
Object result = action.execute();
69-
assertEquals("POST users", String.valueOf(result));
120+
public void testHttpPostRequest() throws Exception {
121+
// Make actual HTTP POST request
122+
String response = sendHttpRequest("POST", BASE_URL + "/?q=api/users", null);
123+
assertTrue(response.contains("POST users"), "POST request should return 'POST users'");
70124
}
71125

72126
@Test
73-
public void testHttpPutRouting() throws ApplicationException {
74-
// Test that PUT requests match HTTP_PUT mode actions
75-
// Note: The path pattern "api/users" with a String parameter will match "api/users/123"
76-
Action action = registry.getAction("api/users/123", Action.Mode.HTTP_PUT);
77-
assertNotNull(action, "PUT action should be found");
78-
assertEquals(Action.Mode.HTTP_PUT, action.getMode());
79-
80-
// The action will extract "123" from the path
81-
Object result = action.execute();
82-
assertEquals("PUT user 123", String.valueOf(result));
127+
public void testHttpPutRequest() throws Exception {
128+
// Make actual HTTP PUT request
129+
String response = sendHttpRequest("PUT", BASE_URL + "/?q=api/users/123", null);
130+
assertTrue(response.contains("PUT user"), "PUT request should return 'PUT user'");
131+
assertTrue(response.contains("123"), "PUT request should include the ID parameter");
83132
}
84133

85134
@Test
86-
public void testHttpDeleteRouting() throws ApplicationException {
87-
// Test that DELETE requests match HTTP_DELETE mode actions
88-
// Note: The path pattern "api/users" with a String parameter will match "api/users/123"
89-
Action action = registry.getAction("api/users/123", Action.Mode.HTTP_DELETE);
90-
assertNotNull(action, "DELETE action should be found");
91-
assertEquals(Action.Mode.HTTP_DELETE, action.getMode());
92-
93-
// The action will extract "123" from the path
94-
Object result = action.execute();
95-
assertEquals("DELETE user 123", String.valueOf(result));
135+
public void testHttpDeleteRequest() throws Exception {
136+
// Make actual HTTP DELETE request
137+
String response = sendHttpRequest("DELETE", BASE_URL + "/?q=api/users/456", null);
138+
assertTrue(response.contains("DELETE user"), "DELETE request should return 'DELETE user'");
139+
assertTrue(response.contains("456"), "DELETE request should include the ID parameter");
96140
}
97141

98142
@Test
99-
public void testHttpMethodMismatch() {
100-
// Test that wrong HTTP method doesn't match
101-
Action getAction = registry.getAction("api/users", Action.Mode.HTTP_GET);
102-
assertNotNull(getAction, "GET action should exist");
103-
104-
// POST mode should not match GET action
105-
Action postAction = registry.getAction("api/users", Action.Mode.HTTP_POST);
106-
assertNotNull(postAction, "POST action should exist");
107-
assertNotEquals(getAction.getMode(), postAction.getMode());
143+
public void testDefaultModeAcceptsAllMethods() throws Exception {
144+
// Test that DEFAULT mode actions accept any HTTP method
145+
String getResponse = sendHttpRequest("GET", BASE_URL + "/?q=api/ping", null);
146+
assertTrue(getResponse.contains("pong"), "GET request to ping should return 'pong'");
147+
148+
String postResponse = sendHttpRequest("POST", BASE_URL + "/?q=api/ping", null);
149+
assertTrue(postResponse.contains("pong"), "POST request to ping should return 'pong'");
150+
151+
String putResponse = sendHttpRequest("PUT", BASE_URL + "/?q=api/ping", null);
152+
assertTrue(putResponse.contains("pong"), "PUT request to ping should return 'pong'");
108153
}
109154

110155
@Test
111-
public void testDefaultModeAcceptsAllMethods() throws ApplicationException {
112-
// Test that DEFAULT mode actions accept any HTTP method
113-
Action getAction = registry.getAction("api/ping", Action.Mode.HTTP_GET);
114-
Action postAction = registry.getAction("api/ping", Action.Mode.HTTP_POST);
115-
Action putAction = registry.getAction("api/ping", Action.Mode.HTTP_PUT);
116-
117-
// All should match the same DEFAULT mode action
118-
assertNotNull(getAction);
119-
assertNotNull(postAction);
120-
assertNotNull(putAction);
121-
122-
// They should all return the same result
123-
assertEquals("pong", String.valueOf(getAction.execute()));
124-
assertEquals("pong", String.valueOf(postAction.execute()));
125-
assertEquals("pong", String.valueOf(putAction.execute()));
156+
public void testHttpMethodMismatch() throws Exception {
157+
// Try to access GET endpoint with POST method - should fail or return error
158+
// Note: This depends on how the server handles method mismatches
159+
String response = sendHttpRequest("POST", BASE_URL + "/?q=api/users", null);
160+
// POST to api/users should work (there's a POST handler), but let's verify it's not the GET handler
161+
assertTrue(response.contains("POST users"), "POST request should match POST handler, not GET");
126162
}
127163

128-
@Test
129-
public void testApplicationManagerCallWithMode() throws ApplicationException {
130-
// Test that ApplicationManager.call correctly uses mode
131-
ApplicationContext context = new ApplicationContext();
132-
133-
// GET request
134-
Object getResult = ApplicationManager.call("api/users", context, Action.Mode.HTTP_GET);
135-
assertEquals("GET users", String.valueOf(getResult));
136-
137-
// POST request
138-
Object postResult = ApplicationManager.call("api/users", context, Action.Mode.HTTP_POST);
139-
assertEquals("POST users", String.valueOf(postResult));
140-
141-
// PUT request with parameter (path includes the ID)
142-
Object putResult = ApplicationManager.call("api/users/456", context, Action.Mode.HTTP_PUT);
143-
assertTrue(String.valueOf(putResult).contains("PUT user"));
164+
/**
165+
* Helper method to send HTTP requests
166+
*/
167+
private String sendHttpRequest(String method, String urlString, String body) throws Exception {
168+
URLRequest request = new URLRequest(URI.create(urlString).toURL());
169+
request.setMethod(method.toUpperCase());
170+
171+
if (body != null && (method.equalsIgnoreCase("POST") || method.equalsIgnoreCase("PUT"))) {
172+
request.setHeader("Content-Type", "application/x-www-form-urlencoded");
173+
request.setBody(body);
174+
}
175+
176+
HTTPHandler handler = new HTTPHandler();
177+
URLResponse response = handler.handleRequest(request);
178+
179+
int statusCode = response.getStatusCode();
180+
String responseText = response.getBody();
181+
182+
if (statusCode >= 200 && statusCode < 300) {
183+
return responseText;
184+
} else {
185+
// return error response text for non-2xx responses
186+
return responseText;
187+
}
144188
}
145189

146190
@Test
147191
public void testHttpMethodExtractionFromRequest() {
148192
// Test that HTTP method can be extracted from Method enum
149-
Method getMethod = Method.GET;
193+
org.tinystruct.http.Method getMethod = org.tinystruct.http.Method.GET;
150194
Action.Mode mode = Action.Mode.fromName(getMethod.name());
151195
assertEquals(Action.Mode.HTTP_GET, mode);
152196

153-
Method postMethod = Method.POST;
197+
org.tinystruct.http.Method postMethod = org.tinystruct.http.Method.POST;
154198
mode = Action.Mode.fromName(postMethod.name());
155199
assertEquals(Action.Mode.HTTP_POST, mode);
156200
}

0 commit comments

Comments
 (0)