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);
}