diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java index a77df0d3bca6..094b79ce9bfa 100644 --- a/core/src/main/java/hudson/PluginWrapper.java +++ b/core/src/main/java/hudson/PluginWrapper.java @@ -522,6 +522,7 @@ public PluginWrapper(PluginManager parent, File archive, Manifest manifest, URL this.archive = archive; } + @Exported(visibility = 2) @Override public String getDisplayName() { String displayName = getLongName(); @@ -595,7 +596,7 @@ public List getOptionalDependencies() { /** * Returns the short name suitable for URL. */ - @Exported + @Exported(visibility = 2) public String getShortName() { return shortName; } @@ -627,7 +628,7 @@ public String getShortName() { * null if this information is unavailable. * @since 1.283 */ - @Exported + @Exported(visibility = 2) public String getUrl() { // first look in update center metadata List siteMetadataList = getInfoFromAllSites(); @@ -683,7 +684,7 @@ public YesNoMaybe supportsDynamicLoad() { /** * Returns the version number of this plugin */ - @Exported + @Exported(visibility = 2) public String getVersion() { return getVersionOf(manifest); } @@ -894,7 +895,7 @@ private Set dependentsToCheck(PluginDisableStrategy strategy) { /** * Returns true if this plugin is enabled for this session. */ - @Exported + @Exported(visibility = 2) public boolean isActive() { return active && !hasCycleDependency(); } @@ -921,7 +922,7 @@ public boolean isBundled() { * If true, the plugin is going to be activated next time * Jenkins runs. */ - @Exported + @Exported(visibility = 2) public boolean isEnabled() { return !disableFile.exists(); } @@ -1080,7 +1081,7 @@ private List getInfoFromAllSites() { * This method is conservative in the sense that if the version number is incomprehensible, * it always returns false. */ - @Exported + @Exported(visibility = 2) public boolean hasUpdate() { return getUpdateInfo() != null; } diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index 8c8306b94d87..a7c6421ff2d7 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -542,6 +542,36 @@ void pluginListJSONApi() throws Throwable { }); } + @Issue("https://github.com/jenkinsci/jenkins/issues/21047") + @WithPlugin("htmlpublisher.jpi") + @Test + void pluginManagerApiJsonReturnsPluginDetails() throws Throwable { + session.then(r -> { + JSONObject response = r.getJSON("pluginManager/api/json").getJSONObject(); + JSONArray plugins = response.getJSONArray("plugins"); + assertThat(plugins, not(empty())); + + // Find the htmlpublisher plugin in the response + JSONObject htmlPublisher = null; + for (int i = 0; i < plugins.size(); i++) { + JSONObject plugin = plugins.getJSONObject(i); + if ("htmlpublisher".equals(plugin.optString("shortName"))) { + htmlPublisher = plugin; + break; + } + } + assertNotNull(htmlPublisher, "htmlpublisher plugin should be present in API response"); + + // Verify key properties are present at default depth (visibility = 2) + assertNotNull(htmlPublisher.optString("shortName", null), "shortName should be exported at default depth"); + assertNotNull(htmlPublisher.optString("version", null), "version should be exported at default depth"); + assertNotNull(htmlPublisher.optString("displayName", null), "displayName should be exported at default depth"); + assertTrue(htmlPublisher.has("active"), "active should be exported at default depth"); + assertTrue(htmlPublisher.has("enabled"), "enabled should be exported at default depth"); + assertTrue(htmlPublisher.has("hasUpdate"), "hasUpdate should be exported at default depth"); + }); + } + @Issue("JENKINS-41684") @Test void requireSystemDuringLoad() throws Throwable {