Add CalDAV integration tests with Baikal server
- Updated base64 usage to new API (BASE64_STANDARD.encode) - Added tokio dev dependency for async testing - Created comprehensive integration tests: - test_baikal_auth: Tests authentication with OPTIONS request - test_propfind_calendars: Tests calendar discovery with PROPFIND - Tests validate: - HTTP Basic Auth with .env credentials - DAV server capabilities detection - CalDAV PROPFIND XML responses - 207 Multi-Status handling - Both tests pass successfully against Baikal server - Tests marked as #[ignore] for CI/network isolation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										110
									
								
								src/config.rs
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								src/config.rs
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use std::env; | ||||
| use base64::prelude::*; | ||||
|  | ||||
| /// Configuration for CalDAV server connection and authentication. | ||||
| ///  | ||||
| @@ -137,7 +138,7 @@ impl CalDAVConfig { | ||||
|     /// ``` | ||||
|     pub fn get_basic_auth(&self) -> String { | ||||
|         let credentials = format!("{}:{}", self.username, self.password); | ||||
|         base64::encode(&credentials) | ||||
|         BASE64_STANDARD.encode(&credentials) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -163,7 +164,6 @@ pub enum ConfigError { | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|     use std::env; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_basic_auth_encoding() { | ||||
| @@ -176,7 +176,111 @@ mod tests { | ||||
|         }; | ||||
|  | ||||
|         let auth = config.get_basic_auth(); | ||||
|         let expected = base64::encode("testuser:testpass"); | ||||
|         let expected = BASE64_STANDARD.encode("testuser:testpass"); | ||||
|         assert_eq!(auth, expected); | ||||
|     } | ||||
|  | ||||
|     /// Integration test that authenticates with the actual Baikal CalDAV server | ||||
|     ///  | ||||
|     /// This test requires a valid .env file with: | ||||
|     /// - CALDAV_SERVER_URL | ||||
|     /// - CALDAV_USERNAME   | ||||
|     /// - CALDAV_PASSWORD | ||||
|     ///  | ||||
|     /// Run with: `cargo test test_baikal_auth -- --ignored` | ||||
|     #[tokio::test] | ||||
|     #[ignore] // Ignored by default since it requires network access and valid credentials | ||||
|     async fn test_baikal_auth() { | ||||
|         // Load config from .env | ||||
|         let config = CalDAVConfig::from_env() | ||||
|             .expect("Failed to load CalDAV config from environment"); | ||||
|  | ||||
|         println!("Testing authentication to: {}", config.server_url); | ||||
|  | ||||
|         // Create HTTP client | ||||
|         let client = reqwest::Client::new(); | ||||
|  | ||||
|         // Make a simple OPTIONS request to test authentication | ||||
|         let response = client | ||||
|             .request(reqwest::Method::OPTIONS, &config.server_url) | ||||
|             .header("Authorization", format!("Basic {}", config.get_basic_auth())) | ||||
|             .header("User-Agent", "calendar-app/0.1.0") | ||||
|             .send() | ||||
|             .await | ||||
|             .expect("Failed to send request to CalDAV server"); | ||||
|  | ||||
|         println!("Response status: {}", response.status()); | ||||
|         println!("Response headers: {:#?}", response.headers()); | ||||
|  | ||||
|         // Check if we got a successful response or at least not a 401 Unauthorized | ||||
|         assert!( | ||||
|             response.status().is_success() || response.status() != 401, | ||||
|             "Authentication failed with status: {}. Check your credentials in .env", | ||||
|             response.status() | ||||
|         ); | ||||
|  | ||||
|         // For Baikal/CalDAV servers, we should see DAV headers | ||||
|         assert!( | ||||
|             response.headers().contains_key("dav") ||  | ||||
|             response.headers().contains_key("DAV") || | ||||
|             response.status().is_success(), | ||||
|             "Server doesn't appear to be a CalDAV server - missing DAV headers" | ||||
|         ); | ||||
|  | ||||
|         println!("✓ Authentication test passed!"); | ||||
|     } | ||||
|  | ||||
|     /// Test making a PROPFIND request to discover calendars | ||||
|     ///  | ||||
|     /// This test requires a valid .env file and makes an actual CalDAV PROPFIND request | ||||
|     ///  | ||||
|     /// Run with: `cargo test test_propfind_calendars -- --ignored` | ||||
|     #[tokio::test] | ||||
|     #[ignore] | ||||
|     async fn test_propfind_calendars() { | ||||
|         let config = CalDAVConfig::from_env() | ||||
|             .expect("Failed to load CalDAV config from environment"); | ||||
|  | ||||
|         let client = reqwest::Client::new(); | ||||
|  | ||||
|         // CalDAV PROPFIND request to discover calendars | ||||
|         let propfind_body = r#"<?xml version="1.0" encoding="utf-8" ?> | ||||
| <d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav"> | ||||
|     <d:prop> | ||||
|         <d:resourcetype /> | ||||
|         <d:displayname /> | ||||
|         <c:calendar-description /> | ||||
|         <c:supported-calendar-component-set /> | ||||
|     </d:prop> | ||||
| </d:propfind>"#; | ||||
|  | ||||
|         let response = client | ||||
|             .request(reqwest::Method::from_bytes(b"PROPFIND").unwrap(), &config.server_url) | ||||
|             .header("Authorization", format!("Basic {}", config.get_basic_auth())) | ||||
|             .header("Content-Type", "application/xml") | ||||
|             .header("Depth", "1") | ||||
|             .header("User-Agent", "calendar-app/0.1.0") | ||||
|             .body(propfind_body) | ||||
|             .send() | ||||
|             .await | ||||
|             .expect("Failed to send PROPFIND request"); | ||||
|  | ||||
|         let status = response.status(); | ||||
|         println!("PROPFIND Response status: {}", status); | ||||
|          | ||||
|         let body = response.text().await.expect("Failed to read response body"); | ||||
|         println!("PROPFIND Response body: {}", body); | ||||
|  | ||||
|         // We should get a 207 Multi-Status for PROPFIND | ||||
|         assert_eq!( | ||||
|             status, | ||||
|             reqwest::StatusCode::from_u16(207).unwrap(), | ||||
|             "PROPFIND should return 207 Multi-Status" | ||||
|         ); | ||||
|  | ||||
|         // The response should contain XML with calendar information | ||||
|         assert!(body.contains("calendar"), "Response should contain calendar information"); | ||||
|  | ||||
|         println!("✓ PROPFIND calendars test passed!"); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Connor Johnstone
					Connor Johnstone