import { expect } from "chai" import "reflect-metadata" import { DataSource } from "../../../src" import { closeTestingConnections, createTestingConnections, } from "../../utils/test-utils" import { User } from "./entity/User" import { Setting } from "./entity/Setting" import { SettingSubscriber } from "./entity/SettingSubscriber" /** * Using OneToMany relation with composed primary key should not error and work correctly */ describe("github issues > #8221", () => { let connections: DataSource[] before( async () => (connections = await createTestingConnections({ entities: [User, Setting], subscribers: [SettingSubscriber], schemaCreate: true, dropSchema: true, })), ) after(() => closeTestingConnections(connections)) function insertSimpleTestData(connection: DataSource) { const userRepo = connection.getRepository(User) // const settingRepo = connection.getRepository(Setting); const user = new User(1, "FooGuy") const settingA = new Setting(1, "A", "foo") const settingB = new Setting(1, "B", "bar") user.settings = [settingA, settingB] return userRepo.save(user) } // important: must not use Promise.all! parallel execution against different drivers would mess up the counter within the SettingSubscriber! it("afterLoad entity modifier must not make relation key matching fail", async () => { for (const connection of connections) { const userRepo = connection.getRepository(User) const subscriber = connection.subscribers.find( (s) => s instanceof SettingSubscriber, ) as SettingSubscriber if (!subscriber) throw new Error(`Subscriber not found`) subscriber.reset() await insertSimpleTestData(connection) subscriber.reset() await userRepo.save([ { id: 1, settings: [ { assertId: 1, name: "A", value: "foobar" }, { assertId: 1, name: "B", value: "testvalue" }, ], }, ]) // we use a subscriber to count generated Subjects based on how often beforeInsert/beforeRemove/beforeUpdate has been called. // the save query should only update settings, so only beforeUpdate should have been called. // if beforeInsert/beforeUpdate has been called, this would indicate that key matching has failed. // the resulting state would be the same, but settings entities would be deleted and inserted instead. expect(subscriber.counter.deletes).to.equal(0) expect(subscriber.counter.inserts).to.equal(0) expect(subscriber.counter.updates).to.equal(2) } }) })