#!/usr/bin/env nu # UpCloud provider API client integration tests (with mocks) # Load mock responses def load-mock-responses []: nothing -> record { let mocks = (open ../../tests/mocks/mock_api_responses.json) $mocks } # Mock HTTP response handler def mock-http-response [endpoint: string]: nothing -> record { let mocks = (load-mock-responses) match $endpoint { "/server" => { $mocks.servers_list }, "/server/00798b85-efb3-41e9-8e46-10d3f8369f90" => { $mocks.server_info }, "/storage" => { $mocks.storages_list }, "/network" => { $mocks.networks_list }, "/plan" => { $mocks.plans_list }, "/zone" => { $mocks.zones_list }, "/error/401" => { $mocks.error_401 }, "/error/404" => { $mocks.error_404 }, _ => { error make {msg: $"Unknown endpoint: ($endpoint)"} } } } # Test framework def test-result [name: string, passed: bool]: nothing -> record { if $passed { print $"✓ ($name)" } else { print $"✗ ($name)" } {name: $name, passed: $passed} } # Test: GET /server (list) response structure def test_get_servers_structure []: nothing -> record { let result = (do { let response = (mock-http-response "/server") ($response | has servers) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "GET /server: response structure" $passed } # Test: GET /server returns list def test_get_servers_list []: nothing -> record { let result = (do { let response = (mock-http-response "/server") ($response.servers | describe) =~ "list" } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "GET /server: returns list" $passed } # Test: GET single server def test_get_single_server []: nothing -> record { let result = (do { let response = (mock-http-response "/server/00798b85-efb3-41e9-8e46-10d3f8369f90") ($response | has server) and (not ($response.server | is-empty)) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "GET /server/{id}: single server response" $passed } # Test: GET storage list def test_get_storages_list []: nothing -> record { let result = (do { let response = (mock-http-response "/storage") ($response | has storages) and (($response.storages | describe) =~ "list") } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "GET /storage: returns list" $passed } # Test: GET networks list def test_get_networks_list []: nothing -> record { let result = (do { let response = (mock-http-response "/network") ($response | has networks) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "GET /network: returns list" $passed } # Test: GET plans list def test_get_plans_list []: nothing -> record { let result = (do { let response = (mock-http-response "/plan") ($response | has plans) and (($response.plans | length) > 0) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "GET /plan: returns list" $passed } # Test: GET zones list def test_get_zones_list []: nothing -> record { let result = (do { let response = (mock-http-response "/zone") ($response | has zones) and (($response.zones | length) > 0) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "GET /zone: returns list" $passed } # Test: Plan pricing structure def test_plan_pricing_structure []: nothing -> record { let result = (do { let response = (mock-http-response "/plan") let plan = ($response.plans | first) {\ has_name: ($plan | has name) has_memory: ($plan | has memory_amount) has_cores: ($plan | has core_number) has_prices: ($plan | has prices) } } | complete) let passed = ($result.exit_code == 0 and $result.stdout.has_name and $result.stdout.has_memory and $result.stdout.has_cores and $result.stdout.has_prices) test-result "plan: pricing structure" $passed } # Test: Error response format (401) def test_error_401_response []: nothing -> record { let result = (do { let response = (mock-http-response "/error/401") ($response | has error) and ($response.error | has error_message) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "error_response: 401 Unauthorized format" $passed } # Test: Error response format (404) def test_error_404_response []: nothing -> record { let result = (do { let response = (mock-http-response "/error/404") ($response | has error) and ($response.error.error_code == "SERVER_NOT_FOUND") } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "error_response: 404 Not Found format" $passed } # Test: Server response has UUID def test_server_uuid_field []: nothing -> record { let result = (do { let response = (mock-http-response "/server") let server = ($response.servers | first) ($server | has uuid) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "response: server has UUID field" $passed } # Test: Server state field def test_server_state_field []: nothing -> record { let result = (do { let response = (mock-http-response "/server") let server = ($response.servers | first) ($server | has state) and ($server.state in ["started", "stopped", "maintenance"]) } | complete) let passed = ($result.exit_code == 0 and $result.stdout) test-result "response: server state is valid" $passed } # Test: Unknown endpoint error def test_unknown_endpoint_error []: nothing -> record { let result = (do { mock-http-response "/unknown" } | complete) let passed = ($result.exit_code != 0) test-result "error_handling: unknown endpoint fails" $passed } # Main test runner def main []: nothing -> record { print "=== UpCloud API Client Integration Tests (Mock Mode) ===" print "" let results = [ (test_get_servers_structure) (test_get_servers_list) (test_get_single_server) (test_get_storages_list) (test_get_networks_list) (test_get_plans_list) (test_get_zones_list) (test_plan_pricing_structure) (test_error_401_response) (test_error_404_response) (test_server_uuid_field) (test_server_state_field) (test_unknown_endpoint_error) ] 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} }