Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

package com.microsoft.copilot.eclipse.ui.preferences;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import com.microsoft.copilot.eclipse.core.Constants;
import com.microsoft.copilot.eclipse.ui.utils.SwtUtils;

class GeneralPreferencesPageTest {

private Shell shell;
private TestPreferencesPage page;

@AfterEach
void tearDown() {
SwtUtils.invokeOnDisplayThread(() -> {
if (page != null) {
page.dispose();
}
if (shell != null && !shell.isDisposed()) {
shell.dispose();
}
});
}

@ParameterizedTest
@ValueSource(strings = {"", "https://company.ghe.com", "https://company.ghe.com/",
"https://github.company.example:8443", "HTTPS://company.ghe.com", "HtTpS://company.ghe.com"})
void testEnterpriseEndpoint_validStoredValue_pageIsValid(String endpoint) {
SwtUtils.invokeOnDisplayThread(() -> {
createPage(endpoint);
assertTrue(page.isValid());
assertNull(page.getErrorMessage());
});
}

@ParameterizedTest
@ValueSource(strings = {"http://company.ghe.com/", "company.ghe.com", "ftp://company.ghe.com",
"https://", "https:///company.ghe.com", "https://company ghe.com", "https://company.ghe.com/%",
" ", " https://company.ghe.com", "https://company.ghe.com "})
void testEnterpriseEndpoint_invalidStoredValue_pageShowsError(String endpoint) {
SwtUtils.invokeOnDisplayThread(() -> {
createPage(endpoint);
assertFalse(page.isValid());
assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage());
});
}

@ParameterizedTest
@ValueSource(strings = {"", "https://company.ghe.com"})
void testEnterpriseEndpoint_nativeHints_preserveValue(String endpoint) {
SwtUtils.invokeOnDisplayThread(() -> {
createPage(endpoint);
Text endpointText = findTextControl((Composite) page.getControl());
assertNotNull(endpointText);
assertEquals(Messages.preferences_page_github_enterprise_placeholder, endpointText.getMessage());
assertEquals(Messages.preferences_page_github_enterprise_tooltip, endpointText.getToolTipText());
assertEquals(endpoint, endpointText.getText());

page.endpointField.store();
assertEquals(endpoint, page.getPreferenceStore().getString(Constants.GITHUB_ENTERPRISE));
});
}

@Test
void testEnterpriseEndpoint_editValue_validationUpdatesImmediately() {
SwtUtils.invokeOnDisplayThread(() -> {
createPage("");
page.endpointField.setStringValue("http://company.ghe.com/");
assertFalse(page.isValid());
assertEquals(Messages.preferences_page_github_enterprise_validation_error, page.getErrorMessage());

page.endpointField.setStringValue("https://company.ghe.com/");
assertTrue(page.isValid());
assertNull(page.getErrorMessage());

page.endpointField.setStringValue("");
assertTrue(page.isValid());
assertNull(page.getErrorMessage());
});
}

private void createPage(String endpoint) {
shell = new Shell(Display.getDefault());
PreferenceStore store = new PreferenceStore();
store.setValue(Constants.GITHUB_ENTERPRISE, endpoint);
page = new TestPreferencesPage();
page.setPreferenceStore(store);
page.createControl(shell);
}

private Text findTextControl(Composite parent) {
for (Control child : parent.getChildren()) {
if (child instanceof Text text) {
return text;
}
if (child instanceof Composite composite) {
Text text = findTextControl(composite);
if (text != null) {
return text;
}
}
}
return null;
}

private static class TestPreferencesPage extends GeneralPreferencesPage {
private StringFieldEditor endpointField;

@Override
protected void addField(FieldEditor editor) {
super.addField(editor);
if (Constants.GITHUB_ENTERPRISE.equals(editor.getPreferenceName())) {
endpointField = (StringFieldEditor) editor;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

package com.microsoft.copilot.eclipse.ui.preferences;

import java.net.URI;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.jface.layout.GridDataFactory;
Expand All @@ -14,6 +17,7 @@
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.osgi.service.prefs.BackingStoreException;
Expand Down Expand Up @@ -82,8 +86,26 @@ public void createFieldEditors() {
ctnGhe.setLayout(gl);
ctnGhe.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
StringFieldEditor sftGhe = new StringFieldEditor(Constants.GITHUB_ENTERPRISE,
Messages.preferences_page_github_enterprise, ctnGhe);
Messages.preferences_page_github_enterprise, ctnGhe) {
@Override
protected boolean doCheckState() {
String endpoint = getStringValue();
if (StringUtils.isEmpty(endpoint)) {
return true;
}
try {
URI uri = URI.create(endpoint);
return "https".equalsIgnoreCase(uri.getScheme()) && StringUtils.isNotBlank(uri.getHost());
Comment thread
jdneo marked this conversation as resolved.
} catch (IllegalArgumentException e) {
return false;
}
}
};
sftGhe.setErrorMessage(Messages.preferences_page_github_enterprise_validation_error);
sftGhe.getLabelControl(ctnGhe).setToolTipText(Messages.preferences_page_github_enterprise_tooltip);
Text endpointText = sftGhe.getTextControl(ctnGhe);
endpointText.setMessage(Messages.preferences_page_github_enterprise_placeholder);
Comment thread
jdneo marked this conversation as resolved.
endpointText.setToolTipText(Messages.preferences_page_github_enterprise_tooltip);
addField(sftGhe);

// What's new group
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public class Messages extends NLS {
public static String preferences_page_enable_strict_ssl_tooltip;
public static String preferences_page_proxy_config_link_tooltip;
public static String preferences_page_github_enterprise_tooltip;
public static String preferences_page_github_enterprise_placeholder;
public static String preferences_page_github_enterprise_validation_error;
public static String preferences_page_mcp_tooltip;
public static String preferences_page_mcp_note_content;
public static String preferences_page_mcp_disabled_tip;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ preferences_page_auth_settings= Authentication
preferences_page_mcp_settings= MCP Servers
preferences_page_enable_strict_ssl_tooltip= Only disable this if your proxy server is not configured to use SSL and do not have a trusted certificate installed.
preferences_page_proxy_config_link_tooltip= Configure proxy settings in Eclipse
preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint if you are using GitHub Enterprise.
preferences_page_github_enterprise_tooltip= Ask your IT administrator for the GitHub Enterprise authentication endpoint. Use an HTTPS URL, for example https://your-company.ghe.com. Leave empty to sign in to GitHub.com.
preferences_page_github_enterprise_placeholder= https://your-company.ghe.com
preferences_page_github_enterprise_validation_error= Enter a valid GitHub Enterprise authentication endpoint starting with https://, or leave it empty to use GitHub.com.
preferences_page_mcp_tooltip= Model Context Protocol server configurations.
preferences_page_note_prefix= Note:
preferences_page_note_content= You can configure proxy settings in Eclipse by clicking on the Configure Proxy link. The Strict SSL option takes effect only when you are accessing GitHub Copilot from a network protected by a proxy server.
Expand Down
Loading