using System.Text; using Microsoft.Extensions.Logging.Abstractions; using w4c_workflows.Data; using w4c_workflows.Services.Credentials; using w4c_workflows.Services.Execution; using w4c_workflows.Services.Quota; using w4c_workflows.Services.Runs; namespace w4c_workflows.Tests; /// /// Reversible (non-cryptographic) cipher for tests that only need round-tripping; /// the real DataProtectionCredentialCipher is covered separately. /// internal sealed class ReversibleTestCipher : ICredentialCipher { private const string Prefix = "enc:"; public string Protect(string plaintext) => Prefix + Convert.ToBase64String(Encoding.UTF8.GetBytes(plaintext)); public string Unprotect(string ciphertext) => Encoding.UTF8.GetString(Convert.FromBase64String(ciphertext[Prefix.Length..])); } /// A self-cleaning temp directory for executor tests. internal sealed class TempDir : IDisposable { public string Path { get; } public TempDir() { Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "wf-test-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(Path); } public string Write(string relativePath, string content) { var full = System.IO.Path.Combine(Path, relativePath); var dir = System.IO.Path.GetDirectoryName(full); if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir); File.WriteAllText(full, content); return full; } public void Dispose() { try { Directory.Delete(Path, recursive: true); } catch { /* best effort */ } } } /// Factories for the execution-quota service and a quota-aware run launcher. internal static class QuotaTestData { public static WorkflowQuotaService Service( WorkflowsDbContext db, WorkflowQuotaOptions? options = null, TimeProvider? time = null) => new( db, options ?? new WorkflowQuotaOptions(), time ?? TimeProvider.System, NullLogger.Instance); public static RunLauncher Launcher(WorkflowsDbContext db, WorkflowQuotaService? quota = null) => new(db, quota ?? Service(db), NullLogger.Instance); } internal static class Invocation { /// Builds a minimal task invocation for a single-file language. public static TaskInvocation For( string language, string entryFile, string? input = null, string? workingDir = null, string? entryFunction = null) => new( TaskInvocation.TypeValue, "run-1", "task-1", "task-key", language, entryFile, entryFunction, new Dictionary(), input, workingDir, "tenant-1", 1); }