@volontariapp/domain-post 2.2.2-snap-8a230de → 2.2.2-snap-cb5b3b4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entities/index.d.ts +2 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +2 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/entities/post.entity.d.ts +9 -0
- package/dist/entities/post.entity.d.ts.map +1 -0
- package/dist/entities/post.entity.js +9 -0
- package/dist/entities/post.entity.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +3 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/mapper.d.ts +2 -0
- package/dist/models/mapper.d.ts.map +1 -0
- package/dist/models/mapper.js +7 -0
- package/dist/models/mapper.js.map +1 -0
- package/dist/models/post.model.d.ts +9 -0
- package/dist/models/post.model.d.ts.map +1 -0
- package/dist/models/post.model.js +47 -0
- package/dist/models/post.model.js.map +1 -0
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +3 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/interfaces/index.d.ts +2 -0
- package/dist/repositories/interfaces/index.d.ts.map +1 -0
- package/dist/repositories/interfaces/index.js +2 -0
- package/dist/repositories/interfaces/index.js.map +1 -0
- package/dist/repositories/interfaces/post.repository.d.ts +12 -0
- package/dist/repositories/interfaces/post.repository.d.ts.map +1 -0
- package/dist/repositories/interfaces/post.repository.js +2 -0
- package/dist/repositories/interfaces/post.repository.js.map +1 -0
- package/dist/repositories/postgres-post.repository.d.ts +14 -0
- package/dist/repositories/postgres-post.repository.d.ts.map +1 -0
- package/dist/repositories/postgres-post.repository.js +54 -0
- package/dist/repositories/postgres-post.repository.js.map +1 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/post.service.d.ts +15 -0
- package/dist/services/post.service.d.ts.map +1 -0
- package/dist/services/post.service.js +134 -0
- package/dist/services/post.service.js.map +1 -0
- package/dist/test/__test-utils__/factories/post.factory.d.ts +6 -0
- package/dist/test/__test-utils__/factories/post.factory.d.ts.map +1 -0
- package/dist/test/__test-utils__/factories/post.factory.js +18 -0
- package/dist/test/__test-utils__/factories/post.factory.js.map +1 -0
- package/dist/test/__test-utils__/mocks/post.repository.mock.d.ts +4 -0
- package/dist/test/__test-utils__/mocks/post.repository.mock.d.ts.map +1 -0
- package/dist/test/__test-utils__/mocks/post.repository.mock.js +12 -0
- package/dist/test/__test-utils__/mocks/post.repository.mock.js.map +1 -0
- package/dist/test/data-source.d.ts +8 -0
- package/dist/test/data-source.d.ts.map +1 -0
- package/dist/test/data-source.js +40 -0
- package/dist/test/data-source.js.map +1 -0
- package/dist/test/integration/post.repository.int.spec.d.ts +2 -0
- package/dist/test/integration/post.repository.int.spec.d.ts.map +1 -0
- package/dist/test/integration/post.repository.int.spec.js +136 -0
- package/dist/test/integration/post.repository.int.spec.js.map +1 -0
- package/dist/test/migrations/1776000000000-InitialPostSchema.d.ts +7 -0
- package/dist/test/migrations/1776000000000-InitialPostSchema.d.ts.map +1 -0
- package/dist/test/migrations/1776000000000-InitialPostSchema.js +11 -0
- package/dist/test/migrations/1776000000000-InitialPostSchema.js.map +1 -0
- package/dist/test/migrations/1776785940565-JobsOutboxAndEventQueue.d.ts +7 -0
- package/dist/test/migrations/1776785940565-JobsOutboxAndEventQueue.d.ts.map +1 -0
- package/dist/test/migrations/1776785940565-JobsOutboxAndEventQueue.js +12 -0
- package/dist/test/migrations/1776785940565-JobsOutboxAndEventQueue.js.map +1 -0
- package/dist/test/migrations/1776975278062-JobsOutboxAndEventQueueWithTraceId.d.ts +7 -0
- package/dist/test/migrations/1776975278062-JobsOutboxAndEventQueueWithTraceId.d.ts.map +1 -0
- package/dist/test/migrations/1776975278062-JobsOutboxAndEventQueueWithTraceId.js +12 -0
- package/dist/test/migrations/1776975278062-JobsOutboxAndEventQueueWithTraceId.js.map +1 -0
- package/dist/test/migrations/1777630651338-UpdateOutboxModels.d.ts +7 -0
- package/dist/test/migrations/1777630651338-UpdateOutboxModels.d.ts.map +1 -0
- package/dist/test/migrations/1777630651338-UpdateOutboxModels.js +12 -0
- package/dist/test/migrations/1777630651338-UpdateOutboxModels.js.map +1 -0
- package/dist/test/setup.d.ts +2 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +2 -0
- package/dist/test/setup.js.map +1 -0
- package/dist/test/unit/post.repository.unit.spec.d.ts +2 -0
- package/dist/test/unit/post.repository.unit.spec.d.ts.map +1 -0
- package/dist/test/unit/post.repository.unit.spec.js +82 -0
- package/dist/test/unit/post.repository.unit.spec.js.map +1 -0
- package/dist/test/unit/post.service.unit.spec.d.ts +2 -0
- package/dist/test/unit/post.service.unit.spec.d.ts.map +1 -0
- package/dist/test/unit/post.service.unit.spec.js +161 -0
- package/dist/test/unit/post.service.unit.spec.js.map +1 -0
- package/package.json +21 -4
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DataSource } from 'typeorm';
|
|
2
|
+
import { PostModel } from '../models/index.js';
|
|
3
|
+
import { registerPostMappings } from '../models/mapper.js';
|
|
4
|
+
import { InitialPostSchema1776000000000 } from './migrations/1776000000000-InitialPostSchema.js';
|
|
5
|
+
import { JobsOutboxAndEventQueue1776785940565 } from './migrations/1776785940565-JobsOutboxAndEventQueue.js';
|
|
6
|
+
import { JobsOutboxAndEventQueueWithTraceId1776975278062 } from './migrations/1776975278062-JobsOutboxAndEventQueueWithTraceId.js';
|
|
7
|
+
import { UpdateOutboxModels1777630651338 } from './migrations/1777630651338-UpdateOutboxModels.js';
|
|
8
|
+
export const testDataSource = new DataSource({
|
|
9
|
+
type: 'postgres',
|
|
10
|
+
host: 'localhost',
|
|
11
|
+
port: 5433,
|
|
12
|
+
username: 'user',
|
|
13
|
+
password: 'password',
|
|
14
|
+
database: 'ms_post',
|
|
15
|
+
entities: [PostModel],
|
|
16
|
+
migrations: [
|
|
17
|
+
InitialPostSchema1776000000000,
|
|
18
|
+
JobsOutboxAndEventQueue1776785940565,
|
|
19
|
+
JobsOutboxAndEventQueueWithTraceId1776975278062,
|
|
20
|
+
UpdateOutboxModels1777630651338,
|
|
21
|
+
],
|
|
22
|
+
synchronize: false,
|
|
23
|
+
logging: false,
|
|
24
|
+
});
|
|
25
|
+
export const getTestRepository = (ModelClass) => testDataSource.getRepository(ModelClass);
|
|
26
|
+
export const initializeTestDb = async () => {
|
|
27
|
+
if (!testDataSource.isInitialized) {
|
|
28
|
+
await testDataSource.initialize();
|
|
29
|
+
}
|
|
30
|
+
registerPostMappings();
|
|
31
|
+
};
|
|
32
|
+
export const closeTestDb = async () => {
|
|
33
|
+
if (testDataSource.isInitialized) {
|
|
34
|
+
await testDataSource.destroy();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export const truncateAll = async () => {
|
|
38
|
+
await testDataSource.query('TRUNCATE TABLE posts RESTART IDENTITY CASCADE');
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=data-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-source.js","sourceRoot":"","sources":["../../src/test/data-source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,8BAA8B,EAAE,MAAM,iDAAiD,CAAC;AACjG,OAAO,EAAE,oCAAoC,EAAE,MAAM,uDAAuD,CAAC;AAC7G,OAAO,EACL,+CAA+C,EAChD,MAAM,kEAAkE,CAAC;AAC1E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kDAAkD,CAAC;AAEnG,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,UAAU,CAAC;IAC3C,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,CAAC,SAAS,CAAC;IACrB,UAAU,EAAE;QACV,8BAA8B;QAC9B,oCAAoC;QACpC,+CAA+C;QAC/C,+BAA+B;KAChC;IACD,WAAW,EAAE,KAAK;IAClB,OAAO,EAAE,KAAK;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAmB,UAAuB,EAAiB,EAAE,CAC5F,cAAc,CAAC,aAAa,CAAC,UAAU,CAA6B,CAAC;AAEvE,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAmB,EAAE;IACxD,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,cAAc,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;IAED,oBAAoB,EAAE,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;IACnD,IAAI,cAAc,CAAC,aAAa,EAAE,CAAC;QACjC,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;IACnD,MAAM,cAAc,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;AAC9E,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.repository.int.spec.d.ts","sourceRoot":"","sources":["../../../src/test/integration/post.repository.int.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
|
|
2
|
+
import { PostgresPostRepository } from '../../repositories/postgres-post.repository.js';
|
|
3
|
+
import { PostModel } from '../../models/post.model.js';
|
|
4
|
+
import { PostFactory } from '../__test-utils__/factories/post.factory.js';
|
|
5
|
+
import { initializeTestDb, closeTestDb, truncateAll, getTestRepository } from '../data-source.js';
|
|
6
|
+
describe('PostgresPostRepository (Integration)', () => {
|
|
7
|
+
let repository;
|
|
8
|
+
beforeAll(async () => {
|
|
9
|
+
await initializeTestDb();
|
|
10
|
+
const typeOrmRepo = getTestRepository(PostModel);
|
|
11
|
+
repository = new PostgresPostRepository(typeOrmRepo);
|
|
12
|
+
});
|
|
13
|
+
afterAll(async () => {
|
|
14
|
+
await closeTestDb();
|
|
15
|
+
});
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
await truncateAll();
|
|
18
|
+
});
|
|
19
|
+
describe('findById()', () => {
|
|
20
|
+
it('should return a post by id', async () => {
|
|
21
|
+
const post = PostFactory.build({ title: 'Test Post' });
|
|
22
|
+
await repository.create(post);
|
|
23
|
+
const result = await repository.findById(post.id);
|
|
24
|
+
expect(result).toBeDefined();
|
|
25
|
+
expect(result?.title).toBe('Test Post');
|
|
26
|
+
expect(result?.id).toBe(post.id);
|
|
27
|
+
});
|
|
28
|
+
it('should return null if post does not exist', async () => {
|
|
29
|
+
const result = await repository.findById('00000000-0000-0000-0000-000000000000');
|
|
30
|
+
expect(result).toBeNull();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('findByAuthorId()', () => {
|
|
34
|
+
it('should return all posts for a specific author', async () => {
|
|
35
|
+
const authorId = '00000000-0000-0000-0000-000000000001';
|
|
36
|
+
const posts = PostFactory.buildMany(3, { authorId });
|
|
37
|
+
for (const post of posts) {
|
|
38
|
+
await repository.create(post);
|
|
39
|
+
}
|
|
40
|
+
await repository.create(PostFactory.build({ authorId: '00000000-0000-0000-0000-000000000002' }));
|
|
41
|
+
const result = await repository.findByAuthorId(authorId);
|
|
42
|
+
expect(result).toHaveLength(3);
|
|
43
|
+
result.forEach(p => { expect(p.authorId).toBe(authorId); });
|
|
44
|
+
});
|
|
45
|
+
it('should return an empty array if author has no posts', async () => {
|
|
46
|
+
const result = await repository.findByAuthorId('00000000-0000-0000-0000-000000000003');
|
|
47
|
+
expect(result).toEqual([]);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('findAll()', () => {
|
|
51
|
+
it('should return all posts in the database', async () => {
|
|
52
|
+
await repository.create(PostFactory.build({ title: 'Post 1' }));
|
|
53
|
+
await repository.create(PostFactory.build({ title: 'Post 2' }));
|
|
54
|
+
const result = await repository.findAll();
|
|
55
|
+
expect(result).toHaveLength(2);
|
|
56
|
+
const titles = result.map(p => p.title);
|
|
57
|
+
expect(titles).toContain('Post 1');
|
|
58
|
+
expect(titles).toContain('Post 2');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('create()', () => {
|
|
62
|
+
it('should persist a new post and return it', async () => {
|
|
63
|
+
const postData = PostFactory.build({ title: 'Persisted Post' });
|
|
64
|
+
const result = await repository.create(postData);
|
|
65
|
+
expect(result.id).toBeDefined();
|
|
66
|
+
expect(result.title).toBe('Persisted Post');
|
|
67
|
+
const found = await repository.findById(result.id);
|
|
68
|
+
expect(found).toBeDefined();
|
|
69
|
+
expect(found?.title).toBe('Persisted Post');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('update()', () => {
|
|
73
|
+
it('should update an existing post', async () => {
|
|
74
|
+
const post = await repository.create(PostFactory.build({ title: 'Old Title' }));
|
|
75
|
+
const updateData = { title: 'New Title' };
|
|
76
|
+
const result = await repository.update(post.id, updateData);
|
|
77
|
+
expect(result?.title).toBe('New Title');
|
|
78
|
+
const found = await repository.findById(post.id);
|
|
79
|
+
expect(found?.title).toBe('New Title');
|
|
80
|
+
});
|
|
81
|
+
it('should return null when updating a non-existent post', async () => {
|
|
82
|
+
const result = await repository.update('00000000-0000-0000-0000-000000000000', { title: 'New' });
|
|
83
|
+
expect(result).toBeNull();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe('delete()', () => {
|
|
87
|
+
it('should delete a post and return true', async () => {
|
|
88
|
+
const post = await repository.create(PostFactory.build());
|
|
89
|
+
const result = await repository.delete(post.id);
|
|
90
|
+
expect(result).toBe(true);
|
|
91
|
+
const found = await repository.findById(post.id);
|
|
92
|
+
expect(found).toBeNull();
|
|
93
|
+
});
|
|
94
|
+
it('should return false when deleting a non-existent post', async () => {
|
|
95
|
+
const result = await repository.delete('00000000-0000-0000-0000-000000000000');
|
|
96
|
+
expect(result).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe('search()', () => {
|
|
100
|
+
it('should find posts with matching title (case-insensitive)', async () => {
|
|
101
|
+
await repository.create(PostFactory.build({ title: 'Hello World' }));
|
|
102
|
+
await repository.create(PostFactory.build({ title: 'HELLO GALAXY' }));
|
|
103
|
+
await repository.create(PostFactory.build({ title: 'Goodbye' }));
|
|
104
|
+
const result = await repository.search('hello');
|
|
105
|
+
expect(result).toHaveLength(2);
|
|
106
|
+
const titles = result.map(p => p.title.toUpperCase());
|
|
107
|
+
expect(titles).toContain('HELLO WORLD');
|
|
108
|
+
expect(titles).toContain('HELLO GALAXY');
|
|
109
|
+
});
|
|
110
|
+
it('should return an empty array if no match found', async () => {
|
|
111
|
+
const result = await repository.search('nonexistent');
|
|
112
|
+
expect(result).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe('deleteByAuthorId()', () => {
|
|
116
|
+
it('should delete all posts from an author and return affected count', async () => {
|
|
117
|
+
const authorId = '00000000-0000-0000-0000-000000000002';
|
|
118
|
+
await repository.create(PostFactory.build({ authorId }));
|
|
119
|
+
await repository.create(PostFactory.build({ authorId }));
|
|
120
|
+
await repository.create(PostFactory.build({
|
|
121
|
+
authorId: '00000000-0000-0000-0000-000000000099',
|
|
122
|
+
}));
|
|
123
|
+
const affected = await repository.deleteByAuthorId(authorId);
|
|
124
|
+
const remainingForAuthor = await repository.findByAuthorId(authorId);
|
|
125
|
+
const allPosts = await repository.findAll();
|
|
126
|
+
expect(affected).toBe(2);
|
|
127
|
+
expect(remainingForAuthor).toHaveLength(0);
|
|
128
|
+
expect(allPosts).toHaveLength(1);
|
|
129
|
+
});
|
|
130
|
+
it('should return 0 if author has no posts to delete', async () => {
|
|
131
|
+
const result = await repository.deleteByAuthorId('00000000-0000-0000-0000-000000000123');
|
|
132
|
+
expect(result).toBe(0);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=post.repository.int.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.repository.int.spec.js","sourceRoot":"","sources":["../../../src/test/integration/post.repository.int.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
export declare class InitialPostSchema1776000000000 implements MigrationInterface {
|
|
3
|
+
name: string;
|
|
4
|
+
up(queryRunner: QueryRunner): Promise<void>;
|
|
5
|
+
down(queryRunner: QueryRunner): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=1776000000000-InitialPostSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1776000000000-InitialPostSchema.d.ts","sourceRoot":"","sources":["../../../src/test/migrations/1776000000000-InitialPostSchema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,8BAA+B,YAAW,kBAAkB;IACvE,IAAI,SAAoC;IAE3B,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3D"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class InitialPostSchema1776000000000 {
|
|
2
|
+
name = 'InitialPostSchema1776000000000';
|
|
3
|
+
async up(queryRunner) {
|
|
4
|
+
await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`);
|
|
5
|
+
await queryRunner.query(`CREATE TABLE "posts" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "authorId" uuid NOT NULL, "title" character varying(255) NOT NULL, "content" text NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_posts_id" PRIMARY KEY ("id"))`);
|
|
6
|
+
}
|
|
7
|
+
async down(queryRunner) {
|
|
8
|
+
await queryRunner.query(`DROP TABLE "posts"`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=1776000000000-InitialPostSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1776000000000-InitialPostSchema.js","sourceRoot":"","sources":["../../../src/test/migrations/1776000000000-InitialPostSchema.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,8BAA8B;IACzC,IAAI,GAAG,gCAAgC,CAAC;IAEjC,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACtE,MAAM,WAAW,CAAC,KAAK,CACrB,2SAA2S,CAC5S,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
export declare class JobsOutboxAndEventQueue1776785940565 implements MigrationInterface {
|
|
3
|
+
name: string;
|
|
4
|
+
up(queryRunner: QueryRunner): Promise<void>;
|
|
5
|
+
down(queryRunner: QueryRunner): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=1776785940565-JobsOutboxAndEventQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1776785940565-JobsOutboxAndEventQueue.d.ts","sourceRoot":"","sources":["../../../src/test/migrations/1776785940565-JobsOutboxAndEventQueue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,oCAAqC,YAAW,kBAAkB;IAC7E,IAAI,SAA0C;IAEjC,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export class JobsOutboxAndEventQueue1776785940565 {
|
|
2
|
+
name = 'JobsOutboxAndEventQueue1776785940565';
|
|
3
|
+
async up(queryRunner) {
|
|
4
|
+
await queryRunner.query(`CREATE TABLE "event_queue" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "status" character varying(20) NOT NULL DEFAULT 'PENDING', "attempts" integer NOT NULL DEFAULT '0', "lastError" text, "type" character varying(100) NOT NULL, "emitter" character varying(100) NOT NULL, "updated_at" TIMESTAMP NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "version" integer NOT NULL, "payload" jsonb NOT NULL, "processed_at" TIMESTAMP, CONSTRAINT "PK_f2ab43ee6a569a89ba286db2fa6" PRIMARY KEY ("id"))`);
|
|
5
|
+
await queryRunner.query(`CREATE TABLE "jobs_outbox" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "status" character varying(20) NOT NULL DEFAULT 'PENDING', "attempts" integer NOT NULL DEFAULT '0', "lastError" text, "type" character varying(100) NOT NULL, "emitter" character varying(100) NOT NULL, "updated_at" TIMESTAMP NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "target" character varying(100) NOT NULL, "payload" jsonb NOT NULL, "scheduled_at" TIMESTAMP NOT NULL, CONSTRAINT "PK_7172b6dd5767f423ecb44d9fb57" PRIMARY KEY ("id"))`);
|
|
6
|
+
}
|
|
7
|
+
async down(queryRunner) {
|
|
8
|
+
await queryRunner.query(`DROP TABLE "jobs_outbox"`);
|
|
9
|
+
await queryRunner.query(`DROP TABLE "event_queue"`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=1776785940565-JobsOutboxAndEventQueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1776785940565-JobsOutboxAndEventQueue.js","sourceRoot":"","sources":["../../../src/test/migrations/1776785940565-JobsOutboxAndEventQueue.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,oCAAoC;IAC/C,IAAI,GAAG,sCAAsC,CAAC;IAEvC,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,qfAAqf,CACtf,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,4gBAA4gB,CAC7gB,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACpD,MAAM,WAAW,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACtD,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
export declare class JobsOutboxAndEventQueueWithTraceId1776975278062 implements MigrationInterface {
|
|
3
|
+
name: string;
|
|
4
|
+
up(queryRunner: QueryRunner): Promise<void>;
|
|
5
|
+
down(queryRunner: QueryRunner): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=1776975278062-JobsOutboxAndEventQueueWithTraceId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1776975278062-JobsOutboxAndEventQueueWithTraceId.d.ts","sourceRoot":"","sources":["../../../src/test/migrations/1776975278062-JobsOutboxAndEventQueueWithTraceId.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,+CAAgD,YAAW,kBAAkB;IACxF,IAAI,SAAqD;IAE5C,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export class JobsOutboxAndEventQueueWithTraceId1776975278062 {
|
|
2
|
+
name = 'JobsOutboxAndEventQueueWithTraceId1776975278062';
|
|
3
|
+
async up(queryRunner) {
|
|
4
|
+
await queryRunner.query(`ALTER TABLE "event_queue" ADD "traceId" uuid`);
|
|
5
|
+
await queryRunner.query(`ALTER TABLE "jobs_outbox" ADD "traceId" uuid`);
|
|
6
|
+
}
|
|
7
|
+
async down(queryRunner) {
|
|
8
|
+
await queryRunner.query(`ALTER TABLE "jobs_outbox" DROP COLUMN "traceId"`);
|
|
9
|
+
await queryRunner.query(`ALTER TABLE "event_queue" DROP COLUMN "traceId"`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=1776975278062-JobsOutboxAndEventQueueWithTraceId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1776975278062-JobsOutboxAndEventQueueWithTraceId.js","sourceRoot":"","sources":["../../../src/test/migrations/1776975278062-JobsOutboxAndEventQueueWithTraceId.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,+CAA+C;IAC1D,IAAI,GAAG,iDAAiD,CAAC;IAElD,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACxE,MAAM,WAAW,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAC1E,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAC3E,MAAM,WAAW,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC7E,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
export declare class UpdateOutboxModels1777630651338 implements MigrationInterface {
|
|
3
|
+
name: string;
|
|
4
|
+
up(queryRunner: QueryRunner): Promise<void>;
|
|
5
|
+
down(queryRunner: QueryRunner): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=1777630651338-UpdateOutboxModels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1777630651338-UpdateOutboxModels.d.ts","sourceRoot":"","sources":["../../../src/test/migrations/1777630651338-UpdateOutboxModels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,+BAAgC,YAAW,kBAAkB;IACxE,IAAI,SAAqC;IAE5B,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export class UpdateOutboxModels1777630651338 {
|
|
2
|
+
name = 'UpdateOutboxModels1777630651338';
|
|
3
|
+
async up(queryRunner) {
|
|
4
|
+
await queryRunner.query(`ALTER TABLE "event_queue" ALTER COLUMN "updated_at" DROP NOT NULL`);
|
|
5
|
+
await queryRunner.query(`ALTER TABLE "jobs_outbox" ALTER COLUMN "updated_at" DROP NOT NULL`);
|
|
6
|
+
}
|
|
7
|
+
async down(queryRunner) {
|
|
8
|
+
await queryRunner.query(`ALTER TABLE "jobs_outbox" ALTER COLUMN "updated_at" SET NOT NULL`);
|
|
9
|
+
await queryRunner.query(`ALTER TABLE "event_queue" ALTER COLUMN "updated_at" SET NOT NULL`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=1777630651338-UpdateOutboxModels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1777630651338-UpdateOutboxModels.js","sourceRoot":"","sources":["../../../src/test/migrations/1777630651338-UpdateOutboxModels.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,+BAA+B;IAC1C,IAAI,GAAG,iCAAiC,CAAC;IAElC,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QAC7F,MAAM,WAAW,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;IAC/F,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAC5F,MAAM,WAAW,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;IAC9F,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.repository.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/unit/post.repository.unit.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jest, describe, it, expect, beforeEach } from '@jest/globals';
|
|
2
|
+
import { PostgresPostRepository } from '../../repositories/postgres-post.repository.js';
|
|
3
|
+
import { registerPostMappings } from '../../models/mapper.js';
|
|
4
|
+
describe('PostgresPostRepository (Unit)', () => {
|
|
5
|
+
let repository;
|
|
6
|
+
let mockTypeOrmRepo;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
registerPostMappings();
|
|
9
|
+
mockTypeOrmRepo = {
|
|
10
|
+
findOne: jest.fn(),
|
|
11
|
+
findOneBy: jest.fn(),
|
|
12
|
+
find: jest.fn(),
|
|
13
|
+
create: jest.fn(),
|
|
14
|
+
save: jest.fn(),
|
|
15
|
+
update: jest.fn(),
|
|
16
|
+
delete: jest.fn(),
|
|
17
|
+
metadata: {
|
|
18
|
+
tableName: 'posts',
|
|
19
|
+
name: 'PostModel',
|
|
20
|
+
primaryColumns: [{ propertyName: 'id' }],
|
|
21
|
+
columns: [],
|
|
22
|
+
relations: [],
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
repository = new PostgresPostRepository(mockTypeOrmRepo);
|
|
26
|
+
});
|
|
27
|
+
describe('findById()', () => {
|
|
28
|
+
it('should call findOne with relations if provided', async () => {
|
|
29
|
+
const id = 'post-1';
|
|
30
|
+
const relations = ['author'];
|
|
31
|
+
const findOneSpy = jest.spyOn(mockTypeOrmRepo, 'findOne').mockResolvedValue({ id });
|
|
32
|
+
const result = await repository.findById(id, relations);
|
|
33
|
+
expect(result?.id).toBe(id);
|
|
34
|
+
expect(findOneSpy).toHaveBeenCalled();
|
|
35
|
+
});
|
|
36
|
+
it('should call super.findById if no relations provided', async () => {
|
|
37
|
+
const id = 'post-1';
|
|
38
|
+
const findOneBySpy = jest.spyOn(mockTypeOrmRepo, 'findOneBy').mockResolvedValue({ id });
|
|
39
|
+
const result = await repository.findById(id);
|
|
40
|
+
expect(result?.id).toBe(id);
|
|
41
|
+
expect(findOneBySpy).toHaveBeenCalled();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('findByAuthorId()', () => {
|
|
45
|
+
it('should call find with authorId filter', async () => {
|
|
46
|
+
const authorId = 'author-1';
|
|
47
|
+
const findSpy = jest.spyOn(mockTypeOrmRepo, 'find').mockResolvedValue([]);
|
|
48
|
+
await repository.findByAuthorId(authorId);
|
|
49
|
+
expect(findSpy).toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe('findAll()', () => {
|
|
53
|
+
it('should call find with relations if provided', async () => {
|
|
54
|
+
const relations = ['comments'];
|
|
55
|
+
const findSpy = jest.spyOn(mockTypeOrmRepo, 'find').mockResolvedValue([]);
|
|
56
|
+
await repository.findAll(relations);
|
|
57
|
+
expect(findSpy).toHaveBeenCalled();
|
|
58
|
+
});
|
|
59
|
+
it('should call super.find if no relations provided', async () => {
|
|
60
|
+
const findSpy = jest.spyOn(mockTypeOrmRepo, 'find').mockResolvedValue([]);
|
|
61
|
+
await repository.findAll();
|
|
62
|
+
expect(findSpy).toHaveBeenCalled();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe('search()', () => {
|
|
66
|
+
it('should call find with ILike pattern', async () => {
|
|
67
|
+
const findSpy = jest.spyOn(mockTypeOrmRepo, 'find').mockResolvedValue([]);
|
|
68
|
+
await repository.search('test');
|
|
69
|
+
expect(findSpy).toHaveBeenCalled();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('deleteByAuthorId()', () => {
|
|
73
|
+
it('should call deleteWhere with authorId and return affected count', async () => {
|
|
74
|
+
const authorId = 'author-1';
|
|
75
|
+
const deleteSpy = jest.spyOn(mockTypeOrmRepo, 'delete').mockResolvedValue({ affected: 3, raw: [] });
|
|
76
|
+
const result = await repository.deleteByAuthorId(authorId);
|
|
77
|
+
expect(result).toBe(3);
|
|
78
|
+
expect(deleteSpy).toHaveBeenCalled();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=post.repository.unit.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.repository.unit.spec.js","sourceRoot":"","sources":["../../../src/test/unit/post.repository.unit.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post.service.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/unit/post.service.unit.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { jest, describe, it, expect, beforeEach, afterEach } from '@jest/globals';
|
|
2
|
+
import { PostService } from '../../services/post.service.js';
|
|
3
|
+
import { createPostRepositoryMock } from '../__test-utils__/mocks/post.repository.mock.js';
|
|
4
|
+
import { PostFactory } from '../__test-utils__/factories/post.factory.js';
|
|
5
|
+
describe('PostService (Unit)', () => {
|
|
6
|
+
let service;
|
|
7
|
+
let mockRepository;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
mockRepository = createPostRepositoryMock();
|
|
10
|
+
service = new PostService(mockRepository);
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
describe('findById()', () => {
|
|
16
|
+
it('should return a post when it exists', async () => {
|
|
17
|
+
const post = PostFactory.build({ id: 'post-1' });
|
|
18
|
+
const findByIdSpy = jest.spyOn(mockRepository, 'findById').mockResolvedValue(post);
|
|
19
|
+
const result = await service.findById('post-1');
|
|
20
|
+
expect(result).toEqual(post);
|
|
21
|
+
expect(findByIdSpy).toHaveBeenCalledWith('post-1');
|
|
22
|
+
});
|
|
23
|
+
it('should throw POST_NOT_FOUND when post does not exist', async () => {
|
|
24
|
+
jest.spyOn(mockRepository, 'findById').mockResolvedValue(null);
|
|
25
|
+
await expect(service.findById('unknown')).rejects.toMatchObject({
|
|
26
|
+
code: 'NOT_FOUND',
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
it('should rethrow BaseError from repository without wrapping', async () => {
|
|
30
|
+
const baseError = { isBaseError: true, code: 'SOME_ERROR' };
|
|
31
|
+
jest.spyOn(mockRepository, 'findById').mockRejectedValue(baseError);
|
|
32
|
+
await expect(service.findById('post-1')).rejects.toEqual(baseError);
|
|
33
|
+
});
|
|
34
|
+
it('should throw DATABASE_ERROR on unexpected repository failure', async () => {
|
|
35
|
+
jest.spyOn(mockRepository, 'findById').mockRejectedValue(new Error('Unexpected'));
|
|
36
|
+
await expect(service.findById('post-1')).rejects.toMatchObject({
|
|
37
|
+
code: 'DATABASE_ERROR',
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe('findByAuthorId()', () => {
|
|
42
|
+
it('should return all posts for an author', async () => {
|
|
43
|
+
const posts = PostFactory.buildMany(2, { authorId: 'author-1' });
|
|
44
|
+
const findByAuthorIdSpy = jest.spyOn(mockRepository, 'findByAuthorId').mockResolvedValue(posts);
|
|
45
|
+
const result = await service.findByAuthorId('author-1');
|
|
46
|
+
expect(result).toEqual(posts);
|
|
47
|
+
expect(findByAuthorIdSpy).toHaveBeenCalledWith('author-1');
|
|
48
|
+
});
|
|
49
|
+
it('should return an empty array if author has no posts', async () => {
|
|
50
|
+
jest.spyOn(mockRepository, 'findByAuthorId').mockResolvedValue([]);
|
|
51
|
+
const result = await service.findByAuthorId('author-none');
|
|
52
|
+
expect(result).toEqual([]);
|
|
53
|
+
});
|
|
54
|
+
it('should throw DATABASE_ERROR on repository failure', async () => {
|
|
55
|
+
jest.spyOn(mockRepository, 'findByAuthorId').mockRejectedValue(new Error('DB Fail'));
|
|
56
|
+
await expect(service.findByAuthorId('author-1')).rejects.toMatchObject({
|
|
57
|
+
code: 'DATABASE_ERROR',
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('findAll()', () => {
|
|
62
|
+
it('should return all posts', async () => {
|
|
63
|
+
const posts = PostFactory.buildMany(3);
|
|
64
|
+
const findAllSpy = jest.spyOn(mockRepository, 'findAll').mockResolvedValue(posts);
|
|
65
|
+
const result = await service.findAll();
|
|
66
|
+
expect(result).toEqual(posts);
|
|
67
|
+
expect(findAllSpy).toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
it('should throw DATABASE_ERROR on repository failure', async () => {
|
|
70
|
+
jest.spyOn(mockRepository, 'findAll').mockRejectedValue(new Error('DB Fail'));
|
|
71
|
+
await expect(service.findAll()).rejects.toMatchObject({
|
|
72
|
+
code: 'DATABASE_ERROR',
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe('create()', () => {
|
|
77
|
+
it('should create and return a new post', async () => {
|
|
78
|
+
const postData = { title: 'New Post', authorId: 'author-1' };
|
|
79
|
+
const createdPost = PostFactory.build(postData);
|
|
80
|
+
const createSpy = jest.spyOn(mockRepository, 'create').mockResolvedValue(createdPost);
|
|
81
|
+
const result = await service.create(postData);
|
|
82
|
+
expect(result).toEqual(createdPost);
|
|
83
|
+
expect(createSpy).toHaveBeenCalledWith(postData);
|
|
84
|
+
});
|
|
85
|
+
it('should throw POST_ALREADY_EXISTS on unique constraint violation (code 23505)', async () => {
|
|
86
|
+
const postData = { title: 'Duplicate' };
|
|
87
|
+
const dbError = Object.assign(new Error('Duplicate'), { code: '23505' });
|
|
88
|
+
jest.spyOn(mockRepository, 'create').mockRejectedValue(dbError);
|
|
89
|
+
await expect(service.create(postData)).rejects.toMatchObject({
|
|
90
|
+
code: 'CONFLICT',
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
it('should throw DATABASE_ERROR on other repository failures', async () => {
|
|
94
|
+
jest.spyOn(mockRepository, 'create').mockRejectedValue(new Error('Connection error'));
|
|
95
|
+
await expect(service.create({})).rejects.toMatchObject({
|
|
96
|
+
code: 'DATABASE_ERROR',
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe('update()', () => {
|
|
101
|
+
it('should update and return the post', async () => {
|
|
102
|
+
const updateData = { title: 'Updated' };
|
|
103
|
+
const updatedPost = PostFactory.build(updateData);
|
|
104
|
+
const updateSpy = jest.spyOn(mockRepository, 'update').mockResolvedValue(updatedPost);
|
|
105
|
+
const result = await service.update('post-1', updateData);
|
|
106
|
+
expect(result).toEqual(updatedPost);
|
|
107
|
+
expect(updateSpy).toHaveBeenCalledWith('post-1', updateData);
|
|
108
|
+
});
|
|
109
|
+
it('should throw POST_NOT_FOUND when post to update does not exist', async () => {
|
|
110
|
+
jest.spyOn(mockRepository, 'update').mockResolvedValue(null);
|
|
111
|
+
await expect(service.update('unknown', {})).rejects.toMatchObject({
|
|
112
|
+
code: 'NOT_FOUND',
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
it('should throw POST_ALREADY_EXISTS on unique constraint violation during update', async () => {
|
|
116
|
+
const dbError = Object.assign(new Error('Duplicate'), { code: '23505' });
|
|
117
|
+
jest.spyOn(mockRepository, 'update').mockRejectedValue(dbError);
|
|
118
|
+
await expect(service.update('post-1', { title: 'Exists' })).rejects.toMatchObject({
|
|
119
|
+
code: 'CONFLICT',
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe('delete()', () => {
|
|
124
|
+
it('should delete the post if it exists', async () => {
|
|
125
|
+
const post = PostFactory.build({ id: 'post-1' });
|
|
126
|
+
const findByIdSpy = jest.spyOn(mockRepository, 'findById').mockResolvedValue(post);
|
|
127
|
+
const deleteSpy = jest.spyOn(mockRepository, 'delete').mockResolvedValue(true);
|
|
128
|
+
await service.delete('post-1');
|
|
129
|
+
expect(findByIdSpy).toHaveBeenCalledWith('post-1');
|
|
130
|
+
expect(deleteSpy).toHaveBeenCalledWith('post-1');
|
|
131
|
+
});
|
|
132
|
+
it('should throw POST_NOT_FOUND if post to delete does not exist', async () => {
|
|
133
|
+
jest.spyOn(mockRepository, 'findById').mockResolvedValue(null);
|
|
134
|
+
await expect(service.delete('unknown')).rejects.toMatchObject({
|
|
135
|
+
code: 'NOT_FOUND',
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
it('should throw DATABASE_ERROR if repository.delete fails', async () => {
|
|
139
|
+
jest.spyOn(mockRepository, 'findById').mockResolvedValue(PostFactory.build());
|
|
140
|
+
jest.spyOn(mockRepository, 'delete').mockRejectedValue(new Error('Fail'));
|
|
141
|
+
await expect(service.delete('post-1')).rejects.toMatchObject({
|
|
142
|
+
code: 'DATABASE_ERROR',
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
describe('deleteByAuthorId()', () => {
|
|
147
|
+
it('should return count of deleted posts', async () => {
|
|
148
|
+
const deleteByAuthorIdSpy = jest.spyOn(mockRepository, 'deleteByAuthorId').mockResolvedValue(5);
|
|
149
|
+
const result = await service.deleteByAuthorId('author-1');
|
|
150
|
+
expect(result).toBe(5);
|
|
151
|
+
expect(deleteByAuthorIdSpy).toHaveBeenCalledWith('author-1');
|
|
152
|
+
});
|
|
153
|
+
it('should throw DATABASE_ERROR on repository failure', async () => {
|
|
154
|
+
jest.spyOn(mockRepository, 'deleteByAuthorId').mockRejectedValue(new Error('Fail'));
|
|
155
|
+
await expect(service.deleteByAuthorId('author-1')).rejects.toMatchObject({
|
|
156
|
+
code: 'DATABASE_ERROR',
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
//# sourceMappingURL=post.service.unit.spec.js.map
|