#[path = "testutils/mod.rs"]
mod testutils;
use graphlite::Value;
use testutils::test_fixture::TestFixture;
#[test]
fn test_role_management_comprehensive() {
let fixture = TestFixture::empty().expect("Failed to create test fixture");
log::debug!("=== Testing Comprehensive Role Management ===");
log::debug!("\n1. Testing role creation and basic functionality...");
fixture.assert_query_succeeds("CREATE ROLE 'test_role_1'");
fixture.assert_query_succeeds("CREATE ROLE 'test_role_2'");
log::debug!("✓ Test roles created successfully");
let roles_query_result = fixture.query("CALL gql.list_roles()");
match roles_query_result {
Ok(roles_result) => {
log::debug!(
"✓ Role listing works, found {} roles",
roles_result.rows.len()
);
}
Err(e) => {
log::debug!("⚠ Role listing not available in test environment: {}", e);
log::debug!("✓ Continuing with direct role operations testing");
}
}
log::debug!("\n2. Testing user creation...");
fixture.assert_query_succeeds("CREATE USER 'alice' PASSWORD 'password123'");
fixture.assert_query_succeeds("CREATE USER 'bob' PASSWORD 'password456'");
fixture.assert_query_succeeds("CREATE USER 'charlie' PASSWORD 'password789'");
log::debug!("✓ Created test users: alice, bob, charlie");
log::debug!("\n3. Testing GRANT ROLE positive scenarios...");
fixture.assert_query_succeeds("GRANT ROLE 'test_role_1' TO 'alice'");
log::debug!("✓ Granted 'test_role_1' role to alice");
fixture.assert_query_succeeds("GRANT ROLE 'test_role_2' TO 'bob'");
log::debug!("✓ Granted 'test_role_2' role to bob");
fixture.assert_query_succeeds("GRANT ROLE 'test_role_1' TO 'charlie'");
fixture.assert_query_succeeds("GRANT ROLE 'test_role_2' TO 'charlie'");
log::debug!("✓ Granted multiple roles to charlie");
log::debug!("\n4. Testing duplicate GRANT ROLE...");
let duplicate_result = fixture.assert_query_succeeds("GRANT ROLE 'test_role_1' TO 'alice'");
if let Some(row) = duplicate_result.rows.first() {
if let Some(Value::String(message)) = row.values.get("status") {
assert!(
message.contains("already has"),
"Should indicate user already has role: {}",
message
);
log::debug!("✓ Correctly handled duplicate role grant: {}", message);
}
}
log::debug!("\n5. Testing REVOKE ROLE positive scenarios...");
fixture.assert_query_succeeds("REVOKE ROLE 'test_role_1' FROM 'alice'");
log::debug!("✓ Revoked 'test_role_1' role from alice");
fixture.assert_query_succeeds("REVOKE ROLE 'test_role_2' FROM 'charlie'");
log::debug!("✓ Revoked 'test_role_2' role from charlie");
log::debug!("✅ ALL POSITIVE SCENARIOS PASSED!");
}
#[test]
fn test_role_management_negative_scenarios() {
let fixture = TestFixture::empty().expect("Failed to create test fixture");
log::debug!("=== Testing Role Management Negative Scenarios ===");
fixture.assert_query_succeeds("CREATE USER 'test_user' PASSWORD 'password'");
log::debug!("\n1. Testing system role protection - 'user' role...");
fixture.assert_query_fails(
"REVOKE ROLE 'user' FROM 'test_user'",
"Cannot revoke system role 'user'",
);
log::debug!("✓ Correctly prevented removal of 'user' role");
log::debug!("\n2. Testing system role protection - 'admin' role from 'admin' user...");
fixture.assert_query_fails(
"REVOKE ROLE 'admin' FROM 'admin'",
"Cannot revoke 'admin' role from 'admin' user",
);
log::debug!("✓ Correctly prevented removal of 'admin' role from 'admin' user");
log::debug!("\n3. Testing grant of non-existent role...");
fixture.assert_query_fails(
"GRANT ROLE 'nonexistent_role' TO 'test_user'",
"Role 'nonexistent_role' does not exist",
);
log::debug!("✓ Correctly failed to grant non-existent role");
log::debug!("\n4. Testing grant to non-existent user...");
fixture.assert_query_fails(
"GRANT ROLE 'user' TO 'nonexistent_user'",
"User 'nonexistent_user' does not exist",
);
log::debug!("✓ Correctly failed to grant role to non-existent user");
log::debug!("\n5. Testing revoke of non-existent role...");
fixture.assert_query_fails(
"REVOKE ROLE 'nonexistent_role' FROM 'test_user'",
"Role 'nonexistent_role' does not exist",
);
log::debug!("✓ Correctly failed to revoke non-existent role");
log::debug!("\n6. Testing revoke from non-existent user...");
fixture.assert_query_succeeds("CREATE ROLE 'test_revoke_role'");
fixture.assert_query_fails(
"REVOKE ROLE 'test_revoke_role' FROM 'nonexistent_user'",
"User 'nonexistent_user' does not exist",
);
log::debug!("✓ Correctly failed to revoke role from non-existent user");
log::debug!("\n7. Testing revoke of role user doesn't have...");
let revoke_missing = fixture.assert_query_succeeds("REVOKE ROLE 'admin' FROM 'test_user'");
if let Some(row) = revoke_missing.rows.first() {
if let Some(Value::String(message)) = row.values.get("status") {
assert!(
message.contains("does not have"),
"Should indicate user doesn't have role: {}",
message
);
log::debug!("✓ Correctly handled missing role revocation: {}", message);
}
}
log::debug!("✅ ALL NEGATIVE SCENARIOS PASSED!");
}
#[test]
fn test_role_assignment_integrity() {
let fixture = TestFixture::empty().expect("Failed to create test fixture");
log::debug!("=== Testing Role Assignment Integrity ===");
fixture.assert_query_succeeds("CREATE ROLE 'test_role'");
fixture.assert_query_succeeds("CREATE USER 'user1' PASSWORD 'pass1'");
fixture.assert_query_succeeds("CREATE USER 'user2' PASSWORD 'pass2'");
fixture.assert_query_succeeds("GRANT ROLE 'test_role' TO 'user1'");
fixture.assert_query_succeeds("GRANT ROLE 'test_role' TO 'user2'");
let users_result = fixture.assert_query_succeeds("CALL gql.list_users()");
let mut users_with_test_role = 0;
for row in &users_result.rows {
if let Some(Value::String(username)) = row.values.get("username") {
if username == "user1" || username == "user2" {
if let Some(Value::String(roles_str)) = row.values.get("roles") {
if roles_str.contains("test_role") {
users_with_test_role += 1;
}
}
}
}
}
assert_eq!(users_with_test_role, 2, "Both users should have test_role");
log::debug!("✓ Multiple users can have the same role");
fixture.assert_query_succeeds("REVOKE ROLE 'test_role' FROM 'user1'");
let users_after_revoke = fixture.assert_query_succeeds("CALL gql.list_users()");
let mut user1_has_role = false;
let mut user2_has_role = false;
for row in &users_after_revoke.rows {
if let Some(Value::String(username)) = row.values.get("username") {
if let Some(Value::String(roles_str)) = row.values.get("roles") {
if username == "user1" && roles_str.contains("test_role") {
user1_has_role = true;
}
if username == "user2" && roles_str.contains("test_role") {
user2_has_role = true;
}
}
}
}
assert!(!user1_has_role, "user1 should no longer have test_role");
assert!(user2_has_role, "user2 should still have test_role");
log::debug!("✓ Role revocation is user-specific");
let mut all_users_have_user_role = true;
for row in &users_after_revoke.rows {
if let Some(Value::String(username)) = row.values.get("username") {
if username == "user1" || username == "user2" {
if let Some(Value::String(roles_str)) = row.values.get("roles") {
if !roles_str.contains("user") {
all_users_have_user_role = false;
break;
}
}
}
}
}
assert!(
all_users_have_user_role,
"All users should retain default 'user' role"
);
log::debug!("✓ Default 'user' role is preserved through role operations");
log::debug!("✅ ALL INTEGRITY TESTS PASSED!");
}
#[test]
fn test_role_management_syntax_validation() {
let fixture = TestFixture::empty().expect("Failed to create test fixture");
log::debug!("=== Testing Role Management Syntax Validation ===");
fixture.assert_query_succeeds("CREATE ROLE 'valid_role'");
fixture.assert_query_succeeds("CREATE USER 'valid_user' PASSWORD 'password'");
log::debug!("\n1. Testing valid syntax variations...");
fixture.assert_query_succeeds("GRANT ROLE 'valid_role' TO 'valid_user'");
log::debug!("✓ Basic GRANT ROLE syntax works");
fixture.assert_query_succeeds("REVOKE ROLE 'valid_role' FROM 'valid_user'");
log::debug!("✓ Basic REVOKE ROLE syntax works");
fixture.assert_query_succeeds("CREATE ROLE 'role_with_underscores'");
fixture.assert_query_succeeds("CREATE USER 'user_with_underscores' PASSWORD 'password'");
fixture.assert_query_succeeds("GRANT ROLE 'role_with_underscores' TO 'user_with_underscores'");
log::debug!("✓ Names with underscores work");
fixture.assert_query_succeeds("CREATE ROLE 'RoleWithMixedCase'");
fixture.assert_query_succeeds("GRANT ROLE 'RoleWithMixedCase' TO 'valid_user'");
log::debug!("✓ Mixed case names work");
log::debug!("✅ ALL SYNTAX VALIDATION TESTS PASSED!");
}
#[test]
fn test_role_management_edge_cases() {
let fixture = TestFixture::empty().expect("Failed to create test fixture");
log::debug!("=== Testing Role Management Edge Cases ===");
log::debug!("\n1. Testing operations with admin user...");
fixture.assert_query_succeeds("CREATE ROLE 'admin_test_role'");
fixture.assert_query_succeeds("GRANT ROLE 'admin_test_role' TO 'admin'");
log::debug!("✓ Can grant additional roles to admin user");
fixture.assert_query_succeeds("REVOKE ROLE 'admin_test_role' FROM 'admin'");
log::debug!("✓ Can revoke non-admin roles from admin user");
fixture.assert_query_fails(
"REVOKE ROLE 'admin' FROM 'admin'",
"Cannot revoke 'admin' role from 'admin' user",
);
log::debug!("✓ Cannot revoke admin role from admin user");
log::debug!("\n2. Testing cross-user role operations...");
fixture.assert_query_succeeds("CREATE ROLE 'shared_role'");
fixture.assert_query_succeeds("CREATE USER 'user_a' PASSWORD 'password'");
fixture.assert_query_succeeds("CREATE USER 'user_b' PASSWORD 'password'");
fixture.assert_query_succeeds("GRANT ROLE 'shared_role' TO 'user_a'");
fixture.assert_query_succeeds("GRANT ROLE 'shared_role' TO 'user_b'");
let users_result = fixture.assert_query_succeeds("CALL gql.list_users()");
let mut users_with_shared_role = 0;
for row in &users_result.rows {
if let Some(Value::String(username)) = row.values.get("username") {
if username == "user_a" || username == "user_b" {
if let Some(Value::String(roles_str)) = row.values.get("roles") {
if roles_str.contains("shared_role") {
users_with_shared_role += 1;
}
}
}
}
}
assert_eq!(
users_with_shared_role, 2,
"Both users should have shared_role"
);
log::debug!("✓ Multiple users can share the same role");
log::debug!("\n3. Testing final system state...");
let final_users = fixture.assert_query_succeeds("CALL gql.list_users()");
let final_roles = fixture.assert_query_succeeds("CALL gql.list_roles()");
log::debug!("Final system state:");
log::debug!(" - Users: {}", final_users.rows.len());
log::debug!(" - Roles: {}", final_roles.rows.len());
for row in &final_users.rows {
if let Some(Value::String(username)) = row.values.get("username") {
if let Some(Value::String(roles_str)) = row.values.get("roles") {
assert!(
roles_str.contains("user"),
"User '{}' should have 'user' role: {}",
username,
roles_str
);
}
}
}
log::debug!("✓ All users maintain required 'user' role");
log::debug!("✅ ALL EDGE CASE TESTS PASSED!");
}