import { afterAll, describe, expect, test } from "bun:test"; import { Entity, EntityManager } from "data/entities"; import { ManyToManyRelation, ManyToOneRelation } from "data/relations"; import { SchemaManager } from "data/schema/SchemaManager"; import { UnableToConnectException } from "data/errors"; import { getDummyConnection } from "../helper"; const { dummyConnection, afterAllCleanup } = getDummyConnection(); afterAll(afterAllCleanup); describe("[data] EntityManager", async () => { test("base empty throw", async () => { // @ts-expect-error - testing invalid input, connection is required expect(() => new EntityManager([], {})).toThrow(UnableToConnectException); }); test("base w/o entities & relations", async () => { const em = new EntityManager([], dummyConnection); expect(em.entities).toEqual([]); expect(em.relations.all).toEqual([]); expect(await em.ping()).toBe(true); expect(() => em.entity("...")).toThrow(); expect(() => em.addRelation(new ManyToOneRelation(new Entity("1"), new Entity("2"))), ).toThrow(); expect(em.schema()).toBeInstanceOf(SchemaManager); // the rest will all throw, since they depend on em.entity() }); test("w/ 2 entities but no initial relations", async () => { const users = new Entity("users"); const posts = new Entity("posts"); const em = new EntityManager([users, posts], dummyConnection); expect(em.entities).toEqual([users, posts]); expect(em.relations.all).toEqual([]); expect(em.entity("users")).toBe(users); expect(em.entity("posts")).toBe(posts); // expect adding relation to pass em.addRelation(new ManyToOneRelation(posts, users)); expect(em.relations.all.length).toBe(1); expect(em.relations.all[0]).toBeInstanceOf(ManyToOneRelation); expect(em.relationsOf("users")).toEqual([em.relations.all[0]!]); expect(em.relationsOf("posts")).toEqual([em.relations.all[0]!]); expect(em.hasRelations("users")).toBe(true); expect(em.hasRelations("posts")).toBe(true); expect(em.relatedEntitiesOf("users")).toEqual([posts]); expect(em.relatedEntitiesOf("posts")).toEqual([users]); expect(em.relationReferencesOf("users")).toEqual(["posts"]); expect(em.relationReferencesOf("posts")).toEqual(["users"]); }); test("test target relations", async () => { const users = new Entity("users"); const posts = new Entity("posts"); const comments = new Entity("comments"); const categories = new Entity("categories"); const em = new EntityManager([users, posts, comments, categories], dummyConnection); em.addRelation(new ManyToOneRelation(posts, users)); em.addRelation(new ManyToOneRelation(comments, users)); em.addRelation(new ManyToOneRelation(comments, posts)); em.addRelation(new ManyToManyRelation(posts, categories)); const userTargetRel = em.relations.targetRelationsOf(users); const postTargetRel = em.relations.targetRelationsOf(posts); const commentTargetRel = em.relations.targetRelationsOf(comments); expect(userTargetRel.map((r) => r.source.entity.name)).toEqual(["posts", "comments"]); expect(postTargetRel.map((r) => r.source.entity.name)).toEqual(["comments"]); expect(commentTargetRel.map((r) => r.source.entity.name)).toEqual([]); }); test("test listable relations", async () => { const users = new Entity("users"); const posts = new Entity("posts"); const comments = new Entity("comments"); const categories = new Entity("categories"); const em = new EntityManager([users, posts, comments, categories], dummyConnection); em.addRelation(new ManyToOneRelation(posts, users)); em.addRelation(new ManyToOneRelation(comments, users)); em.addRelation(new ManyToOneRelation(comments, posts)); em.addRelation(new ManyToManyRelation(posts, categories)); const userTargetRel = em.relations.listableRelationsOf(users); const postTargetRel = em.relations.listableRelationsOf(posts); const commentTargetRel = em.relations.listableRelationsOf(comments); const categoriesTargetRel = em.relations.listableRelationsOf(categories); expect(userTargetRel.map((r) => r.other(users).entity.name)).toEqual(["posts", "comments"]); expect(postTargetRel.map((r) => r.other(posts).entity.name)).toEqual([ "comments", "categories", ]); expect(commentTargetRel.map((r) => r.other(comments).entity.name)).toEqual([]); expect(categoriesTargetRel.map((r) => r.other(categories).entity.name)).toEqual(["posts"]); }); });