UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

196 lines (158 loc) 5.91 kB
import { Alepha, z } from "alepha"; import type { SQL } from "drizzle-orm"; import type { PgColumn } from "drizzle-orm/pg-core"; import { boolean, integer, PgDialect, pgTable, text, } from "drizzle-orm/pg-core"; import { describe, expect, it } from "vitest"; import { QueryManager } from "../core/services/QueryManager.ts"; const dialect = new PgDialect(); const toSqlString = (sql: SQL) => dialect.sqlToQuery(sql).sql; const testTable = pgTable("test", { age: integer("age"), name: text("name"), active: boolean("active"), }); const testSchema = z.object({ age: z.number(), name: z.text(), active: z.boolean(), }); const col = (key: string) => (testTable as any)[key] as PgColumn; describe("QueryManager", () => { const alepha = Alepha.create(); const qm = alepha.inject(QueryManager); describe("parsePaginationSort", () => { it("should parse single ascending column", () => { const result = qm.parsePaginationSort("name"); expect(result).toEqual({ column: "name", direction: "asc" }); }); it("should parse single descending column", () => { const result = qm.parsePaginationSort("-createdAt"); expect(result).toEqual({ column: "createdAt", direction: "desc" }); }); it("should parse multiple columns", () => { const result = qm.parsePaginationSort("firstName,-lastName"); expect(result).toEqual([ { column: "firstName", direction: "asc" }, { column: "lastName", direction: "desc" }, ]); }); it("should handle whitespace around columns", () => { const result = qm.parsePaginationSort("name , -age"); expect(result).toEqual([ { column: "name", direction: "asc" }, { column: "age", direction: "desc" }, ]); }); it("should parse multiple ascending and descending columns", () => { const result = qm.parsePaginationSort("-priority,status,-createdAt"); expect(result).toEqual([ { column: "priority", direction: "desc" }, { column: "status", direction: "asc" }, { column: "createdAt", direction: "desc" }, ]); }); }); describe("normalizeOrderBy", () => { it("should normalize string to array", () => { const result = qm.normalizeOrderBy("name"); expect(result).toEqual([{ column: "name", direction: "asc" }]); }); it("should normalize object to array", () => { const result = qm.normalizeOrderBy({ column: "age", direction: "desc", }); expect(result).toEqual([{ column: "age", direction: "desc" }]); }); it("should default direction to asc for object mode", () => { const result = qm.normalizeOrderBy({ column: "name" }); expect(result).toEqual([{ column: "name", direction: "asc" }]); }); it("should normalize array with default directions", () => { const result = qm.normalizeOrderBy([ { column: "name" }, { column: "age", direction: "desc" }, ]); expect(result).toEqual([ { column: "name", direction: "asc" }, { column: "age", direction: "desc" }, ]); }); it("should return empty array for undefined", () => { expect(qm.normalizeOrderBy(undefined)).toEqual([]); }); it("should return empty array for non-object non-string non-array", () => { expect(qm.normalizeOrderBy(42)).toEqual([]); }); }); describe("toSQL", () => { const options = { schema: testSchema, col, dialect: "postgresql" as const, }; it("should produce a condition when filtering by zero", () => { const result = qm.toSQL({ age: 0 } as any, options); expect(result).toBeDefined(); }); it("should produce a condition when filtering by false", () => { const result = qm.toSQL({ active: false } as any, options); expect(result).toBeDefined(); }); it("should produce a condition when filtering by empty string", () => { const result = qm.toSQL({ name: "" } as any, options); expect(result).toBeDefined(); }); it("should produce a condition when filtering by string value", () => { const result = qm.toSQL({ name: "alice" } as any, options); expect(result).toBeDefined(); }); it("should produce a condition when filtering with eq operator on zero", () => { const result = qm.toSQL({ age: { eq: 0 } } as any, options); expect(result).toBeDefined(); }); it("should return undefined for null values", () => { const result = qm.toSQL({ age: null } as any, options); expect(result).toBeUndefined(); }); it("should return undefined for undefined values", () => { const result = qm.toSQL({ age: undefined } as any, options); expect(result).toBeUndefined(); }); it("should include not condition alongside sibling conditions", () => { const result = qm.toSQL( { name: "John", not: { active: false } } as any, options, ); expect(result).toBeDefined(); const sqlStr = toSqlString(result!); expect(sqlStr).toContain('"name"'); expect(sqlStr).toContain("not"); expect(sqlStr).toContain('"active"'); }); it("should not discard conditions after not", () => { const result = qm.toSQL( { not: { active: false }, name: "Alice", age: { eq: 30 } } as any, options, ); expect(result).toBeDefined(); const sqlStr = toSqlString(result!); expect(sqlStr).toContain('"name"'); expect(sqlStr).toContain('"age"'); expect(sqlStr).toContain("not"); }); it("should handle not as the only condition", () => { const result = qm.toSQL({ not: { active: true } } as any, options); expect(result).toBeDefined(); const sqlStr = toSqlString(result!); expect(sqlStr).toContain("not"); expect(sqlStr).toContain('"active"'); }); }); });