#!/usr/bin/env nu # Hetzner provider server lifecycle integration tests (with mocks) # Mock API responses loader def load-mock-responses []: nothing -> record { let mocks = (open ../../tests/mocks/mock_api_responses.json) $mocks } # Mock: list servers def mock-list-servers []: nothing -> list { let mocks = (load-mock-responses) $mocks.servers_list.servers } # Mock: get server info def mock-server-info [hostname: string]: nothing -> record { let mocks = (load-mock-responses) # For testing, return first server if exists if ($hostname == "test-server-1") { $mocks.server_info.server } else { error make {msg: $"Server not found: ($hostname)"} } } # Mock: create server def mock-create-server [name: string]: nothing -> record { let mocks = (load-mock-responses) $mocks.server_create_success.server } # Test framework def test-result [name: string, passed: bool]: nothing -> record { if $passed { print $"✓ ($name)" } else { print $"✗ ($name)" } {name: $name, passed: $passed} } # Test: List servers def test_list_servers []: nothing -> record { let result = (do { let servers = (mock-list-servers) ($servers | length) > 0 } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "list_servers: returns list" $passed } # Test: Server info structure def test_server_info_structure []: nothing -> record { let result = (do { let server = (mock-server-info "test-server-1") ($server | has id) and ($server | has name) and ($server | has status) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "server_info: has required fields" $passed } # Test: Server name field def test_server_name_field []: nothing -> record { let result = (do { let server = (mock-server-info "test-server-1") $server.name } | complete) let passed = ($result.exit_code == 0 and $result.stdout == "test-server-1") test-result "server_info: name matches request" $passed } # Test: Server status field def test_server_status_field []: nothing -> record { let result = (do { let server = (mock-server-info "test-server-1") $server.status } | complete) let passed = ($result.exit_code == 0 and $result.stdout == "running") test-result "server_info: status is running" $passed } # Test: Server public IPs def test_server_public_ips []: nothing -> record { let result = (do { let server = (mock-server-info "test-server-1") { ipv4: ($server.public_net.ipv4.ip | default "") ipv6: ($server.public_net.ipv6.ip | default "") } } | complete) let passed = ($result.exit_code == 0) test-result "server_info: public IPs present" $passed } # Test: Server type information def test_server_type_info []: nothing -> record { let result = (do { let server = (mock-server-info "test-server-1") { name: ($server.server_type.name | default "") cores: ($server.server_type.cores | default 0) memory: ($server.server_type.memory | default 0) } } | complete) let passed = ($result.exit_code == 0) test-result "server_info: server type details available" $passed } # Test: Create server response structure def test_create_server_response []: nothing -> record { let result = (do { let server = (mock-create-server "new-test-server") { has_id: ($server | has id) has_name: ($server | has name) has_status: ($server | has status) } } | complete) let passed = ($result.exit_code == 0 and $result.stdout.has_id and $result.stdout.has_name and $result.stdout.has_status) test-result "create_server: response has required fields" $passed } # Test: Server not found error def test_server_not_found_error []: nothing -> record { let result = (do { mock-server-info "nonexistent-server" } | complete) let passed = ($result.exit_code != 0) test-result "server_info: error on nonexistent server" $passed } # Test: List servers contains expected count def test_list_servers_count []: nothing -> record { let result = (do { let servers = (mock-list-servers) $servers | length } | complete) let passed = ($result.exit_code == 0 and $result.stdout > 0) test-result "list_servers: contains servers" $passed } # Test: Verify server status transitions (mock simulation) def test_server_status_value []: nothing -> record { let result = (do { let server = (mock-server-info "test-server-1") $server.status in ["running", "stopped", "initializing", "off"] } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "server_status: valid status value" $passed } # Test: Location information structure def test_server_location_info []: nothing -> record { let result = (do { let server = (mock-server-info "test-server-1") { has_id: ($server.location | has id) has_name: ($server.location | has name) has_zone: ($server.location | has network_zone) } } | complete) let passed = ($result.exit_code == 0 and $result.stdout.has_id and $result.stdout.has_name and $result.stdout.has_zone) test-result "server_location: location data complete" $passed } # Main test runner def main []: nothing -> record { print "=== Hetzner Provider Integration Tests (Mock Mode) ===" print "" let results = [ (test_list_servers) (test_server_info_structure) (test_server_name_field) (test_server_status_field) (test_server_public_ips) (test_server_type_info) (test_create_server_response) (test_server_not_found_error) (test_list_servers_count) (test_server_status_value) (test_server_location_info) ] print "" print "Test Summary:" print "=============" let passed = ($results | where {|r| $r.passed} | length) let failed = ($results | where {|r| not $r.passed} | length) let total = ($results | length) print $"Passed: ($passed)/$total" print $"Failed: ($failed)/$total" {passed: $passed, failed: $failed, total: $total} }