Files
query-orchestration/cmd/auth_related/user.creation.tool/validate_roles_test.go
T
Jay Brown 6dccf494f8 Merged in feature/permit-policy-cleanup (pull request #210)
cleanup permit policies and correct documentation

* docs

* policy cleanup

* refactor

* Merge remote-tracking branch 'origin/feature/permit-policy-cleanup' into feature/permit-policy-cleanup

* docs and edits
2026-02-19 20:22:59 +00:00

403 lines
10 KiB
Go

//go:build aws
package main
import (
"net/http"
"os"
"strings"
"testing"
"time"
"github.com/joho/godotenv"
)
// Test configuration constants
const (
testProjectIDForRoles = "ebde1e1e9623491cab6f8112e67bd61c"
testEnvIDForRoles = "9d6801123cfd4a0ea2ef1df2f430e9d3"
)
// Replace the existing TestValidateCSVRoles function with these separate functions:
// setupTestConfig creates a test configuration for role validation tests
func setupTestConfig(t *testing.T) (AppConfig, *http.Client, bool) {
// Load environment variables
if err := godotenv.Overload(); err != nil {
t.Logf("Warning: problem loading .env file - ignoring: %v", err)
}
// Skip test if required environment variables are not set
if !checkRequiredEnvVarsForRoles(t) {
return AppConfig{}, nil, false
}
// Setup real HTTP client and configuration
httpClient := &http.Client{Timeout: 30 * time.Second}
config := AppConfig{
PermitAPIKey: os.Getenv("PERMIT_KEY"),
PermitProjectID: testProjectIDForRoles,
PermitEnvID: testEnvIDForRoles,
PermitBaseURL: "https://api.permit.io",
}
return config, httpClient, true
}
func TestValidateCSVRoles_MissingRoles(t *testing.T) {
config, httpClient, ok := setupTestConfig(t)
if !ok {
return
}
// Test CSV data with existing roles (admin, viewer, editor) and one non-existent role 'foo'
csvUsers := []map[string]string{
{
"email": "user1@example.com",
"first_name": "John",
"last_name": "Doe",
"roles": "admin,viewer",
},
{
"email": "user2@example.com",
"first_name": "Jane",
"last_name": "Smith",
"roles": "editor,foo", // 'foo' doesn't exist in real Permit.io
},
{
"email": "user3@example.com",
"first_name": "Bob",
"last_name": "Wilson",
"roles": "viewer",
},
}
// Call the function under test with real API
result, err := ValidateCSVRoles(httpClient, config, csvUsers)
// Verify that an error was returned for missing role 'foo'
if err == nil {
t.Fatalf("Expected error for missing role 'foo', but got nil. Returned roles: %v", result)
}
// Verify the error message mentions the missing role
if !strings.Contains(err.Error(), "foo") {
t.Errorf("Error message should mention missing role 'foo', got: %s", err.Error())
}
// Verify that 'foo' is in the list of missing roles
foundFoo := false
for _, role := range result {
if role == "foo" {
foundFoo = true
break
}
}
if !foundFoo {
t.Errorf("Expected 'foo' to be in missing roles list, got %v", result)
}
// Verify the error message format
if !strings.Contains(err.Error(), "the following roles do not exist in Permit.io") {
t.Errorf("Error message should contain expected prefix, got: %s", err.Error())
}
t.Logf("Successfully detected missing role 'foo'. Missing roles: %v", result)
}
func TestValidateCSVRoles_AllRolesExist(t *testing.T) {
config, httpClient, ok := setupTestConfig(t)
if !ok {
return
}
// Test CSV data with only roles that should exist (admin, viewer, editor)
csvUsers := []map[string]string{
{
"email": "user1@example.com",
"first_name": "John",
"last_name": "Doe",
"roles": "admin,viewer",
},
{
"email": "user2@example.com",
"first_name": "Jane",
"last_name": "Smith",
"roles": "editor,admin",
},
}
// Call the function under test with real API
result, err := ValidateCSVRoles(httpClient, config, csvUsers)
// Verify that no error was returned since all roles should exist
if err != nil {
t.Fatalf("Expected no error when all roles exist, but got: %v", err)
}
// Verify that all unique requested roles are returned
expectedRoleCount := 3 // admin, viewer, editor
if len(result) != expectedRoleCount {
t.Errorf("Expected %d unique roles, got %d: %v", expectedRoleCount, len(result), result)
}
// Verify expected roles are present
expectedRoles := map[string]bool{
"admin": false,
"viewer": false,
"editor": false,
}
for _, role := range result {
if _, exists := expectedRoles[role]; exists {
expectedRoles[role] = true
} else {
t.Errorf("Unexpected role in result: %s", role)
}
}
// Check that all expected roles were found
for role, found := range expectedRoles {
if !found {
t.Errorf("Expected role '%s' not found in result", role)
}
}
t.Logf("Successfully validated all existing roles: %v", result)
}
func TestValidateCSVRoles_EmptyCSV(t *testing.T) {
config, httpClient, ok := setupTestConfig(t)
if !ok {
return
}
// Empty CSV data
csvUsers := []map[string]string{}
// Call the function under test
result, err := ValidateCSVRoles(httpClient, config, csvUsers)
// Verify that no error was returned
if err != nil {
t.Fatalf("Expected no error for empty CSV, but got: %v", err)
}
// Verify that no roles are returned
if len(result) != 0 {
t.Errorf("Expected empty result for empty CSV, got %v", result)
}
t.Logf("Successfully handled empty CSV")
}
func TestValidateCSVRoles_NoRolesInCSV(t *testing.T) {
config, httpClient, ok := setupTestConfig(t)
if !ok {
return
}
// CSV data with users but no roles
csvUsers := []map[string]string{
{
"email": "user1@example.com",
"first_name": "John",
"last_name": "Doe",
"roles": "", // empty roles
},
{
"email": "user2@example.com",
"first_name": "Jane",
"last_name": "Smith",
// no roles field
},
}
// Call the function under test
result, err := ValidateCSVRoles(httpClient, config, csvUsers)
// Verify that no error was returned
if err != nil {
t.Fatalf("Expected no error when no roles specified, but got: %v", err)
}
// Verify that no roles are returned
if len(result) != 0 {
t.Errorf("Expected empty result when no roles specified, got %v", result)
}
t.Logf("Successfully handled CSV with no roles")
}
// TestExtractUniqueRolesFromCSV tests the role extraction helper function
func TestExtractUniqueRolesFromCSV(t *testing.T) {
t.Run("ExtractUniqueRoles_NormalCase", func(t *testing.T) {
csvUsers := []map[string]string{
{"roles": "admin,viewer"},
{"roles": "editor,admin"}, // admin is duplicate
{"roles": "viewer"}, // viewer is duplicate
{"roles": ""}, // empty roles
}
result := extractUniqueRolesFromCSV(csvUsers)
// Should get 3 unique roles
expectedCount := 3
if len(result) != expectedCount {
t.Errorf("Expected %d unique roles, got %d: %v", expectedCount, len(result), result)
}
// Check that all expected roles are present
expectedRoles := map[string]bool{
"admin": false,
"viewer": false,
"editor": false,
}
for _, role := range result {
if _, exists := expectedRoles[role]; exists {
expectedRoles[role] = true
} else {
t.Errorf("Unexpected role: %s", role)
}
}
// Verify all expected roles were found
for role, found := range expectedRoles {
if !found {
t.Errorf("Expected role '%s' not found", role)
}
}
})
t.Run("ExtractUniqueRoles_WithWhitespace", func(t *testing.T) {
csvUsers := []map[string]string{
{"roles": " admin , viewer "}, // roles with whitespace
{"roles": "editor, admin "}, // more whitespace
}
result := extractUniqueRolesFromCSV(csvUsers)
// Verify whitespace is trimmed and duplicates removed
expectedRoles := map[string]bool{
"admin": false,
"viewer": false,
"editor": false,
}
if len(result) != 3 {
t.Errorf("Expected 3 unique roles, got %d: %v", len(result), result)
}
for _, role := range result {
if _, exists := expectedRoles[role]; exists {
expectedRoles[role] = true
} else {
t.Errorf("Unexpected role: %s", role)
}
}
// Verify all expected roles were found
for role, found := range expectedRoles {
if !found {
t.Errorf("Expected role '%s' not found", role)
}
}
})
}
// TestFindMissingRoles tests the missing roles detection helper function
func TestFindMissingRoles(t *testing.T) {
t.Run("FindMissingRoles_SomeMissing", func(t *testing.T) {
requestedRoles := []string{"admin", "viewer", "foo", "bar"}
existingRoles := []string{"admin", "viewer", "editor"}
result := findMissingRoles(requestedRoles, existingRoles)
expectedMissing := map[string]bool{
"foo": false,
"bar": false,
}
if len(result) != 2 {
t.Errorf("Expected 2 missing roles, got %d: %v", len(result), result)
}
for _, role := range result {
if _, exists := expectedMissing[role]; exists {
expectedMissing[role] = true
} else {
t.Errorf("Unexpected missing role: %s", role)
}
}
// Verify all expected missing roles were found
for role, found := range expectedMissing {
if !found {
t.Errorf("Expected missing role '%s' not found", role)
}
}
})
t.Run("FindMissingRoles_NoneMissing", func(t *testing.T) {
requestedRoles := []string{"admin", "viewer"}
existingRoles := []string{"admin", "viewer", "editor"}
result := findMissingRoles(requestedRoles, existingRoles)
if len(result) != 0 {
t.Errorf("Expected no missing roles, got %v", result)
}
})
t.Run("FindMissingRoles_AllMissing", func(t *testing.T) {
requestedRoles := []string{"foo", "bar"}
existingRoles := []string{"admin", "viewer", "editor"}
result := findMissingRoles(requestedRoles, existingRoles)
if len(result) != 2 {
t.Errorf("Expected 2 missing roles, got %d: %v", len(result), result)
}
expectedMissing := map[string]bool{
"foo": false,
"bar": false,
}
for _, role := range result {
if _, exists := expectedMissing[role]; exists {
expectedMissing[role] = true
} else {
t.Errorf("Unexpected missing role: %s", role)
}
}
// Verify all expected missing roles were found
for role, found := range expectedMissing {
if !found {
t.Errorf("Expected missing role '%s' not found", role)
}
}
})
}
// checkRequiredEnvVarsForRoles checks if required environment variables are set for role validation tests
func checkRequiredEnvVarsForRoles(t *testing.T) bool {
required := []string{"PERMIT_KEY"}
missing := []string{}
for _, env := range required {
if os.Getenv(env) == "" {
missing = append(missing, env)
}
}
if len(missing) > 0 {
t.Skipf("Skipping role validation integration test - missing required environment variables: %v", missing)
return false
}
return true
}