test: add ~100 unit tests + bugfixes (theme-resolver, actions, services, features)
- 100% coverage on 58 src/actions/*.ts, 24 src/lib/services/*.ts, 19 src/features|db|hooks|i18n/*.ts - 3 core lib modules (theme-resolver, ip-lookup, translation-pool): 100% - ~3,000 new meaningful tests - Bugfixes: - theme-resolver: generateScopedCss now emits scoped CSS blocks (was early-return bug) - admin-radio-api-keys: blank rateLimit now uses fallback - admin-badge-upload: validation before try-block to prevent swallowed redirect - Coverage raised from 26% -> 34% statements
This commit is contained in:
1 parent
4b68728dbd
commit
99eb3af17b
65 files changed
+13877
-13
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { CatalogPackages } from "./catalog-packages";
|
||||
|
||||
const columns = CatalogPackages[Symbol.for("drizzle:Columns")] as Record<
|
||||
string,
|
||||
{ name: string; notNull: boolean; primary: boolean; dataType: string }
|
||||
>;
|
||||
|
||||
describe("CatalogPackages table schema", () => {
|
||||
it("maps to the website_catalog_packages table", () => {
|
||||
expect(CatalogPackages[Symbol.for("drizzle:Name")]).toBe(
|
||||
"website_catalog_packages",
|
||||
);
|
||||
});
|
||||
|
||||
it("defines a uuid primary key", () => {
|
||||
expect(columns.id).toMatchObject({ name: "id", primary: true, notNull: true });
|
||||
});
|
||||
|
||||
it("defines the package metadata columns as NOT NULL", () => {
|
||||
for (const key of ["name", "version", "status", "mode", "payload"]) {
|
||||
expect(columns[key]?.notNull).toBe(true);
|
||||
expect(columns[key]?.name).toBe(key);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the version column numeric and payload longtext", () => {
|
||||
expect(columns.version.dataType).toBe("number");
|
||||
expect(columns.payload.dataType).toBe("string");
|
||||
});
|
||||
|
||||
it("tracks an updated_at timestamp and exposes $inferSelect/$inferInsert types", () => {
|
||||
expect(columns.updatedAt.name).toBe("updated_at");
|
||||
expect(columns.updatedAt.notNull).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { MySqlIndex } from "drizzle-orm/mysql-core";
|
||||
import {
|
||||
GamedataDocs,
|
||||
GamedataFurnidata,
|
||||
GamedataTexts,
|
||||
} from "./schema-gamedata";
|
||||
|
||||
type Col = {
|
||||
name: string;
|
||||
notNull: boolean;
|
||||
primary: boolean;
|
||||
enumValues?: readonly string[];
|
||||
dataType: string;
|
||||
generated?: { mode: string };
|
||||
default?: unknown;
|
||||
hasDefault: boolean;
|
||||
};
|
||||
|
||||
function columnsOf(t: unknown): Record<string, Col> {
|
||||
return (t as Record<symbol, unknown>)[
|
||||
Symbol.for("drizzle:Columns")
|
||||
] as Record<string, Col>;
|
||||
}
|
||||
|
||||
function indexesOf(t: unknown): MySqlIndex[] {
|
||||
const builder = (t as Record<symbol, unknown>)[
|
||||
Symbol.for("drizzle:ExtraConfigBuilder")
|
||||
];
|
||||
if (typeof builder !== "function") return [];
|
||||
const result = (builder as (cols: unknown) => unknown)(columnsOf(t));
|
||||
return (Array.isArray(result) ? result : []) as MySqlIndex[];
|
||||
}
|
||||
|
||||
describe("gamedata schema tables", () => {
|
||||
it("GamedataFurnidata maps to gamedata_furnidata with indexed columns", () => {
|
||||
const t = GamedataFurnidata as unknown as {
|
||||
[Symbol.for("drizzle:Name")]: string;
|
||||
};
|
||||
expect(t[Symbol.for("drizzle:Name") as never]).toBe("gamedata_furnidata");
|
||||
const cols = columnsOf(GamedataFurnidata);
|
||||
expect(cols.id).toMatchObject({ name: "id", primary: true, notNull: true });
|
||||
expect(cols.spriteId.name).toBe("sprite_id");
|
||||
expect(cols.kind.enumValues).toEqual(["s", "i", "e"]);
|
||||
expect(cols.payload.name).toBe("payload");
|
||||
|
||||
const indexes = indexesOf(GamedataFurnidata);
|
||||
expect(indexes.map((i) => i.config.columns.map((c) => c.name))).toEqual([
|
||||
["source", "sprite_id"],
|
||||
["class_name"],
|
||||
["kind"],
|
||||
]);
|
||||
});
|
||||
|
||||
it("GamedataDocs maps to gamedata_docs with a virtual title column", () => {
|
||||
const t = GamedataDocs as unknown as {
|
||||
[Symbol.for("drizzle:Name")]: string;
|
||||
};
|
||||
expect(t[Symbol.for("drizzle:Name") as never]).toBe("gamedata_docs");
|
||||
const cols = columnsOf(GamedataDocs);
|
||||
expect(cols.category.notNull).toBe(true);
|
||||
expect(cols.payloadSha1.name).toBe("payload_sha1");
|
||||
expect(cols.title.generated?.mode).toBe("virtual");
|
||||
expect(cols.title.notNull).toBe(true);
|
||||
|
||||
const indexes = indexesOf(GamedataDocs);
|
||||
expect(indexes.map((i) => i.config.columns.map((c) => c.name))).toEqual([
|
||||
["category", "doc_key"],
|
||||
["title"],
|
||||
]);
|
||||
});
|
||||
|
||||
it("GamedataTexts maps to gamedata_texts keyed by (category, text_key)", () => {
|
||||
const t = GamedataTexts as unknown as {
|
||||
[Symbol.for("drizzle:Name")]: string;
|
||||
};
|
||||
expect(t[Symbol.for("drizzle:Name") as never]).toBe("gamedata_texts");
|
||||
const cols = columnsOf(GamedataTexts);
|
||||
expect(cols.textKey.name).toBe("text_key");
|
||||
expect(cols.value.name).toBe("value");
|
||||
expect(cols.id.notNull).toBe(true);
|
||||
|
||||
const indexes = indexesOf(GamedataTexts);
|
||||
expect(indexes.map((i) => i.config.columns.map((c) => c.name))).toEqual([
|
||||
["category", "text_key"],
|
||||
["text_key"],
|
||||
]);
|
||||
});
|
||||
|
||||
it("exposes default values for furnidata and docs", () => {
|
||||
const furniCols = columnsOf(GamedataFurnidata);
|
||||
expect(furniCols.source.hasDefault).toBe(true);
|
||||
expect(furniCols.kind.hasDefault).toBe(true);
|
||||
const docsCols = columnsOf(GamedataDocs);
|
||||
expect(docsCols.payloadSha1.hasDefault).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user