Testing Infrastructure
This directory contains test utilities and integration tests for the runway calculator application.
Contents
auth_test_config.rs- Configuration and constants for authentication testsapi_integration/- Integration tests for API functionalityauth_integration_tests.rs- Tests for auth service integrationhttp_mock.rs- HTTP mocking utilities for API testing
Running Tests
To run the WebAssembly tests, use one of the provided test scripts in the root directory:
# Run all WASM tests (requires wasm-pack)
./run_tests.sh
# Run just the HTTP mock tests
./run_http_mock_test.sh
HTTP Mocking
The http_mock.rs module provides utilities for mocking HTTP requests in tests. This allows testing API integrations without making actual network requests.
Basic Usage
use crate::tests::api_integration::http_mock::HttpMockInterceptor;
use wasm_bindgen_test::*;
use std::rc::Rc;
#[wasm_bindgen_test]
async fn test_with_http_mock() {
// Create HTTP mock
let mock = HttpMockInterceptor::new();
// Configure mock responses
mock.add_response(
"api/users", // URL pattern to match
200, // HTTP status code
r#"{"users": [{"id": 1, "name": "Test User"}]}"# // Response body
);
// Configure response with more options
mock.add_response_with_config(
"api/auth", // URL pattern
Some("POST"), // HTTP method (optional)
401, // Status code
r#"{"error": "Unauthorized"}"#, // Response body
vec![("Content-Type", "application/json")], // Headers
Some(100) // Response delay in ms (optional)
);
// Install the mock (intercepts fetch calls)
mock.install().expect("Failed to install HTTP mock");
// Make API calls that will be intercepted by the mock...
// Access recorded requests
let requests = mock.get_requests();
assert_eq!(requests.len(), 2);
// Get requests matching a pattern
let auth_requests = mock.get_requests_matching("api/auth");
assert_eq!(auth_requests.len(), 1);
// Clean up requests if needed
mock.clear_requests();
// Uninstall mock when done
mock.uninstall().expect("Failed to uninstall HTTP mock");
}
Advanced Features
Delayed Responses
You can simulate network latency with delayed responses:
// Add a delayed response (500ms delay)
mock.add_delayed_response(
"api/slow-endpoint",
200,
r#"{"data": "response after delay"}"#,
500 // milliseconds
);
// The response will be delayed by approximately 500ms
let response = api_client.fetch("api/slow-endpoint").await;
Request Verification
Verify request contents:
// Make API call with specific payload
api_client.post_json("api/users", json!({
"username": "new_user",
"email": "user@example.com"
})).await;
// Verify the request contained expected data
assert!(mock.verify_request_contains("api/users", "new_user"));
Sequence-Based Responses
Configure different responses for sequential calls to the same endpoint:
// Configure a sequence of responses for an endpoint
mock.add_sequence_responses(
"api/data",
Some("GET"),
vec![
// First call response
MockResponse::new("api/data", 200, r#"{"page": 1, "data": [...]}"#),
// Second call response
MockResponse::new("api/data", 200, r#"{"page": 2, "data": [...]}"#),
// Third call response - error
MockResponse::new("api/data", 500, r#"{"error": "Server error"}"#),
]
);
// First call gets first response
let response1 = api_client.fetch("api/data").await;
// Second call gets second response
let response2 = api_client.fetch("api/data").await;
// Third call gets third response
let response3 = api_client.fetch("api/data").await;
Integration with Auth Tests
For auth integration tests, set up the HTTP mock with authentication-related endpoints:
// Configure login endpoint
mock.add_response_with_config(
"_open/auth",
Some("POST"),
200,
r#"{"error": false, "code": 200, "result": {"jwt": "mock.jwt.token"}}"#,
vec![("Content-Type", "application/json")],
None
);
// Configure user info endpoint
mock.add_response(
"api/users/me",
200,
r#"{
"error": false,
"code": 200,
"result": {
"id": "test_id",
"username": "test_user",
"email": "test@example.com",
"display_name": "Test User",
"roles": ["user"],
"email_verified": true
}
}"#
);
// Test login functionality with mock
let auth_service = AuthService::new(client);
let result = auth_service.login("test_user", "password").await;
assert!(result.is_ok());
Notes
- The mock intercepts the global
fetch()function in the browser environment - It restores the original
fetch()when uninstalled - In wasm-bindgen-test environment, full interception may not work due to limitations
- For component-level testing, consider using dependency injection to provide a mock client
- Always call
uninstall()when done to restore the original fetch function