Skip to content

Commit 9e01c69

Browse files
authored
feat: auto-refresh open HTML settings page on configuration change [IDE-1954] (#430)
feat(settings): auto-refresh open HTML settings page on configuration change [IDE-1954] When $/snyk.configuration arrives from the Language Server, the HTML settings preference page now reloads its content if it is currently open. The LS emits this notification on auth, org change, folder add, and folder remove — all the triggers from IDE-1954. Implementation mirrors the existing notifyAuthTokenChanged() pattern: a static reloadIfOpen() method guards against null/disposed browser (capturing instance to a local variable to avoid TOCTOU), then delegates to the existing loadContent() which dispatches the fetch and browser.setText() via asyncExec internally. The LS-side SettingIsLspInitialized guard (snyk-ls PR #1345) prevents refresh storms during startup.
1 parent ea124ce commit 9e01c69

5 files changed

Lines changed: 84 additions & 0 deletions

File tree

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,27 @@ tests.json
215215
.commit-reviewed
216216
.pr-review-*.md
217217
.verify-metrics-pending
218+
.verify-complete
219+
.verify-precommit-hash
220+
.verify-staged-hash
221+
.verify-agents
222+
.verify-counts
223+
.verify-staged-diff
224+
.verify-branch-diff
225+
.verify-pr-context
226+
.verify-oracle.json
227+
.verify-oracle.log
228+
.verify-oracle-scope.txt
229+
.verify-oracle.pid
230+
.verify-lang-skill
231+
.verify-chunk-diff
232+
.verify-triage.json
233+
.verify-source-map.json
234+
.verify-dedup-findings.json
235+
.verify-reranked.json
236+
.snyk-sca-output.json
237+
.snyk-sca-output.err
238+
.snyk-code-output.json
239+
.snyk-code-output.err
240+
.verification-result.*
241+
*_????????_??????_*.log

plugin/src/main/java/io/snyk/eclipse/plugin/preferences/HTMLSettingsPreferencePage.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,14 @@ public void dispose() {
367367
super.dispose();
368368
}
369369

370+
public static void reloadIfOpen() {
371+
HTMLSettingsPreferencePage page = instance;
372+
if (page == null || page.browser == null || page.browser.isDisposed()) {
373+
return;
374+
}
375+
page.loadContent();
376+
}
377+
370378
public static void notifyAuthTokenChanged(String token, String apiUrl) {
371379
if (instance != null && instance.browser != null && !instance.browser.isDisposed()) {
372380
Display.getDefault()

plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ public void snykConfiguration(LspConfigurationParam param) {
434434
this.toolView.refreshDeltaReference();
435435
}
436436
}
437+
HTMLSettingsPreferencePage.reloadIfOpen();
437438
} catch (Exception e) {
438439
SnykLogger.logError(e);
439440
}

tests/src/test/java/io/snyk/eclipse/plugin/preferences/HTMLSettingsPreferencePageTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,21 @@ void parseAndSaveConfig_mixedNullAndValueFields() throws Exception {
325325
assertEquals("new-org", prefs.getPref(Preferences.ORGANIZATION_KEY));
326326
}
327327

328+
@Test
329+
void reloadIfOpen_noOpWhenPageNeverOpened() throws Exception {
330+
// Force instance to null by disposing the page created in setUp()
331+
page.dispose();
332+
// Now instance == null; reloadIfOpen() must not throw
333+
org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> HTMLSettingsPreferencePage.reloadIfOpen());
334+
}
335+
336+
@Test
337+
void reloadIfOpen_noOpWhenBrowserNotCreated() {
338+
// page was created in setUp() but createContents() was never called,
339+
// so browser is null — reloadIfOpen() must not throw
340+
org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> HTMLSettingsPreferencePage.reloadIfOpen());
341+
}
342+
328343
@Test
329344
void parseAndSaveConfig_folderFieldSentAsNullBecomesReset() throws Exception {
330345
FolderConfigSettings.setInstance(new FolderConfigSettings());

tests/src/test/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClientTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.mockito.Mockito;
3131

3232
import io.snyk.eclipse.plugin.analytics.TaskProcessor;
33+
import io.snyk.eclipse.plugin.preferences.HTMLSettingsPreferencePage;
3334
import io.snyk.eclipse.plugin.preferences.Preferences;
3435
import io.snyk.eclipse.plugin.views.snyktoolview.ISnykToolView;
3536
import io.snyk.languageserver.LsBaseTest;
@@ -718,4 +719,39 @@ private static void setAuthCompleteFuture(SnykExtendedLanguageClient lc,
718719
f.setAccessible(true);
719720
((java.util.concurrent.atomic.AtomicReference<java.util.concurrent.CompletableFuture<Void>>) f.get(lc)).set(future);
720721
}
722+
723+
@Test
724+
void snykConfigurationReloadsOpenSettingsPage() {
725+
var gson = new com.google.gson.Gson();
726+
String json = """
727+
{
728+
"settings": {
729+
"api_endpoint": {
730+
"value": "https://reload-test.snyk.io"
731+
}
732+
}
733+
}
734+
""";
735+
LspConfigurationParam param = gson.fromJson(json, LspConfigurationParam.class);
736+
737+
try (MockedStatic<HTMLSettingsPreferencePage> mockedPage = mockStatic(HTMLSettingsPreferencePage.class)) {
738+
cut = new SnykExtendedLanguageClient();
739+
cut.snykConfiguration(param);
740+
741+
mockedPage.verify(() -> HTMLSettingsPreferencePage.reloadIfOpen(), Mockito.times(1));
742+
}
743+
}
744+
745+
@Test
746+
void snykConfigurationReloadsEvenWithEmptyPayload() {
747+
var gson = new com.google.gson.Gson();
748+
LspConfigurationParam param = gson.fromJson("{}", LspConfigurationParam.class);
749+
750+
try (MockedStatic<HTMLSettingsPreferencePage> mockedPage = mockStatic(HTMLSettingsPreferencePage.class)) {
751+
cut = new SnykExtendedLanguageClient();
752+
assertDoesNotThrow(() -> cut.snykConfiguration(param));
753+
754+
mockedPage.verify(() -> HTMLSettingsPreferencePage.reloadIfOpen(), Mockito.times(1));
755+
}
756+
}
721757
}

0 commit comments

Comments
 (0)