re-uploading work

This commit is contained in:
2026-02-04 17:46:30 -06:00
commit 3b14c65998
1388 changed files with 381262 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
//! Integration tests for webhook functionality
use attune_common::models::trigger::Trigger;
use attune_common::repositories::trigger::{CreateTriggerInput, TriggerRepository};
use attune_common::repositories::{Create, FindById};
use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;
async fn setup_test_db() -> PgPool {
let database_url = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgresql://postgres:postgres@localhost:5432/attune".to_string());
PgPoolOptions::new()
.max_connections(5)
.connect(&database_url)
.await
.expect("Failed to create database pool")
}
async fn create_test_trigger(pool: &PgPool) -> Trigger {
let input = CreateTriggerInput {
r#ref: format!("test.webhook_trigger_{}", uuid::Uuid::new_v4()),
pack: None,
pack_ref: Some("test".to_string()),
label: "Test Webhook Trigger".to_string(),
description: Some("A test trigger for webhook functionality".to_string()),
enabled: true,
param_schema: None,
out_schema: None,
is_adhoc: false,
};
TriggerRepository::create(pool, input)
.await
.expect("Failed to create test trigger")
}
#[tokio::test]
async fn test_webhook_enable() {
let pool = setup_test_db().await;
let trigger = create_test_trigger(&pool).await;
// Initially, webhook should be disabled
assert!(!trigger.webhook_enabled);
assert!(trigger.webhook_key.is_none());
// Enable webhooks
let webhook_info = TriggerRepository::enable_webhook(&pool, trigger.id)
.await
.expect("Failed to enable webhook");
// Verify webhook info
assert!(webhook_info.enabled);
assert!(webhook_info.webhook_key.starts_with("wh_"));
assert_eq!(webhook_info.webhook_key.len(), 35); // "wh_" + 32 chars
assert!(webhook_info.webhook_url.contains(&webhook_info.webhook_key));
// Fetch trigger again to verify database state
let updated_trigger = TriggerRepository::find_by_id(&pool, trigger.id)
.await
.expect("Failed to fetch trigger")
.expect("Trigger not found");
assert!(updated_trigger.webhook_enabled);
assert_eq!(
updated_trigger.webhook_key.as_ref().unwrap(),
&webhook_info.webhook_key
);
// Cleanup
sqlx::query("DELETE FROM attune.trigger WHERE id = $1")
.bind(trigger.id)
.execute(&pool)
.await
.expect("Failed to cleanup");
}
#[tokio::test]
async fn test_webhook_disable() {
let pool = setup_test_db().await;
let trigger = create_test_trigger(&pool).await;
// Enable webhooks first
let webhook_info = TriggerRepository::enable_webhook(&pool, trigger.id)
.await
.expect("Failed to enable webhook");
let webhook_key = webhook_info.webhook_key.clone();
// Disable webhooks
let result = TriggerRepository::disable_webhook(&pool, trigger.id)
.await
.expect("Failed to disable webhook");
assert!(result);
// Fetch trigger to verify
let updated_trigger = TriggerRepository::find_by_id(&pool, trigger.id)
.await
.expect("Failed to fetch trigger")
.expect("Trigger not found");
assert!(!updated_trigger.webhook_enabled);
// Key should still be present (for audit purposes)
assert_eq!(updated_trigger.webhook_key.as_ref().unwrap(), &webhook_key);
// Cleanup
sqlx::query("DELETE FROM attune.trigger WHERE id = $1")
.bind(trigger.id)
.execute(&pool)
.await
.expect("Failed to cleanup");
}
#[tokio::test]
async fn test_webhook_key_regeneration() {
let pool = setup_test_db().await;
let trigger = create_test_trigger(&pool).await;
// Enable webhooks
let initial_info = TriggerRepository::enable_webhook(&pool, trigger.id)
.await
.expect("Failed to enable webhook");
let old_key = initial_info.webhook_key.clone();
// Regenerate key
let regenerate_result = TriggerRepository::regenerate_webhook_key(&pool, trigger.id)
.await
.expect("Failed to regenerate webhook key");
assert!(regenerate_result.previous_key_revoked);
assert_ne!(regenerate_result.webhook_key, old_key);
assert!(regenerate_result.webhook_key.starts_with("wh_"));
// Fetch trigger to verify new key
let updated_trigger = TriggerRepository::find_by_id(&pool, trigger.id)
.await
.expect("Failed to fetch trigger")
.expect("Trigger not found");
assert_eq!(
updated_trigger.webhook_key.as_ref().unwrap(),
&regenerate_result.webhook_key
);
// Cleanup
sqlx::query("DELETE FROM attune.trigger WHERE id = $1")
.bind(trigger.id)
.execute(&pool)
.await
.expect("Failed to cleanup");
}
#[tokio::test]
async fn test_find_by_webhook_key() {
let pool = setup_test_db().await;
let trigger = create_test_trigger(&pool).await;
// Enable webhooks
let webhook_info = TriggerRepository::enable_webhook(&pool, trigger.id)
.await
.expect("Failed to enable webhook");
// Find by webhook key
let found_trigger = TriggerRepository::find_by_webhook_key(&pool, &webhook_info.webhook_key)
.await
.expect("Failed to find trigger by webhook key")
.expect("Trigger not found");
assert_eq!(found_trigger.id, trigger.id);
assert_eq!(found_trigger.r#ref, trigger.r#ref);
assert!(found_trigger.webhook_enabled);
// Test with invalid key
let not_found =
TriggerRepository::find_by_webhook_key(&pool, "wh_invalid_key_12345678901234567890")
.await
.expect("Query failed");
assert!(not_found.is_none());
// Cleanup
sqlx::query("DELETE FROM attune.trigger WHERE id = $1")
.bind(trigger.id)
.execute(&pool)
.await
.expect("Failed to cleanup");
}
#[tokio::test]
async fn test_webhook_key_uniqueness() {
let pool = setup_test_db().await;
let trigger1 = create_test_trigger(&pool).await;
let trigger2 = create_test_trigger(&pool).await;
// Enable webhooks for both triggers
let info1 = TriggerRepository::enable_webhook(&pool, trigger1.id)
.await
.expect("Failed to enable webhook for trigger 1");
let info2 = TriggerRepository::enable_webhook(&pool, trigger2.id)
.await
.expect("Failed to enable webhook for trigger 2");
// Keys should be different
assert_ne!(info1.webhook_key, info2.webhook_key);
// Both should be valid format
assert!(info1.webhook_key.starts_with("wh_"));
assert!(info2.webhook_key.starts_with("wh_"));
// Cleanup
sqlx::query("DELETE FROM attune.trigger WHERE id IN ($1, $2)")
.bind(trigger1.id)
.bind(trigger2.id)
.execute(&pool)
.await
.expect("Failed to cleanup");
}
#[tokio::test]
async fn test_enable_webhook_idempotent() {
let pool = setup_test_db().await;
let trigger = create_test_trigger(&pool).await;
// Enable webhooks first time
let info1 = TriggerRepository::enable_webhook(&pool, trigger.id)
.await
.expect("Failed to enable webhook");
// Enable webhooks second time (should return same key)
let info2 = TriggerRepository::enable_webhook(&pool, trigger.id)
.await
.expect("Failed to enable webhook again");
// Should return the same key
assert_eq!(info1.webhook_key, info2.webhook_key);
assert!(info2.enabled);
// Cleanup
sqlx::query("DELETE FROM attune.trigger WHERE id = $1")
.bind(trigger.id)
.execute(&pool)
.await
.expect("Failed to cleanup");
}