comparison mrjunejune/test/integration_test.c @ 126:e7899c93da77

Remove playground.
author June Park <parkjune1995@gmail.com>
date Thu, 08 Jan 2026 18:03:34 -0800
parents 96628cf126a0
children 7eb79fd91c7e
comparison
equal deleted inserted replaced
125:f236c895604e 126:e7899c93da77
1 #include "seobeo/seobeo.h" 1 #include "seobeo/test/test.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/wait.h>
7 #include <signal.h>
8 #include <assert.h>
9
10 #define TEST_PORT "6969"
11 #define TEST_HOST "127.0.0.1"
12 #define MAX_RESPONSE_SIZE (1024 * 1024)
13 #ifndef SNAPSHOT_DIR
14 // TODO: Make it as current directory /snapshots...
15 #define SNAPSHOT_DIR "mrjunejune/test/snapshots"
16 #endif
17 2
18 // Test case structure 3 // Test case structure
19 typedef struct { 4 typedef struct {
20 const char *path; 5 const char *path;
21 int expected_status; 6 int expected_status;
115 } 100 }
116 101
117 return 0; 102 return 0;
118 } 103 }
119 104
120 // Helper: Create test client
121 Seobeo_Handle* create_test_client()
122 {
123 Seobeo_Handle *client = Seobeo_Stream_Handle_Client_Create(TEST_HOST, TEST_PORT, FALSE);
124 if (!client || client->socket < 0)
125 {
126 if (client)
127 {
128 Seobeo_Handle_Destroy(client);
129 }
130 return NULL;
131 }
132 return client;
133 }
134
135 // Helper: Generate default HTTP GET request
136 int generate_http_get_request(char *buffer, size_t buffer_size, const char *path)
137 {
138 return snprintf(
139 buffer, buffer_size,
140 "GET %s HTTP/1.1\r\n"
141 "Host: %s\r\n"
142 "Connection: close\r\n"
143 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
144 "User-Agent: SeobeoTestClient/1.0\r\n"
145 "\r\n",
146 path, TEST_HOST
147 );
148 }
149
150 // Helper: Send HTTP request
151 int send_http_request(Seobeo_Handle *client, const char *path, const char *custom_request)
152 {
153 char request_buffer[4096];
154 int request_len;
155
156 if (custom_request)
157 {
158 request_len = snprintf(request_buffer, sizeof(request_buffer), "%s", custom_request);
159 }
160 else
161 {
162 request_len = generate_http_get_request(request_buffer, sizeof(request_buffer), path);
163 }
164
165 if (request_len < 0 || request_len >= sizeof(request_buffer))
166 {
167 fprintf(stderr, "Request buffer too small\n");
168 return -1;
169 }
170
171 Seobeo_Handle_Queue(client, (uint8*)request_buffer, (uint32)request_len);
172 return Seobeo_Handle_Flush(client);
173 }
174
175 // Helper: Read HTTP response
176 int read_http_response(Seobeo_Handle *client, char **response_out, size_t *response_len_out)
177 {
178 char *response = malloc(MAX_RESPONSE_SIZE);
179 if (!response)
180 {
181 return -1;
182 }
183
184 size_t total_bytes = 0;
185 int attempts = 0;
186 const int max_attempts = 100;
187
188 while (attempts++ < max_attempts && total_bytes < MAX_RESPONSE_SIZE - 1)
189 {
190 int bytes_read = Seobeo_Handle_Read(client);
191
192 if (bytes_read > 0)
193 {
194 size_t to_copy = client->read_buffer_len;
195 if (total_bytes + to_copy > MAX_RESPONSE_SIZE - 1)
196 {
197 to_copy = MAX_RESPONSE_SIZE - 1 - total_bytes;
198 }
199
200 memcpy(response + total_bytes, client->read_buffer, to_copy);
201 total_bytes += to_copy;
202 Seobeo_Handle_Consume(client, (uint32)to_copy);
203 }
204 else if (bytes_read == -2)
205 {
206 // Connection closed
207 break;
208 }
209 else if (bytes_read == 0)
210 {
211 // Would block
212 usleep(10000);
213 continue;
214 }
215 else
216 {
217 free(response);
218 return -1;
219 }
220 }
221
222 response[total_bytes] = '\0';
223 *response_out = response;
224 *response_len_out = total_bytes;
225
226 return (total_bytes > 0) ? 0 : -1;
227 }
228
229 // Helper: Parse HTTP status code
230 int parse_http_status(const char *response)
231 {
232 if (!response || strlen(response) < 12)
233 {
234 return -1;
235 }
236
237 const char *status_start = strstr(response, "HTTP/1.1 ");
238 if (!status_start)
239 {
240 status_start = strstr(response, "HTTP/1.0 ");
241 }
242
243 if (!status_start)
244 {
245 return -1;
246 }
247
248 int status_code;
249 if (sscanf(status_start + 9, "%d", &status_code) == 1)
250 {
251 return status_code;
252 }
253
254 return -1;
255 }
256
257 // Helper: Check if status is a redirect
258 int is_redirect_status(int status)
259 {
260 return (status >= 300 && status < 400);
261 }
262
263 // Helper: Execute a test case
264 int execute_test_case(TestCase *test, pid_t server_pid) 105 int execute_test_case(TestCase *test, pid_t server_pid)
265 { 106 {
266 printf(" Testing: GET %s (expecting %d)\n", test->path, test->expected_status); 107 printf(" Testing: GET %s (expecting %d)\n", test->path, test->expected_status);
267 108
268 Seobeo_Handle *client = create_test_client(); 109 int32 max_url_length = 1024*3;
269 if (!client) 110 char *url = malloc(sizeof(char)*max_url_length);
270 { 111 snprintf(url, max_url_length, "%s%s", TEST_URL, test->path);
271 printf(" ✗ Failed to create client connection\n"); 112 Seobeo_Client_Request *p_req = Seobeo_Client_Request_Create(url);
272 return -1; 113 if (!p_req)
273 } 114 {
274 115 printf("Can't create requests");
275 if (send_http_request(client, test->path, NULL) < 0) 116 return -1;
276 { 117 }
277 printf(" ✗ Failed to send request\n"); 118
278 Seobeo_Handle_Destroy(client); 119 Seobeo_Client_Response *p_resp = Seobeo_Client_Request_Execute(p_req);
279 return -1; 120 if (!p_resp)
280 } 121 {
281 122 printf("No response");
282 char *response = NULL; 123 return -1;
283 size_t response_len = 0; 124 }
284 if (read_http_response(client, &response, &response_len) < 0) 125
285 { 126 if (p_resp->status_code != test->expected_status)
286 printf(" ✗ Failed to read response\n");
287 Seobeo_Handle_Destroy(client);
288 return -1;
289 }
290
291 test->actual_response = response;
292 test->response_len = response_len;
293
294 int actual_status = parse_http_status(response);
295 if (actual_status != test->expected_status)
296 { 127 {
297 printf(" ✗ Status mismatch: expected %d, got %d\n", 128 printf(" ✗ Status mismatch: expected %d, got %d\n",
298 test->expected_status, actual_status); 129 test->expected_status, p_resp->status_code);
299 Seobeo_Handle_Destroy(client); 130 Seobeo_Client_Response_Destroy(p_resp);
300 return -1; 131 Seobeo_Client_Request_Destroy(p_req);
301 } 132 return -1;
302 133 }
303 printf(" ✓ Status code: %d\n", actual_status); 134
304 135 printf(" ✓ Status code: %d\n", p_resp->status_code);
305 // For redirects, skip content comparison 136
306 if (is_redirect_status(actual_status)) 137 if (p_resp->status_code == 200)
307 {
308 printf(" ⚠ Redirect status - skipping content comparison\n");
309 Seobeo_Handle_Destroy(client);
310 return 0;
311 }
312
313 // Only verify 200 OK responses against snapshots
314 if (actual_status == 200)
315 { 138 {
316 if (!test->expected_content) 139 if (!test->expected_content)
317 { 140 {
318 printf(" ✗ No expected snapshot found: %s\n", test->expected_file_path); 141 printf(" ✗ No expected snapshot found: %s\n", test->expected_file_path);
319 printf(" → Run: bazel run //mrjunejune:create_snapshots\n"); 142 printf(" → Run: bazel run //mrjunejune:create_snapshots\n");
320 Seobeo_Handle_Destroy(client); 143 Seobeo_Client_Response_Destroy(p_resp);
144 Seobeo_Client_Request_Destroy(p_req);
321 return -1; 145 return -1;
322 } 146 }
323 147
324 if (strcmp(response, test->expected_content) != 0) 148 if (strcmp(p_resp->body, test->expected_content) != 0)
325 { 149 {
326 printf(" ✗ Response does not match expected snapshot\n"); 150 printf(" ✗ Response does not match expected snapshot\n");
327 printf(" Expected file: %s\n", test->expected_file_path); 151 printf(" Expected file: %s\n", test->expected_file_path);
328 Seobeo_Handle_Destroy(client); 152 Seobeo_Client_Response_Destroy(p_resp);
153 Seobeo_Client_Request_Destroy(p_req);
329 return -1; 154 return -1;
330 } 155 }
331 156
332 printf(" ✓ Response matches snapshot (%zu bytes)\n", response_len); 157 printf(" ✓ Response matches snapshot (%zu bytes)\n", p_resp->body_length);
333 } 158 }
334 159
335 Seobeo_Handle_Destroy(client); 160 Seobeo_Client_Response_Destroy(p_resp);
161 Seobeo_Client_Request_Destroy(p_req);
336 return 0; 162 return 0;
337 } 163 }
338 164
339 // Helper: Execute custom request test 165 int send_post_file(Seobeo_Handle *p_req, const char *path, const char *file_data, size_t file_size)
340 int execute_custom_request_test(const char *name, const char *custom_request,
341 int expected_status, pid_t server_pid)
342 {
343 printf(" Testing: %s (expecting %d)\n", name, expected_status);
344
345 Seobeo_Handle *client = create_test_client();
346 if (!client)
347 {
348 printf(" ✗ Failed to create client connection\n");
349 return -1;
350 }
351
352 if (send_http_request(client, NULL, custom_request) < 0)
353 {
354 printf(" ✗ Failed to send request\n");
355 Seobeo_Handle_Destroy(client);
356 return -1;
357 }
358
359 char *response = NULL;
360 size_t response_len = 0;
361 if (read_http_response(client, &response, &response_len) < 0)
362 {
363 printf(" ✗ Failed to read response\n");
364 Seobeo_Handle_Destroy(client);
365 return -1;
366 }
367
368 int actual_status = parse_http_status(response);
369 if (actual_status != expected_status)
370 {
371 printf(" ✗ Status mismatch: expected %d, got %d\n",
372 expected_status, actual_status);
373 free(response);
374 Seobeo_Handle_Destroy(client);
375 return -1;
376 }
377
378 printf(" ✓ Status code: %d\n", actual_status);
379 printf(" ✓ Response received (%zu bytes)\n", response_len);
380
381 free(response);
382 Seobeo_Handle_Destroy(client);
383 return 0;
384 }
385
386 // Helper: Send POST request with file data
387 int send_post_file(Seobeo_Handle *client, const char *path, const char *file_data, size_t file_size)
388 { 166 {
389 char request_buffer[8192]; 167 char request_buffer[8192];
390 int header_len = snprintf( 168 int header_len = snprintf(
391 request_buffer, sizeof(request_buffer), 169 request_buffer, sizeof(request_buffer),
392 "POST %s HTTP/1.1\r\n" 170 "POST %s HTTP/1.1\r\n"
403 fprintf(stderr, "Request header too large\n"); 181 fprintf(stderr, "Request header too large\n");
404 return -1; 182 return -1;
405 } 183 }
406 184
407 // Send headers 185 // Send headers
408 Seobeo_Handle_Queue(client, (uint8*)request_buffer, (uint32)header_len); 186 Seobeo_Handle_Queue(p_req, (uint8*)request_buffer, (uint32)header_len);
409 187
410 // Send file data in chunks if needed 188 // Send file data in chunks if needed
411 size_t remaining = file_size; 189 size_t remaining = file_size;
412 const char *ptr = file_data; 190 const char *ptr = file_data;
413 while (remaining > 0) 191 while (remaining > 0)
414 { 192 {
415 size_t chunk_size = remaining > 4096 ? 4096 : remaining; 193 size_t chunk_size = remaining > 4096 ? 4096 : remaining;
416 Seobeo_Handle_Queue(client, (uint8*)ptr, (uint32)chunk_size); 194 Seobeo_Handle_Queue(p_req, (uint8*)ptr, (uint32)chunk_size);
417 ptr += chunk_size; 195 ptr += chunk_size;
418 remaining -= chunk_size; 196 remaining -= chunk_size;
419 } 197 }
420 198
421 return Seobeo_Handle_Flush(client); 199 return Seobeo_Handle_Flush(p_req);
422 } 200 }
423 201
424 // Helper: Extract JSON field value from response body
425 char* extract_json_field(const char *json, const char *field, char *buffer, size_t buffer_size) 202 char* extract_json_field(const char *json, const char *field, char *buffer, size_t buffer_size)
426 { 203 {
427 char search_pattern[256]; 204 char search_pattern[256];
428 snprintf(search_pattern, sizeof(search_pattern), "\"%s\":\"", field); 205 snprintf(search_pattern, sizeof(search_pattern), "\"%s\":\"", field);
429 206
450 buffer[len] = '\0'; 227 buffer[len] = '\0';
451 228
452 return buffer; 229 return buffer;
453 } 230 }
454 231
455 // Helper: Test POST file conversion
456 int test_file_conversion(const char *endpoint, const char *test_file_path, 232 int test_file_conversion(const char *endpoint, const char *test_file_path,
457 const char *expected_format, pid_t server_pid) 233 const char *expected_format, pid_t server_pid)
458 { 234 {
459 printf(" Testing: POST %s\n", endpoint); 235 printf(" Testing: POST %s\n", endpoint);
460 236
461 // Read test file 237 // Read test file
462 size_t file_size; 238 size_t file_size;
463 char *file_data = read_file(test_file_path, &file_size); 239 char *file_data = read_file(test_file_path, &file_size);
464 if (!file_data) 240 if (!file_data) {
465 {
466 printf(" ✗ Failed to read test file: %s\n", test_file_path); 241 printf(" ✗ Failed to read test file: %s\n", test_file_path);
467 return -1; 242 return -1;
468 } 243 }
469 244
470 printf(" → Loaded test file (%zu bytes)\n", file_size); 245 char url[1024];
471 246 snprintf(url, sizeof(url), "%s%s", TEST_URL, endpoint);
472 // Create client and send request 247
473 Seobeo_Handle *client = create_test_client(); 248 Seobeo_Client_Request *p_req = Seobeo_Client_Request_Create(url);
474 if (!client) 249 Seobeo_Client_Request_Set_Method(p_req, "POST");
475 { 250 Seobeo_Client_Request_Set_Body(p_req, (uint8*)file_data, (uint32)file_size);
476 printf(" ✗ Failed to create client connection\n"); 251 Seobeo_Client_Request_Add_Header_Array(p_req, "Content-Type: application/octet-stream");
477 free(file_data); 252
478 return -1; 253 Seobeo_Client_Response *p_resp = Seobeo_Client_Request_Execute(p_req);
479 }
480
481 if (send_post_file(client, endpoint, file_data, file_size) < 0)
482 {
483 printf(" ✗ Failed to send POST request\n");
484 free(file_data);
485 Seobeo_Handle_Destroy(client);
486 return -1;
487 }
488
489 free(file_data); 254 free(file_data);
490 255
491 // Read response 256 if (!p_resp || p_resp->status_code != 200) {
492 char *response = NULL; 257 printf(" ✗ Conversion failed with status: %d\n", p_resp ? p_resp->status_code : 0);
493 size_t response_len = 0; 258 if (p_resp) Seobeo_Client_Response_Destroy(p_resp);
494 if (read_http_response(client, &response, &response_len) < 0) 259
495 { 260 Seobeo_Client_Response_Destroy(p_resp);
496 printf(" ✗ Failed to read response\n"); 261 Seobeo_Client_Request_Destroy(p_req);
497 Seobeo_Handle_Destroy(client); 262 return -1;
498 return -1; 263 }
499 } 264
500 265 // Extract download URL from JSON body
501 Seobeo_Handle_Destroy(client); 266 char download_url_path[512];
502 267 if (!extract_json_field((char*)p_resp->body, "download_url", download_url_path, sizeof(download_url_path))) {
503 // Parse status 268 printf(" ✗ Failed to extract download_url\n");
504 int status = parse_http_status(response); 269 Seobeo_Client_Response_Destroy(p_resp);
505 if (status != 200) 270 Seobeo_Client_Request_Destroy(p_req);
506 { 271 return -1;
507 printf(" ✗ Conversion failed with status: %d\n", status); 272 }
508 printf(" Response: %s\n", response); 273
509 free(response); 274 printf(" ✓ Conversion succeeded. Download URL: %s\n", download_url_path);
510 return -1; 275 Seobeo_Client_Response_Destroy(p_resp);
511 } 276 Seobeo_Client_Request_Destroy(p_req);
512 277
513 printf(" ✓ Status code: 200\n"); 278 printf(" → Testing download: GET %s\n", download_url_path);
514 279 char full_download_url[1024];
515 // Extract download URL from JSON response 280 snprintf(full_download_url, sizeof(full_download_url), "%s%s", TEST_URL, download_url_path);
516 const char *body = strstr(response, "\r\n\r\n"); 281
517 if (!body) 282 p_req = Seobeo_Client_Request_Create(full_download_url);
518 { 283 p_resp = Seobeo_Client_Request_Execute(p_req);
519 printf(" ✗ No response body found\n"); 284
520 free(response); 285 if (!p_resp || p_resp->status_code != 200)
521 return -1; 286 {
522 } 287 printf(" ✗ Download failed\n");
523 body += 4; 288 if (p_resp) Seobeo_Client_Response_Destroy(p_resp);
524 289 Seobeo_Client_Request_Destroy(p_req);
525 char download_url[512]; 290 return -1;
526 if (!extract_json_field(body, "download_url", download_url, sizeof(download_url))) 291 }
527 { 292
528 printf(" ✗ Failed to extract download_url from response\n"); 293 printf(" ✓ Downloaded converted file (%u bytes)\n", p_resp->body_length);
529 printf(" Response body: %s\n", body); 294
530 free(response); 295 Seobeo_Client_Response_Destroy(p_resp);
531 return -1; 296 Seobeo_Client_Request_Destroy(p_req);
532 }
533
534 printf(" ✓ Conversion succeeded\n");
535 printf(" ✓ Download URL: %s\n", download_url);
536 free(response);
537
538 // Test downloading the converted file
539 printf(" → Testing download: GET %s\n", download_url);
540
541 client = create_test_client();
542 if (!client)
543 {
544 printf(" ✗ Failed to create client for download\n");
545 return -1;
546 }
547
548 if (send_http_request(client, download_url, NULL) < 0)
549 {
550 printf(" ✗ Failed to send download request\n");
551 Seobeo_Handle_Destroy(client);
552 return -1;
553 }
554
555 response = NULL;
556 response_len = 0;
557 if (read_http_response(client, &response, &response_len) < 0)
558 {
559 printf(" ✗ Failed to read download response\n");
560 Seobeo_Handle_Destroy(client);
561 return -1;
562 }
563
564 Seobeo_Handle_Destroy(client);
565
566 status = parse_http_status(response);
567 if (status != 200)
568 {
569 printf(" ✗ Download failed with status: %d\n", status);
570 free(response);
571 return -1;
572 }
573
574 // Find body in download response
575 body = strstr(response, "\r\n\r\n");
576 if (!body)
577 {
578 printf(" ✗ No file data in download response\n");
579 free(response);
580 return -1;
581 }
582 body += 4;
583
584 size_t downloaded_size = response_len - (body - response);
585
586 // Verify content type in response headers
587 const char *content_type = strstr(response, "Content-Type: ");
588 if (!content_type)
589 {
590 printf(" ✗ No Content-Type header in download\n");
591 free(response);
592 return -1;
593 }
594
595 if (strstr(content_type, expected_format) == NULL)
596 {
597 printf(" ✗ Wrong content type (expected %s)\n", expected_format);
598 free(response);
599 return -1;
600 }
601
602 printf(" ✓ Downloaded converted file (%zu bytes)\n", downloaded_size);
603 printf(" ✓ Content-Type: %s\n", expected_format);
604
605 free(response);
606 return 0; 297 return 0;
607 } 298 }
608 299
609 // Helper: Start test server
610 pid_t start_test_server(const char *server_binary) 300 pid_t start_test_server(const char *server_binary)
611 { 301 {
612 pid_t server_pid = fork(); 302 pid_t server_pid = fork();
613 303
614 if (server_pid < 0) 304 if (server_pid < 0)
692 } 382 }
693 383
694 // Main integration test 384 // Main integration test
695 int test_server_client_integration(const char *server_binary) 385 int test_server_client_integration(const char *server_binary)
696 { 386 {
697 printf("=== Server-Client Integration Test ===\n"); 387 printf("=== Server-p_req Integration Test ===\n");
698 printf("MODE: Verifying Against Snapshots\n\n"); 388 printf("MODE: Verifying Against Snapshots\n\n");
699 389
700 char cwd[1024]; 390 char cwd[1024];
701 if (getcwd(cwd, sizeof(cwd)) != NULL) 391 if (getcwd(cwd, sizeof(cwd)) != NULL)
702 {
703 printf("Working directory: %s\n", cwd); 392 printf("Working directory: %s\n", cwd);
704 }
705 393
706 if (access(server_binary, X_OK) != 0) 394 if (access(server_binary, X_OK) != 0)
707 { 395 {
708 printf("Server binary not found: %s\n", server_binary); 396 printf("Server binary not found: %s\n", server_binary);
709 perror("access"); 397 perror("access");
712 printf("Server binary: %s\n", server_binary); 400 printf("Server binary: %s\n", server_binary);
713 printf("Snapshot directory: %s\n\n", SNAPSHOT_DIR); 401 printf("Snapshot directory: %s\n\n", SNAPSHOT_DIR);
714 402
715 pid_t server_pid = start_test_server(server_binary); 403 pid_t server_pid = start_test_server(server_binary);
716 if (server_pid < 0) 404 if (server_pid < 0)
717 { 405 return -1;
718 return -1;
719 }
720 406
721 int failed_tests = 0; 407 int failed_tests = 0;
722 int passed_tests = 0; 408 int passed_tests = 0;
723 409
724 // Define test cases - paths that should succeed (200 OK)
725 TestCase success_tests[] = { 410 TestCase success_tests[] = {
726 {"/", 200, NULL, NULL, NULL, 0}, 411 {"/", 200, NULL, NULL, NULL, 0},
727 {"/resume", 200, NULL, NULL, NULL, 0}, 412 {"/resume", 200, NULL, NULL, NULL, 0},
728 {"/tools", 200, NULL, NULL, NULL, 0}, 413 {"/tools", 200, NULL, NULL, NULL, 0},
729 {"/tools/markdown_to_html", 200, NULL, NULL, NULL, 0}, 414 {"/tools/markdown_to_html", 200, NULL, NULL, NULL, 0},
730 {"/tools/file_converter", 200, NULL, NULL, NULL, 0}, 415 {"/tools/file_converter", 200, NULL, NULL, NULL, 0},
731 }; 416 };
732 int num_success_tests = sizeof(success_tests) / sizeof(success_tests[0]); 417 int num_success_tests = sizeof(success_tests) / sizeof(success_tests[0]);
733 418
734 // Define test cases - paths that should redirect (301)
735 TestCase redirect_tests[] = { 419 TestCase redirect_tests[] = {
736 {"/index.html", 301, NULL, NULL, NULL, 0}, 420 {"/index.html", 301, NULL, NULL, NULL, 0},
737 {"/resume/index.html", 301, NULL, NULL, NULL, 0}, 421 {"/resume/index.html", 301, NULL, NULL, NULL, 0},
738 {"/tools/index.html", 301, NULL, NULL, NULL, 0}, 422 {"/tools/index.html", 301, NULL, NULL, NULL, 0},
739 {"/tools/markdown_to_html/index.html", 301, NULL, NULL, NULL, 0}, 423 {"/tools/markdown_to_html/index.html", 301, NULL, NULL, NULL, 0},
740 {"/tools/file_converter/index.html", 301, NULL, NULL, NULL, 0}, 424 {"/tools/file_converter/index.html", 301, NULL, NULL, NULL, 0},
741 }; 425 };
742 int num_redirect_tests = sizeof(redirect_tests) / sizeof(redirect_tests[0]); 426 int num_redirect_tests = sizeof(redirect_tests) / sizeof(redirect_tests[0]);
743 427
744 // Define test cases - paths that should fail (404)
745 TestCase failure_tests[] = { 428 TestCase failure_tests[] = {
746 {"/nonexistent", 404, NULL, NULL, NULL, 0}, 429 {"/nonexistent", 404, NULL, NULL, NULL, 0},
747 {"/does/not/exist", 404, NULL, NULL, NULL, 0}, 430 {"/does/not/exist", 404, NULL, NULL, NULL, 0},
748 {"/missing.html", 404, NULL, NULL, NULL, 0}, 431 {"/missing.html", 404, NULL, NULL, NULL, 0},
749 }; 432 };
750 int num_failure_tests = sizeof(failure_tests) / sizeof(failure_tests[0]); 433 int num_failure_tests = sizeof(failure_tests) / sizeof(failure_tests[0]);
751 434
752 // Initialize all test cases
753 for (int i = 0; i < num_success_tests; i++) 435 for (int i = 0; i < num_success_tests; i++)
754 {
755 init_test_case(&success_tests[i]); 436 init_test_case(&success_tests[i]);
756 } 437
757 for (int i = 0; i < num_redirect_tests; i++) 438 for (int i = 0; i < num_redirect_tests; i++)
758 {
759 init_test_case(&redirect_tests[i]); 439 init_test_case(&redirect_tests[i]);
760 } 440
761 for (int i = 0; i < num_failure_tests; i++) 441 for (int i = 0; i < num_failure_tests; i++)
762 {
763 init_test_case(&failure_tests[i]); 442 init_test_case(&failure_tests[i]);
764 } 443
765
766 // Run success tests
767 printf("Running tests for paths that should succeed:\n"); 444 printf("Running tests for paths that should succeed:\n");
768 for (int i = 0; i < num_success_tests; i++) 445 for (int i = 0; i < num_success_tests; i++)
769 { 446 {
770 if (execute_test_case(&success_tests[i], server_pid) == 0) 447 if (execute_test_case(&success_tests[i], server_pid) == 0)
771 {
772 passed_tests++; 448 passed_tests++;
773 }
774 else 449 else
775 {
776 failed_tests++; 450 failed_tests++;
777 }
778 } 451 }
779 452
780 printf("\n"); 453 printf("\n");
781 454
782 // Run redirect tests
783 printf("Running tests for paths that should redirect:\n"); 455 printf("Running tests for paths that should redirect:\n");
784 for (int i = 0; i < num_redirect_tests; i++) 456 for (int i = 0; i < num_redirect_tests; i++)
785 { 457 {
786 if (execute_test_case(&redirect_tests[i], server_pid) == 0) 458 if (execute_test_case(&redirect_tests[i], server_pid) == 0)
787 {
788 passed_tests++; 459 passed_tests++;
789 }
790 else 460 else
791 {
792 failed_tests++; 461 failed_tests++;
793 }
794 } 462 }
795 463
796 printf("\n"); 464 printf("\n");
797 465
798 // Run failure tests
799 printf("Running tests for paths that should fail:\n"); 466 printf("Running tests for paths that should fail:\n");
800 for (int i = 0; i < num_failure_tests; i++) 467 for (int i = 0; i < num_failure_tests; i++)
801 { 468 {
802 if (execute_test_case(&failure_tests[i], server_pid) == 0) 469 if (execute_test_case(&failure_tests[i], server_pid) == 0)
803 {
804 passed_tests++; 470 passed_tests++;
805 }
806 else 471 else
807 {
808 failed_tests++; 472 failed_tests++;
809 }
810 } 473 }
811 474
812 printf("\n"); 475 printf("\n");
813 476
814 // Test with custom request
815 printf("Running tests with custom requests:\n");
816 char custom_request[4096];
817 snprintf(custom_request, sizeof(custom_request),
818 "GET / HTTP/1.1\r\n"
819 "Host: %s\r\n"
820 "Connection: close\r\n"
821 "X-Custom-Header: TestValue\r\n"
822 "\r\n",
823 TEST_HOST);
824
825 if (execute_custom_request_test("Custom headers GET /", custom_request, 200, server_pid) == 0)
826 {
827 passed_tests++;
828 }
829 else
830 {
831 failed_tests++;
832 }
833
834 printf("\n");
835
836 // Test POST endpoints
837 printf("Running tests for POST conversion endpoints:\n"); 477 printf("Running tests for POST conversion endpoints:\n");
838
839 // Test image-to-webp conversion
840 if (test_file_conversion("/api/convert/image-to-webp", 478 if (test_file_conversion("/api/convert/image-to-webp",
841 "mrjunejune/test/shiba.webp", 479 "mrjunejune/test/shiba.webp",
842 "image/webp", 480 "image/webp",
843 server_pid) == 0) 481 server_pid) == 0)
844 {
845 passed_tests++; 482 passed_tests++;
846 }
847 else 483 else
848 {
849 failed_tests++; 484 failed_tests++;
850 }
851 485
852 printf("\n"); 486 printf("\n");
853 487
854 // Test video-to-mp4 conversion
855 if (test_file_conversion("/api/convert/video-to-mp4", 488 if (test_file_conversion("/api/convert/video-to-mp4",
856 "mrjunejune/test/test_avi.avi", 489 "mrjunejune/test/test_avi.avi",
857 "video/mp4", 490 "video/mp4",
858 server_pid) == 0) 491 server_pid) == 0)
859 {
860 passed_tests++; 492 passed_tests++;
861 }
862 else 493 else
863 {
864 failed_tests++; 494 failed_tests++;
865 } 495
866
867 // Cleanup test cases
868 for (int i = 0; i < num_success_tests; i++) 496 for (int i = 0; i < num_success_tests; i++)
869 {
870 cleanup_test_case(&success_tests[i]); 497 cleanup_test_case(&success_tests[i]);
871 }
872 for (int i = 0; i < num_redirect_tests; i++) 498 for (int i = 0; i < num_redirect_tests; i++)
873 {
874 cleanup_test_case(&redirect_tests[i]); 499 cleanup_test_case(&redirect_tests[i]);
875 }
876 for (int i = 0; i < num_failure_tests; i++) 500 for (int i = 0; i < num_failure_tests; i++)
877 {
878 cleanup_test_case(&failure_tests[i]); 501 cleanup_test_case(&failure_tests[i]);
879 }
880 502
881 stop_test_server(server_pid); 503 stop_test_server(server_pid);
882 504
883 printf("\n=== Test Summary ===\n"); 505 printf("\n=== Test Summary ===\n");
884 printf("Passed: %d\n", passed_tests); 506 printf("Passed: %d\n", passed_tests);
891 { 513 {
892 printf("=== Seobeo Integration Tests ===\n\n"); 514 printf("=== Seobeo Integration Tests ===\n\n");
893 515
894 const char *server_binary = "./mrjunejune_server"; 516 const char *server_binary = "./mrjunejune_server";
895 if (argc > 1) 517 if (argc > 1)
896 {
897 server_binary = argv[1]; 518 server_binary = argv[1];
898 }
899 519
900 int result = test_server_client_integration(server_binary); 520 int result = test_server_client_integration(server_binary);
901 521
902 if (result == 0) 522 if (result == 0)
903 {
904 printf("\n✓ All tests passed!\n"); 523 printf("\n✓ All tests passed!\n");
905 }
906 else 524 else
907 {
908 printf("\n✗ Some tests failed\n"); 525 printf("\n✗ Some tests failed\n");
909 }
910 526
911 return result; 527 return result;
912 } 528 }