@@ -242,6 +242,113 @@ suite('SqlIntegrationEnvironmentVariablesProvider', () => {
242242 // Should return empty object when integration config is missing
243243 assert . deepStrictEqual ( envVars , { } ) ;
244244 } ) ;
245+
246+ test ( 'Properly encodes special characters in PostgreSQL credentials' , async ( ) => {
247+ const uri = Uri . file ( '/test/notebook.deepnote' ) ;
248+ const integrationId = 'special-chars-db' ;
249+ const config : PostgresIntegrationConfig = {
250+ id : integrationId ,
251+ name : 'Special Chars DB' ,
252+ type : IntegrationType . Postgres ,
253+ host : 'db.example.com' ,
254+ port : 5432 ,
255+ database : 'my@db:name' ,
256+ username : 'user@domain' ,
257+ password : 'pa:ss@word!#$%' ,
258+ ssl : false
259+ } ;
260+
261+ const notebook = createMockNotebook ( uri , [
262+ createMockCell ( 0 , NotebookCellKind . Code , 'sql' , 'SELECT * FROM users' , {
263+ sql_integration_id : integrationId
264+ } )
265+ ] ) ;
266+
267+ when ( mockedVSCodeNamespaces . workspace . notebookDocuments ) . thenReturn ( [ notebook ] ) ;
268+ when ( integrationStorage . get ( integrationId ) ) . thenResolve ( config ) ;
269+
270+ const envVars = await provider . getEnvironmentVariables ( uri ) ;
271+
272+ // Check that the environment variable is set
273+ assert . property ( envVars , 'SQL_SPECIAL_CHARS_DB' ) ;
274+ const credentialsJson = JSON . parse ( envVars [ 'SQL_SPECIAL_CHARS_DB' ] ! ) ;
275+
276+ // Verify that special characters are properly URL-encoded
277+ assert . strictEqual (
278+ credentialsJson . url ,
279+ 'postgresql://user%40domain:pa%3Ass%40word!%23%24%[email protected] :5432/my%40db%3Aname' 280+ ) ;
281+ assert . deepStrictEqual ( credentialsJson . params , { } ) ;
282+ assert . strictEqual ( credentialsJson . param_style , 'format' ) ;
283+ } ) ;
284+
285+ test ( 'Normalizes integration ID with spaces and mixed case for env var name' , async ( ) => {
286+ const uri = Uri . file ( '/test/notebook.deepnote' ) ;
287+ const integrationId = 'My Production DB' ;
288+ const config : PostgresIntegrationConfig = {
289+ id : integrationId ,
290+ name : 'Production Database' ,
291+ type : IntegrationType . Postgres ,
292+ host : 'prod.example.com' ,
293+ port : 5432 ,
294+ database : 'proddb' ,
295+ username : 'admin' ,
296+ password : 'secret' ,
297+ ssl : true
298+ } ;
299+
300+ const notebook = createMockNotebook ( uri , [
301+ createMockCell ( 0 , NotebookCellKind . Code , 'sql' , 'SELECT * FROM products' , {
302+ sql_integration_id : integrationId
303+ } )
304+ ] ) ;
305+
306+ when ( mockedVSCodeNamespaces . workspace . notebookDocuments ) . thenReturn ( [ notebook ] ) ;
307+ when ( integrationStorage . get ( integrationId ) ) . thenResolve ( config ) ;
308+
309+ const envVars = await provider . getEnvironmentVariables ( uri ) ;
310+
311+ // Check that the environment variable name is properly normalized
312+ // Spaces should be converted to underscores and uppercased
313+ assert . property ( envVars , 'SQL_MY_PRODUCTION_DB' ) ;
314+ const credentialsJson = JSON . parse ( envVars [ 'SQL_MY_PRODUCTION_DB' ] ! ) ;
315+ assert . strictEqual ( credentialsJson . url , 'postgresql://admin:[email protected] :5432/proddb' ) ; 316+ assert . deepStrictEqual ( credentialsJson . params , { sslmode : 'require' } ) ;
317+ assert . strictEqual ( credentialsJson . param_style , 'format' ) ;
318+ } ) ;
319+
320+ test ( 'Normalizes integration ID with special characters for env var name' , async ( ) => {
321+ const uri = Uri . file ( '/test/notebook.deepnote' ) ;
322+ const integrationId = 'my-db@2024!' ;
323+ const config : PostgresIntegrationConfig = {
324+ id : integrationId ,
325+ name : 'Test DB' ,
326+ type : IntegrationType . Postgres ,
327+ host : 'localhost' ,
328+ port : 5432 ,
329+ database : 'testdb' ,
330+ username : 'user' ,
331+ password : 'pass' ,
332+ ssl : false
333+ } ;
334+
335+ const notebook = createMockNotebook ( uri , [
336+ createMockCell ( 0 , NotebookCellKind . Code , 'sql' , 'SELECT 1' , {
337+ sql_integration_id : integrationId
338+ } )
339+ ] ) ;
340+
341+ when ( mockedVSCodeNamespaces . workspace . notebookDocuments ) . thenReturn ( [ notebook ] ) ;
342+ when ( integrationStorage . get ( integrationId ) ) . thenResolve ( config ) ;
343+
344+ const envVars = await provider . getEnvironmentVariables ( uri ) ;
345+
346+ // Check that special characters in integration ID are normalized for env var name
347+ // Non-alphanumeric characters should be converted to underscores
348+ assert . property ( envVars , 'SQL_MY_DB_2024_' ) ;
349+ const credentialsJson = JSON . parse ( envVars [ 'SQL_MY_DB_2024_' ] ! ) ;
350+ assert . strictEqual ( credentialsJson . url , 'postgresql://user:pass@localhost:5432/testdb' ) ;
351+ } ) ;
245352} ) ;
246353
247354function createMockNotebook ( uri : Uri , cells : NotebookCell [ ] ) : NotebookDocument {
0 commit comments