make some overall QoL improvements
This commit is contained in:
@@ -252,6 +252,48 @@ test("account export, logout-all, and deletion controls work", async () => {
|
||||
await server.close();
|
||||
});
|
||||
|
||||
test("username and password changes keep account data and sessions consistent", async t => {
|
||||
const server = await startTestServer();
|
||||
t.after(() => server.close());
|
||||
const jar = new CookieJar();
|
||||
const otherSession = new CookieJar();
|
||||
await request(server.baseUrl, "/register", {method: "POST", body: {username: "accountowner", password: "old-password"}});
|
||||
await request(server.baseUrl, "/register", {method: "POST", body: {username: "alreadytaken", password: "password123"}});
|
||||
assert.equal((await request(server.baseUrl, "/login", {method: "POST", body: {username: "accountowner", password: "old-password"}, jar})).status, 200);
|
||||
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);
|
||||
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 (?, ?, ?, ?, ?, ?, ?, ?)")
|
||||
.run(attachmentId, "accountowner", "picture.png", "rename-test-image", "image/png", 1, 1, 1);
|
||||
|
||||
assert.equal((await request(server.baseUrl, "/settings/username", {method: "PUT", body: {username: "newowner", password: "wrong"}, jar})).status, 403);
|
||||
assert.equal((await request(server.baseUrl, "/settings/username", {method: "PUT", body: {username: "alreadytaken", password: "old-password"}, jar})).status, 400);
|
||||
const renamed = await request(server.baseUrl, "/settings/username", {method: "PUT", body: {username: "newowner", password: "old-password"}, jar});
|
||||
assert.equal(renamed.status, 200);
|
||||
assert.equal(renamed.json.username, "newowner");
|
||||
assert.equal((await request(server.baseUrl, "/settings/profile", {jar})).json.username, "newowner");
|
||||
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"), []);
|
||||
|
||||
assert.equal((await request(server.baseUrl, "/login", {method: "POST", body: {username: "newowner", password: "old-password"}, jar: otherSession})).status, 200);
|
||||
assert.equal((await request(server.baseUrl, "/settings/password", {method: "PUT", body: {currentPassword: "wrong", newPassword: "new-password"}, jar})).status, 403);
|
||||
assert.equal((await request(server.baseUrl, "/settings/password", {method: "PUT", body: {currentPassword: "old-password", newPassword: "new-password"}, jar})).status, 200);
|
||||
assert.equal((await request(server.baseUrl, "/settings/profile", {jar})).status, 200);
|
||||
assert.equal((await request(server.baseUrl, "/session", {jar: otherSession})).json.user, null);
|
||||
assert.equal((await request(server.baseUrl, "/login", {method: "POST", body: {username: "newowner", password: "old-password"}})).status, 403);
|
||||
assert.equal((await request(server.baseUrl, "/login", {method: "POST", body: {username: "newowner", password: "new-password"}})).status, 200);
|
||||
assert.equal((await request(server.baseUrl, "/login", {method: "POST", body: {username: "accountowner", password: "new-password"}})).status, 400);
|
||||
assert.equal((await request(server.baseUrl, "/settings/export", {jar})).json.account.username, "newowner");
|
||||
});
|
||||
|
||||
test("admin diagnostics require admin and return model status", async () => {
|
||||
const server = await startTestServer({
|
||||
config: {
|
||||
@@ -772,9 +814,18 @@ test("chat search, organization, and workspace export work", async () => {
|
||||
jar
|
||||
});
|
||||
|
||||
await request(server.baseUrl, "/chat", {
|
||||
method: "POST",
|
||||
body: {chatId, message: "another keyword passage", model: "mistral:latest"},
|
||||
jar
|
||||
});
|
||||
|
||||
const search = await request(server.baseUrl, "/chats/search?q=keyword", {jar});
|
||||
assert.equal(search.status, 200);
|
||||
assert.equal(search.json.chats.length, 1);
|
||||
assert.equal(search.json.chats[0].matched_content, "another keyword passage");
|
||||
const messages = await request(server.baseUrl, `/chats/${chatId}/messages`, {jar});
|
||||
assert.equal(search.json.chats[0].matched_message_id, messages.json.messages.find(message => message.content === "another keyword passage").id);
|
||||
|
||||
const organize = await request(server.baseUrl, `/chats/${chatId}/organization`, {
|
||||
method: "PUT",
|
||||
|
||||
@@ -97,3 +97,32 @@ test("discarding a chat draft aborts upload, deletes temporary files, and serial
|
||||
composer.clear();
|
||||
assert.deepEqual(deletes, [`/attachments/${temporaryId}`], "Sent attachments are retained");
|
||||
});
|
||||
|
||||
test("attachments stay with their chat while uploads finish after switching", async t => {
|
||||
const originalDocument = globalThis.document, originalFetch = globalThis.fetch;
|
||||
t.after(() => { globalThis.document = originalDocument; globalThis.fetch = originalFetch; });
|
||||
const elements = Object.fromEntries(["attachImage", "imagePicker", "uploadPreviews", "composer"].map(id => [id, new Element()]));
|
||||
globalThis.document = {getElementById: id => elements[id], querySelector: () => elements.composer, createElement: () => new Element()};
|
||||
let completeUpload;
|
||||
const deletes = [];
|
||||
globalThis.fetch = (url) => {
|
||||
if (url === "/uploads/config") return Promise.resolve(Response.json({maxFiles: 5, maxSizeMb: 10}));
|
||||
if (url === "/uploads") return new Promise(resolve => { completeUpload = resolve; });
|
||||
deletes.push(url);
|
||||
return Promise.resolve(Response.json({success: true}));
|
||||
};
|
||||
const composer = createAttachmentComposer({onChange() {}, onError: message => assert.fail(message)});
|
||||
elements.imagePicker.files = [new File(["fixture"], "draft.png", {type: "image/png"})];
|
||||
elements.imagePicker.onchange();
|
||||
composer.saveDraft(1);
|
||||
composer.restoreDraft(2);
|
||||
assert.equal(composer.attachments.length, 0);
|
||||
const metadata = {id: "12345678-1234-1234-1234-123456789abc"};
|
||||
completeUpload(Response.json(metadata));
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
assert.deepEqual(deletes, []);
|
||||
composer.saveDraft(2);
|
||||
composer.restoreDraft(1);
|
||||
assert.deepEqual(composer.attachments, [metadata]);
|
||||
composer.discard();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user