Skip to content

Commit e771ea9

Browse files
authored
fix: added Missing test cases for cleanup of the databases and updated the readme.md file (#38)
1 parent 8fb941f commit e771ea9

File tree

3 files changed

+131
-29
lines changed

3 files changed

+131
-29
lines changed

README.md

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
</p>
1111

1212
<p align="center">
13-
<img src="https://img.shields.io/badge/version-0.1.0--beta.1-blue" alt="Version" />
13+
<img src="https://img.shields.io/badge/version-0.1.0--beta.4-blue" alt="Version" />
1414
<img src="https://img.shields.io/badge/license-MIT-green" alt="License" />
1515
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20Linux-lightgrey" alt="Platform" />
16-
<img src="https://img.shields.io/badge/databases-PostgreSQL%20%7C%20MySQL-orange" alt="Databases" />
16+
<img src="https://img.shields.io/badge/databases-PostgreSQL%20%7C%20MySQL%20%7C%20MariaDB-orange" alt="Databases" />
1717
</p>
1818

1919
<p align="center">
2020
<a href="https://github.com/Yashh56/RelWave/releases"><strong>Download</strong></a> |
21-
<a href="#-features"><strong>Features</strong></a> |
22-
<a href="#-installation"><strong>Installation</strong></a> |
23-
<a href="#-contributing"><strong>Contributing</strong></a>
21+
<a href="#Features"><strong>Features</strong></a> |
22+
<a href="#Installation"><strong>Installation</strong></a> |
23+
<a href="#Contributing"><strong>Contributing</strong></a>
2424
</p>
2525

2626
---
@@ -232,11 +232,71 @@ Database connection configurations are stored in:
232232

233233
### Running Tests
234234

235+
The bridge includes a comprehensive test suite with integration tests for database connectors.
236+
237+
#### Prerequisites
238+
239+
1. **Docker** - Required for running test databases:
240+
241+
```bash
242+
cd bridge
243+
docker-compose -f docker-compose.test.yml up -d
244+
```
245+
246+
This starts PostgreSQL, MySQL, and MariaDB containers for testing.
247+
248+
2. **Environment Variables** - Create a `.env` file in the `bridge` directory:
249+
250+
```env
251+
# PostgreSQL Test Configuration
252+
REAL_POSTGRES_HOST=localhost
253+
REAL_POSTGRES_PORT=5432
254+
REAL_POSTGRES_USER=testuser
255+
REAL_POSTGRES_PASSWORD=testpass
256+
REAL_POSTGRES_DATABASE=testdb
257+
REAL_POSTGRES_SSL=false
258+
259+
# MySQL Test Configuration
260+
REAL_MYSQL_HOST=localhost
261+
REAL_MYSQL_PORT=3306
262+
REAL_MYSQL_USER=testuser
263+
REAL_MYSQL_PASSWORD=testpass
264+
REAL_MYSQL_DATABASE=testdb
265+
266+
# MariaDB Test Configuration
267+
REAL_MARIADB_HOST=localhost
268+
REAL_MARIADB_PORT=3307
269+
REAL_MARIADB_USER=testuser
270+
REAL_MARIADB_PASSWORD=testpass
271+
REAL_MARIADB_DATABASE=testdb
272+
```
273+
274+
#### Running Tests
275+
235276
```bash
236277
cd bridge
237278
pnpm test
238279
```
239280

281+
#### Test Suites
282+
283+
| Test Suite | Description |
284+
|------------|-------------|
285+
| `databaseService.test.ts` | Database service CRUD operations and validation |
286+
| `dbStore.test.ts` | Database store caching, encryption, and persistence |
287+
| `connectionBuilder.test.ts` | Connection configuration building |
288+
| `postgres.test.ts` | PostgreSQL connector integration tests |
289+
| `mysql.test.ts` | MySQL connector integration tests |
290+
| `mariadb.test.ts` | MariaDB connector integration tests |
291+
| `*.cache.test.ts` | Query result caching tests for each connector |
292+
293+
#### Stopping Test Databases
294+
295+
```bash
296+
cd bridge
297+
docker-compose -f docker-compose.test.yml down
298+
```
299+
240300
### Architecture
241301

242302
The application uses a **bridge architecture**:

bridge/__tests__/databaseService.test.ts

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { afterEach, describe, expect, test } from "@jest/globals";
1+
import { afterAll, describe, expect, test } from "@jest/globals";
22
import { DatabaseService } from "../src/services/databaseService";
33

44
const mockInput = {
@@ -11,32 +11,50 @@ const mockInput = {
1111
ssl: true,
1212
};
1313

14-
let createdDbId: string | null = null;
14+
// Test database names that should be cleaned up
15+
const TEST_DB_NAMES = ["TestDB", "DeleteTestDB"];
16+
17+
// Track all created database IDs for cleanup
18+
const createdDbIds: string[] = [];
1519

1620
describe("Database Service Method", () => {
1721
const dbService = new DatabaseService();
1822

19-
afterEach(async () => {
20-
if (createdDbId) {
23+
// Clean up ALL test databases after all tests complete
24+
afterAll(async () => {
25+
// First, clean up databases we explicitly tracked
26+
for (const id of createdDbIds) {
2127
try {
22-
await dbService.deleteDatabase(createdDbId);
28+
await dbService.deleteDatabase(id);
2329
} catch (e) {
24-
// Silently ignore "Database not found" errors - expected when test didn't create a DB
25-
if (!(e instanceof Error && e.message === "Database not found")) {
26-
console.warn("Cleanup failed:", e);
30+
// Ignore - may already be deleted
31+
}
32+
}
33+
34+
// Then, clean up any remaining test databases by name (safety net)
35+
try {
36+
const dbs = await dbService.listDatabases();
37+
for (const db of dbs) {
38+
if (TEST_DB_NAMES.includes(db.name)) {
39+
try {
40+
await dbService.deleteDatabase(db.id);
41+
} catch (e) {
42+
// Ignore deletion errors during cleanup
43+
}
2744
}
2845
}
29-
createdDbId = null;
46+
} catch (e) {
47+
// Ignore errors during final cleanup
3048
}
3149
});
50+
3251
// Test Case 1: All required fields provided
3352
test("should add database when all required fields are provided", async () => {
3453
// Arrange
35-
const dbService = new DatabaseService();
3654
const payload = { ...mockInput };
3755
// Act
3856
const result = await dbService.addDatabase(payload);
39-
createdDbId = result.id;
57+
createdDbIds.push(result.id); // Track for cleanup
4058
// Assert
4159
expect(result).toBeDefined();
4260
expect(result.name).toBe(payload.name);
@@ -46,7 +64,6 @@ describe("Database Service Method", () => {
4664

4765
test("should throw error when required field 'host' is missing", async () => {
4866
// Arrange
49-
const dbService = new DatabaseService();
5067
const { host, ...payload } = mockInput;
5168
// Act & Assert
5269
await expect(dbService.addDatabase(payload)).rejects.toThrow(
@@ -57,7 +74,6 @@ describe("Database Service Method", () => {
5774
// Test Case 3: Missing required field 'user'
5875
test("should throw error when required field 'user' is missing", async () => {
5976
// Arrange
60-
const dbService = new DatabaseService();
6177
const { user, ...payload } = mockInput;
6278
// Act & Assert
6379
await expect(dbService.addDatabase(payload)).rejects.toThrow(
@@ -68,7 +84,6 @@ describe("Database Service Method", () => {
6884
// Test Case 4: Missing required field 'database'
6985
test("should throw error when required field 'database' is missing", async () => {
7086
// Arrange
71-
const dbService = new DatabaseService();
7287
const { database, ...payload } = mockInput;
7388
// Act & Assert
7489
await expect(dbService.addDatabase(payload)).rejects.toThrow(
@@ -79,7 +94,6 @@ describe("Database Service Method", () => {
7994
// Test Case 5: Missing required field 'type'
8095
test("should throw error when required field 'type' is missing", async () => {
8196
// Arrange
82-
const dbService = new DatabaseService();
8397
const { type, ...payload } = mockInput;
8498
// Act & Assert
8599
await expect(dbService.addDatabase(payload)).rejects.toThrow(
@@ -90,7 +104,6 @@ describe("Database Service Method", () => {
90104
// Test Case 6: Missing required field 'name'
91105
test("should throw error when required field 'name' is missing", async () => {
92106
// Arrange
93-
const dbService = new DatabaseService();
94107
const { name, ...payload } = mockInput;
95108
// Act & Assert
96109
await expect(dbService.addDatabase(payload)).rejects.toThrow(
@@ -101,7 +114,6 @@ describe("Database Service Method", () => {
101114
// Test Case 7: Missing required field 'port'
102115
test("should throw error when required field 'port' is missing", async () => {
103116
// Arrange
104-
const dbService = new DatabaseService();
105117
const { port, ...payload } = mockInput;
106118
// Act & Assert
107119
await expect(dbService.addDatabase(payload)).rejects.toThrow(
@@ -112,7 +124,6 @@ describe("Database Service Method", () => {
112124
// Test Case 8 : List databases does not expose credentialId
113125
test("should not expose credentialId when listing databases", async () => {
114126
// Arrange
115-
const dbService = new DatabaseService();
116127
// Act
117128
const dbs = await dbService.listDatabases();
118129
// Assert
@@ -124,7 +135,6 @@ describe("Database Service Method", () => {
124135
// Test Case 9: Get database connection for non-existent DB
125136
test("should throw error when getting connection for non-existent database", async () => {
126137
// Arrange
127-
const dbService = new DatabaseService();
128138
const fakeDbId = "nonexistent-id";
129139
// Act & Assert
130140
await expect(dbService.getDatabaseConnection(fakeDbId)).rejects.toThrow(
@@ -135,7 +145,6 @@ describe("Database Service Method", () => {
135145
// Test Case 10: Update database with missing ID
136146
test("should throw error when updating database with missing ID", async () => {
137147
// Arrange
138-
const dbService = new DatabaseService();
139148
const payload = { name: "UpdatedName" };
140149
// Act & Assert
141150
await expect(dbService.updateDatabase("", payload)).rejects.toThrow(
@@ -146,8 +155,41 @@ describe("Database Service Method", () => {
146155
// Test Case 11: Delete database with missing ID
147156
test("should throw error when deleting database with missing ID", async () => {
148157
// Arrange
149-
const dbService = new DatabaseService();
150158
// Act & Assert
151159
await expect(dbService.deleteDatabase("")).rejects.toThrow("Missing id");
152160
});
161+
162+
// Test Case 12: Successfully delete an existing database
163+
test("should successfully delete an existing database", async () => {
164+
// Arrange
165+
const payload = { ...mockInput, name: "DeleteTestDB" };
166+
167+
// Act - Create a database first
168+
const createdDb = await dbService.addDatabase(payload);
169+
expect(createdDb).toBeDefined();
170+
expect(createdDb.id).toBeDefined();
171+
172+
// Verify it exists in the list
173+
let dbList = await dbService.listDatabases();
174+
expect(dbList.some((db) => db.id === createdDb.id)).toBe(true);
175+
176+
// Act - Delete the database
177+
await dbService.deleteDatabase(createdDb.id);
178+
179+
// Assert - Verify it no longer exists in the list
180+
dbList = await dbService.listDatabases();
181+
expect(dbList.some((db) => db.id === createdDb.id)).toBe(false);
182+
183+
// Note: No need to set createdDbId here since we already deleted it
184+
});
185+
186+
// Test Case 13: Delete non-existent database should throw error
187+
test("should throw error when deleting non-existent database", async () => {
188+
// Arrange
189+
const fakeDbId = "nonexistent-database-id";
190+
// Act & Assert
191+
await expect(dbService.deleteDatabase(fakeDbId)).rejects.toThrow(
192+
"Database not found"
193+
);
194+
});
153195
});

bridge/__tests__/dbStore.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const TEST_CREDENTIALS_FILE = path.join(TEST_CONFIG_FOLDER, ".credentials");
1212
const TEST_ENCRYPTION_KEY = "test-encryption-key";
1313

1414
// Short TTL for testing cache expiration
15-
const SHORT_CACHE_TTL = 100; // 100ms for testing
15+
const SHORT_CACHE_TTL = 200; // 200ms for testing
1616
const NORMAL_CACHE_TTL = 30000; // 30 seconds
1717

1818
const mockDBPayload = {
@@ -207,8 +207,8 @@ describe("DbStore Cache Tests", () => {
207207
// Cache should be populated after addDB (saveAll updates cache)
208208
expect(shortTtlStore.getCacheStats().configCached).toBe(true);
209209

210-
// Wait for TTL to expire
211-
await new Promise((resolve) => setTimeout(resolve, SHORT_CACHE_TTL + 50));
210+
// Wait for TTL to expire (add extra buffer for system lag)
211+
await new Promise((resolve) => setTimeout(resolve, SHORT_CACHE_TTL + 150));
212212

213213
// Cache should be expired now
214214
expect(shortTtlStore.getCacheStats().configCached).toBe(false);

0 commit comments

Comments
 (0)