feat: Add soft remove and recover methods to entity (#5854) · typeorm/typeorm@9d2b8e0

1+

import "reflect-metadata";

2+

import {expect} from "chai";

3+

import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../../utils/test-utils";

4+

import {Connection} from "../../../../src/connection/Connection";

5+

import {Post} from "./entity/Post";

6+

import { PostWithoutDeleteDateColumn } from "./entity/PostWithoutDeleteDateColumn";

7+

import { MissingDeleteDateColumnError } from "../../../../src/error/MissingDeleteDateColumnError";

8+

import { PromiseUtils } from "../../../../src";

9+10+

describe("entity > soft-remove", () => {

11+12+

let connections: Connection[];

13+

before(async () => connections = await createTestingConnections({

14+

entities: [__dirname + "/entity/*{.js,.ts}"],

15+

}));

16+

beforeEach(() => reloadTestingDatabases(connections));

17+

after(() => closeTestingConnections(connections));

18+19+

it("should perform soft removal and recovery correctly", () => PromiseUtils.runInSequence(connections, async connection => {

20+

Post.useConnection(connection); // change connection each time because of AR specifics

21+22+

const postRepository = connection.getRepository(Post);

23+24+

// save a new posts

25+

const newPost1 = postRepository.create({

26+

id: 1,

27+

name: "post#1"

28+

});

29+

const newPost2 = postRepository.create({

30+

id: 2,

31+

name: "post#2"

32+

});

33+34+

await postRepository.save(newPost1);

35+

await postRepository.save(newPost2);

36+37+

// soft-remove one

38+

await newPost1.softRemove();

39+40+

// load to check

41+

const loadedPosts = await postRepository.find({ withDeleted: true });

42+43+

// assert

44+

loadedPosts.length.should.be.equal(2);

45+46+

const loadedPost1 = loadedPosts.find(p => p.id === 1);

47+

expect(loadedPost1).to.exist;

48+

expect(loadedPost1!.deletedAt).to.be.instanceof(Date);

49+

expect(loadedPost1!.name).to.equals("post#1");

50+

const loadedPost2 = loadedPosts.find(p => p.id === 2);

51+

expect(loadedPost2).to.exist;

52+

expect(loadedPost2!.deletedAt).to.equals(null);

53+

expect(loadedPost2!.name).to.equals("post#2");

54+55+

// recover one

56+

await loadedPost1!.recover();

57+

// load to check

58+

const recoveredPosts = await postRepository.find({ withDeleted: true });

59+60+

// assert

61+

recoveredPosts.length.should.be.equal(2);

62+63+

const recoveredPost1 = recoveredPosts.find(p => p.id === 1);

64+

expect(recoveredPost1).to.exist;

65+

expect(recoveredPost1!.deletedAt).to.equals(null);

66+

expect(recoveredPost1!.name).to.equals("post#1");

67+

const recoveredPost2 = recoveredPosts.find(p => p.id === 2);

68+

expect(recoveredPost2).to.exist;

69+

expect(recoveredPost2!.deletedAt).to.equals(null);

70+

expect(recoveredPost2!.name).to.equals("post#2");

71+72+

}));

73+74+

it("should throw error when delete date column is missing", () => PromiseUtils.runInSequence(connections, async connection => {

75+

PostWithoutDeleteDateColumn.useConnection(connection); // change connection each time because of AR specifics

76+77+

const postRepository = connection.getRepository(PostWithoutDeleteDateColumn);

78+79+

// save a new posts

80+

const newPost1 = postRepository.create({

81+

id: 1,

82+

name: "post#1"

83+

});

84+85+

await postRepository.save(newPost1);

86+87+

let error1: Error | undefined;

88+

try {

89+

// soft-remove one

90+

await newPost1.softRemove();

91+

} catch (err) {

92+

error1 = err;

93+

}

94+

expect(error1).to.be.an.instanceof(MissingDeleteDateColumnError);

95+96+

let error2: Error | undefined;

97+

try {

98+

// recover one

99+

await newPost1.recover();

100+

} catch (err) {

101+

error2 = err;

102+

}

103+

expect(error2).to.be.an.instanceof(MissingDeleteDateColumnError);

104+105+

}));

106+

});