mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
test: issue #11269
This commit is contained in:
parent
50a660aecc
commit
759cf7cf54
@ -1,15 +1,17 @@
|
||||
import "reflect-metadata"
|
||||
import { expect } from "chai"
|
||||
|
||||
import { DataSource } from "../../../src/data-source/DataSource"
|
||||
import {
|
||||
closeTestingConnections,
|
||||
createTestingConnections,
|
||||
reloadTestingDatabases,
|
||||
} from "../../utils/test-utils"
|
||||
import { DataSource } from "../../../src/data-source/DataSource"
|
||||
|
||||
import { Company } from "./entity/Company"
|
||||
import { Office } from "./entity/Office"
|
||||
import { expect } from "chai"
|
||||
|
||||
describe("deferrable uq constraints should be check at the end of transaction", () => {
|
||||
describe("deferrable unique constraint", () => {
|
||||
let connections: DataSource[]
|
||||
before(
|
||||
async () =>
|
||||
@ -21,7 +23,7 @@ describe("deferrable uq constraints should be check at the end of transaction",
|
||||
beforeEach(() => reloadTestingDatabases(connections))
|
||||
after(() => closeTestingConnections(connections))
|
||||
|
||||
it("use initially deferred deferrable uq constraints", () =>
|
||||
it("initially deferred unique should be validated at the end of transaction", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
await connection.manager.transaction(async (entityManager) => {
|
||||
@ -63,7 +65,7 @@ describe("deferrable uq constraints should be check at the end of transaction",
|
||||
}),
|
||||
))
|
||||
|
||||
it("use initially immediated deferrable uq constraints", () =>
|
||||
it("initially immediate unique should be validated at the end at transaction with deferred check time", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
await connection.manager.transaction(async (entityManager) => {
|
||||
|
||||
@ -1,28 +1,30 @@
|
||||
import "reflect-metadata"
|
||||
import { expect } from "chai"
|
||||
|
||||
import { DataSource } from "../../../src/data-source/DataSource"
|
||||
import {
|
||||
closeTestingConnections,
|
||||
createTestingConnections,
|
||||
reloadTestingDatabases,
|
||||
} from "../../utils/test-utils"
|
||||
import { DataSource } from "../../../src/data-source/DataSource"
|
||||
|
||||
import { Company } from "./entity/Company"
|
||||
import { Office } from "./entity/Office"
|
||||
import { User } from "./entity/User"
|
||||
import { expect } from "chai"
|
||||
|
||||
describe("deferrable fk constraints should be check at the end of transaction (#2191)", () => {
|
||||
describe("deferrable foreign key constraint", () => {
|
||||
let connections: DataSource[]
|
||||
before(
|
||||
async () =>
|
||||
(connections = await createTestingConnections({
|
||||
entities: [__dirname + "/entity/*{.js,.ts}"],
|
||||
enabledDrivers: ["postgres"],
|
||||
enabledDrivers: ["better-sqlite3", "postgres", "sap", "sqlite"],
|
||||
})),
|
||||
)
|
||||
beforeEach(() => reloadTestingDatabases(connections))
|
||||
after(() => closeTestingConnections(connections))
|
||||
|
||||
it("use initially deferred deferrable fk constraints", () =>
|
||||
it("initially deferred fk should be validated at the end of transaction", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
await connection.manager.transaction(async (entityManager) => {
|
||||
@ -40,7 +42,7 @@ describe("deferrable fk constraints should be check at the end of transaction (#
|
||||
company.name = "Acme"
|
||||
|
||||
await entityManager.save(company)
|
||||
})
|
||||
}).should.not.be.rejected
|
||||
|
||||
// now check
|
||||
const user = await connection.manager.findOne(User, {
|
||||
@ -48,9 +50,7 @@ describe("deferrable fk constraints should be check at the end of transaction (#
|
||||
where: { id: 1 },
|
||||
})
|
||||
|
||||
expect(user).not.to.be.null
|
||||
|
||||
user!.should.be.eql({
|
||||
expect(user).to.deep.equal({
|
||||
id: 1,
|
||||
name: "Bob",
|
||||
company: {
|
||||
@ -61,9 +61,12 @@ describe("deferrable fk constraints should be check at the end of transaction (#
|
||||
}),
|
||||
))
|
||||
|
||||
it("use initially immediated deferrable fk constraints", () =>
|
||||
it("initially immediate fk should be validated at the end at transaction with deferred check time", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
// changing the constraint check time is only supported on postgres
|
||||
if (connection.driver.options.type !== "postgres") return
|
||||
|
||||
await connection.manager.transaction(async (entityManager) => {
|
||||
// first set constraints deferred manually
|
||||
await entityManager.query("SET CONSTRAINTS ALL DEFERRED")
|
||||
@ -82,7 +85,7 @@ describe("deferrable fk constraints should be check at the end of transaction (#
|
||||
company.name = "Emca"
|
||||
|
||||
await entityManager.save(company)
|
||||
})
|
||||
}).should.not.be.rejected
|
||||
|
||||
// now check
|
||||
const office = await connection.manager.findOne(Office, {
|
||||
@ -90,9 +93,7 @@ describe("deferrable fk constraints should be check at the end of transaction (#
|
||||
where: { id: 2 },
|
||||
})
|
||||
|
||||
expect(office).not.to.be.null
|
||||
|
||||
office!.should.be.eql({
|
||||
expect(office).to.deep.equal({
|
||||
id: 2,
|
||||
name: "Barcelona",
|
||||
company: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { Column } from "../../../../src/decorator/columns/Column"
|
||||
import { PrimaryColumn } from "../../../../src/decorator/columns/PrimaryColumn"
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { Unique } from "../../../../src/decorator/Unique"
|
||||
|
||||
@Entity()
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { Column } from "../../../../src/decorator/columns/Column"
|
||||
import { ManyToOne } from "../../../../src/decorator/relations/ManyToOne"
|
||||
import { PrimaryColumn } from "../../../../src/decorator/columns/PrimaryColumn"
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { ManyToOne } from "../../../../src/decorator/relations/ManyToOne"
|
||||
import { Unique } from "../../../../src/decorator/Unique"
|
||||
|
||||
import { Company } from "./Company"
|
||||
|
||||
@Entity()
|
||||
@ -14,8 +15,6 @@ export class Office {
|
||||
@Column()
|
||||
name: string
|
||||
|
||||
@ManyToOne((type) => Company, (company) => company.id, {
|
||||
deferrable: "INITIALLY IMMEDIATE",
|
||||
})
|
||||
@ManyToOne(() => Company, { deferrable: "INITIALLY IMMEDIATE" })
|
||||
company: Company
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { Column } from "../../../../src/decorator/columns/Column"
|
||||
import { ManyToOne } from "../../../../src/decorator/relations/ManyToOne"
|
||||
import { PrimaryColumn } from "../../../../src/decorator/columns/PrimaryColumn"
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { ManyToOne } from "../../../../src/decorator/relations/ManyToOne"
|
||||
|
||||
import { Company } from "./Company"
|
||||
|
||||
@Entity()
|
||||
@ -12,8 +13,6 @@ export class User {
|
||||
@Column()
|
||||
name: string
|
||||
|
||||
@ManyToOne((type) => Company, (company) => company.id, {
|
||||
deferrable: "INITIALLY DEFERRED",
|
||||
})
|
||||
@ManyToOne(() => Company, { deferrable: "INITIALLY DEFERRED" })
|
||||
company: Company
|
||||
}
|
||||
|
||||
14
test/github-issues/11260/entity/Company.ts
Normal file
14
test/github-issues/11260/entity/Company.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Column } from "../../../../src/decorator/columns/Column"
|
||||
import { PrimaryColumn } from "../../../../src/decorator/columns/PrimaryColumn"
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { Unique } from "../../../../src/decorator/Unique"
|
||||
|
||||
@Entity()
|
||||
@Unique(["name"], { deferrable: "INITIALLY DEFERRED" })
|
||||
export class Company {
|
||||
@PrimaryColumn()
|
||||
id: number
|
||||
|
||||
@Column()
|
||||
name?: string
|
||||
}
|
||||
18
test/github-issues/11260/entity/User.ts
Normal file
18
test/github-issues/11260/entity/User.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Column } from "../../../../src/decorator/columns/Column"
|
||||
import { PrimaryColumn } from "../../../../src/decorator/columns/PrimaryColumn"
|
||||
import { Entity } from "../../../../src/decorator/entity/Entity"
|
||||
import { ManyToOne } from "../../../../src/decorator/relations/ManyToOne"
|
||||
|
||||
import { Company } from "./Company"
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
@PrimaryColumn()
|
||||
id: number
|
||||
|
||||
@Column()
|
||||
name: string
|
||||
|
||||
@ManyToOne(() => Company, { deferrable: "INITIALLY DEFERRED" })
|
||||
company: Company
|
||||
}
|
||||
93
test/github-issues/11260/issue-11260.ts
Normal file
93
test/github-issues/11260/issue-11260.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import "reflect-metadata"
|
||||
import { expect } from "chai"
|
||||
|
||||
import { DataSource } from "../../../src/data-source/DataSource"
|
||||
import {
|
||||
closeTestingConnections,
|
||||
createTestingConnections,
|
||||
reloadTestingDatabases,
|
||||
} from "../../utils/test-utils"
|
||||
|
||||
import { EntityManager } from "../../../src"
|
||||
import { BaseQueryRunner } from "../../../src/query-runner/BaseQueryRunner"
|
||||
import { Company } from "./entity/Company"
|
||||
import { User } from "./entity/User"
|
||||
|
||||
describe("github issues > #10626 Regression in transactionDepth handling", () => {
|
||||
let connections: DataSource[]
|
||||
before(
|
||||
async () =>
|
||||
(connections = await createTestingConnections({
|
||||
entities: [__dirname + "/entity/*{.js,.ts}"],
|
||||
enabledDrivers: ["better-sqlite3", "postgres", "sqlite"],
|
||||
})),
|
||||
)
|
||||
beforeEach(() => reloadTestingDatabases(connections))
|
||||
after(() => closeTestingConnections(connections))
|
||||
|
||||
it("transactionDepth should be updated correctly when commit fails", () =>
|
||||
Promise.all(
|
||||
connections.map(async (connection) => {
|
||||
const queryRunner = connection.createQueryRunner()
|
||||
const transactionDepths: Record<string, number> = {}
|
||||
const recordDepth = (mark: string) => {
|
||||
transactionDepths[mark] = (
|
||||
queryRunner as unknown as BaseQueryRunner
|
||||
)["transactionDepth"]
|
||||
}
|
||||
|
||||
recordDepth("initial")
|
||||
|
||||
await queryRunner.startTransaction()
|
||||
recordDepth("startTransaction")
|
||||
|
||||
const runInTransaction = async (
|
||||
entityManager: EntityManager,
|
||||
) => {
|
||||
// first save user
|
||||
const user = new User()
|
||||
user.id = 1
|
||||
user.company = { id: 100 }
|
||||
user.name = "Bob"
|
||||
|
||||
await entityManager.save(user)
|
||||
|
||||
// then save company
|
||||
const company = new Company()
|
||||
company.id = 200
|
||||
company.name = "Acme"
|
||||
|
||||
await entityManager.save(company)
|
||||
}
|
||||
await runInTransaction(queryRunner.manager).should.not.rejected
|
||||
recordDepth("afterStatements")
|
||||
|
||||
await queryRunner.commitTransaction().should.be.rejected
|
||||
recordDepth("afterCommit")
|
||||
|
||||
await queryRunner.rollbackTransaction().should.not.be.rejected
|
||||
recordDepth("afterRollback")
|
||||
|
||||
await queryRunner.release()
|
||||
recordDepth("afterRelease")
|
||||
|
||||
expect(transactionDepths).to.deep.equal({
|
||||
initial: 0,
|
||||
startTransaction: 1,
|
||||
afterStatements: 1,
|
||||
afterCommit: 1,
|
||||
afterRollback: 0,
|
||||
afterRelease: 0,
|
||||
})
|
||||
|
||||
// check data
|
||||
const user = await connection.manager.findOneBy(User, { id: 1 })
|
||||
expect(user).to.equal(null)
|
||||
|
||||
const company = await connection.manager.findOneBy(Company, {
|
||||
id: 200,
|
||||
})
|
||||
expect(company).to.equal(null)
|
||||
}),
|
||||
))
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user