mirror of https://github.com/buster-so/buster.git
297 lines
9.4 KiB
Rust
297 lines
9.4 KiB
Rust
use anyhow::Result;
|
|
use axum::http::StatusCode;
|
|
use serde_json::json;
|
|
use uuid::Uuid;
|
|
|
|
use crate::common::TestApp;
|
|
|
|
#[tokio::test]
|
|
async fn test_update_dashboard_endpoint() -> Result<()> {
|
|
// Setup test app
|
|
let app = TestApp::new().await?;
|
|
|
|
// Create a test dashboard first
|
|
let create_response = app
|
|
.client
|
|
.post("/api/v1/dashboards")
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"name": "Test Dashboard",
|
|
"description": "Test Description",
|
|
"file": "name: Test Dashboard\ndescription: Test Description\nrows: []"
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
let create_body: serde_json::Value = create_response.json().await?;
|
|
let dashboard_id = create_body["dashboard"]["id"].as_str().unwrap();
|
|
|
|
// Make request to update dashboard
|
|
let update_response = app
|
|
.client
|
|
.put(&format!("/api/v1/dashboards/{}", dashboard_id))
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"name": "Updated Dashboard Name",
|
|
"description": "Updated description"
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
// Verify response
|
|
assert_eq!(update_response.status(), StatusCode::OK);
|
|
|
|
// Parse response body
|
|
let update_body: serde_json::Value = update_response.json().await?;
|
|
|
|
// Verify dashboard properties
|
|
assert_eq!(update_body["dashboard"]["name"], "Updated Dashboard Name");
|
|
assert_eq!(update_body["dashboard"]["description"], "Updated description");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_update_dashboard_with_file_endpoint() -> Result<()> {
|
|
// Setup test app
|
|
let app = TestApp::new().await?;
|
|
|
|
// Create a test dashboard first
|
|
let create_response = app
|
|
.client
|
|
.post("/api/v1/dashboards")
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"name": "Test Dashboard",
|
|
"description": "Test Description",
|
|
"file": "name: Test Dashboard\ndescription: Test Description\nrows: []"
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
let create_body: serde_json::Value = create_response.json().await?;
|
|
let dashboard_id = create_body["dashboard"]["id"].as_str().unwrap();
|
|
|
|
// YAML content for update
|
|
let yaml_content = r#"
|
|
name: File Updated Dashboard
|
|
description: Updated from file
|
|
rows: []
|
|
"#;
|
|
|
|
// Make request to update dashboard with file
|
|
let update_response = app
|
|
.client
|
|
.put(&format!("/api/v1/dashboards/{}", dashboard_id))
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"file": yaml_content
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
// Verify response
|
|
assert_eq!(update_response.status(), StatusCode::OK);
|
|
|
|
// Parse response body
|
|
let update_body: serde_json::Value = update_response.json().await?;
|
|
|
|
// Verify dashboard properties
|
|
assert_eq!(update_body["dashboard"]["name"], "File Updated Dashboard");
|
|
assert_eq!(update_body["dashboard"]["description"], "Updated from file");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_restore_dashboard_version() -> Result<()> {
|
|
// Setup test app
|
|
let app = TestApp::new().await?;
|
|
|
|
// 1. Create a dashboard with initial content (version 1)
|
|
let v1_yaml_content = r#"
|
|
name: Original Dashboard
|
|
description: Original description
|
|
rows:
|
|
- items:
|
|
- id: "00000000-0000-0000-0000-000000000001"
|
|
row_height: 300
|
|
column_sizes: [12]
|
|
id: 1
|
|
"#;
|
|
|
|
let create_response = app
|
|
.client
|
|
.post("/api/v1/dashboards")
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"file": v1_yaml_content
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
let create_body: serde_json::Value = create_response.json().await?;
|
|
let dashboard_id = create_body["dashboard"]["id"].as_str().unwrap();
|
|
assert_eq!(create_body["dashboard"]["version"], 1);
|
|
|
|
// 2. Update to create version 2 with different content
|
|
let v2_yaml_content = r#"
|
|
name: Updated Dashboard
|
|
description: Updated description
|
|
rows:
|
|
- items:
|
|
- id: "00000000-0000-0000-0000-000000000001"
|
|
- id: "00000000-0000-0000-0000-000000000002"
|
|
row_height: 400
|
|
column_sizes: [6, 6]
|
|
id: 1
|
|
- items:
|
|
- id: "00000000-0000-0000-0000-000000000003"
|
|
row_height: 300
|
|
column_sizes: [12]
|
|
id: 2
|
|
"#;
|
|
|
|
let update_response = app
|
|
.client
|
|
.put(&format!("/api/v1/dashboards/{}", dashboard_id))
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"file": v2_yaml_content
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
let update_body: serde_json::Value = update_response.json().await?;
|
|
assert_eq!(update_body["dashboard"]["version"], 2);
|
|
assert_eq!(update_body["dashboard"]["name"], "Updated Dashboard");
|
|
|
|
// 3. Restore to version 1
|
|
let restore_response = app
|
|
.client
|
|
.put(&format!("/api/v1/dashboards/{}", dashboard_id))
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"restore_to_version": 1,
|
|
// Also add other fields to verify they're ignored
|
|
"name": "This Name Should Be Ignored",
|
|
"description": "This Description Should Be Ignored"
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
// Verify response
|
|
assert_eq!(restore_response.status(), StatusCode::OK);
|
|
|
|
// Parse response body
|
|
let restore_body: serde_json::Value = restore_response.json().await?;
|
|
|
|
// 4. Verify a new version (3) is created with content from version 1
|
|
assert_eq!(restore_body["dashboard"]["version"], 3);
|
|
assert_eq!(restore_body["dashboard"]["name"], "Original Dashboard");
|
|
assert_eq!(restore_body["dashboard"]["description"], "Original description");
|
|
|
|
// 5. Verify by fetching the dashboard again
|
|
let get_response = app
|
|
.client
|
|
.get(&format!("/api/v1/dashboards/{}", dashboard_id))
|
|
.bearer_auth(&app.test_user.token)
|
|
.send()
|
|
.await?;
|
|
|
|
assert_eq!(get_response.status(), StatusCode::OK);
|
|
let fetched_dashboard: serde_json::Value = get_response.json().await?;
|
|
|
|
// Verify the fetched dashboard matches the restored version
|
|
assert_eq!(fetched_dashboard["dashboard"]["name"], "Original Dashboard");
|
|
assert_eq!(fetched_dashboard["dashboard"]["version"], 3);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_restore_nonexistent_version() -> Result<()> {
|
|
// Setup test app
|
|
let app = TestApp::new().await?;
|
|
|
|
// 1. Create a dashboard
|
|
let create_response = app
|
|
.client
|
|
.post("/api/v1/dashboards")
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"name": "Test Dashboard",
|
|
"description": "Test Description",
|
|
"file": "name: Test Dashboard\ndescription: Test Description\nrows: []"
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
let create_body: serde_json::Value = create_response.json().await?;
|
|
let dashboard_id = create_body["dashboard"]["id"].as_str().unwrap();
|
|
|
|
// 2. Attempt to restore to a non-existent version (999)
|
|
let restore_response = app
|
|
.client
|
|
.put(&format!("/api/v1/dashboards/{}", dashboard_id))
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"restore_to_version": 999
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
// 3. Verify the request fails with an appropriate status code
|
|
assert_eq!(restore_response.status(), StatusCode::BAD_REQUEST);
|
|
|
|
// 4. Verify error message contains information about the version not being found
|
|
let error_body: serde_json::Value = restore_response.json().await?;
|
|
let error_message = error_body["error"].as_str().unwrap_or("");
|
|
assert!(error_message.contains("Version") && error_message.contains("not found"),
|
|
"Error message does not indicate version not found issue: {}", error_message);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_permission_checks_for_restoration() -> Result<()> {
|
|
// Setup test app
|
|
let app = TestApp::new().await?;
|
|
|
|
// 1. Create a dashboard as first user
|
|
let create_response = app
|
|
.client
|
|
.post("/api/v1/dashboards")
|
|
.bearer_auth(&app.test_user.token)
|
|
.json(&json!({
|
|
"name": "Test Dashboard",
|
|
"description": "Test Description",
|
|
"file": "name: Test Dashboard\ndescription: Test Description\nrows: []"
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
let create_body: serde_json::Value = create_response.json().await?;
|
|
let dashboard_id = create_body["dashboard"]["id"].as_str().unwrap();
|
|
|
|
// 2. Create a second user with no access to the dashboard
|
|
// Note: In a real test, you would create a second user and ensure they don't have access
|
|
// We'll simulate an unauthorized access attempt directly
|
|
|
|
// 3. Attempt to restore as unauthorized user
|
|
let restore_response = app
|
|
.client
|
|
.put(&format!("/api/v1/dashboards/{}", dashboard_id))
|
|
.bearer_auth("invalid-token") // Using invalid token to simulate unauthorized access
|
|
.json(&json!({
|
|
"restore_to_version": 1
|
|
}))
|
|
.send()
|
|
.await?;
|
|
|
|
// 4. Verify the request fails with a 401 Unauthorized or 403 Forbidden
|
|
assert!(restore_response.status() == StatusCode::UNAUTHORIZED ||
|
|
restore_response.status() == StatusCode::FORBIDDEN);
|
|
|
|
Ok(())
|
|
} |