//go:build aws package main import ( "fmt" "os" "strings" "testing" "time" ) // Test data for disable/enable operations var disableTestUsers = []map[string]string{ { "email": "disable-test1@gmail.com", "first_name": "DisableTest", "last_name": "User1", "roles": "editor", }, { "email": "disable-test2@gmail.com", "first_name": "DisableTest", "last_name": "User2", "roles": "viewer", }, } const disableTestCSVPath = "./temp-disable-users.csv" func TestDisableEnableUserLifecycle(t *testing.T) { // Skip test if required environment variables are not set if !checkRequiredEnvVars(t) { return } // Create test CSV file for disable/enable tests if err := createDisableTestCSV(); err != nil { t.Fatalf("Failed to create test CSV: %v", err) } // Cleanup test CSV file after test defer func() { if err := os.Remove(disableTestCSVPath); err != nil && !os.IsNotExist(err) { t.Logf("Warning: failed to cleanup test CSV file: %v", err) } }() // Test the complete lifecycle: create -> disable -> enable -> delete t.Run("CreateTestUsers", func(t *testing.T) { testCreateDisableTestUsers(t) }) t.Run("VerifyUsersCreated", func(t *testing.T) { testVerifyDisableTestUsersExist(t) }) t.Run("DisableUsers", func(t *testing.T) { testDisableUsers(t) }) t.Run("VerifyUsersDisabled", func(t *testing.T) { testVerifyUsersDisabled(t) }) t.Run("EnableUsers", func(t *testing.T) { testEnableUsers(t) }) t.Run("VerifyUsersEnabled", func(t *testing.T) { testVerifyUsersEnabled(t) }) t.Run("CleanupTestUsers", func(t *testing.T) { testDeleteDisableTestUsers(t) }) } func createDisableTestCSV() error { csvContent := "email,first_name,last_name,role1\n" csvContent += "disable-test1@gmail.com,DisableTest,User1,editor\n" csvContent += "disable-test2@gmail.com,DisableTest,User2,viewer\n" return os.WriteFile(disableTestCSVPath, []byte(csvContent), 0600) } func testCreateDisableTestUsers(t *testing.T) { // Save original os.Args originalArgs := os.Args // Set up args for user creation os.Args = []string{ "cognito-permit-sync", "-project", testProjectID, "-env", testEnvID, "-csv", disableTestCSVPath, } // Restore os.Args after test defer func() { os.Args = originalArgs }() // Reset flags for testing resetFlags() // Run the application err := run() if err != nil { t.Fatalf("Failed to create disable test users: %v", err) } t.Logf("Successfully created disable test users") } func testVerifyDisableTestUsersExist(t *testing.T) { ctx := t.Context() // Initialize clients cognitoClient, err := initializeCognitoClient() if err != nil { t.Fatalf("Failed to initialize Cognito client: %v", err) } config := AppConfig{ CognitoUserPoolID: os.Getenv("COGNITO_USER_POOL_ID"), CognitoRegion: os.Getenv("AWS_REGION"), } for _, user := range disableTestUsers { t.Run(fmt.Sprintf("VerifyUser_%s", user["email"]), func(t *testing.T) { // Verify user exists in Cognito and is enabled cognitoUser, err := getCognitoUser(ctx, cognitoClient, config.CognitoUserPoolID, user["email"]) if err != nil { t.Fatalf("Failed to find user %s in Cognito: %v", user["email"], err) } if cognitoUser.Status != "CONFIRMED" && cognitoUser.Status != "FORCE_CHANGE_PASSWORD" { t.Fatalf("User %s is not in expected enabled state. Status: %s", user["email"], cognitoUser.Status) } t.Logf("User %s found in Cognito with enabled status: %s", user["email"], cognitoUser.Status) }) } } func testDisableUsers(t *testing.T) { // Save original os.Args originalArgs := os.Args // Set up args for user disabling os.Args = []string{ "cognito-permit-sync", "-project", testProjectID, "-env", testEnvID, "-csv", disableTestCSVPath, "--disable-users", } // Restore os.Args after test defer func() { os.Args = originalArgs }() // Reset flags for testing resetFlags() // Run the application in disable mode err := run() if err != nil { t.Fatalf("Failed to disable users: %v", err) } t.Logf("Successfully disabled users") } func testVerifyUsersDisabled(t *testing.T) { ctx := t.Context() // Initialize clients cognitoClient, err := initializeCognitoClient() if err != nil { t.Fatalf("Failed to initialize Cognito client: %v", err) } config := AppConfig{ CognitoUserPoolID: os.Getenv("COGNITO_USER_POOL_ID"), CognitoRegion: os.Getenv("AWS_REGION"), } for _, user := range disableTestUsers { t.Run(fmt.Sprintf("VerifyUserDisabled_%s", user["email"]), func(t *testing.T) { // Give Cognito a moment to process the disable request time.Sleep(2 * time.Second) // Check if the user is disabled using the Enabled field isEnabled, err := isCognitoUserEnabled(ctx, cognitoClient, config.CognitoUserPoolID, user["email"]) if err != nil { t.Fatalf("Failed to check enabled state for %s: %v", user["email"], err) } if isEnabled { t.Fatalf("User %s is still enabled. Expected disabled state", user["email"]) } t.Logf("User %s successfully verified as disabled (enabled=%v)", user["email"], isEnabled) }) } } func testEnableUsers(t *testing.T) { // Save original os.Args originalArgs := os.Args // Set up args for user enabling os.Args = []string{ "cognito-permit-sync", "-project", testProjectID, "-env", testEnvID, "-csv", disableTestCSVPath, "--enable-users", } // Restore os.Args after test defer func() { os.Args = originalArgs }() // Reset flags for testing resetFlags() // Run the application in enable mode err := run() if err != nil { t.Fatalf("Failed to enable users: %v", err) } t.Logf("Successfully enabled users") } func testVerifyUsersEnabled(t *testing.T) { ctx := t.Context() // Initialize clients cognitoClient, err := initializeCognitoClient() if err != nil { t.Fatalf("Failed to initialize Cognito client: %v", err) } config := AppConfig{ CognitoUserPoolID: os.Getenv("COGNITO_USER_POOL_ID"), CognitoRegion: os.Getenv("AWS_REGION"), } for _, user := range disableTestUsers { t.Run(fmt.Sprintf("VerifyUserEnabled_%s", user["email"]), func(t *testing.T) { // Give Cognito a moment to process the enable request time.Sleep(2 * time.Second) // Check if the user is enabled using the Enabled field isEnabled, err := isCognitoUserEnabled(ctx, cognitoClient, config.CognitoUserPoolID, user["email"]) if err != nil { t.Fatalf("Failed to check enabled state for %s: %v", user["email"], err) } if !isEnabled { t.Fatalf("User %s is not enabled. Expected enabled state", user["email"]) } t.Logf("User %s successfully verified as enabled (enabled=%v)", user["email"], isEnabled) }) } } func testDeleteDisableTestUsers(t *testing.T) { // Save original os.Args originalArgs := os.Args // Set up args for user deletion os.Args = []string{ "cognito-permit-sync", "-project", testProjectID, "-env", testEnvID, "-csv", disableTestCSVPath, "--delete-users", } // Restore os.Args after test defer func() { os.Args = originalArgs }() // Reset flags for testing resetFlags() // Run the application in delete mode err := run() if err != nil { t.Fatalf("Failed to delete disable test users: %v", err) } t.Logf("Successfully deleted disable test users") } // Test individual disable/enable functions func TestDisableEnableOperations(t *testing.T) { if !checkRequiredEnvVars(t) { return } ctx := t.Context() cognitoClient, err := initializeCognitoClient() if err != nil { t.Fatalf("Failed to initialize Cognito client: %v", err) } userPoolID := os.Getenv("COGNITO_USER_POOL_ID") testEmail := "individual-test@example.com" // Create a test user first testUser := map[string]string{ "email": testEmail, "first_name": "Individual", "last_name": "Test", } cognitoConfig := &CognitoConfig{ UserPoolID: userPoolID, Region: os.Getenv("AWS_REGION"), } // Create user _, err = createCognitoUser(ctx, cognitoClient, cognitoConfig, testUser) if err != nil { // If user already exists, that's fine if !strings.Contains(err.Error(), "already exists") && !strings.Contains(err.Error(), "UsernameExistsException") { t.Fatalf("Failed to create test user: %v", err) } } defer func() { // Cleanup: delete the test user _ = deleteCognitoUser(ctx, cognitoClient, userPoolID, testEmail) }() t.Run("TestDisableFunction", func(t *testing.T) { // Test disable function err := disableCognitoUser(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("Failed to disable user: %v", err) } // Verify user is disabled using the Enabled field isEnabled, err := isCognitoUserEnabled(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("Failed to check enabled state: %v", err) } if isEnabled { t.Fatalf("User should be disabled but is still enabled") } t.Logf("User successfully disabled (enabled=%v)", isEnabled) }) t.Run("TestEnableFunction", func(t *testing.T) { // Test enable function err := enableCognitoUser(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("Failed to enable user: %v", err) } // Verify user is enabled using the Enabled field isEnabled, err := isCognitoUserEnabled(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("Failed to check enabled state: %v", err) } if !isEnabled { t.Fatalf("User should be enabled but is still disabled") } t.Logf("User successfully enabled (enabled=%v)", isEnabled) }) } // Test idempotent behavior func TestIdempotentDisableEnable(t *testing.T) { if !checkRequiredEnvVars(t) { return } ctx := t.Context() cognitoClient, err := initializeCognitoClient() if err != nil { t.Fatalf("Failed to initialize Cognito client: %v", err) } userPoolID := os.Getenv("COGNITO_USER_POOL_ID") testEmail := "idempotent-test@example.com" // Create a test user testUser := map[string]string{ "email": testEmail, "first_name": "Idempotent", "last_name": "Test", } cognitoConfig := &CognitoConfig{ UserPoolID: userPoolID, Region: os.Getenv("AWS_REGION"), } _, err = createCognitoUser(ctx, cognitoClient, cognitoConfig, testUser) if err != nil && !strings.Contains(err.Error(), "already exists") && !strings.Contains(err.Error(), "UsernameExistsException") { t.Fatalf("Failed to create test user: %v", err) } defer func() { // Cleanup: delete the test user _ = deleteCognitoUser(ctx, cognitoClient, userPoolID, testEmail) }() t.Run("TestDisableIdempotent", func(t *testing.T) { // Disable user twice - second should be idempotent err := disableCognitoUser(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("First disable failed: %v", err) } err = disableCognitoUser(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("Second disable (idempotent) failed: %v", err) } t.Logf("Disable operation is idempotent") }) t.Run("TestEnableIdempotent", func(t *testing.T) { // Enable user twice - second should be idempotent err := enableCognitoUser(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("First enable failed: %v", err) } err = enableCognitoUser(ctx, cognitoClient, userPoolID, testEmail) if err != nil { t.Fatalf("Second enable (idempotent) failed: %v", err) } t.Logf("Enable operation is idempotent") }) }