diff mrjunejune/test/integration_test.c @ 94:092afa595764

[MrJuneJune] Added Integration tests.
author June Park <parkjune1995@gmail.com>
date Fri, 02 Jan 2026 18:13:32 -0800
parents 6626ec933933
children 96628cf126a0
line wrap: on
line diff
--- a/mrjunejune/test/integration_test.c	Fri Jan 02 18:02:22 2026 -0800
+++ b/mrjunejune/test/integration_test.c	Fri Jan 02 18:13:32 2026 -0800
@@ -380,6 +380,229 @@
   return 0;
 }
 
+// Helper: Send POST request with file data
+int send_post_file(Seobeo_Handle *client, const char *path, const char *file_data, size_t file_size)
+{
+  char request_buffer[8192];
+  int header_len = snprintf(
+    request_buffer, sizeof(request_buffer),
+    "POST %s HTTP/1.1\r\n"
+    "Host: %s\r\n"
+    "Content-Type: application/octet-stream\r\n"
+    "Content-Length: %zu\r\n"
+    "Connection: close\r\n"
+    "\r\n",
+    path, TEST_HOST, file_size
+  );
+
+  if (header_len < 0 || header_len >= sizeof(request_buffer))
+  {
+    fprintf(stderr, "Request header too large\n");
+    return -1;
+  }
+
+  // Send headers
+  Seobeo_Handle_Queue(client, (uint8*)request_buffer, (uint32)header_len);
+
+  // Send file data in chunks if needed
+  size_t remaining = file_size;
+  const char *ptr = file_data;
+  while (remaining > 0)
+  {
+    size_t chunk_size = remaining > 4096 ? 4096 : remaining;
+    Seobeo_Handle_Queue(client, (uint8*)ptr, (uint32)chunk_size);
+    ptr += chunk_size;
+    remaining -= chunk_size;
+  }
+
+  return Seobeo_Handle_Flush(client);
+}
+
+// Helper: Extract JSON field value from response body
+char* extract_json_field(const char *json, const char *field, char *buffer, size_t buffer_size)
+{
+  char search_pattern[256];
+  snprintf(search_pattern, sizeof(search_pattern), "\"%s\":\"", field);
+
+  const char *start = strstr(json, search_pattern);
+  if (!start)
+  {
+    return NULL;
+  }
+
+  start += strlen(search_pattern);
+  const char *end = strchr(start, '"');
+  if (!end)
+  {
+    return NULL;
+  }
+
+  size_t len = end - start;
+  if (len >= buffer_size)
+  {
+    len = buffer_size - 1;
+  }
+
+  memcpy(buffer, start, len);
+  buffer[len] = '\0';
+
+  return buffer;
+}
+
+// Helper: Test POST file conversion
+int test_file_conversion(const char *endpoint, const char *test_file_path,
+                         const char *expected_format, pid_t server_pid)
+{
+  printf("  Testing: POST %s\n", endpoint);
+
+  // Read test file
+  size_t file_size;
+  char *file_data = read_file(test_file_path, &file_size);
+  if (!file_data)
+  {
+    printf("    ✗ Failed to read test file: %s\n", test_file_path);
+    return -1;
+  }
+
+  printf("    → Loaded test file (%zu bytes)\n", file_size);
+
+  // Create client and send request
+  Seobeo_Handle *client = create_test_client();
+  if (!client)
+  {
+    printf("    ✗ Failed to create client connection\n");
+    free(file_data);
+    return -1;
+  }
+
+  if (send_post_file(client, endpoint, file_data, file_size) < 0)
+  {
+    printf("    ✗ Failed to send POST request\n");
+    free(file_data);
+    Seobeo_Handle_Destroy(client);
+    return -1;
+  }
+
+  free(file_data);
+
+  // Read response
+  char *response = NULL;
+  size_t response_len = 0;
+  if (read_http_response(client, &response, &response_len) < 0)
+  {
+    printf("    ✗ Failed to read response\n");
+    Seobeo_Handle_Destroy(client);
+    return -1;
+  }
+
+  Seobeo_Handle_Destroy(client);
+
+  // Parse status
+  int status = parse_http_status(response);
+  if (status != 200)
+  {
+    printf("    ✗ Conversion failed with status: %d\n", status);
+    printf("    Response: %s\n", response);
+    free(response);
+    return -1;
+  }
+
+  printf("    ✓ Status code: 200\n");
+
+  // Extract download URL from JSON response
+  const char *body = strstr(response, "\r\n\r\n");
+  if (!body)
+  {
+    printf("    ✗ No response body found\n");
+    free(response);
+    return -1;
+  }
+  body += 4;
+
+  char download_url[512];
+  if (!extract_json_field(body, "download_url", download_url, sizeof(download_url)))
+  {
+    printf("    ✗ Failed to extract download_url from response\n");
+    printf("    Response body: %s\n", body);
+    free(response);
+    return -1;
+  }
+
+  printf("    ✓ Conversion succeeded\n");
+  printf("    ✓ Download URL: %s\n", download_url);
+  free(response);
+
+  // Test downloading the converted file
+  printf("    → Testing download: GET %s\n", download_url);
+
+  client = create_test_client();
+  if (!client)
+  {
+    printf("    ✗ Failed to create client for download\n");
+    return -1;
+  }
+
+  if (send_http_request(client, download_url, NULL) < 0)
+  {
+    printf("    ✗ Failed to send download request\n");
+    Seobeo_Handle_Destroy(client);
+    return -1;
+  }
+
+  response = NULL;
+  response_len = 0;
+  if (read_http_response(client, &response, &response_len) < 0)
+  {
+    printf("    ✗ Failed to read download response\n");
+    Seobeo_Handle_Destroy(client);
+    return -1;
+  }
+
+  Seobeo_Handle_Destroy(client);
+
+  status = parse_http_status(response);
+  if (status != 200)
+  {
+    printf("    ✗ Download failed with status: %d\n", status);
+    free(response);
+    return -1;
+  }
+
+  // Find body in download response
+  body = strstr(response, "\r\n\r\n");
+  if (!body)
+  {
+    printf("    ✗ No file data in download response\n");
+    free(response);
+    return -1;
+  }
+  body += 4;
+
+  size_t downloaded_size = response_len - (body - response);
+
+  // Verify content type in response headers
+  const char *content_type = strstr(response, "Content-Type: ");
+  if (!content_type)
+  {
+    printf("    ✗ No Content-Type header in download\n");
+    free(response);
+    return -1;
+  }
+
+  if (strstr(content_type, expected_format) == NULL)
+  {
+    printf("    ✗ Wrong content type (expected %s)\n", expected_format);
+    free(response);
+    return -1;
+  }
+
+  printf("    ✓ Downloaded converted file (%zu bytes)\n", downloaded_size);
+  printf("    ✓ Content-Type: %s\n", expected_format);
+
+  free(response);
+  return 0;
+}
+
 // Helper: Start test server
 pid_t start_test_server(const char *server_binary)
 {
@@ -498,10 +721,23 @@
   // Define test cases - paths that should succeed (200 OK)
   TestCase success_tests[] = {
     {"/", 200, NULL, NULL, NULL, 0},
-    {"/index.html", 200, NULL, NULL, NULL, 0},
+    {"/resume", 200, NULL, NULL, NULL, 0},
+    {"/tools", 200, NULL, NULL, NULL, 0},
+    {"/tools/markdown_to_html", 200, NULL, NULL, NULL, 0},
+    {"/tools/file_converter", 200, NULL, NULL, NULL, 0},
   };
   int num_success_tests = sizeof(success_tests) / sizeof(success_tests[0]);
 
+  // Define test cases - paths that should redirect (301)
+  TestCase redirect_tests[] = {
+    {"/index.html", 301, NULL, NULL, NULL, 0},
+    {"/resume/index.html", 301, NULL, NULL, NULL, 0},
+    {"/tools/index.html", 301, NULL, NULL, NULL, 0},
+    {"/tools/markdown_to_html/index.html", 301, NULL, NULL, NULL, 0},
+    {"/tools/file_converter/index.html", 301, NULL, NULL, NULL, 0},
+  };
+  int num_redirect_tests = sizeof(redirect_tests) / sizeof(redirect_tests[0]);
+
   // Define test cases - paths that should fail (404)
   TestCase failure_tests[] = {
     {"/nonexistent", 404, NULL, NULL, NULL, 0},
@@ -515,6 +751,10 @@
   {
     init_test_case(&success_tests[i]);
   }
+  for (int i = 0; i < num_redirect_tests; i++)
+  {
+    init_test_case(&redirect_tests[i]);
+  }
   for (int i = 0; i < num_failure_tests; i++)
   {
     init_test_case(&failure_tests[i]);
@@ -536,6 +776,22 @@
 
   printf("\n");
 
+  // Run redirect tests
+  printf("Running tests for paths that should redirect:\n");
+  for (int i = 0; i < num_redirect_tests; i++)
+  {
+    if (execute_test_case(&redirect_tests[i], server_pid) == 0)
+    {
+      passed_tests++;
+    }
+    else
+    {
+      failed_tests++;
+    }
+  }
+
+  printf("\n");
+
   // Run failure tests
   printf("Running tests for paths that should fail:\n");
   for (int i = 0; i < num_failure_tests; i++)
@@ -572,11 +828,48 @@
     failed_tests++;
   }
 
+  printf("\n");
+
+  // Test POST endpoints
+  printf("Running tests for POST conversion endpoints:\n");
+
+  // Test image-to-webp conversion
+  if (test_file_conversion("/api/convert/image-to-webp",
+                           "mrjunejune/test/shiba.webp",
+                           "image/webp",
+                           server_pid) == 0)
+  {
+    passed_tests++;
+  }
+  else
+  {
+    failed_tests++;
+  }
+
+  printf("\n");
+
+  // Test video-to-mp4 conversion
+  if (test_file_conversion("/api/convert/video-to-mp4",
+                           "mrjunejune/test/test_avi.avi",
+                           "video/mp4",
+                           server_pid) == 0)
+  {
+    passed_tests++;
+  }
+  else
+  {
+    failed_tests++;
+  }
+
   // Cleanup test cases
   for (int i = 0; i < num_success_tests; i++)
   {
     cleanup_test_case(&success_tests[i]);
   }
+  for (int i = 0; i < num_redirect_tests; i++)
+  {
+    cleanup_test_case(&redirect_tests[i]);
+  }
   for (int i = 0; i < num_failure_tests; i++)
   {
     cleanup_test_case(&failure_tests[i]);