fetch_ml/tests/unit/queue/queue_permissions_test.go
Jeremie Fraeys ea15af1833 Fix multi-user authentication and clean up debug code
- Fix YAML tags in auth config struct (json -> yaml)
- Update CLI configs to use pre-hashed API keys
- Remove double hashing in WebSocket client
- Fix port mapping (9102 -> 9103) in CLI commands
- Update permission keys to use jobs:read, jobs:create, etc.
- Clean up all debug logging from CLI and server
- All user roles now authenticate correctly:
  * Admin: Can queue jobs and see all jobs
  * Researcher: Can queue jobs and see own jobs
  * Analyst: Can see status (read-only access)

Multi-user authentication is now fully functional.
2025-12-06 12:35:32 -05:00

159 lines
3.6 KiB
Go

package queue
import (
"testing"
"time"
"github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/require"
"github.com/jfraeys/fetch_ml/internal/queue"
)
const testUser = "testuser"
func TestTask_UserFields(t *testing.T) {
t.Parallel()
task := &queue.Task{
UserID: "testuser",
Username: "testuser",
CreatedBy: "testuser",
}
if task.UserID != "testuser" {
t.Errorf("Expected UserID to be 'testuser', got '%s'", task.UserID)
}
if task.Username != testUser {
t.Errorf("Expected Username to be 'testuser', got '%s'", task.Username)
}
if task.CreatedBy != testUser {
t.Errorf("Expected CreatedBy to be 'testuser', got '%s'", task.CreatedBy)
}
}
func TestTaskQueue_UserFiltering(t *testing.T) {
// Setup test Redis configuration
s, err := miniredis.Run()
if err != nil {
t.Skip("Redis not available for integration testing")
}
t.Cleanup(s.Close)
queueCfg := queue.Config{
RedisAddr: s.Addr(),
RedisDB: 15, // Use dedicated test DB
}
// Create task queue
taskQueue, err := queue.NewTaskQueue(queueCfg)
if err != nil {
t.Skip("Redis not available for integration testing")
return
}
t.Cleanup(func() {
if err := taskQueue.Close(); err != nil {
t.Logf("Warning: failed to close task queue: %v", err)
}
})
// Clear test database
s.FlushAll()
// Create test tasks with different users
tasks := []*queue.Task{
{
ID: "task1",
JobName: "user1_job1",
Status: "queued",
UserID: "user1",
CreatedBy: "user1",
CreatedAt: time.Now(),
},
{
ID: "task2",
JobName: "user1_job2",
Status: "running",
UserID: "user1",
CreatedBy: "user1",
CreatedAt: time.Now(),
},
{
ID: "task3",
JobName: "user2_job1",
Status: "queued",
UserID: "user2",
CreatedBy: "user2",
CreatedAt: time.Now(),
},
{
ID: "task4",
JobName: "admin_job",
Status: "completed",
UserID: "admin",
CreatedBy: "admin",
CreatedAt: time.Now(),
},
}
// Add tasks to queue
for _, task := range tasks {
require.NoError(t, taskQueue.AddTask(task))
}
// Test GetAllTasks
allTasks, err := taskQueue.GetAllTasks()
require.NoError(t, err)
if len(allTasks) != len(tasks) {
t.Errorf("Expected %d tasks, got %d", len(tasks), len(allTasks))
}
// Test user filtering logic
filterTasksForUser := func(tasks []*queue.Task, userID string) []*queue.Task {
var filtered []*queue.Task
for _, task := range tasks {
if task.UserID == userID || task.CreatedBy == userID {
filtered = append(filtered, task)
}
}
return filtered
}
// Test filtering for user1 (should get 2 tasks)
user1Tasks := filterTasksForUser(allTasks, "user1")
if len(user1Tasks) != 2 {
t.Errorf("Expected 2 tasks for user1, got %d", len(user1Tasks))
}
// Test filtering for user2 (should get 1 task)
user2Tasks := filterTasksForUser(allTasks, "user2")
if len(user2Tasks) != 1 {
t.Errorf("Expected 1 task for user2, got %d", len(user2Tasks))
}
// Test filtering for admin (should get 1 task)
adminTasks := filterTasksForUser(allTasks, "admin")
if len(adminTasks) != 1 {
t.Errorf("Expected 1 task for admin, got %d", len(adminTasks))
}
// Test GetTaskByName
task, err := taskQueue.GetTaskByName("user1_job1")
if err != nil {
t.Errorf("Failed to get task by name: %v", err)
}
if task == nil || task.UserID != "user1" {
t.Error("Got wrong task or nil task")
}
// Test CancelTask
require.NoError(t, taskQueue.CancelTask("task1"))
// Verify task was cancelled
cancelledTask, err := taskQueue.GetTask("task1")
require.NoError(t, err)
if cancelledTask.Status != "cancelled" {
t.Errorf("Expected status 'cancelled', got '%s'", cancelledTask.Status)
}
}