minifly-api 0.1.2

API server for Minifly - Local Fly.io development simulator
Documentation
// Integration tests temporarily disabled due to complex mocking requirements
// TODO: Implement proper test infrastructure with mock Docker and database

/*
use minifly_api::*;
use minifly_core::models::*;
use reqwest::StatusCode;
use serde_json::json;

mod common;
use common::*;

#[tokio::test]
async fn test_create_volume() {
    let (url, _handle) = start_test_server().await;
    let client = test_client();
    
    // Create app first
    let app_req = CreateAppRequest {
        name: "volume-test-app".to_string(),
        org_slug: "test-org".to_string(),
    };
    
    client
        .post(&format!("{}/v1/apps", url))
        .header("fly-region", "local")
        .json(&app_req)
        .send()
        .await
        .expect("Failed to create app");
    
    // Create volume
    let volume_req = CreateVolumeRequest {
        name: "test-volume".to_string(),
        size_gb: 1,
        encrypted: false,
        region: Some("local".to_string()),
        snapshot_id: None,
        snapshot_retention: None,
        machines_only: false,
        require_unique_zone: false,
    };
    
    let response = client
        .post(&format!("{}/v1/apps/volume-test-app/volumes", url))
        .header("fly-region", "local")
        .json(&volume_req)
        .send()
        .await
        .expect("Failed to send request");
    
    assert_status!(response, StatusCode::CREATED);
    
    let volume: Volume = response.json().await.expect("Failed to parse response");
    assert_eq!(volume.name, "test-volume");
    assert_eq!(volume.size_gb, 1);
    assert_eq!(volume.app_id, "volume-test-app");
}

#[tokio::test]
async fn test_list_volumes() {
    let (url, _handle) = start_test_server().await;
    let client = test_client();
    
    // Create app
    let app_req = CreateAppRequest {
        name: "list-volumes-app".to_string(),
        org_slug: "test-org".to_string(),
    };
    
    client
        .post(&format!("{}/v1/apps", url))
        .header("fly-region", "local")
        .json(&app_req)
        .send()
        .await
        .expect("Failed to create app");
    
    // Create multiple volumes
    for i in 0..3 {
        let volume_req = CreateVolumeRequest {
            name: format!("volume-{}", i),
            size_gb: 1,
            encrypted: false,
            region: Some("local".to_string()),
            snapshot_id: None,
            snapshot_retention: None,
            machines_only: false,
            require_unique_zone: false,
        };
        
        client
            .post(&format!("{}/v1/apps/list-volumes-app/volumes", url))
            .header("fly-region", "local")
            .json(&volume_req)
            .send()
            .await
            .expect("Failed to create volume");
    }
    
    // List volumes
    let response = client
        .get(&format!("{}/v1/apps/list-volumes-app/volumes", url))
        .header("fly-region", "local")
        .send()
        .await
        .expect("Failed to send request");
    
    assert_status!(response, StatusCode::OK);
    
    let volumes: Vec<Volume> = response.json().await.expect("Failed to parse response");
    assert_eq!(volumes.len(), 3);
}

#[tokio::test]
async fn test_get_volume() {
    let (url, _handle) = start_test_server().await;
    let client = test_client();
    
    // Create app and volume
    let app_req = CreateAppRequest {
        name: "get-volume-app".to_string(),
        org_slug: "test-org".to_string(),
    };
    
    client
        .post(&format!("{}/v1/apps", url))
        .header("fly-region", "local")
        .json(&app_req)
        .send()
        .await
        .expect("Failed to create app");
    
    let volume_req = CreateVolumeRequest {
        name: "get-test-volume".to_string(),
        size_gb: 2,
        encrypted: true,
        region: Some("local".to_string()),
        snapshot_id: None,
        snapshot_retention: None,
        machines_only: false,
        require_unique_zone: false,
    };
    
    let create_response = client
        .post(&format!("{}/v1/apps/get-volume-app/volumes", url))
        .header("fly-region", "local")
        .json(&volume_req)
        .send()
        .await
        .expect("Failed to create volume");
    
    let created_volume: Volume = create_response.json().await.expect("Failed to parse response");
    
    // Get the volume
    let response = client
        .get(&format!("{}/v1/apps/get-volume-app/volumes/{}", url, created_volume.id))
        .header("fly-region", "local")
        .send()
        .await
        .expect("Failed to send request");
    
    assert_status!(response, StatusCode::OK);
    
    let volume: Volume = response.json().await.expect("Failed to parse response");
    assert_eq!(volume.id, created_volume.id);
    assert_eq!(volume.encrypted, true);
}

#[tokio::test]
async fn test_delete_volume() {
    let (url, _handle) = start_test_server().await;
    let client = test_client();
    
    // Create app and volume
    let app_req = CreateAppRequest {
        name: "delete-volume-app".to_string(),
        org_slug: "test-org".to_string(),
    };
    
    client
        .post(&format!("{}/v1/apps", url))
        .header("fly-region", "local")
        .json(&app_req)
        .send()
        .await
        .expect("Failed to create app");
    
    let volume_req = CreateVolumeRequest {
        name: "delete-test-volume".to_string(),
        size_gb: 1,
        encrypted: false,
        region: Some("local".to_string()),
        snapshot_id: None,
        snapshot_retention: None,
        machines_only: false,
        require_unique_zone: false,
    };
    
    let create_response = client
        .post(&format!("{}/v1/apps/delete-volume-app/volumes", url))
        .header("fly-region", "local")
        .json(&volume_req)
        .send()
        .await
        .expect("Failed to create volume");
    
    let volume: Volume = create_response.json().await.expect("Failed to parse response");
    
    // Delete the volume
    let response = client
        .delete(&format!("{}/v1/apps/delete-volume-app/volumes/{}", url, volume.id))
        .header("fly-region", "local")
        .send()
        .await
        .expect("Failed to send request");
    
    assert_status!(response, StatusCode::NO_CONTENT);
    
    // Verify it's gone
    let response = client
        .get(&format!("{}/v1/apps/delete-volume-app/volumes/{}", url, volume.id))
        .header("fly-region", "local")
        .send()
        .await
        .expect("Failed to send request");
    
    assert_status!(response, StatusCode::NOT_FOUND);
}

#[tokio::test]
async fn test_volume_attachment() {
    let (url, _handle) = start_test_server().await;
    let client = test_client();
    
    // Create app
    let app_req = CreateAppRequest {
        name: "attachment-app".to_string(),
        org_slug: "test-org".to_string(),
    };
    
    client
        .post(&format!("{}/v1/apps", url))
        .header("fly-region", "local")
        .json(&app_req)
        .send()
        .await
        .expect("Failed to create app");
    
    // Create volume
    let volume_req = CreateVolumeRequest {
        name: "attach-volume".to_string(),
        size_gb: 1,
        encrypted: false,
        region: Some("local".to_string()),
        snapshot_id: None,
        snapshot_retention: None,
        machines_only: false,
        require_unique_zone: false,
    };
    
    let volume_response = client
        .post(&format!("{}/v1/apps/attachment-app/volumes", url))
        .header("fly-region", "local")
        .json(&volume_req)
        .send()
        .await
        .expect("Failed to create volume");
    
    let volume: Volume = volume_response.json().await.expect("Failed to parse response");
    
    // Create machine with volume mount
    let machine_req = CreateMachineRequest {
        name: Some("volume-machine".to_string()),
        config: MachineConfig {
            image: "nginx:latest".to_string(),
            guest: None,
            env: std::collections::HashMap::new(),
            services: vec![],
            mounts: vec![MountConfig {
                volume: volume.id.clone(),
                path: "/data".to_string(),
                size_gb: None,
            }],
            size: MachineSize::Shared1x,
            restart: None,
            auto_destroy: false,
            schedule: None,
        },
        region: Some("local".to_string()),
        skip_launch: false,
        skip_service_registration: false,
    };
    
    let machine_response = client
        .post(&format!("{}/v1/apps/attachment-app/machines", url))
        .header("fly-region", "local")
        .json(&machine_req)
        .send()
        .await
        .expect("Failed to create machine");
    
    let machine: Machine = machine_response.json().await.expect("Failed to parse response");
    
    // Get volume to check attachment
    let response = client
        .get(&format!("{}/v1/apps/attachment-app/volumes/{}", url, volume.id))
        .header("fly-region", "local")
        .send()
        .await
        .expect("Failed to send request");
    
    assert_status!(response, StatusCode::OK);
    
    let updated_volume: Volume = response.json().await.expect("Failed to parse response");
    assert_eq!(updated_volume.attached_machine_id, Some(machine.id));
}
*/