test(frontend): pin connection string parsing to libpq behaviour

This commit is contained in:
Guilhem Lemouel
2026-08-13 10:38:36 +02:00
parent d5d51c9bcd
commit 5ac3d19a09
2 changed files with 13 additions and 0 deletions
@@ -35,6 +35,14 @@ describe('parsePostgresConnectionString', () => {
expect(parsePostgresConnectionString('mysql://u:p@host/db')).toBeUndefined()
expect(parsePostgresConnectionString('')).toBeUndefined()
})
// Verified against psql: `postgres://role:p%40ss@host/db` authenticates as `p@ss`, and an
// unencoded `@` puts the rest of the password in libpq's host too. Reading these any other
// way would make the same string mean something here that it means nowhere else.
it('decodes percent escapes in credentials, as libpq does', () => {
expect(parsePostgresConnectionString('postgres://u:p%40ss@host/db')?.password).toBe('p@ss')
expect(parsePostgresConnectionString('postgres://u%40corp:p@host/db')?.user).toBe('u@corp')
})
})
// The wizard offers the same connection as a string or as fields and switches between them
@@ -8,6 +8,11 @@
* The wizard offers the same connection as a string or as fields and lets the
* user switch, so parse and compose have to be inverses: whatever one produces,
* the other must read back unchanged.
*
* libpq is the arbiter of what a connection string means, so this follows it rather than
* RFC 3986 where they differ: credentials are split at the *first* `@` -- an unencoded one
* lands in the host for libpq too -- and percent escapes in them are decoded, so `p%40ss`
* authenticates as `p@ss`.
*/
const CONNECTION_STRING =