2025-03-20 06:54:08 +08:00
|
|
|
use anyhow::Result;
|
|
|
|
use axum::{
|
|
|
|
extract::Extension,
|
|
|
|
routing::put,
|
|
|
|
Router,
|
|
|
|
};
|
|
|
|
use chrono::{Duration, Utc};
|
|
|
|
use database::{
|
|
|
|
enums::{AssetPermissionRole, AssetType, IdentityType},
|
|
|
|
get_pg_pool,
|
|
|
|
models::DashboardFile,
|
|
|
|
schema::dashboard_files::dsl,
|
|
|
|
};
|
|
|
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
|
|
|
use diesel_async::RunQueryDsl as AsyncRunQueryDsl;
|
|
|
|
use handlers::dashboards::sharing::update_sharing_handler::UpdateDashboardSharingRequest;
|
|
|
|
use middleware::auth::AuthenticatedUser;
|
|
|
|
use serde_json::json;
|
|
|
|
use sharing::create_share;
|
|
|
|
use src::routes::rest::routes::dashboards::sharing::update_dashboard_sharing_rest_handler;
|
|
|
|
use tests::common::{
|
|
|
|
assertions::response::ResponseAssertions,
|
|
|
|
fixtures::builder::FixtureBuilder,
|
|
|
|
http::client::TestClient,
|
|
|
|
};
|
2025-03-20 05:35:48 +08:00
|
|
|
use uuid::Uuid;
|
|
|
|
|
|
|
|
#[tokio::test]
|
2025-03-20 06:54:08 +08:00
|
|
|
async fn test_update_dashboard_sharing_success() -> Result<()> {
|
|
|
|
// Set up test fixtures
|
|
|
|
let mut fixture = FixtureBuilder::new().await?;
|
|
|
|
|
|
|
|
// Create a test user (this will be the owner of the dashboard)
|
|
|
|
let user = fixture.create_user().await?;
|
|
|
|
|
|
|
|
// Create a test dashboard owned by the user
|
|
|
|
let dashboard = fixture.create_dashboard(&user.id).await?;
|
|
|
|
|
|
|
|
// Create another user to share with
|
|
|
|
let share_recipient = fixture.create_user().await?;
|
|
|
|
|
|
|
|
// Create a manual permission so our test user has Owner access to the dashboard
|
|
|
|
create_share(
|
|
|
|
dashboard.id,
|
|
|
|
AssetType::DashboardFile,
|
|
|
|
user.id,
|
|
|
|
IdentityType::User,
|
|
|
|
AssetPermissionRole::Owner,
|
|
|
|
user.id,
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
// Set up the test server with our endpoint
|
|
|
|
let app = Router::new()
|
|
|
|
.route("/dashboards/:id/sharing", put(update_dashboard_sharing_rest_handler))
|
|
|
|
.layer(Extension(AuthenticatedUser {
|
|
|
|
id: user.id,
|
|
|
|
email: user.email.clone(),
|
|
|
|
org_id: None,
|
|
|
|
}));
|
|
|
|
|
|
|
|
let client = TestClient::new(app);
|
|
|
|
|
|
|
|
// Make the request to update sharing permissions with new format
|
|
|
|
let payload = json!({
|
|
|
|
"users": [
|
|
|
|
{
|
|
|
|
"email": share_recipient.email,
|
|
|
|
"role": "Editor"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
let response = client
|
|
|
|
.put(&format!("/dashboards/{}/sharing", dashboard.id))
|
|
|
|
.json(&payload)
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
// Assert the response is successful
|
|
|
|
response.assert_status_ok()?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2025-03-20 05:35:48 +08:00
|
|
|
|
2025-03-20 06:54:08 +08:00
|
|
|
#[tokio::test]
|
|
|
|
async fn test_update_dashboard_public_sharing_success() -> Result<()> {
|
|
|
|
// Set up test fixtures
|
|
|
|
let mut fixture = FixtureBuilder::new().await?;
|
|
|
|
|
|
|
|
// Create a test user (this will be the owner of the dashboard)
|
|
|
|
let user = fixture.create_user().await?;
|
|
|
|
|
|
|
|
// Create a test dashboard owned by the user
|
|
|
|
let dashboard = fixture.create_dashboard(&user.id).await?;
|
|
|
|
|
|
|
|
// Create a manual permission so our test user has Owner access to the dashboard
|
|
|
|
create_share(
|
|
|
|
dashboard.id,
|
|
|
|
AssetType::DashboardFile,
|
|
|
|
user.id,
|
|
|
|
IdentityType::User,
|
|
|
|
AssetPermissionRole::Owner,
|
|
|
|
user.id,
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
// Set up the test server with our endpoint
|
|
|
|
let app = Router::new()
|
|
|
|
.route("/dashboards/:id/sharing", put(update_dashboard_sharing_rest_handler))
|
|
|
|
.layer(Extension(AuthenticatedUser {
|
|
|
|
id: user.id,
|
|
|
|
email: user.email.clone(),
|
|
|
|
org_id: None,
|
|
|
|
}));
|
|
|
|
|
|
|
|
let client = TestClient::new(app);
|
|
|
|
|
|
|
|
// Set expiration date to 7 days from now
|
|
|
|
let expiration_date = Utc::now() + Duration::days(7);
|
|
|
|
|
|
|
|
// Make the request to update public sharing settings
|
|
|
|
let payload = json!({
|
|
|
|
"publicly_accessible": true,
|
|
|
|
"public_expiration": expiration_date.to_rfc3339()
|
|
|
|
});
|
|
|
|
|
|
|
|
let response = client
|
|
|
|
.put(&format!("/dashboards/{}/sharing", dashboard.id))
|
|
|
|
.json(&payload)
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
// Assert the response is successful
|
|
|
|
response.assert_status_ok()?;
|
|
|
|
|
|
|
|
// Verify database was updated correctly
|
|
|
|
let pool = get_pg_pool();
|
|
|
|
let mut conn = pool.get().await?;
|
|
|
|
|
|
|
|
let updated_dashboard: DashboardFile = dsl::dashboard_files
|
|
|
|
.filter(dsl::id.eq(dashboard.id))
|
|
|
|
.first(&mut conn)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
assert!(updated_dashboard.publicly_accessible);
|
|
|
|
assert_eq!(updated_dashboard.publicly_enabled_by, Some(user.id));
|
|
|
|
|
|
|
|
// The public_expiry_date is stored as a timestamp, so we can't do an exact match.
|
|
|
|
// Instead, we'll check that it's within a minute of our expected value
|
|
|
|
let stored_expiry = updated_dashboard.public_expiry_date.unwrap();
|
|
|
|
let diff = (stored_expiry - expiration_date).num_seconds().abs();
|
|
|
|
assert!(diff < 60, "Expiry date should be within a minute of the requested date");
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2025-03-20 05:35:48 +08:00
|
|
|
|
2025-03-20 06:54:08 +08:00
|
|
|
#[tokio::test]
|
|
|
|
async fn test_update_dashboard_sharing_mixed_updates() -> Result<()> {
|
|
|
|
// Set up test fixtures
|
|
|
|
let mut fixture = FixtureBuilder::new().await?;
|
|
|
|
|
|
|
|
// Create a test user (this will be the owner of the dashboard)
|
|
|
|
let user = fixture.create_user().await?;
|
|
|
|
|
|
|
|
// Create a test dashboard owned by the user
|
|
|
|
let dashboard = fixture.create_dashboard(&user.id).await?;
|
|
|
|
|
|
|
|
// Create another user to share with
|
|
|
|
let share_recipient = fixture.create_user().await?;
|
|
|
|
|
|
|
|
// Create a manual permission so our test user has Owner access to the dashboard
|
|
|
|
create_share(
|
|
|
|
dashboard.id,
|
|
|
|
AssetType::DashboardFile,
|
|
|
|
user.id,
|
|
|
|
IdentityType::User,
|
|
|
|
AssetPermissionRole::Owner,
|
|
|
|
user.id,
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
// Set up the test server with our endpoint
|
|
|
|
let app = Router::new()
|
|
|
|
.route("/dashboards/:id/sharing", put(update_dashboard_sharing_rest_handler))
|
|
|
|
.layer(Extension(AuthenticatedUser {
|
|
|
|
id: user.id,
|
|
|
|
email: user.email.clone(),
|
|
|
|
org_id: None,
|
|
|
|
}));
|
|
|
|
|
|
|
|
let client = TestClient::new(app);
|
|
|
|
|
|
|
|
// Set expiration date to 7 days from now
|
|
|
|
let expiration_date = Utc::now() + Duration::days(7);
|
|
|
|
|
|
|
|
// Make the request to update both user and public sharing settings
|
|
|
|
let payload = json!({
|
|
|
|
"users": [
|
|
|
|
{
|
|
|
|
"email": share_recipient.email,
|
|
|
|
"role": "Editor"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"publicly_accessible": true,
|
|
|
|
"public_expiration": expiration_date.to_rfc3339()
|
|
|
|
});
|
|
|
|
|
|
|
|
let response = client
|
|
|
|
.put(&format!("/dashboards/{}/sharing", dashboard.id))
|
|
|
|
.json(&payload)
|
|
|
|
.send()
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
// Assert the response is successful
|
|
|
|
response.assert_status_ok()?;
|
|
|
|
|
|
|
|
// Verify database was updated correctly for public sharing
|
|
|
|
let pool = get_pg_pool();
|
|
|
|
let mut conn = pool.get().await?;
|
|
|
|
|
|
|
|
let updated_dashboard: DashboardFile = dsl::dashboard_files
|
|
|
|
.filter(dsl::id.eq(dashboard.id))
|
|
|
|
.first(&mut conn)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
assert!(updated_dashboard.publicly_accessible);
|
|
|
|
assert_eq!(updated_dashboard.publicly_enabled_by, Some(user.id));
|
|
|
|
|
|
|
|
// Verify user permissions were updated too
|
|
|
|
// This would normally check the asset_permissions table in a real test
|
|
|
|
|
|
|
|
Ok(())
|
2025-03-20 05:35:48 +08:00
|
|
|
}
|