provisioning-catalog/providers/hetzner/tests/integration/test_api_client.nu

237 lines
7 KiB
Text

#!/usr/bin/env nu
# Hetzner 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 {
"/servers" => {
$mocks.servers_list
}
"/servers/12345" => {
$mocks.server_info
}
"/volumes" => {
$mocks.volumes_list
}
"/networks" => {
$mocks.networks_list
}
"/floating_ips" => {
$mocks.floating_ips_list
}
"/server_types" => {
$mocks.server_types_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 request response structure
def test_get_request_servers []: nothing -> record {
let result = (do {
let response = (mock-http-response "/servers")
($response | has servers)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "GET /servers: response structure" $passed
}
# Test: GET request returns list
def test_get_request_list []: nothing -> record {
let result = (do {
let response = (mock-http-response "/servers")
($response.servers | describe) =~ "list"
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "GET /servers: returns list" $passed
}
# Test: GET single server
def test_get_single_server []: nothing -> record {
let result = (do {
let response = (mock-http-response "/servers/12345")
($response | has server) and (not ($response.server | is-empty))
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "GET /servers/{id}: single server response" $passed
}
# Test: GET volumes list
def test_get_volumes_list []: nothing -> record {
let result = (do {
let response = (mock-http-response "/volumes")
($response | has volumes) and (($response.volumes | describe) =~ "list")
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "GET /volumes: returns list" $passed
}
# Test: GET networks list
def test_get_networks_list []: nothing -> record {
let result = (do {
let response = (mock-http-response "/networks")
($response | has networks)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "GET /networks: returns list" $passed
}
# Test: GET floating IPs list
def test_get_floating_ips_list []: nothing -> record {
let result = (do {
let response = (mock-http-response "/floating_ips")
($response | has floating_ips)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "GET /floating_ips: returns list" $passed
}
# Test: GET server types list
def test_get_server_types_list []: nothing -> record {
let result = (do {
let response = (mock-http-response "/server_types")
($response | has server_types) and (($response.server_types | length) > 0)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "GET /server_types: returns list" $passed
}
# Test: Server type pricing structure
def test_server_type_pricing []: nothing -> record {
let result = (do {
let response = (mock-http-response "/server_types")
let st = ($response.server_types | first)
{
has_name: ($st | has name)
has_cores: ($st | has cores)
has_prices: ($st | has prices)
}
} | complete)
let passed = ($result.exit_code == 0 and
$result.stdout.has_name and
$result.stdout.has_cores and
$result.stdout.has_prices)
test-result "server_types: 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 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.code == "not_found")
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "error_response: 404 Not Found format" $passed
}
# Test: Server pagination fields (if present)
def test_response_server_count []: nothing -> record {
let result = (do {
let response = (mock-http-response "/servers")
($response.servers | length)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout > 0)
test-result "response: contains servers" $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
}
# Test: Server ID type
def test_server_id_type []: nothing -> record {
let result = (do {
let response = (mock-http-response "/servers")
let server = ($response.servers | first)
($server.id | describe) =~ "int"
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "response: server ID is integer" $passed
}
# Main test runner
def main []: nothing -> record {
print "=== Hetzner API Client Integration Tests (Mock Mode) ==="
print ""
let results = [
(test_get_request_servers)
(test_get_request_list)
(test_get_single_server)
(test_get_volumes_list)
(test_get_networks_list)
(test_get_floating_ips_list)
(test_get_server_types_list)
(test_server_type_pricing)
(test_error_401_response)
(test_error_404_response)
(test_response_server_count)
(test_unknown_endpoint_error)
(test_server_id_type)
]
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}
}