module webdav
import time
import encoding.xml
fn test_property_xml() {
// Test DisplayName property
display_name := DisplayName('test-file.txt')
assert display_name.xml_str() == 'test-file.txt'
assert display_name.xml_name() == ''
// Test GetLastModified property
last_modified := GetLastModified('Mon, 01 Jan 2024 12:00:00 GMT')
assert last_modified.xml_str() == 'Mon, 01 Jan 2024 12:00:00 GMT'
assert last_modified.xml_name() == ''
// Test GetContentType property
content_type := GetContentType('text/plain')
assert content_type.xml_str() == 'text/plain'
assert content_type.xml_name() == ''
// Test GetContentLength property
content_length := GetContentLength('1024')
assert content_length.xml_str() == '1024'
assert content_length.xml_name() == ''
// Test ResourceType property for collection (directory)
resource_type_dir := ResourceType(true)
assert resource_type_dir.xml_str() == ''
assert resource_type_dir.xml_name() == ''
// Test ResourceType property for non-collection (file)
resource_type_file := ResourceType(false)
assert resource_type_file.xml_str() == ''
assert resource_type_file.xml_name() == ''
// Test CreationDate property
creation_date := CreationDate('2024-01-01T12:00:00Z')
assert creation_date.xml_str() == '2024-01-01T12:00:00Z'
assert creation_date.xml_name() == ''
// Test SupportedLock property
supported_lock := SupportedLock('')
supported_lock_str := supported_lock.xml_str()
assert supported_lock_str.contains('')
assert supported_lock.xml_name() == ''
// Test LockDiscovery property
lock_discovery := LockDiscovery('lock-info')
assert lock_discovery.xml_str() == 'lock-info'
assert lock_discovery.xml_name() == ''
}
fn test_property_array_xml() {
// Create an array of properties
mut properties := []Property{}
// Add different property types to the array
properties << DisplayName('test-file.txt')
properties << GetContentType('text/plain')
properties << ResourceType(false)
// Test the xml_str() function for the array of properties
xml_output := properties.xml_str()
// Verify the XML output contains the expected structure
assert xml_output.contains('')
assert xml_output.contains('')
assert xml_output.contains('test-file.txt')
assert xml_output.contains('text/plain')
assert xml_output.contains('')
assert xml_output.contains('HTTP/1.1 200 OK')
}
fn test_format_iso8601() {
// Create a test time
test_time := time.Time{
year: 2024
month: 1
day: 1
hour: 12
minute: 30
second: 45
}
// Format the time using the format_iso8601 function
formatted_time := format_iso8601(test_time)
// Verify the formatted time matches the expected ISO8601 format
assert formatted_time == '2024-01-01T12:30:45Z'
}
// Custom property implementation for testing
struct CustomProperty {
name string
value string
namespace string
}
// Property interface implementation for CustomProperty
fn (p CustomProperty) xml() xml.XMLNodeContents {
return xml.XMLNode{
name: '${p.namespace}:${p.name}'
children: [xml.XMLNodeContents(p.value)]
}
}
fn (p CustomProperty) xml_name() string {
return '<${p.name}/>'
}
fn (p CustomProperty) xml_str() string {
return '<${p.namespace}:${p.name}>${p.value}${p.namespace}:${p.name}>'
}
fn test_custom_property() {
// Test custom property
custom_prop := CustomProperty{
name: 'author'
value: 'Kristof'
namespace: 'C'
}
assert custom_prop.xml_str() == 'Kristof'
assert custom_prop.xml_name() == ''
}
fn test_propfind_response() {
// Create an array of properties for a resource
mut props := []Property{}
props << DisplayName('test-file.txt')
props << GetLastModified('Mon, 01 Jan 2024 12:00:00 GMT')
props << GetContentLength('1024')
// Build a complete PROPFIND response with multistatus
xml_output := '
/test-file.txt
${props.xml_str()}
'
// Verify the XML structure
assert xml_output.contains('')
assert xml_output.contains('')
assert xml_output.contains('')
assert xml_output.contains('HTTP/1.1 200 OK')
assert xml_output.contains('')
}
fn test_propfind_with_missing_properties() {
// Test response for missing properties
missing_prop_response := '
HTTP/1.1 404 Not Found
'
// Simple verification of structure
assert missing_prop_response.contains('')
assert missing_prop_response.contains('')
assert missing_prop_response.contains('HTTP/1.1 404 Not Found')
}
fn test_supported_lock_detailed() {
supported_lock := SupportedLock('')
xml_output := supported_lock.xml_str()
// Test SupportedLock provides a fully formed XML snippet for supportedlock
// Note: This test assumes the actual implementation returns a simplified version
// as indicated by the xml_str() method which returns '...'
assert xml_output.contains('')
// Detailed testing would need proper parsing of the XML to verify elements
// For real implementation, test should check for:
// - lockentry elements
// - lockscope elements (exclusive and shared)
// - locktype elements (write)
}
fn test_proppatch_request() {
// Create property to set
author_prop := CustomProperty{
name: 'author'
value: 'Kristof'
namespace: 'C'
}
// Create XML for PROPPATCH request (set)
proppatch_set := '
${author_prop.xml_str()}
'
// Check structure
assert proppatch_set.contains('')
assert proppatch_set.contains('')
assert proppatch_set.contains('Kristof')
// Create XML for PROPPATCH request (remove)
proppatch_remove := '
'
// Check structure
assert proppatch_remove.contains('')
assert proppatch_remove.contains('')
assert proppatch_remove.contains('')
}
fn test_prop_name_listing() {
// Create sample properties
mut props := []Property{}
props << DisplayName('file.txt')
props << GetContentType('text/plain')
// Generate propname response
// Note: In a complete implementation, there would be a function to generate this XML
// For testing purposes, we're manually creating the expected structure
propname_response := '
/file.txt
HTTP/1.1 200 OK
'
// Verify structure
assert propname_response.contains('')
assert propname_response.contains('')
assert propname_response.contains('')
}
fn test_namespace_declarations() {
// Test proper namespace declarations
response_with_ns := '
/file.txt
file.txt
Kristof
HTTP/1.1 200 OK
'
// Verify key namespace elements
assert response_with_ns.contains('xmlns:D="DAV:"')
assert response_with_ns.contains('xmlns:C="http://example.com/customns"')
}
fn test_depth_header_responses() {
// Test properties for multiple resources (simulating Depth: 1)
multi_response := '
/collection/
HTTP/1.1 200 OK
/collection/file.txt
HTTP/1.1 200 OK
'
// Verify structure contains multiple responses
assert multi_response.contains('')
assert multi_response.count('') == 2
assert multi_response.contains('/collection/')
assert multi_response.contains('/collection/file.txt')
}