Skip to content

Commit b78e928

Browse files
authored
test: add SQL formatting tests (#4052)
* perf: handle undefined values in SQL formatting * ci: add "no values" and `Date` tests * chore: reverse unnecessary changes * test: add tests for `stringifyObjects` as `false` * chore: close the connection before starting tests
1 parent d0c8317 commit b78e928

File tree

2 files changed

+250
-0
lines changed

2 files changed

+250
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { assert, describe, it } from 'poku';
2+
import { createRequire } from 'node:module';
3+
4+
const require = createRequire(import.meta.url);
5+
const { config } = require('../../../common.test.cjs');
6+
const driver = require('../../../../index.js');
7+
8+
const connection = driver
9+
.createConnection({
10+
...config,
11+
stringifyObjects: false,
12+
})
13+
.promise();
14+
15+
const format = (sql, values) => connection.connection.format(sql, values);
16+
17+
await connection.end();
18+
19+
describe('SELECT without values', () => {
20+
it('should return the query unchanged', () => {
21+
const query = format('SELECT * FROM users', []);
22+
23+
assert.strictEqual(query, 'SELECT * FROM users');
24+
});
25+
});
26+
27+
describe('SELECT with object parameter', () => {
28+
it('should generate a safe query for a legitimate string', () => {
29+
const query = format('SELECT * FROM users WHERE email = ?', [
30+
'admin@example.com',
31+
]);
32+
33+
assert.strictEqual(
34+
query,
35+
"SELECT * FROM users WHERE email = 'admin@example.com'"
36+
);
37+
});
38+
39+
it.todo('should not generate a SQL fragment for object { email: 1 }', () => {
40+
const query = format('SELECT * FROM users WHERE email = ?', [{ email: 1 }]);
41+
42+
assert.strictEqual(
43+
query,
44+
"SELECT * FROM users WHERE email = '[object Object]'"
45+
);
46+
});
47+
});
48+
49+
describe('SELECT with multiple parameters', () => {
50+
it('should generate a safe query for a wrong password', () => {
51+
const query = format(
52+
'SELECT * FROM users WHERE email = ? AND password = ?',
53+
['admin@example.com', 'wrong_password']
54+
);
55+
56+
assert.strictEqual(
57+
query,
58+
"SELECT * FROM users WHERE email = 'admin@example.com' AND password = 'wrong_password'"
59+
);
60+
});
61+
62+
it.todo(
63+
'should not alter the query structure for object { email: 1 }',
64+
() => {
65+
const query = format(
66+
'SELECT * FROM users WHERE email = ? AND password = ?',
67+
[{ email: 1 }, 'user1_pass']
68+
);
69+
70+
assert.strictEqual(
71+
query,
72+
"SELECT * FROM users WHERE email = '[object Object]' AND password = 'user1_pass'"
73+
);
74+
}
75+
);
76+
});
77+
78+
describe('DELETE with object parameter', () => {
79+
it('should generate a safe query for a legitimate id', () => {
80+
const query = format('DELETE FROM users WHERE id = ?', [1]);
81+
82+
assert.strictEqual(query, 'DELETE FROM users WHERE id = 1');
83+
});
84+
85+
it.todo('should not generate a SQL fragment for object { id: true }', () => {
86+
const query = format('DELETE FROM users WHERE id = ?', [{ id: true }]);
87+
88+
assert.strictEqual(query, "DELETE FROM users WHERE id = '[object Object]'");
89+
});
90+
});
91+
92+
describe('SET with object parameter', () => {
93+
it('should convert object to key-value pairs for SET clause', () => {
94+
const query = format('UPDATE users SET ?', [
95+
{ name: 'foo', email: 'bar@test.com' },
96+
]);
97+
98+
assert.strictEqual(
99+
query,
100+
"UPDATE users SET `name` = 'foo', `email` = 'bar@test.com'"
101+
);
102+
});
103+
});
104+
105+
describe('SELECT and INSERT with Date parameter', () => {
106+
it('should format Date as a valid datetime string, not as [object Object]', () => {
107+
const date = new Date('2026-01-01T10:30:00.000Z');
108+
const query = format('SELECT * FROM events WHERE created_at = ?', [date]);
109+
110+
assert.strictEqual(
111+
query,
112+
"SELECT * FROM events WHERE created_at = '2026-01-01 10:30:00.000'"
113+
);
114+
});
115+
116+
it('should format Date in INSERT statements', () => {
117+
const date = new Date('2026-01-01T00:00:00.000Z');
118+
const query = format(
119+
'INSERT INTO logs (message, created_at) VALUES (?, ?)',
120+
['test', date]
121+
);
122+
123+
assert.strictEqual(
124+
query,
125+
"INSERT INTO logs (message, created_at) VALUES ('test', '2026-01-01 00:00:00.000')"
126+
);
127+
});
128+
});
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { assert, describe, it } from 'poku';
2+
import { createRequire } from 'node:module';
3+
4+
const require = createRequire(import.meta.url);
5+
const { config } = require('../../../common.test.cjs');
6+
const driver = require('../../../../index.js');
7+
8+
const connection = driver
9+
.createConnection({
10+
...config,
11+
stringifyObjects: true,
12+
})
13+
.promise();
14+
15+
const format = (sql, values) => connection.connection.format(sql, values);
16+
17+
await connection.end();
18+
19+
describe('SELECT without values', () => {
20+
it('should return the query unchanged', () => {
21+
const query = format('SELECT * FROM users', []);
22+
23+
assert.strictEqual(query, 'SELECT * FROM users');
24+
});
25+
});
26+
27+
describe('SELECT with object parameter', () => {
28+
it('should generate a safe query for a legitimate string', () => {
29+
const query = format('SELECT * FROM users WHERE email = ?', [
30+
'admin@example.com',
31+
]);
32+
33+
assert.strictEqual(
34+
query,
35+
"SELECT * FROM users WHERE email = 'admin@example.com'"
36+
);
37+
});
38+
39+
it('should not generate a SQL fragment for object { email: 1 }', () => {
40+
const query = format('SELECT * FROM users WHERE email = ?', [{ email: 1 }]);
41+
42+
assert.strictEqual(
43+
query,
44+
"SELECT * FROM users WHERE email = '[object Object]'"
45+
);
46+
});
47+
});
48+
49+
describe('SELECT with multiple parameters', () => {
50+
it('should generate a safe query for a wrong password', () => {
51+
const query = format(
52+
'SELECT * FROM users WHERE email = ? AND password = ?',
53+
['admin@example.com', 'wrong_password']
54+
);
55+
56+
assert.strictEqual(
57+
query,
58+
"SELECT * FROM users WHERE email = 'admin@example.com' AND password = 'wrong_password'"
59+
);
60+
});
61+
62+
it('should not alter the query structure for object { email: 1 }', () => {
63+
const query = format(
64+
'SELECT * FROM users WHERE email = ? AND password = ?',
65+
[{ email: 1 }, 'user1_pass']
66+
);
67+
68+
assert.strictEqual(
69+
query,
70+
"SELECT * FROM users WHERE email = '[object Object]' AND password = 'user1_pass'"
71+
);
72+
});
73+
});
74+
75+
describe('DELETE with object parameter', () => {
76+
it('should generate a safe query for a legitimate id', () => {
77+
const query = format('DELETE FROM users WHERE id = ?', [1]);
78+
79+
assert.strictEqual(query, 'DELETE FROM users WHERE id = 1');
80+
});
81+
82+
it('should not generate a SQL fragment for object { id: true }', () => {
83+
const query = format('DELETE FROM users WHERE id = ?', [{ id: true }]);
84+
85+
assert.strictEqual(query, "DELETE FROM users WHERE id = '[object Object]'");
86+
});
87+
});
88+
89+
describe('SET with object parameter', () => {
90+
it('should stringify object instead of expanding to key-value pairs', () => {
91+
const query = format('UPDATE users SET ?', [
92+
{ name: 'foo', email: 'bar@test.com' },
93+
]);
94+
95+
assert.strictEqual(query, "UPDATE users SET '[object Object]'");
96+
});
97+
});
98+
99+
describe('SELECT and INSERT with Date parameter', () => {
100+
it('should format Date as a valid datetime string, not as [object Object]', () => {
101+
const date = new Date('2026-01-01T10:30:00.000Z');
102+
const query = format('SELECT * FROM events WHERE created_at = ?', [date]);
103+
104+
assert.strictEqual(
105+
query,
106+
"SELECT * FROM events WHERE created_at = '2026-01-01 10:30:00.000'"
107+
);
108+
});
109+
110+
it('should format Date in INSERT statements', () => {
111+
const date = new Date('2026-01-01T00:00:00.000Z');
112+
const query = format(
113+
'INSERT INTO logs (message, created_at) VALUES (?, ?)',
114+
['test', date]
115+
);
116+
117+
assert.strictEqual(
118+
query,
119+
"INSERT INTO logs (message, created_at) VALUES ('test', '2026-01-01 00:00:00.000')"
120+
);
121+
});
122+
});

0 commit comments

Comments
 (0)