mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-20 02:03:16 +00:00
Fixes #933
This commit is contained in:
parent
6b4188fa0b
commit
ef5149fdf6
1 changed files with 83 additions and 2 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
import { mkdirSync, rmSync, writeFileSync } from "fs";
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
||||||
import { tmpdir } from "os";
|
import { tmpdir } from "os";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||||
import { findMostRecentSession, loadEntriesFromFile } from "../../src/core/session-manager.js";
|
import { findMostRecentSession, loadEntriesFromFile, SessionManager } from "../../src/core/session-manager.js";
|
||||||
|
|
||||||
describe("loadEntriesFromFile", () => {
|
describe("loadEntriesFromFile", () => {
|
||||||
let tempDir: string;
|
let tempDir: string;
|
||||||
|
|
@ -125,3 +125,84 @@ describe("findMostRecentSession", () => {
|
||||||
expect(findMostRecentSession(tempDir)).toBe(valid);
|
expect(findMostRecentSession(tempDir)).toBe(valid);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("SessionManager.setSessionFile with corrupted files", () => {
|
||||||
|
let tempDir: string;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tempDir = join(tmpdir(), `session-test-${Date.now()}`);
|
||||||
|
mkdirSync(tempDir, { recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rmSync(tempDir, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("truncates and rewrites empty file with valid header", () => {
|
||||||
|
const emptyFile = join(tempDir, "empty.jsonl");
|
||||||
|
writeFileSync(emptyFile, "");
|
||||||
|
|
||||||
|
const sm = SessionManager.open(emptyFile, tempDir);
|
||||||
|
|
||||||
|
// Should have created a new session with valid header
|
||||||
|
expect(sm.getSessionId()).toBeTruthy();
|
||||||
|
expect(sm.getHeader()).toBeTruthy();
|
||||||
|
expect(sm.getHeader()?.type).toBe("session");
|
||||||
|
|
||||||
|
// File should now contain a valid header
|
||||||
|
const content = readFileSync(emptyFile, "utf-8");
|
||||||
|
const lines = content.trim().split("\n").filter(Boolean);
|
||||||
|
expect(lines.length).toBe(1);
|
||||||
|
const header = JSON.parse(lines[0]);
|
||||||
|
expect(header.type).toBe("session");
|
||||||
|
expect(header.id).toBe(sm.getSessionId());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("truncates and rewrites file without valid header", () => {
|
||||||
|
const noHeaderFile = join(tempDir, "no-header.jsonl");
|
||||||
|
// File with messages but no session header (corrupted state)
|
||||||
|
writeFileSync(
|
||||||
|
noHeaderFile,
|
||||||
|
'{"type":"message","id":"abc","parentId":"orphaned","timestamp":"2025-01-01T00:00:00Z","message":{"role":"assistant","content":"test"}}\n',
|
||||||
|
);
|
||||||
|
|
||||||
|
const sm = SessionManager.open(noHeaderFile, tempDir);
|
||||||
|
|
||||||
|
// Should have created a new session with valid header
|
||||||
|
expect(sm.getSessionId()).toBeTruthy();
|
||||||
|
expect(sm.getHeader()).toBeTruthy();
|
||||||
|
expect(sm.getHeader()?.type).toBe("session");
|
||||||
|
|
||||||
|
// File should now contain only a valid header (old content truncated)
|
||||||
|
const content = readFileSync(noHeaderFile, "utf-8");
|
||||||
|
const lines = content.trim().split("\n").filter(Boolean);
|
||||||
|
expect(lines.length).toBe(1);
|
||||||
|
const header = JSON.parse(lines[0]);
|
||||||
|
expect(header.type).toBe("session");
|
||||||
|
expect(header.id).toBe(sm.getSessionId());
|
||||||
|
});
|
||||||
|
|
||||||
|
it("preserves explicit session file path when recovering from corrupted file", () => {
|
||||||
|
const explicitPath = join(tempDir, "my-session.jsonl");
|
||||||
|
writeFileSync(explicitPath, "");
|
||||||
|
|
||||||
|
const sm = SessionManager.open(explicitPath, tempDir);
|
||||||
|
|
||||||
|
// The session file path should be preserved
|
||||||
|
expect(sm.getSessionFile()).toBe(explicitPath);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("subsequent loads of recovered file work correctly", () => {
|
||||||
|
const corruptedFile = join(tempDir, "corrupted.jsonl");
|
||||||
|
writeFileSync(corruptedFile, "garbage content\n");
|
||||||
|
|
||||||
|
// First open recovers the file
|
||||||
|
const sm1 = SessionManager.open(corruptedFile, tempDir);
|
||||||
|
const sessionId = sm1.getSessionId();
|
||||||
|
|
||||||
|
// Second open should load the recovered file successfully
|
||||||
|
const sm2 = SessionManager.open(corruptedFile, tempDir);
|
||||||
|
expect(sm2.getSessionId()).toBe(sessionId);
|
||||||
|
expect(sm2.getHeader()?.type).toBe("session");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue