journal/Journal.SmokeTests/Program.Shared.cs

170 lines
5.2 KiB
C#

internal static partial class Program
{
static FragmentService NewService()
{
IFragmentRepository repo = new InMemoryFragmentRepository();
return new FragmentService(repo);
}
static Entry NewEntry()
{
var dbService = new JournalDatabaseService(new JournalConfigService());
var session = new DatabaseSessionService(dbService);
return new Entry(
NewService(),
new EntrySearchService(),
new VaultStorageService(new VaultCryptoService()),
dbService,
session,
new JournalConfigService(),
new DisabledAiService("none"),
new DisabledSpeechBridgeService("none"),
new EntryFileService(new DiskEntryFileRepository()),
new ListService(new SqliteListRepository(session)),
new TodoService(new SqliteTodoRepository(session)),
new CommandLogger());
}
static IJournalDatabaseService NewDatabaseService() => new JournalDatabaseService(new JournalConfigService());
static Dictionary<string, string> ReadVaultEntryTexts(string vaultPath, string password)
{
var crypto = new VaultCryptoService();
var encrypted = File.ReadAllBytes(vaultPath);
var zipBytes = crypto.DecryptData(encrypted, password);
using var stream = new MemoryStream(zipBytes);
using var archive = new ZipArchive(stream, ZipArchiveMode.Read);
var result = new Dictionary<string, string>(StringComparer.Ordinal);
foreach (var entry in archive.Entries)
{
if (string.IsNullOrEmpty(entry.Name))
continue;
using var reader = new StreamReader(entry.Open());
result[entry.Name] = reader.ReadToEnd();
}
return result;
}
static byte[] CreateZipBytes(Dictionary<string, string> files)
{
using var stream = new MemoryStream();
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
{
foreach (var (name, content) in files)
{
var entry = archive.CreateEntry(name);
using var writer = new StreamWriter(entry.Open());
writer.Write(content);
}
}
return stream.ToArray();
}
static void WriteSearchFixtureFiles(string root)
{
File.WriteAllText(Path.Combine(root, "2026-02-01.md"), """
Date: 2026-02-01
## Summary
Alpha common
## Reflection
focus area
- [x] med taken
!TRIGGER #stress
fragment one
""");
File.WriteAllText(Path.Combine(root, "2026-02-05.md"), """
Date: 2026-02-05
## Summary
Beta common
## Reflection
other notes
- [ ] drink water
!NOTE #daily
fragment two
""");
File.WriteAllText(Path.Combine(root, "2026-03-01.md"), """
Date: 2026-03-01
## Summary
Gamma unique
## Reflection
nothing related
!NOTE #other
fragment three
""");
}
static (int ExitCode, string Stdout, string Stderr) CaptureConsole(Func<int> action)
{
var originalOut = Console.Out;
var originalError = Console.Error;
using var stdout = new StringWriter();
using var stderr = new StringWriter();
try
{
Console.SetOut(stdout);
Console.SetError(stderr);
var exitCode = action();
return (exitCode, stdout.ToString(), stderr.ToString());
}
finally
{
Console.SetOut(originalOut);
Console.SetError(originalError);
}
}
static JournalConfig BuildAiConfig(string sidecarScriptPath, int timeoutMs)
{
var baseConfig = new JournalConfigService().Current;
var pythonExe = Environment.GetEnvironmentVariable("JOURNAL_PYTHON_EXE");
if (string.IsNullOrWhiteSpace(pythonExe))
pythonExe = "python";
return baseConfig with
{
AiProvider = "python-sidecar",
PythonExecutable = pythonExe,
PythonAiSidecarPath = sidecarScriptPath,
AiSidecarTimeoutMs = timeoutMs
};
}
static async Task<List<TransportFixture>> LoadTransportFixturesAsync()
{
var path = Path.Combine(AppContext.BaseDirectory, "Fixtures", "transport_cases.json");
if (!File.Exists(path))
throw new FileNotFoundException($"Transport fixture file not found: {path}");
var json = await File.ReadAllTextAsync(path);
return JsonSerializer.Deserialize<List<TransportFixture>>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
}) ?? [];
}
static JsonValueKind ParseValueKind(string value) => value.Trim().ToLowerInvariant() switch
{
"array" => JsonValueKind.Array,
"object" => JsonValueKind.Object,
"null" => JsonValueKind.Null,
"string" => JsonValueKind.String,
"number" => JsonValueKind.Number,
"true" => JsonValueKind.True,
"false" => JsonValueKind.False,
_ => throw new InvalidOperationException($"Unsupported JsonValueKind '{value}' in transport fixture.")
};
static void Assert(bool condition, string message)
{
if (!condition)
throw new InvalidOperationException(message);
}
}