WorkingServiceTests.csโข14.5 kB
using NUnit.Framework;
using COA.Goldfish.McpServer.Models;
using COA.Goldfish.McpServer.Services.Storage;
using COA.Goldfish.McpServer.Tools;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;
namespace COA.Goldfish.IntegrationTests;
/// <summary>
/// Working demonstration of the testing theater elimination solution.
/// These tests prove that database isolation, direct service calling, and realistic data work.
/// </summary>
[TestFixture]
public class WorkingServiceTests : ServiceTestBase
{
    /// <summary>
    /// Override to use SQLite for better concurrency support in tests
    /// </summary>
    protected override GoldfishDbContext CreateTestContext()
    {
        return TestDbContextFactory.CreateInMemorySqliteContext();
    }
    [Test]
    public async Task DatabaseOperations_Should_WorkWithoutProcessSpawning()
    {
        // Arrange: Create realistic checkpoint data using TestDataFactory
        var (description, highlights, activeFiles) = TestDataFactory.GenerateCheckpointData("ecommerce");
        var request = CreateCheckpointRequest(description, highlights, activeFiles);
        // Act: Direct service call - NO MCP server process spawning
        var result = await _checkpointTool!.ExecuteAsync(request);
        // Assert: Verify real database persistence
        if (!result.Success)
        {
            TestContext.WriteLine($"โ Checkpoint tool failed: {result.Error?.Message ?? result.Message}");
            TestContext.WriteLine($"๐ Error code: {result.Error?.Code}");
        }
        Assert.That(result.Success, Is.True, $"Checkpoint failed: {result.Error?.Message ?? result.Message}");
        Assert.That(result.Message, Contains.Substring("Checkpoint saved"));
        
        // Verify data was actually saved to database
        var savedCheckpoint = await _context!.Checkpoints
            .FirstOrDefaultAsync(c => c.Description == description);
        Assert.That(savedCheckpoint, Is.Not.Null);
        Assert.That(savedCheckpoint.Highlights, Is.EquivalentTo(highlights));
        Assert.That(savedCheckpoint.ActiveFiles, Is.EquivalentTo(activeFiles));
        
        TestContext.WriteLine($"โ
 Database operation completed in isolated test database");
        TestContext.WriteLine($"๐ Checkpoint: {description}");
    }
    [Test]
    public async Task TodoOperations_Should_ValidateRealBusinessLogic()
    {
        // Arrange: Create realistic todo data
        var (title, items) = TestDataFactory.GenerateTodoData("devops");
        var request = CreateTodoRequest(title, items);
        // Act: Direct service call validates all business rules
        var result = await _todoTool!.ExecuteAsync(request);
        // Assert: Verify real Entity Framework operations
        Assert.That(result.Success, Is.True);
        
        // Verify todo list was created in database
        var savedTodoList = await _context!.TodoLists
            .Include(tl => tl.Items)
            .FirstOrDefaultAsync(tl => tl.Title == title);
        
        Assert.That(savedTodoList, Is.Not.Null);
        Assert.That(savedTodoList.Items.Count, Is.EqualTo(items.Count));
        
        // Verify all todo items were saved with correct status
        foreach (var item in items)
        {
            var savedItem = savedTodoList.Items.FirstOrDefault(i => i.Content == item);
            Assert.That(savedItem, Is.Not.Null);
            Assert.That(savedItem.Status, Is.EqualTo(TodoItemStatus.Pending));
        }
        
        TestContext.WriteLine($"โ
 Todo list created with {items.Count} items");
        TestContext.WriteLine($"๐ Title: {title}");
    }
    [Test]
    public async Task WorkspaceIsolation_Should_PreventDataContamination()
    {
        // Arrange: Create data in this test's isolated workspace
        var request1 = CreateCheckpointRequest("Workspace Test 1");
        var result1 = await _checkpointTool!.ExecuteAsync(request1);
        
        // Act: Create another test with different workspace
        var isolatedWorkspaceId = Guid.NewGuid().ToString();
        var request2 = CreateCheckpointRequest("Workspace Test 2");
        request2.Workspace = isolatedWorkspaceId;
        
        // This should succeed but create checkpoint in different workspace
        var result2 = await _checkpointTool.ExecuteAsync(request2);
        // Assert: Verify workspace isolation
        Assert.That(result1.Success, Is.True);
        Assert.That(result2.Success, Is.True); // Different workspace should succeed
        
        // Verify both checkpoints exist but in different workspaces
        var allCheckpoints = await _context!.Checkpoints.ToListAsync();
        Assert.That(allCheckpoints.Count, Is.EqualTo(2)); // Both checkpoints
        
        // Verify workspace isolation - each checkpoint belongs to its respective workspace
        var checkpoint1 = allCheckpoints.FirstOrDefault(c => c.Description == "Workspace Test 1");
        var checkpoint2 = allCheckpoints.FirstOrDefault(c => c.Description == "Workspace Test 2");
        
        Assert.That(checkpoint1, Is.Not.Null);
        Assert.That(checkpoint2, Is.Not.Null);
        Assert.That(checkpoint1.WorkspaceId, Is.EqualTo(_testWorkspaceId));
        Assert.That(checkpoint2.WorkspaceId, Is.EqualTo(isolatedWorkspaceId));
        Assert.That(checkpoint1.WorkspaceId, Is.Not.EqualTo(checkpoint2.WorkspaceId));
        
        TestContext.WriteLine($"โ
 Workspace isolation verified");
        TestContext.WriteLine($"๐ Test workspace: {_testWorkspaceId[..8]}...");
    }
    [Test]
    public async Task PerformanceTest_Should_ExecuteQuicklyWithoutProcessOverhead()
    {
        // Arrange: Measure performance of 50 operations
        var stopwatch = Stopwatch.StartNew();
        var operationCount = 50;
        
        // Act: Create multiple checkpoints rapidly
        for (int i = 0; i < operationCount; i++)
        {
            var (description, highlights, activeFiles) = TestDataFactory.GenerateCheckpointData("random");
            var request = CreateCheckpointRequest($"{description} #{i}", highlights, activeFiles);
            var result = await _checkpointTool!.ExecuteAsync(request);
            Assert.That(result.Success, Is.True);
        }
        
        stopwatch.Stop();
        
        // Assert: Performance should be excellent without process spawning
        Assert.That(stopwatch.ElapsedMilliseconds, Is.LessThan(2000)); // Under 2 seconds
        
        // Verify all operations succeeded
        var checkpointCount = await _context!.Checkpoints.CountAsync();
        Assert.That(checkpointCount, Is.EqualTo(operationCount));
        
        TestContext.WriteLine($"โ
 {operationCount} operations completed in {stopwatch.ElapsedMilliseconds}ms");
        TestContext.WriteLine($"โก Average: {stopwatch.ElapsedMilliseconds / operationCount}ms per operation");
    }
    [Test]
    public async Task ComplexScenario_Should_TestRealWorkflowWithoutMocks()
    {
        // Arrange: Create a complete development workflow
        var (planTitle, planDescription, planItems, category) = TestDataFactory.GeneratePlanData("saas");
        var (todoTitle, todoItems) = TestDataFactory.GenerateTodoData("saas");
        var (checkpointDesc, highlights, activeFiles) = TestDataFactory.GenerateCheckpointData("saas");
        // Act: Execute complete workflow - Plan โ Todos โ Checkpoint
        
        // 1. Create strategic plan
        var planRequest = CreatePlanRequest(planTitle, planDescription, planItems);
        var planResult = await _planTool!.ExecuteAsync(planRequest);
        
        // 2. Create todo list
        var todoRequest = CreateTodoRequest(todoTitle, todoItems);
        var todoResult = await _todoTool!.ExecuteAsync(todoRequest);
        
        // 3. Create checkpoint
        var checkpointRequest = CreateCheckpointRequest(checkpointDesc, highlights, activeFiles);
        var checkpointResult = await _checkpointTool!.ExecuteAsync(checkpointRequest);
        // Assert: All operations succeeded and are related
        if (!planResult.Success)
        {
            TestContext.WriteLine($"โ Plan failed: {planResult.Error?.Message ?? planResult.Message}");
            TestContext.WriteLine($"๐ Plan error code: {planResult.Error?.Code}");
        }
        if (!todoResult.Success)
        {
            TestContext.WriteLine($"โ Todo failed: {todoResult.Error?.Message ?? todoResult.Message}");
            TestContext.WriteLine($"๐ Todo error code: {todoResult.Error?.Code}");
        }
        if (!checkpointResult.Success)
        {
            TestContext.WriteLine($"โ Checkpoint failed: {checkpointResult.Error?.Message ?? checkpointResult.Message}");
            TestContext.WriteLine($"๐ Checkpoint error code: {checkpointResult.Error?.Code}");
        }
        
        Assert.That(planResult.Success, Is.True);
        Assert.That(todoResult.Success, Is.True);
        Assert.That(checkpointResult.Success, Is.True);
        
        // Verify all data exists in database with proper relationships
        var plan = await _context!.Plans.FirstOrDefaultAsync(p => p.Title == planTitle);
        var todoList = await _context.TodoLists.Include(tl => tl.Items).FirstOrDefaultAsync(tl => tl.Title == todoTitle);
        var checkpoint = await _context.Checkpoints.FirstOrDefaultAsync(c => c.Description == checkpointDesc);
        
        Assert.That(plan, Is.Not.Null);
        Assert.That(todoList, Is.Not.Null);
        Assert.That(checkpoint, Is.Not.Null);
        
        // All should belong to same workspace
        Assert.That(plan.WorkspaceId, Is.EqualTo(_testWorkspaceId));
        Assert.That(todoList.WorkspaceId, Is.EqualTo(_testWorkspaceId));
        Assert.That(checkpoint.WorkspaceId, Is.EqualTo(_testWorkspaceId));
        
        TestContext.WriteLine($"โ
 Complete workflow executed successfully");
        TestContext.WriteLine($"๐ Plan: {planTitle}");
        TestContext.WriteLine($"๐ Todo: {todoTitle} ({todoItems.Count} items)");
        TestContext.WriteLine($"๐พ Checkpoint: {checkpointDesc}");
    }
    [Test]
    public async Task DatabaseConstraints_Should_BeEnforced()
    {
        // Arrange: Try to create invalid data
        var invalidRequest = CreateCheckpointRequest("");
        invalidRequest.Description = ""; // Empty description should fail validation
        // Act: Attempt to save invalid data
        var result = await _checkpointTool!.ExecuteAsync(invalidRequest);
        // Assert: Entity Framework validation should prevent invalid data
        Assert.That(result.Success, Is.False);
        Assert.That(result.Error?.Message, Contains.Substring("description").IgnoreCase);
        
        // Verify no invalid data was saved
        var checkpointCount = await _context!.Checkpoints.CountAsync();
        Assert.That(checkpointCount, Is.EqualTo(0));
        
        TestContext.WriteLine($"โ
 Database constraints enforced");
        TestContext.WriteLine($"๐ซ Invalid data rejected: {result.Error?.Message}");
    }
    [Test]
    public async Task ConcurrentAccess_Should_HandleMultipleConnections()
    {
        // Arrange: Create multiple concurrent operations
        var tasks = new List<Task<bool>>();
        var operationCount = 5; // Reduced for SQLite concurrency limits
        
        // Act: Execute concurrent operations with separate scopes
        for (int i = 0; i < operationCount; i++)
        {
            int operationId = i; // Capture loop variable
            var task = Task.Run(async () =>
            {
                // Create separate scope for each thread to avoid DbContext sharing
                using var scope = _serviceProvider!.CreateScope();
                var checkpointTool = scope.ServiceProvider.GetRequiredService<CheckpointTool>();
                
                var (description, highlights, activeFiles) = TestDataFactory.GenerateCheckpointData("random");
                var request = CreateCheckpointRequest($"{description} - Concurrent #{operationId}", highlights, activeFiles);
                var result = await checkpointTool.ExecuteAsync(request);
                return result.Success;
            });
            tasks.Add(task);
        }
        
        var results = await Task.WhenAll(tasks);
        
        // Assert: All concurrent operations should succeed
        Assert.That(results.All(r => r), Is.True);
        
        // Verify correct number of records created
        var checkpointCount = await _context!.Checkpoints.CountAsync();
        Assert.That(checkpointCount, Is.EqualTo(operationCount));
        
        TestContext.WriteLine($"โ
 {operationCount} concurrent operations completed successfully");
        TestContext.WriteLine($"๐ Database handled concurrent access properly");
    }
    [Test]
    [Ignore("Skipped - use SearchServiceFts5Tests.cs for dedicated FTS5 testing")]
    public async Task RealFtsSearch_Should_WorkWithSqliteDatabase()
    {
        // Arrange: Override default context to use SQLite for FTS5 testing
        await CleanupServicesAsync();
        _context = TestDbContextFactory.CreateInMemorySqliteContext();
        await TestDbContextFactory.InitializeAsync(_context, false);
        await SetUpServicesAsync(); // Re-setup services with SQLite context
        
        // Create searchable data
        var (description, highlights, activeFiles) = TestDataFactory.GenerateCheckpointData("ecommerce");
        var request = CreateCheckpointRequest(description, highlights, activeFiles);
        var result = await _checkpointTool!.ExecuteAsync(request);
        
        Assert.That(result.Success, Is.True);
        
        // Act: Search for the created checkpoint
        var searchRequest = new COA.Goldfish.McpServer.Models.SearchParameters
        {
            Query = "payment integration", // Should match ecommerce scenarios
            Limit = 10,
            WorkspaceId = _testWorkspaceId
        };
        
        var searchResult = await _searchTool!.ExecuteAsync(searchRequest);
        
        // Assert: FTS5 search should find relevant results
        Assert.That(searchResult.Success, Is.True);
        Assert.That(searchResult.Message, Contains.Substring("payment").IgnoreCase);
        
        TestContext.WriteLine($"โ
 SQLite FTS5 search working correctly");
        TestContext.WriteLine($"๐ Found results for: payment integration");
    }
}