@accounter/server 0.0.9-alpha-20251210173458-9f3d75bb8729ec6038c777f7dbf9a1b5fa727888 → 0.0.9-alpha-20251210173721-a5bb944d9abd3f354daf897072b78bea4d8269c9
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/CHANGELOG.md +5 -21
- package/dist/server/src/__tests__/helpers/db-setup.d.ts +1 -0
- package/dist/server/src/__tests__/helpers/db-setup.js +2 -0
- package/dist/server/src/__tests__/helpers/db-setup.js.map +1 -1
- package/dist/server/src/__tests__/helpers/seed-helpers.business.test.js +31 -23
- package/dist/server/src/__tests__/helpers/seed-helpers.business.test.js.map +1 -1
- package/dist/server/src/__tests__/helpers/seed-helpers.concurrent.test.js +8 -8
- package/dist/server/src/__tests__/helpers/seed-helpers.concurrent.test.js.map +1 -1
- package/dist/server/src/__tests__/helpers/seed-helpers.financial-entity.test.js +50 -41
- package/dist/server/src/__tests__/helpers/seed-helpers.financial-entity.test.js.map +1 -1
- package/dist/server/src/__tests__/helpers/seed-helpers.tax-category.test.js +31 -23
- package/dist/server/src/__tests__/helpers/seed-helpers.tax-category.test.js.map +1 -1
- package/dist/server/src/__tests__/helpers/test-db-config.js +1 -1
- package/dist/server/src/__tests__/helpers/test-db-config.js.map +1 -1
- package/dist/server/src/__tests__/seed-admin-context.integration.test.js +131 -128
- package/dist/server/src/__tests__/seed-admin-context.integration.test.js.map +1 -1
- package/dist/server/src/modules/business-trips/providers/business-trips.provider.d.ts +1 -1
- package/dist/server/src/modules/business-trips/providers/business-trips.provider.js +1 -1
- package/dist/server/src/modules/business-trips/providers/business-trips.provider.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/helpers/db-setup.ts +3 -0
- package/src/__tests__/helpers/seed-helpers.business.test.ts +147 -145
- package/src/__tests__/helpers/seed-helpers.concurrent.test.ts +10 -10
- package/src/__tests__/helpers/seed-helpers.financial-entity.test.ts +231 -218
- package/src/__tests__/helpers/seed-helpers.tax-category.test.ts +164 -162
- package/src/__tests__/helpers/test-db-config.ts +1 -1
- package/src/__tests__/seed-admin-context.integration.test.ts +208 -199
- package/src/modules/business-trips/providers/business-trips.provider.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @accounter/server
|
|
2
2
|
|
|
3
|
-
## 0.0.9-alpha-
|
|
3
|
+
## 0.0.9-alpha-20251210173721-a5bb944d9abd3f354daf897072b78bea4d8269c9
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
@@ -122,22 +122,6 @@
|
|
|
122
122
|
utilize the `businessId` when constructing links to business detail pages, resolving the issue
|
|
123
123
|
of incorrect navigation.
|
|
124
124
|
|
|
125
|
-
- [#2802](https://github.com/Urigo/accounter-fullstack/pull/2802)
|
|
126
|
-
[`b385a79`](https://github.com/Urigo/accounter-fullstack/commit/b385a79f96fe9435b30511bea0af76407e375da6)
|
|
127
|
-
Thanks [@gilgardosh](https://github.com/gilgardosh)! - - **Centralized Test Database Management**:
|
|
128
|
-
Integration tests now leverage a `TestDatabase` utility class, centralizing database connection,
|
|
129
|
-
pooling, and transaction management for improved consistency and isolation.
|
|
130
|
-
- **Transactional Test Isolation**: Individual test cases are now wrapped in `db.withTransaction`
|
|
131
|
-
blocks, ensuring that each test runs within its own transaction and automatically rolls back
|
|
132
|
-
changes, preventing data leakage between tests.
|
|
133
|
-
- **Simplified Test Setup/Teardown**: The `beforeAll`, `afterAll`, `beforeEach`, and `afterEach`
|
|
134
|
-
hooks in several test files have been streamlined, removing manual `pg.Pool` and `pg.PoolClient`
|
|
135
|
-
management in favor of the `TestDatabase` class's methods.
|
|
136
|
-
- **Removed Obsolete Function**: The `resetSetupFlags` function, previously a no-op, has been
|
|
137
|
-
removed from `db-setup.ts`.
|
|
138
|
-
- **Import Path Correction**: A minor import path correction for `DBProvider` was made in
|
|
139
|
-
`business-trips.provider.ts`.
|
|
140
|
-
|
|
141
125
|
- [#2750](https://github.com/Urigo/accounter-fullstack/pull/2750)
|
|
142
126
|
[`98b8b85`](https://github.com/Urigo/accounter-fullstack/commit/98b8b859ad566372ec3cd65bc57bcc0d6fcdd6fb)
|
|
143
127
|
Thanks [@gilgardosh](https://github.com/gilgardosh)! - - **Database Schema Update**: A new `users`
|
|
@@ -287,10 +271,10 @@
|
|
|
287
271
|
[`ef68321`](https://github.com/Urigo/accounter-fullstack/commit/ef68321608d60a7208e82a2c413f27beb502e3cc),
|
|
288
272
|
[`ef68321`](https://github.com/Urigo/accounter-fullstack/commit/ef68321608d60a7208e82a2c413f27beb502e3cc),
|
|
289
273
|
[`c7d6f21`](https://github.com/Urigo/accounter-fullstack/commit/c7d6f21ed62658159b1323334501daca03c8d3e5)]:
|
|
290
|
-
- @accounter/green-invoice-graphql@0.8.3-alpha-
|
|
291
|
-
- @accounter/pcn874-generator@0.6.4-alpha-
|
|
292
|
-
- @accounter/shaam-uniform-format-generator@0.2.3-alpha-
|
|
293
|
-
- @accounter/shaam6111-generator@0.1.5-alpha-
|
|
274
|
+
- @accounter/green-invoice-graphql@0.8.3-alpha-20251210173721-a5bb944d9abd3f354daf897072b78bea4d8269c9
|
|
275
|
+
- @accounter/pcn874-generator@0.6.4-alpha-20251210173721-a5bb944d9abd3f354daf897072b78bea4d8269c9
|
|
276
|
+
- @accounter/shaam-uniform-format-generator@0.2.3-alpha-20251210173721-a5bb944d9abd3f354daf897072b78bea4d8269c9
|
|
277
|
+
- @accounter/shaam6111-generator@0.1.5-alpha-20251210173721-a5bb944d9abd3f354daf897072b78bea4d8269c9
|
|
294
278
|
|
|
295
279
|
## 0.0.8
|
|
296
280
|
|
|
@@ -5,3 +5,4 @@ export { withTestTransaction, withConcurrentTransactions } from './test-transact
|
|
|
5
5
|
export { isPoolHealthy, debugLog, emitMetrics } from './diagnostics.js';
|
|
6
6
|
export { TestDbConnectionError, TestDbMigrationError, TestDbSeedError } from './errors.js';
|
|
7
7
|
export { TestDatabase } from './test-database.js';
|
|
8
|
+
export declare function resetSetupFlags(): void;
|
|
@@ -5,4 +5,6 @@ export { withTestTransaction, withConcurrentTransactions } from './test-transact
|
|
|
5
5
|
export { isPoolHealthy, debugLog, emitMetrics } from './diagnostics.js';
|
|
6
6
|
export { TestDbConnectionError, TestDbMigrationError, TestDbSeedError } from './errors.js';
|
|
7
7
|
export { TestDatabase } from './test-database.js';
|
|
8
|
+
// Backward-compatible no-op reset (seed flag lives in db-fixtures now)
|
|
9
|
+
export function resetSetupFlags() { }
|
|
8
10
|
//# sourceMappingURL=db-setup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-setup.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/db-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"db-setup.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/db-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,uEAAuE;AACvE,MAAM,UAAU,eAAe,KAAU,CAAC"}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import pg from 'pg';
|
|
2
3
|
import { ensureFinancialEntity, ensureBusinessForEntity } from './seed-helpers.js';
|
|
3
|
-
import { qualifyTable } from './test-db-config.js';
|
|
4
|
+
import { testDbConfig, qualifyTable } from './test-db-config.js';
|
|
4
5
|
import { EntityValidationError } from './seed-errors.js';
|
|
5
|
-
import { TestDatabase } from './db-setup.js';
|
|
6
6
|
describe('ensureBusinessForEntity', () => {
|
|
7
|
-
let
|
|
7
|
+
let pool;
|
|
8
|
+
let client;
|
|
8
9
|
beforeAll(async () => {
|
|
9
|
-
|
|
10
|
-
await
|
|
10
|
+
pool = new pg.Pool(testDbConfig);
|
|
11
|
+
client = await pool.connect();
|
|
11
12
|
});
|
|
12
13
|
afterAll(async () => {
|
|
13
|
-
|
|
14
|
+
client.release();
|
|
15
|
+
await pool.end();
|
|
14
16
|
});
|
|
15
|
-
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
await client.query('BEGIN');
|
|
19
|
+
});
|
|
20
|
+
afterEach(async () => {
|
|
21
|
+
await client.query('ROLLBACK');
|
|
22
|
+
});
|
|
23
|
+
it('should create a new business for a financial entity', async () => {
|
|
16
24
|
// Create a financial entity first
|
|
17
25
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
18
26
|
name: 'Test Business Entity',
|
|
@@ -25,8 +33,8 @@ describe('ensureBusinessForEntity', () => {
|
|
|
25
33
|
expect(result.rows).toHaveLength(1);
|
|
26
34
|
expect(result.rows[0].id).toBe(entityId);
|
|
27
35
|
expect(result.rows[0].no_invoices_required).toBe(false);
|
|
28
|
-
})
|
|
29
|
-
it('should be idempotent - repeated calls do not create duplicates', async () =>
|
|
36
|
+
});
|
|
37
|
+
it('should be idempotent - repeated calls do not create duplicates', async () => {
|
|
30
38
|
// Create a financial entity first
|
|
31
39
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
32
40
|
name: 'Test Business Entity 2',
|
|
@@ -40,8 +48,8 @@ describe('ensureBusinessForEntity', () => {
|
|
|
40
48
|
const result = await client.query(`SELECT id FROM ${qualifyTable('businesses')} WHERE id = $1`, [entityId]);
|
|
41
49
|
expect(result.rows).toHaveLength(1);
|
|
42
50
|
expect(result.rows[0].id).toBe(entityId);
|
|
43
|
-
})
|
|
44
|
-
it('should support noInvoicesRequired option', async () =>
|
|
51
|
+
});
|
|
52
|
+
it('should support noInvoicesRequired option', async () => {
|
|
45
53
|
// Create a financial entity first
|
|
46
54
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
47
55
|
name: 'Test Business Entity 3',
|
|
@@ -54,8 +62,8 @@ describe('ensureBusinessForEntity', () => {
|
|
|
54
62
|
expect(result.rows).toHaveLength(1);
|
|
55
63
|
expect(result.rows[0].id).toBe(entityId);
|
|
56
64
|
expect(result.rows[0].no_invoices_required).toBe(true);
|
|
57
|
-
})
|
|
58
|
-
it('should default noInvoicesRequired to false when not specified', async () =>
|
|
65
|
+
});
|
|
66
|
+
it('should default noInvoicesRequired to false when not specified', async () => {
|
|
59
67
|
// Create a financial entity first
|
|
60
68
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
61
69
|
name: 'Test Business Entity 4',
|
|
@@ -67,8 +75,8 @@ describe('ensureBusinessForEntity', () => {
|
|
|
67
75
|
const result = await client.query(`SELECT no_invoices_required FROM ${qualifyTable('businesses')} WHERE id = $1`, [entityId]);
|
|
68
76
|
expect(result.rows).toHaveLength(1);
|
|
69
77
|
expect(result.rows[0].no_invoices_required).toBe(false);
|
|
70
|
-
})
|
|
71
|
-
it('should not modify existing business when called again', async () =>
|
|
78
|
+
});
|
|
79
|
+
it('should not modify existing business when called again', async () => {
|
|
72
80
|
// Create a financial entity first
|
|
73
81
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
74
82
|
name: 'Test Business Entity 5',
|
|
@@ -82,21 +90,21 @@ describe('ensureBusinessForEntity', () => {
|
|
|
82
90
|
const result = await client.query(`SELECT no_invoices_required FROM ${qualifyTable('businesses')} WHERE id = $1`, [entityId]);
|
|
83
91
|
expect(result.rows).toHaveLength(1);
|
|
84
92
|
expect(result.rows[0].no_invoices_required).toBe(true); // Original value preserved
|
|
85
|
-
})
|
|
86
|
-
it('should not leak data between tests', async () =>
|
|
93
|
+
});
|
|
94
|
+
it('should not leak data between tests', async () => {
|
|
87
95
|
// This test verifies transactional isolation by checking that data
|
|
88
96
|
// from previous tests is not visible
|
|
89
97
|
const result = await client.query(`SELECT COUNT(*) as count FROM ${qualifyTable('businesses')} WHERE id IN (SELECT id FROM ${qualifyTable('financial_entities')} WHERE name LIKE 'Test Business Entity%')`);
|
|
90
98
|
// Due to ROLLBACK after each test, count should be 0
|
|
91
99
|
expect(parseInt(result.rows[0].count)).toBe(0);
|
|
92
|
-
})
|
|
100
|
+
});
|
|
93
101
|
// Validation tests
|
|
94
|
-
it('should reject invalid UUID format', async () =>
|
|
102
|
+
it('should reject invalid UUID format', async () => {
|
|
95
103
|
await expect(ensureBusinessForEntity(client, 'not-a-valid-uuid')).rejects.toThrow(EntityValidationError);
|
|
96
|
-
})
|
|
97
|
-
it('should reject non-existent financial entity', async () =>
|
|
104
|
+
});
|
|
105
|
+
it('should reject non-existent financial entity', async () => {
|
|
98
106
|
const fakeId = '00000000-0000-0000-0000-000000000000';
|
|
99
107
|
await expect(ensureBusinessForEntity(client, fakeId)).rejects.toThrow(EntityValidationError);
|
|
100
|
-
})
|
|
108
|
+
});
|
|
101
109
|
});
|
|
102
110
|
//# sourceMappingURL=seed-helpers.business.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-helpers.business.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/seed-helpers.business.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"seed-helpers.business.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/seed-helpers.business.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import pg from 'pg';
|
|
2
3
|
import { ensureFinancialEntity } from './seed-helpers.js';
|
|
4
|
+
import { testDbConfig } from './test-db-config.js';
|
|
3
5
|
import { withConcurrentTransactions } from './test-transaction.js';
|
|
4
|
-
import { TestDatabase } from './db-setup.js';
|
|
5
6
|
describe('ensureFinancialEntity - Concurrent Access', () => {
|
|
6
|
-
let
|
|
7
|
+
let pool;
|
|
7
8
|
beforeAll(async () => {
|
|
8
|
-
|
|
9
|
-
await db.connect();
|
|
9
|
+
pool = new pg.Pool(testDbConfig);
|
|
10
10
|
});
|
|
11
11
|
afterAll(async () => {
|
|
12
|
-
await
|
|
12
|
+
await pool.end();
|
|
13
13
|
});
|
|
14
14
|
it('should handle concurrent inserts of same entity gracefully', async () => {
|
|
15
15
|
const params = {
|
|
@@ -17,7 +17,7 @@ describe('ensureFinancialEntity - Concurrent Access', () => {
|
|
|
17
17
|
type: 'business',
|
|
18
18
|
};
|
|
19
19
|
// Two separate transactions attempting to create the same entity
|
|
20
|
-
const [result1, result2] = await withConcurrentTransactions(
|
|
20
|
+
const [result1, result2] = await withConcurrentTransactions(pool, [
|
|
21
21
|
async (client) => ensureFinancialEntity(client, params),
|
|
22
22
|
async (client) => ensureFinancialEntity(client, params),
|
|
23
23
|
]);
|
|
@@ -29,7 +29,7 @@ describe('ensureFinancialEntity - Concurrent Access', () => {
|
|
|
29
29
|
// This is expected behavior with ROLLBACK isolation
|
|
30
30
|
});
|
|
31
31
|
it('should handle concurrent inserts of different entities', async () => {
|
|
32
|
-
const [result1, result2, result3] = await withConcurrentTransactions(
|
|
32
|
+
const [result1, result2, result3] = await withConcurrentTransactions(pool, [
|
|
33
33
|
async (client) => ensureFinancialEntity(client, {
|
|
34
34
|
name: 'Concurrent Entity A',
|
|
35
35
|
type: 'business',
|
|
@@ -51,7 +51,7 @@ describe('ensureFinancialEntity - Concurrent Access', () => {
|
|
|
51
51
|
it('should handle concurrent creation with separate namespaces', async () => {
|
|
52
52
|
// Test that concurrent operations in separate transactions don't interfere
|
|
53
53
|
const timestamp = Date.now();
|
|
54
|
-
const [result1, result2, result3] = await withConcurrentTransactions(
|
|
54
|
+
const [result1, result2, result3] = await withConcurrentTransactions(pool, [
|
|
55
55
|
async (client) => ensureFinancialEntity(client, {
|
|
56
56
|
name: `Namespace A - ${timestamp}`,
|
|
57
57
|
type: 'business',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-helpers.concurrent.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/seed-helpers.concurrent.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"seed-helpers.concurrent.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/seed-helpers.concurrent.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,35 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import pg from 'pg';
|
|
2
3
|
import { ensureFinancialEntity } from './seed-helpers.js';
|
|
3
|
-
import { qualifyTable } from './test-db-config.js';
|
|
4
|
+
import { testDbConfig, qualifyTable } from './test-db-config.js';
|
|
4
5
|
import { EntityValidationError } from './seed-errors.js';
|
|
5
|
-
import { TestDatabase } from './db-setup.js';
|
|
6
6
|
describe('ensureFinancialEntity', () => {
|
|
7
|
-
let
|
|
7
|
+
let pool;
|
|
8
|
+
let client;
|
|
8
9
|
beforeAll(async () => {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
// Create connection pool with shared config
|
|
11
|
+
pool = new pg.Pool(testDbConfig);
|
|
12
|
+
// Get a client for transactions
|
|
13
|
+
client = await pool.connect();
|
|
11
14
|
});
|
|
12
15
|
afterAll(async () => {
|
|
13
|
-
|
|
16
|
+
// Release client and close pool
|
|
17
|
+
if (client) {
|
|
18
|
+
client.release();
|
|
19
|
+
}
|
|
20
|
+
if (pool) {
|
|
21
|
+
await pool.end();
|
|
22
|
+
}
|
|
14
23
|
});
|
|
15
|
-
|
|
24
|
+
beforeEach(async () => {
|
|
25
|
+
// Start transaction before each test
|
|
26
|
+
await client.query('BEGIN');
|
|
27
|
+
});
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
// Rollback transaction after each test to clean up
|
|
30
|
+
await client.query('ROLLBACK');
|
|
31
|
+
});
|
|
32
|
+
it('should create a new financial entity when it does not exist', async () => {
|
|
16
33
|
const result = await ensureFinancialEntity(client, {
|
|
17
34
|
name: 'Test Entity',
|
|
18
35
|
type: 'business',
|
|
@@ -25,8 +42,8 @@ describe('ensureFinancialEntity', () => {
|
|
|
25
42
|
expect(checkResult.rows[0].name).toBe('Test Entity');
|
|
26
43
|
expect(checkResult.rows[0].type).toBe('business');
|
|
27
44
|
expect(checkResult.rows[0].owner_id).toBeNull();
|
|
28
|
-
})
|
|
29
|
-
it('should return existing entity when called twice with same parameters', async () =>
|
|
45
|
+
});
|
|
46
|
+
it('should return existing entity when called twice with same parameters', async () => {
|
|
30
47
|
const firstResult = await ensureFinancialEntity(client, {
|
|
31
48
|
name: 'Duplicate Test',
|
|
32
49
|
type: 'tax_category',
|
|
@@ -39,17 +56,15 @@ describe('ensureFinancialEntity', () => {
|
|
|
39
56
|
// Verify only one row exists
|
|
40
57
|
const countResult = await client.query(`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')} WHERE name = $1 AND type = $2`, ['Duplicate Test', 'tax_category']);
|
|
41
58
|
expect(parseInt(countResult.rows[0].count)).toBe(1);
|
|
42
|
-
})
|
|
43
|
-
it('should handle entities with owner_id', async () =>
|
|
59
|
+
});
|
|
60
|
+
it('should handle entities with owner_id', async () => {
|
|
44
61
|
// First create an owner entity (business)
|
|
45
62
|
const ownerEntityResult = await ensureFinancialEntity(client, {
|
|
46
63
|
name: 'Owner Entity',
|
|
47
64
|
type: 'business',
|
|
48
65
|
});
|
|
49
66
|
// Create corresponding business record (required for foreign key)
|
|
50
|
-
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [
|
|
51
|
-
ownerEntityResult.id,
|
|
52
|
-
]);
|
|
67
|
+
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [ownerEntityResult.id]);
|
|
53
68
|
// Create owned entity (tax_category)
|
|
54
69
|
const result = await ensureFinancialEntity(client, {
|
|
55
70
|
name: 'Owned Entity',
|
|
@@ -60,16 +75,14 @@ describe('ensureFinancialEntity', () => {
|
|
|
60
75
|
// Verify owner_id is set correctly
|
|
61
76
|
const checkResult = await client.query(`SELECT owner_id FROM ${qualifyTable('financial_entities')} WHERE id = $1`, [result.id]);
|
|
62
77
|
expect(checkResult.rows[0].owner_id).toBe(ownerEntityResult.id);
|
|
63
|
-
})
|
|
64
|
-
it('should be idempotent for entities with owner_id', async () =>
|
|
78
|
+
});
|
|
79
|
+
it('should be idempotent for entities with owner_id', async () => {
|
|
65
80
|
const ownerEntityResult = await ensureFinancialEntity(client, {
|
|
66
81
|
name: 'Owner Business',
|
|
67
82
|
type: 'business',
|
|
68
83
|
});
|
|
69
84
|
// Create corresponding business record
|
|
70
|
-
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [
|
|
71
|
-
ownerEntityResult.id,
|
|
72
|
-
]);
|
|
85
|
+
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [ownerEntityResult.id]);
|
|
73
86
|
const firstResult = await ensureFinancialEntity(client, {
|
|
74
87
|
name: 'Child Entity',
|
|
75
88
|
type: 'tax_category',
|
|
@@ -85,8 +98,8 @@ describe('ensureFinancialEntity', () => {
|
|
|
85
98
|
const countResult = await client.query(`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')}
|
|
86
99
|
WHERE name = $1 AND type = $2 AND owner_id = $3`, ['Child Entity', 'tax_category', ownerEntityResult.id]);
|
|
87
100
|
expect(parseInt(countResult.rows[0].count)).toBe(1);
|
|
88
|
-
})
|
|
89
|
-
it('should distinguish entities by type', async () =>
|
|
101
|
+
});
|
|
102
|
+
it('should distinguish entities by type', async () => {
|
|
90
103
|
const businessResult = await ensureFinancialEntity(client, {
|
|
91
104
|
name: 'Same Name',
|
|
92
105
|
type: 'business',
|
|
@@ -96,22 +109,18 @@ describe('ensureFinancialEntity', () => {
|
|
|
96
109
|
type: 'tax_category',
|
|
97
110
|
});
|
|
98
111
|
expect(businessResult.id).not.toBe(taxCategoryResult.id);
|
|
99
|
-
})
|
|
100
|
-
it('should distinguish entities by owner_id', async () =>
|
|
112
|
+
});
|
|
113
|
+
it('should distinguish entities by owner_id', async () => {
|
|
101
114
|
const owner1Entity = await ensureFinancialEntity(client, {
|
|
102
115
|
name: 'Owner 1',
|
|
103
116
|
type: 'business',
|
|
104
117
|
});
|
|
105
|
-
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [
|
|
106
|
-
owner1Entity.id,
|
|
107
|
-
]);
|
|
118
|
+
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [owner1Entity.id]);
|
|
108
119
|
const owner2Entity = await ensureFinancialEntity(client, {
|
|
109
120
|
name: 'Owner 2',
|
|
110
121
|
type: 'business',
|
|
111
122
|
});
|
|
112
|
-
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [
|
|
113
|
-
owner2Entity.id,
|
|
114
|
-
]);
|
|
123
|
+
await client.query(`INSERT INTO ${qualifyTable('businesses')} (id) VALUES ($1)`, [owner2Entity.id]);
|
|
115
124
|
const entity1 = await ensureFinancialEntity(client, {
|
|
116
125
|
name: 'Same Child',
|
|
117
126
|
type: 'tax_category',
|
|
@@ -123,8 +132,8 @@ describe('ensureFinancialEntity', () => {
|
|
|
123
132
|
ownerId: owner2Entity.id,
|
|
124
133
|
});
|
|
125
134
|
expect(entity1.id).not.toBe(entity2.id);
|
|
126
|
-
})
|
|
127
|
-
it('should handle null vs undefined owner_id consistently', async () =>
|
|
135
|
+
});
|
|
136
|
+
it('should handle null vs undefined owner_id consistently', async () => {
|
|
128
137
|
const result1 = await ensureFinancialEntity(client, {
|
|
129
138
|
name: 'No Owner Entity',
|
|
130
139
|
type: 'business',
|
|
@@ -135,8 +144,8 @@ describe('ensureFinancialEntity', () => {
|
|
|
135
144
|
type: 'business',
|
|
136
145
|
});
|
|
137
146
|
expect(result1.id).toBe(result2.id);
|
|
138
|
-
})
|
|
139
|
-
it('should not leak data between tests', async () =>
|
|
147
|
+
});
|
|
148
|
+
it('should not leak data between tests', async () => {
|
|
140
149
|
// This test verifies that ROLLBACK works correctly
|
|
141
150
|
// Create an entity in this test
|
|
142
151
|
await ensureFinancialEntity(client, {
|
|
@@ -147,25 +156,25 @@ describe('ensureFinancialEntity', () => {
|
|
|
147
156
|
const checkInTransaction = await client.query(`SELECT COUNT(*) FROM ${qualifyTable('financial_entities')} WHERE name = $1`, ['Transient Entity']);
|
|
148
157
|
expect(parseInt(checkInTransaction.rows[0].count)).toBe(1);
|
|
149
158
|
// After ROLLBACK in afterEach, this data won't be visible in next test
|
|
150
|
-
})
|
|
159
|
+
});
|
|
151
160
|
// Validation tests
|
|
152
|
-
it('should reject empty entity name', async () =>
|
|
161
|
+
it('should reject empty entity name', async () => {
|
|
153
162
|
await expect(ensureFinancialEntity(client, {
|
|
154
163
|
name: '',
|
|
155
164
|
type: 'business',
|
|
156
165
|
})).rejects.toThrow(EntityValidationError);
|
|
157
|
-
})
|
|
158
|
-
it('should reject invalid entity type', async () =>
|
|
166
|
+
});
|
|
167
|
+
it('should reject invalid entity type', async () => {
|
|
159
168
|
await expect(ensureFinancialEntity(client, {
|
|
160
169
|
name: 'Test Entity',
|
|
161
170
|
type: 'invalid_type',
|
|
162
171
|
})).rejects.toThrow(EntityValidationError);
|
|
163
|
-
})
|
|
164
|
-
it('should reject whitespace-only name', async () =>
|
|
172
|
+
});
|
|
173
|
+
it('should reject whitespace-only name', async () => {
|
|
165
174
|
await expect(ensureFinancialEntity(client, {
|
|
166
175
|
name: ' ',
|
|
167
176
|
type: 'business',
|
|
168
177
|
})).rejects.toThrow(EntityValidationError);
|
|
169
|
-
})
|
|
178
|
+
});
|
|
170
179
|
});
|
|
171
180
|
//# sourceMappingURL=seed-helpers.financial-entity.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-helpers.financial-entity.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/seed-helpers.financial-entity.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"seed-helpers.financial-entity.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/helpers/seed-helpers.financial-entity.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
import { describe, expect, it, beforeAll, afterAll } from 'vitest';
|
|
2
|
-
import
|
|
1
|
+
import { describe, expect, it, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import pg from 'pg';
|
|
3
|
+
import { testDbConfig, qualifyTable } from './test-db-config.js';
|
|
3
4
|
import { ensureFinancialEntity, ensureTaxCategoryForEntity } from './seed-helpers.js';
|
|
4
5
|
import { EntityValidationError } from './seed-errors.js';
|
|
5
|
-
import { TestDatabase } from './db-setup.js';
|
|
6
6
|
describe('ensureTaxCategoryForEntity', () => {
|
|
7
|
-
let
|
|
7
|
+
let pool;
|
|
8
|
+
let client;
|
|
8
9
|
beforeAll(async () => {
|
|
9
|
-
|
|
10
|
-
await
|
|
10
|
+
pool = new pg.Pool(testDbConfig);
|
|
11
|
+
client = await pool.connect();
|
|
11
12
|
});
|
|
12
13
|
afterAll(async () => {
|
|
13
|
-
|
|
14
|
+
client.release();
|
|
15
|
+
await pool.end();
|
|
14
16
|
});
|
|
15
|
-
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
await client.query('BEGIN');
|
|
19
|
+
});
|
|
20
|
+
afterEach(async () => {
|
|
21
|
+
await client.query('ROLLBACK');
|
|
22
|
+
});
|
|
23
|
+
it('should create tax category on first call', async () => {
|
|
16
24
|
// Create financial entity
|
|
17
25
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
18
26
|
name: 'VAT Category',
|
|
@@ -24,8 +32,8 @@ describe('ensureTaxCategoryForEntity', () => {
|
|
|
24
32
|
const result = await client.query(`SELECT id FROM ${qualifyTable('tax_categories')} WHERE id = $1`, [entityId]);
|
|
25
33
|
expect(result.rows).toHaveLength(1);
|
|
26
34
|
expect(result.rows[0].id).toBe(entityId);
|
|
27
|
-
})
|
|
28
|
-
it('should be idempotent (no-op on repeated calls)', async () =>
|
|
35
|
+
});
|
|
36
|
+
it('should be idempotent (no-op on repeated calls)', async () => {
|
|
29
37
|
// Create financial entity
|
|
30
38
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
31
39
|
name: 'Income Tax',
|
|
@@ -37,8 +45,8 @@ describe('ensureTaxCategoryForEntity', () => {
|
|
|
37
45
|
// Verify only one row exists
|
|
38
46
|
const result = await client.query(`SELECT COUNT(*) as count FROM ${qualifyTable('tax_categories')} WHERE id = $1`, [entityId]);
|
|
39
47
|
expect(result.rows[0].count).toBe('1');
|
|
40
|
-
})
|
|
41
|
-
it('should preserve existing values on subsequent calls', async () =>
|
|
48
|
+
});
|
|
49
|
+
it('should preserve existing values on subsequent calls', async () => {
|
|
42
50
|
// Create financial entity
|
|
43
51
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
44
52
|
name: 'Expense Category',
|
|
@@ -55,24 +63,24 @@ describe('ensureTaxCategoryForEntity', () => {
|
|
|
55
63
|
const finalResult = await client.query(`SELECT * FROM ${qualifyTable('tax_categories')} WHERE id = $1`, [entityId]);
|
|
56
64
|
const finalRow = finalResult.rows[0];
|
|
57
65
|
expect(finalRow).toEqual(initialRow);
|
|
58
|
-
})
|
|
59
|
-
it('should reject invalid UUID format', async () =>
|
|
66
|
+
});
|
|
67
|
+
it('should reject invalid UUID format', async () => {
|
|
60
68
|
await expect(ensureTaxCategoryForEntity(client, 'not-a-uuid')).rejects.toThrow(EntityValidationError);
|
|
61
69
|
await expect(ensureTaxCategoryForEntity(client, '')).rejects.toThrow(EntityValidationError);
|
|
62
70
|
await expect(ensureTaxCategoryForEntity(client, '12345')).rejects.toThrow(EntityValidationError);
|
|
63
|
-
})
|
|
64
|
-
it('should reject non-existent financial entity', async () =>
|
|
71
|
+
});
|
|
72
|
+
it('should reject non-existent financial entity', async () => {
|
|
65
73
|
const fakeUuid = '00000000-0000-0000-0000-000000000001';
|
|
66
74
|
await expect(ensureTaxCategoryForEntity(client, fakeUuid)).rejects.toThrow(EntityValidationError);
|
|
67
|
-
})
|
|
68
|
-
it('should not leak data between tests', async () =>
|
|
75
|
+
});
|
|
76
|
+
it('should not leak data between tests', async () => {
|
|
69
77
|
// This test verifies transactional isolation by checking that data
|
|
70
78
|
// from previous tests is not visible
|
|
71
79
|
const result = await client.query(`SELECT COUNT(*) as count FROM ${qualifyTable('tax_categories')} WHERE id IN (SELECT id FROM ${qualifyTable('financial_entities')} WHERE name LIKE 'VAT Category' OR name LIKE 'Income Tax' OR name LIKE 'Expense Category')`);
|
|
72
80
|
// Due to ROLLBACK after each test, count should be 0
|
|
73
81
|
expect(parseInt(result.rows[0].count)).toBe(0);
|
|
74
|
-
})
|
|
75
|
-
it('should work with entities that have owner_id', async () =>
|
|
82
|
+
});
|
|
83
|
+
it('should work with entities that have owner_id', async () => {
|
|
76
84
|
// Create owner business entity (without owner_id requirement)
|
|
77
85
|
const { id: _ownerId } = await ensureFinancialEntity(client, {
|
|
78
86
|
name: 'Owner Business',
|
|
@@ -89,8 +97,8 @@ describe('ensureTaxCategoryForEntity', () => {
|
|
|
89
97
|
const result = await client.query(`SELECT id FROM ${qualifyTable('tax_categories')} WHERE id = $1`, [taxCatId]);
|
|
90
98
|
expect(result.rows).toHaveLength(1);
|
|
91
99
|
expect(result.rows[0].id).toBe(taxCatId);
|
|
92
|
-
})
|
|
93
|
-
it('should handle options parameter gracefully (future-proofing)', async () =>
|
|
100
|
+
});
|
|
101
|
+
it('should handle options parameter gracefully (future-proofing)', async () => {
|
|
94
102
|
// Create financial entity
|
|
95
103
|
const { id: entityId } = await ensureFinancialEntity(client, {
|
|
96
104
|
name: 'Category with Options',
|
|
@@ -101,6 +109,6 @@ describe('ensureTaxCategoryForEntity', () => {
|
|
|
101
109
|
// Verify tax category exists
|
|
102
110
|
const result = await client.query(`SELECT id FROM ${qualifyTable('tax_categories')} WHERE id = $1`, [entityId]);
|
|
103
111
|
expect(result.rows).toHaveLength(1);
|
|
104
|
-
})
|
|
112
|
+
});
|
|
105
113
|
});
|
|
106
114
|
//# sourceMappingURL=seed-helpers.tax-category.test.js.map
|