Skip to content

Commit 71a3e45

Browse files
committed
fix: issue 327
1 parent a1fdb5b commit 71a3e45

File tree

1 file changed

+381
-0
lines changed

1 file changed

+381
-0
lines changed

crates/pgt_lsp/tests/server.rs

+381
Original file line numberDiff line numberDiff line change
@@ -1112,3 +1112,384 @@ async fn test_issue_303() -> Result<()> {
11121112

11131113
Ok(())
11141114
}
1115+
1116+
#[tokio::test]
1117+
async fn test_issue_328() -> Result<()> {
1118+
let factory = ServerFactory::default();
1119+
let mut fs = MemoryFileSystem::default();
1120+
let test_db = get_new_test_db().await;
1121+
1122+
let setup = r#"
1123+
create table public.users (
1124+
id serial primary key,
1125+
name varchar(255) not null
1126+
);
1127+
"#;
1128+
1129+
test_db
1130+
.execute(setup)
1131+
.await
1132+
.expect("Failed to setup test database");
1133+
1134+
let mut conf = PartialConfiguration::init();
1135+
conf.merge_with(PartialConfiguration {
1136+
db: Some(PartialDatabaseConfiguration {
1137+
database: Some(
1138+
test_db
1139+
.connect_options()
1140+
.get_database()
1141+
.unwrap()
1142+
.to_string(),
1143+
),
1144+
..Default::default()
1145+
}),
1146+
..Default::default()
1147+
});
1148+
fs.insert(
1149+
url!("postgrestools.jsonc").to_file_path().unwrap(),
1150+
serde_json::to_string_pretty(&conf).unwrap(),
1151+
);
1152+
1153+
let (service, client) = factory
1154+
.create_with_fs(None, DynRef::Owned(Box::new(fs)))
1155+
.into_inner();
1156+
1157+
let (stream, sink) = client.split();
1158+
let mut server = Server::new(service);
1159+
1160+
let (sender, mut receiver) = channel(CHANNEL_BUFFER_SIZE);
1161+
let reader = tokio::spawn(client_handler(stream, sink, sender));
1162+
1163+
server.initialize().await?;
1164+
server.initialized().await?;
1165+
1166+
server.load_configuration().await?;
1167+
1168+
server
1169+
.open_document("-- Create the company table\nCREATE TABLE company (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n name VARCHAR(255) NOT NULL,\n email VARCHAR(255) UNIQUE NOT NULL\n);\n\n-- Create the business table\nCREATE TABLE business (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n name VARCHAR(255) NOT NULL,\n email VARCHAR(255) UNIQUE NOT NULL,\n company_id UUID REFERENCES company(id) NOT NULL,\n INDEX (company_id)\n);")
1170+
.await?;
1171+
1172+
let notification = tokio::time::timeout(Duration::from_secs(5), async {
1173+
loop {
1174+
match receiver.next().await {
1175+
Some(ServerNotification::PublishDiagnostics(msg)) => {
1176+
if msg
1177+
.diagnostics
1178+
.iter()
1179+
.any(|d| d.message.contains("column \"unknown\" does not exist"))
1180+
{
1181+
return true;
1182+
}
1183+
}
1184+
_ => continue,
1185+
}
1186+
}
1187+
})
1188+
.await
1189+
.is_ok();
1190+
1191+
assert!(notification, "expected diagnostics for unknown column");
1192+
1193+
server.shutdown().await?;
1194+
reader.abort();
1195+
1196+
Ok(())
1197+
}
1198+
1199+
#[tokio::test]
1200+
async fn test_issue_327() -> Result<()> {
1201+
let factory = ServerFactory::default();
1202+
let mut fs = MemoryFileSystem::default();
1203+
let test_db = get_new_test_db().await;
1204+
1205+
let setup = r#"
1206+
create table public.users (
1207+
id serial primary key,
1208+
name varchar(255) not null
1209+
);
1210+
"#;
1211+
1212+
test_db
1213+
.execute(setup)
1214+
.await
1215+
.expect("Failed to setup test database");
1216+
1217+
let mut conf = PartialConfiguration::init();
1218+
conf.merge_with(PartialConfiguration {
1219+
db: Some(PartialDatabaseConfiguration {
1220+
database: Some(
1221+
test_db
1222+
.connect_options()
1223+
.get_database()
1224+
.unwrap()
1225+
.to_string(),
1226+
),
1227+
..Default::default()
1228+
}),
1229+
..Default::default()
1230+
});
1231+
fs.insert(
1232+
url!("postgrestools.jsonc").to_file_path().unwrap(),
1233+
serde_json::to_string_pretty(&conf).unwrap(),
1234+
);
1235+
1236+
let (service, client) = factory
1237+
.create_with_fs(None, DynRef::Owned(Box::new(fs)))
1238+
.into_inner();
1239+
1240+
let (stream, sink) = client.split();
1241+
let mut server = Server::new(service);
1242+
1243+
let (sender, _) = channel(CHANNEL_BUFFER_SIZE);
1244+
let reader = tokio::spawn(client_handler(stream, sink, sender));
1245+
1246+
server.initialize().await?;
1247+
server.initialized().await?;
1248+
1249+
server.load_configuration().await?;
1250+
1251+
// Initial document content - a complex SQL file with multiple statements
1252+
let initial_content = r#"/* https://supabase.com/docs/guides/database/postgres/custom-claims-and-role-based-access-control-rbac#create-a-table-to-track-user-roles-and-permissions */
1253+
-----------------------------
1254+
/* User Permission Levels */
1255+
---------------------------
1256+
CREATE TYPE public.user_permission_level
1257+
AS ENUM('admin', 'manager', 'member');
1258+
1259+
1260+
CREATE SCHEMA private;
1261+
1262+
sadjhkyjcxv sd 23
1263+
1264+
1265+
CREATE TABLE private.user_permission_levels (
1266+
user_id UUID PRIMARY KEY,
1267+
permission_level user_permission_level NOT NULL,
1268+
1269+
CONSTRAINT "user_permission_levels_user_id_fkey"
1270+
FOREIGN KEY (user_id)
1271+
REFERENCES auth.users (id)
1272+
ON UPDATE CASCADE
1273+
ON DELETE CASCADE
1274+
);
1275+
1276+
1277+
COMMENT ON TABLE private.user_permission_levels
1278+
IS 'Permission levels for each user.';
1279+
1280+
1281+
/*
1282+
ALTER TABLE private.user_permission_levels ENABLE ROW LEVEL SECURITY; */
1283+
/*
1284+
GRANT ALL ON TABLE private.user_permission_levels TO supabase_auth_admin; */
1285+
/* CREATE POLICY "Allow auth admin to read user permission levels" ON private.user_permission_levels FOR
1286+
SELECT
1287+
TO supabase_auth_admin USING (TRUE); */
1288+
/* */
1289+
-------------------------------
1290+
/* Custom Access Token Hook */
1291+
/* Executed while building JWT for user access token */
1292+
/* Must be enabled in Supabase Dashboard (for managed) or in config.toml (for local dev) */
1293+
------------------------------------------------------------------------------------------"#;
1294+
1295+
server
1296+
.open_named_document(initial_content, url!("document.sql"))
1297+
.await?;
1298+
1299+
server
1300+
.change_document(
1301+
21,
1302+
vec![TextDocumentContentChangeEvent {
1303+
range: Some(Range {
1304+
start: Position {
1305+
line: 9,
1306+
character: 0,
1307+
},
1308+
end: Position {
1309+
line: 10,
1310+
character: 17,
1311+
},
1312+
}),
1313+
range_length: Some(19),
1314+
text: "".to_string(),
1315+
}],
1316+
)
1317+
.await?;
1318+
1319+
server
1320+
.change_document(
1321+
22,
1322+
vec![TextDocumentContentChangeEvent {
1323+
range: Some(Range {
1324+
start: Position {
1325+
line: 8,
1326+
character: 22,
1327+
},
1328+
end: Position {
1329+
line: 9,
1330+
character: 0,
1331+
},
1332+
}),
1333+
range_length: Some(2),
1334+
text: "".to_string(),
1335+
}],
1336+
)
1337+
.await?;
1338+
1339+
server
1340+
.change_document(
1341+
50,
1342+
vec![TextDocumentContentChangeEvent {
1343+
range: Some(Range {
1344+
start: Position {
1345+
line: 0,
1346+
character: 0,
1347+
},
1348+
end: Position {
1349+
line: 0,
1350+
character: 0,
1351+
},
1352+
}),
1353+
range_length: Some(0),
1354+
text: "-".to_string(),
1355+
}],
1356+
)
1357+
.await?;
1358+
1359+
server
1360+
.change_document(
1361+
51,
1362+
vec![TextDocumentContentChangeEvent {
1363+
range: Some(Range {
1364+
start: Position {
1365+
line: 0,
1366+
character: 1,
1367+
},
1368+
end: Position {
1369+
line: 0,
1370+
character: 1,
1371+
},
1372+
}),
1373+
range_length: Some(0),
1374+
text: "-".to_string(),
1375+
}],
1376+
)
1377+
.await?;
1378+
1379+
server
1380+
.change_document(
1381+
52,
1382+
vec![TextDocumentContentChangeEvent {
1383+
range: Some(Range {
1384+
start: Position {
1385+
line: 0,
1386+
character: 2,
1387+
},
1388+
end: Position {
1389+
line: 0,
1390+
character: 2,
1391+
},
1392+
}),
1393+
range_length: Some(0),
1394+
text: " ".to_string(),
1395+
}],
1396+
)
1397+
.await?;
1398+
1399+
server
1400+
.change_document(
1401+
57,
1402+
vec![
1403+
TextDocumentContentChangeEvent {
1404+
range: Some(Range {
1405+
start: Position {
1406+
line: 33,
1407+
character: 0,
1408+
},
1409+
end: Position {
1410+
line: 33,
1411+
character: 0,
1412+
},
1413+
}),
1414+
range_length: Some(0),
1415+
text: "-".to_string(),
1416+
},
1417+
TextDocumentContentChangeEvent {
1418+
range: Some(Range {
1419+
start: Position {
1420+
line: 32,
1421+
character: 0,
1422+
},
1423+
end: Position {
1424+
line: 32,
1425+
character: 0,
1426+
},
1427+
}),
1428+
range_length: Some(0),
1429+
text: "-".to_string(),
1430+
},
1431+
TextDocumentContentChangeEvent {
1432+
range: Some(Range {
1433+
start: Position {
1434+
line: 31,
1435+
character: 0,
1436+
},
1437+
end: Position {
1438+
line: 31,
1439+
character: 0,
1440+
},
1441+
}),
1442+
range_length: Some(0),
1443+
text: "-".to_string(),
1444+
},
1445+
TextDocumentContentChangeEvent {
1446+
range: Some(Range {
1447+
start: Position {
1448+
line: 30,
1449+
character: 0,
1450+
},
1451+
end: Position {
1452+
line: 30,
1453+
character: 0,
1454+
},
1455+
}),
1456+
range_length: Some(0),
1457+
text: "-".to_string(),
1458+
},
1459+
TextDocumentContentChangeEvent {
1460+
range: Some(Range {
1461+
start: Position {
1462+
line: 29,
1463+
character: 0,
1464+
},
1465+
end: Position {
1466+
line: 29,
1467+
character: 0,
1468+
},
1469+
}),
1470+
range_length: Some(0),
1471+
text: "-".to_string(),
1472+
},
1473+
TextDocumentContentChangeEvent {
1474+
range: Some(Range {
1475+
start: Position {
1476+
line: 28,
1477+
character: 0,
1478+
},
1479+
end: Position {
1480+
line: 28,
1481+
character: 0,
1482+
},
1483+
}),
1484+
range_length: Some(0),
1485+
text: "-".to_string(),
1486+
},
1487+
],
1488+
)
1489+
.await?;
1490+
1491+
server.shutdown().await?;
1492+
reader.abort();
1493+
1494+
Ok(())
1495+
}

0 commit comments

Comments
 (0)