Remove unused persona marketplace and discover page files.
CI / check (22) (push) Failing after 16m32s
CI / check (24) (push) Failing after 15m50s

This commit is contained in:
2026-10-07 23:41:27 +02:00
parent 10ec76d437
commit 5ca611c113
34 changed files with 368 additions and 1216 deletions
+40 -21
View File
@@ -127,6 +127,31 @@ test("public health checks reach the backend without exposing diagnostics or req
assert.equal((await request(server.baseUrl, "/admin/diagnostics")).status, 403);
});
test("personality API keeps prompts private, validates IDs, and enforces chat ownership", async t => {
const server = await startTestServer();
t.after(() => server.close());
const owner = new CookieJar(), other = new CookieJar();
await request(server.baseUrl, "/register", {method:"POST", jar:owner, body:{username:"personality-owner", password:"password123"}});
await request(server.baseUrl, "/register", {method:"POST", jar:other, body:{username:"personality-other", password:"password123"}});
const listed = await request(server.baseUrl, "/personalities", {jar:owner});
assert.equal(listed.json.personalities.length, 6);
assert.equal(listed.json.personalities.filter(item => item.isDefault).length, 1);
assert.equal(listed.json.personalities.find(item => item.id === "programmer").name, "Ada");
assert.equal(listed.json.personalities.find(item => item.id === "programmer").specialization, "Programming & Development");
assert.equal(listed.json.personalities.find(item => item.id === "programmer").historicalInspiration, "Ada Lovelace");
assert.equal(JSON.stringify(listed.json).includes("systemPrompt"), false);
const catalog = await fetch(`${server.baseUrl}/app/personas`, {headers:owner.headers()});
assert.match(await catalog.text(), /Personalities/);
const created = await request(server.baseUrl, "/chats", {method:"POST", jar:owner, body:{personalityId:"programmer"}});
assert.equal(created.json.chat.personality_id, "programmer");
const defaultChat = await request(server.baseUrl, "/chats", {method:"POST", jar:owner, body:{systemPrompt:"Injected"}});
assert.equal(defaultChat.json.chat.personality_id, "general-assistant");
assert.equal((await request(server.baseUrl, "/chats", {method:"POST", jar:owner, body:{personalityId:"invented"}})).status, 400);
assert.equal((await request(server.baseUrl, `/chats/${created.json.chat.id}/personality`, {method:"PUT", jar:other, body:{personalityId:"tutor"}})).status, 404);
assert.equal((await request(server.baseUrl, `/chats/${created.json.chat.id}/personality`, {method:"PUT", jar:owner, body:{personalityId:"tutor"}})).json.chat.personality_id, "tutor");
assert.equal((await request(server.baseUrl, "/personas", {method:"POST", jar:owner, body:{name:"Custom"}})).status, 404);
});
test("new passwords are limited to 72 UTF-8 bytes while legacy credentials remain usable", async t => {
const server = await startTestServer({config: {authRateLimitMax: 100}});
t.after(() => server.close());
@@ -362,8 +387,7 @@ test("username and password changes keep account data and sessions consistent",
assert.equal((await request(server.baseUrl, "/login", {method: "POST", body: {username: "accountowner", password: "old-password"}, jar: otherSession})).status, 200);
const chat = await request(server.baseUrl, "/chats", {method: "POST", body: {title: "Keep this chat"}, jar});
assert.equal(chat.status, 200);
const persona = await request(server.baseUrl, "/personas", {method: "POST", body: {name: "Keeper", personaType: "user"}, jar});
assert.equal(persona.status, 200);
assert.equal((await request(server.baseUrl, "/personas", {method: "POST", body: {name: "Keeper", personaType: "user"}, jar})).status, 404);
const db = server.app.locals.db;
const attachmentId = "12345678-1234-1234-1234-123456789abc";
db.prepare("INSERT INTO attachments (id, username, original_name, storage_key, mime_type, size_bytes, width, height) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
@@ -378,7 +402,6 @@ test("username and password changes keep account data and sessions consistent",
assert.equal((await request(server.baseUrl, "/session", {jar})).json.user, "newowner");
assert.equal((await request(server.baseUrl, "/session", {jar: otherSession})).json.user, null);
assert.equal((await request(server.baseUrl, "/chats", {jar})).json.chats[0].id, chat.json.chat.id);
assert.equal((await request(server.baseUrl, "/personas", {jar})).json.userPersonas[0].id, persona.json.persona.id);
assert.equal(db.prepare("SELECT username FROM attachments WHERE id = ?").get(attachmentId).username, "newowner");
assert.deepEqual(db.pragma("foreign_key_check"), []);
@@ -770,7 +793,7 @@ test("chat context summary rolls up older messages into future payloads", async
await server.close();
});
test("roleplay start keeps the session and roleplay messages work", async () => {
test.skip("legacy character roleplay endpoints are retired", async () => {
const server = await startTestServer();
const jar = new CookieJar();
@@ -808,7 +831,7 @@ test("roleplay start keeps the session and roleplay messages work", async () =>
await server.close();
});
test("roleplay start degrades to an open chat when opener generation fails", async () => {
test.skip("legacy character opener generation is retired", async () => {
const modelService = {
async generateReply() {
throw new Error("Model backend timed out.");
@@ -854,7 +877,7 @@ test("roleplay start degrades to an open chat when opener generation fails", asy
await server.close();
});
test("persona publish and collect flow works across accounts", async () => {
test.skip("legacy persona publishing and collection are retired", async () => {
const server = await startTestServer();
const creatorJar = new CookieJar();
const collectorJar = new CookieJar();
@@ -1011,7 +1034,7 @@ test("archiving frees an active chat slot and restoring respects the limit", asy
} finally { await server.close(); }
});
test("persona clone, version restore, and market feedback endpoints work", async () => {
test.skip("legacy persona cloning, versions, and market feedback are retired", async () => {
const server = await startTestServer();
const jar = new CookieJar();
@@ -1073,7 +1096,7 @@ test("persona clone, version restore, and market feedback endpoints work", async
await server.close();
});
test("market listing supports persona type filters, sorting, and favorite state", async () => {
test.skip("legacy public persona market is retired", async () => {
const server = await startTestServer();
const creatorJar = new CookieJar();
const fanJar = new CookieJar();
@@ -1173,13 +1196,16 @@ test("market listing supports persona type filters, sorting, and favorite state"
test("public pages, workspace guards, and legacy chat links have distinct destinations", async () => {
const server = await startTestServer();
try {
for (const [url, marker] of [["/", "A space for every conversation."], ["/login", 'id="accountForm"'], ["/register", 'id="accountForm"'], ["/market", 'id="publicSearch"']]) {
for (const [url, marker] of [["/", "A space for every conversation."], ["/login", 'id="accountForm"'], ["/register", 'id="accountForm"']]) {
const response = await fetch(server.baseUrl + url);
assert.equal(response.status, 200);
const html = await response.text();
assert.ok(html.includes(marker));
assert.ok(!html.includes('id="chat"'));
}
const retiredMarket = await fetch(server.baseUrl + "/market", {redirect:"manual"});
assert.equal(retiredMarket.status, 302);
assert.equal(retiredMarket.headers.get("location"), "/login");
for (const url of ["/app", "/app/personas", "/app/settings", "/app/chats/42", "/app/chats/new?prompt=hello"]) {
const response = await fetch(server.baseUrl + url, {redirect: "manual"});
assert.equal(response.status, 302);
@@ -1203,20 +1229,13 @@ test("public pages, workspace guards, and legacy chat links have distinct destin
} finally { await server.close(); }
});
test("public discovery only exposes published persona summaries", async () => {
test("legacy persona creation, publishing, and public discovery are unavailable", async () => {
const server = await startTestServer();
try {
const jar = new CookieJar();
await request(server.baseUrl, "/register", {method: "POST", body: {username: "publicmaker", password: "password123"}, jar});
const created = await request(server.baseUrl, "/personas", {method: "POST", body: {name: "Rainkeeper", background: "A guide to a rainy city", details: "Private implementation detail", personaType: "assistant"}, jar});
const id = created.json.persona.id;
assert.equal((await request(server.baseUrl, "/api/discover")).json.personas.length, 0);
await request(server.baseUrl, `/personas/${id}/publish`, {method: "POST", body: {}, jar});
const result = await request(server.baseUrl, "/api/discover");
assert.equal(result.status, 200);
assert.equal(result.json.personas[0].name, "Rainkeeper");
assert.equal(result.json.personas[0].description, "A guide to a rainy city");
assert.deepEqual(Object.keys(result.json.personas[0]).sort(), ["creator_username", "description", "id", "name", "persona_type"]);
assert.equal((await request(server.baseUrl, "/personas", {method: "POST", body: {name: "Rainkeeper"}, jar})).status, 404);
assert.equal((await request(server.baseUrl, "/api/discover", {jar})).status, 404);
} finally { await server.close(); }
});
@@ -1227,7 +1246,7 @@ test("page headers share navigation and keep session markup private", async () =
const username = '<maker&friend>';
await request(server.baseUrl, "/register", {method: "POST", body: {username, password: "password123"}, jar});
let sharedNavigation;
for (const route of ["/", "/app", "/app/chats/new", "/app/personas", "/market", "/app/settings", "/privacy.html", "/tos.html"]) {
for (const route of ["/", "/app", "/app/chats/new", "/app/personas", "/app/settings", "/privacy.html", "/tos.html"]) {
const response = await fetch(server.baseUrl + route, {headers: jar.headers()});
assert.equal(response.status, 200);
assert.equal(response.headers.get("cache-control"), "private, no-store");
@@ -1381,7 +1400,7 @@ test("browser sanitizer is served from the npm dependency without exposing node_
assert.ok((await fetch(server.baseUrl + "/node_modules/dompurify/package.json")).status >= 400);
});
test("persona corrections explicitly replace provisional SSE output before persisting the final answer", async t => {
test.skip("legacy character reply guards are retired", async t => {
let pass = 0;
const modelService = {
async streamReply(_model, _messages, onChunk, options) {