* Mark the fixture admin as primary admin in the account tests
Creating accounts needs a primary admin or an admin with user management rights since migration 0050, but the fixture inserted its admin without is_primary_admin, so every create call got a 403.
* Let the agent tool test call mutating tools without chat approval
In chat, mark_email_read, move_email and discard_draft now return pending_approval instead of acting. The test still expected the change to happen right away. It now checks that chat only asks, and runs the direct calls with the mcp origin.
* Test the migrated schema instead of the removed bootstrap SQL
The old test read MIGRATION_NAMES and INITIAL_SCHEMA_SQL out of src/lib/setup/migration.ts, which now just runs the migration files. The replacement applies drizzle/migrations to an empty database, checks that every file is recorded and not re-applied, and keeps the mailbox, license and spam table checks.
* Expect the shortened pt-BR inbox label in the i18n tests
6978c01 changed navigation.inbox from "Caixa de entrada" to "Entrada" in pt-BR, but four tests still expected the old label.
---------
Co-authored-by: Can Kirca <9063990+cankirca@users.noreply.github.com>
67 lines
3.3 KiB
JavaScript
67 lines
3.3 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { mkdtempSync, readdirSync, rmSync } from "node:fs";
|
|
import { dirname, join } from "node:path";
|
|
import test, { after } from "node:test";
|
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
import { build } from "esbuild";
|
|
|
|
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
const migrationsDirectory = join(root, "drizzle/migrations");
|
|
const bundleDirectory = mkdtempSync(join(root, "node_modules", "mailflare-bootstrap-bundle-"));
|
|
after(() => rmSync(bundleDirectory, { recursive: true, force: true }));
|
|
|
|
await build({
|
|
stdin: {
|
|
contents: `
|
|
export { SqliteDatabase } from "./server/runtime/sqlite-database.ts";
|
|
export { applyMigrations } from "./server/runtime/migrate.ts";
|
|
`,
|
|
resolveDir: root,
|
|
sourcefile: "bootstrap-schema-test-entry.ts",
|
|
},
|
|
outfile: join(bundleDirectory, "entry.mjs"),
|
|
bundle: true,
|
|
platform: "node",
|
|
format: "esm",
|
|
target: "node24",
|
|
tsconfig: join(root, "tsconfig.json"),
|
|
packages: "external",
|
|
logLevel: "silent",
|
|
});
|
|
const { SqliteDatabase, applyMigrations } = await import(pathToFileURL(join(bundleDirectory, "entry.mjs")).href);
|
|
|
|
const columns = (database, table) => database.db.prepare(`PRAGMA table_info(${table})`).all().map((column) => column.name);
|
|
|
|
test("a fresh database records every migration, so later deploys do not re-apply them", async (t) => {
|
|
const database = new SqliteDatabase(":memory:");
|
|
t.after(() => database.db.close());
|
|
const files = readdirSync(migrationsDirectory).filter((name) => name.endsWith(".sql"));
|
|
const applied = await applyMigrations(database, migrationsDirectory);
|
|
assert.deepEqual([...applied].sort(), [...files].sort());
|
|
const recorded = database.db.prepare("SELECT name FROM d1_migrations").all().map((row) => row.name);
|
|
assert.deepEqual(recorded.sort(), [...files].sort());
|
|
assert.deepEqual(await applyMigrations(database, migrationsDirectory), []);
|
|
});
|
|
|
|
test("fresh schema accepts the current Drizzle mailbox and license inserts", async (t) => {
|
|
const database = new SqliteDatabase(":memory:");
|
|
t.after(() => database.db.close());
|
|
await applyMigrations(database, migrationsDirectory);
|
|
const db = database.db;
|
|
|
|
assert.ok(["signature", "auto_reply_enabled", "auto_reply_subject", "auto_reply_body"].every((name) => columns(database, "mailboxes").includes(name)));
|
|
assert.ok(columns(database, "domains").includes("sending_requested"));
|
|
for (const table of ["license_settings", "auto_reply_deliveries", "spam_token_stats", "spam_reputation", "spam_feedback"]) {
|
|
assert.ok(db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(table), `${table} is missing`);
|
|
}
|
|
|
|
db.prepare("INSERT INTO users (id, email, password_hash, name, created_at) VALUES ('u', 'a@b.c', 'x', 'n', 1)").run();
|
|
db.prepare("INSERT INTO domains (id, user_id, hostname, zone_id, created_at) VALUES ('d', 'u', 'ex.com', 'z', 1)").run();
|
|
db.prepare(`
|
|
INSERT INTO mailboxes (id, user_id, domain_id, local_part, display_name, signature, auto_reply_enabled, auto_reply_subject, auto_reply_body, created_at)
|
|
VALUES ('m', 'u', 'd', 'admin', 'admin', 'sig', 0, 'Out of office', '', 1)
|
|
`).run();
|
|
db.prepare("INSERT INTO license_settings (id, instance_id, updated_at) VALUES ('default', 'inst', 1)").run();
|
|
assert.equal(db.prepare("SELECT count(*) AS count FROM mailboxes").get().count, 1);
|
|
});
|