Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supports multiple connections in the neo4j VSCode plugin #357

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

ncordon
Copy link
Collaborator

@ncordon ncordon commented Feb 12, 2025

Adds the ability to maintain several connections in the VSCode plugin.

Copy link

changeset-bot bot commented Feb 12, 2025

⚠️ No Changeset found

Latest commit: c3b33c1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment on lines +23 to +26
if (found) {
await found.notification.dismiss();
return true;
} else {
Copy link
Collaborator Author

@ncordon ncordon Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this so we always close a notification when we've found it. Otherwise notifications keep piling up and if I connect to an instance and I disconnect, I would still be able to find the notification Connected to neo4j when that's not the state of the extension anymore

Comment on lines -19 to -47
const activityBar = workbench.getActivityBar();
const maybeNeo4jTile = await activityBar.getViewControl('Neo4j');
if (maybeNeo4jTile) {
neo4jTile = maybeNeo4jTile;
const connectionPannel = await neo4jTile.openView();
const content = connectionPannel.getContent();
const sections = await content.getSections();
connectionSection = sections.at(0);
}
connectionSection = await getConnectionSection(workbench);
});

async function clickOnContextMenuItem(item: string) {
const items = await connectionSection.getVisibleItems();
await expect(items.length).toBeGreaterThan(0);
const connectionItem = items.at(0) as TreeItem;

const contextMenu = await connectionItem.openContextMenu();
const menuItems = await contextMenu.getItems();
const connect = menuItems.find(async (menuItem) => {
const menuText = await menuItem.elem.getText();
return menuText === item;
});

if (connect) {
const connectOption = await connect.elem;
await connectOption.click();
}
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just extracted this to common helpers

await workbench.executeCommand(CONSTANTS.COMMANDS.RUN_CYPHER);
const webviews = await workbench.getAllWebviews();
await expect(webviews.length).toBe(1);
test('results should depend on the instance we are connected to', async function () {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really the only new test from this file, the rest is restructuring

@ncordon ncordon force-pushed the multiple-connections branch from 0aa2a31 to ad2131b Compare February 14, 2025 16:06
Comment on lines -1 to -6
NEO4J_SCHEME=neo4j
NEO4J_HOST=localhost
NEO4J_PORT={PORT}
NEO4J_USER=neo4j
NEO4J_DATABASE=neo4j
NEO4J_PASSWORD={PASSWORD}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized we don't need this file anymore because it was used to pass the port and password to the tests, but we can do that via a better mechanism

extensionTestsEnv: { CYPHER_25: 'true' },
extensionTestsEnv: {
CYPHER_25: 'true',
NEO4J_PORT: neo4jInstance.getMappedPort(7687).toString(),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the proper way to pass env variables to the tests

Comment on lines -35 to -49
function setSetting(file: string, variable: RegExp, value: string) {
const data = fs.readFileSync(file).toString();
const result = data.replace(variable, value);
fs.writeFileSync(file, result);
}

function updateDotenvFile(port: number, password: string) {
const dotenvPath = path.join(__dirname, '../../tests/fixtures/');
const dotenvTemplate = path.join(dotenvPath, '.env');
const dotenvFile = path.join(dotenvPath, '.env.test');
fs.copyFileSync(dotenvTemplate, dotenvFile);
setSetting(dotenvFile, /\{PORT\}/g, port.toString());
setSetting(dotenvFile, /\{PASSWORD\}/g, password);
dotenv.config({ path: dotenvFile });
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just cleans up these because we can pass the env variables better to the tests

Copy link
Collaborator

@anderson4j anderson4j left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had one question, otherwise looks good. I tested around a bit with it in the playground though, and found 2 things that were a bit unexpected.

1 - (and I think this one is how it was before too) - if I want to close down a "create new connection" pop-up, I dont have an x in the corner, or something like pressing esc or outside the pop-up to close it which is what I first expected. I then found that the pop-up actually opens like a new tab/file in the playground. If you agree that this is less intuitive (and its not too hard to change) maybe we should change it in a follow-up PR?

2 -
Creating new connections - to me it works like this:
if active db at given connection info (port etc) exists, creating connection with password x only works if x is the correct password. Too many tries gets your session blocked, You are also allowed to create multiple sessions with the exact same info (including password) this way

If db at connection info is not active, you get a pop-up ("Unable to connect...") and are allowed to add the connection.

The disparity of how this works is confusing to me, I would expect to either
A: never be able to add a db I can connect to, or
B: to always be allowed to add connections that dont exist at the moment.
(As a user, I would prefer option B, since I might want to create 3 dbs with same info but different passwords, and having to start/stop dbs between to create connections (instead of doing all at once) seems annoying)

Also once these connections are created, the order of creation and password length is the only way to tell them apart, so I could easily see myself forgetting which has which password. Possible solutions - nicknames for connections displayed next to the existing info. Or maybe we just dont allow multiple connections to same scheme/host/port/user, but I think I prefer the other one.

(edit: also another follow-up suggestion: since we don't show the password I assume we want it secret, so another step for that could be showing x amount of *s always, instead of having them match the password in length)

const webviews = await workbench.getAllWebviews();
await expect(webviews.length).toBe(1);
test('results should depend on the instance we are connected to', async function () {
if (os.platform() === 'darwin') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I find online, "darwin" is a unix-variant used by Mac-OS, so would this test not run on Mac? Why if so?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess because of the issue mentioned in the comment on clickOnContextMenuItem? Are the test servers used in github not macos so it still runs regularly then? (PS test:apiAndUnit works for me on windows, so I guess test still passes right now)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants