Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
Expand Up @@ -143,12 +143,10 @@ public String getDescription() {
return "Reload your configuration or update configuration source.";
}

/**
* Name of the category for this management link.
* TODO: Use getCategory when core requirement is greater or equal to 2.226
*/
public @NonNull String getCategoryName() {
return "CONFIGURATION";
@NonNull
@Override
public Category getCategory() {
return Category.CONFIGURATION;
}

@NonNull
Expand Down Expand Up @@ -228,7 +226,8 @@ public void doReplace(StaplerRequest2 request, StaplerResponse2 response) throws
candidateSources.add(candidateSource);
} else {
LOGGER.log(Level.WARNING, "Source {0} could not be applied", candidateSource);
// todo: show message in UI
throw new ConfiguratorException(
"Source " + candidateSource + " could not be applied or does not exist.");
}
}
if (!candidateSources.isEmpty()) {
Expand All @@ -244,7 +243,8 @@ public void doReplace(StaplerRequest2 request, StaplerResponse2 response) throws
LOGGER.log(Level.FINE, "Replace configuration with: " + normalizedSource);
} else {
LOGGER.log(Level.WARNING, "Provided sources could not be applied");
// todo: show message in UI
throw new ConfiguratorException(
"Provided sources could not be applied. Please check the syntax and validity of the provided configuration.");
}
} else {
LOGGER.log(Level.FINE, "No such source exists, applying default");
Expand Down Expand Up @@ -453,7 +453,12 @@ public List<String> getBundledCasCURIs() {
URL bundled = servletContext.getResource(cascItem);
if (bundled != null && matcher.matches(new File(bundled.getPath()).toPath())) {
res.add(bundled.toString());
} // TODO: else do some handling?
} else if (bundled != null) {
LOGGER.log(
Level.FINE,
"Skipped bundled resource {0} as it does not match the YAML pattern.",
bundled.getPath());
}
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Failed to execute " + res, e);
}
Expand Down Expand Up @@ -569,23 +574,7 @@ public void doViewExport(StaplerRequest2 req, StaplerResponse2 res) throws Excep
ByteArrayOutputStream out = new ByteArrayOutputStream();
export(out);

req.setAttribute("viewExport", new ManagementLink() {
@Override
public String getIconFileName() {
return "";
}

// TODO - FIX - EXTREMELY HACKY - couldn't expose a public method for some reason
@Override
public String getUrlName() {
return out.toString(StandardCharsets.UTF_8);
}

@Override
public String getDisplayName() {
return "Export configuration";
Comment thread
somiljain2006 marked this conversation as resolved.
}
});
req.setAttribute("exportedYaml", out.toString(StandardCharsets.UTF_8));
req.getView(this, "viewExport.jelly").forward(req, res);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
xmlns:f="/lib/form">
<j:set var="header">
<l:view>
<l:app-bar title="${viewExport.displayName}">
<l:app-bar title="${%Export configuration}">
<f:form method="post" action="export" name="export">
<f:submit icon="symbol-download" primary="false" name="export" value="${%Download}"/>
</f:form>
</l:app-bar>
</l:view>
</j:set>

<l:settings-subpage includeBreadcrumb="true" header="${header}" managementLink="${viewExport}" noDefer="true">
<l:settings-subpage includeBreadcrumb="true" header="${header}">
Comment thread
somiljain2006 marked this conversation as resolved.
Outdated
<st:adjunct includes="io.jenkins.plugins.casc.assets.viewExport" />

<div class="jenkins-alert jenkins-alert-info">
Expand All @@ -20,7 +20,7 @@

<p:prism configuration="${it.prismConfiguration}" />
<pre>
<code class="language-yaml">${viewExport.urlName}</code>
<code class="language-yaml">${exportedYaml}</code>
</pre>
</l:settings-subpage>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
import static org.hamcrest.Matchers.is;

import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import jenkins.model.Jenkins;
import org.htmlunit.HttpMethod;
import org.htmlunit.WebRequest;
import org.htmlunit.WebResponse;
import org.htmlunit.util.NameValuePair;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
Expand Down Expand Up @@ -159,4 +163,26 @@ public void testDoConfigure_ValidYaml_NoChanges() throws Exception {
assertThat(j.jenkins.getSystemMessage(), is("Idempotency Test"));
}
}

@Test
public void testDoReplace_ValidSource() throws Exception {
configureAdminSecurity();

Path configFile = Files.createTempFile("valid", ".yaml");
Files.writeString(configFile, "jenkins:\n systemMessage: 'Hello Replace'");

try (JenkinsRule.WebClient wc = j.createWebClient().withBasicApiToken(ADMIN)) {
wc.setThrowExceptionOnFailingStatusCode(false);

WebRequest request =
new WebRequest(new URL(j.getURL(), "manage/configuration-as-code/replace"), HttpMethod.POST);

request.setRequestParameters(List.of(new NameValuePair("_.newSource", configFile.toString())));

WebResponse response = wc.getPage(request).getWebResponse();

assertThat(response.getStatusCode(), is(200));
assertThat(j.jenkins.getSystemMessage(), is("Hello Replace"));
}
}
}
45 changes: 45 additions & 0 deletions plugin/src/test/java/io/jenkins/plugins/casc/ErrorPageTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package io.jenkins.plugins.casc;

import static hudson.model.ManagementLink.Category.CONFIGURATION;
import static jenkins.model.Jenkins.ADMINISTER;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.File;
import java.io.IOException;
Expand All @@ -16,6 +19,7 @@
import org.junit.jupiter.api.io.TempDir;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.WebClient;
import org.jvnet.hudson.test.MockAuthorizationStrategy;
import org.jvnet.hudson.test.junit.jupiter.WithJenkins;

@WithJenkins
Expand Down Expand Up @@ -87,4 +91,45 @@ void noImplementationFoundForSymbol() throws Exception {
assertThat(pageContent, containsString("Attribute was:"));
assertThat(pageContent, containsString("unknown"));
}

@Test
void replaceWithInvalidSource() throws Exception {
String pageContent = replaceConfiguration();

assertThat(
pageContent, containsString("Source non-existent-file.yaml could not be applied or does not exist."));
}

private String replaceConfiguration() throws Exception {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
r.jenkins.setAuthorizationStrategy(
new MockAuthorizationStrategy().grant(ADMINISTER).everywhere().to("admin"));

try (WebClient webClient = r.createWebClient().withThrowExceptionOnFailingStatusCode(false)) {
webClient.login("admin", "admin");

HtmlPage htmlPage = webClient.goTo("manage/configuration-as-code/");

HtmlButton button = (HtmlButton) htmlPage.getElementById("btn-open-apply-configuration");
HtmlElementUtil.click(button);

HtmlForm replaceForm = htmlPage.getFormByName("replace");
replaceForm.getInputByName("_.newSource").setValue("non-existent-file.yaml");

HtmlPage submit = r.submit(replaceForm);

return submit.asNormalizedText();
}
}

@Test
void verifyManagementLinkProperties() {
ConfigurationAsCode casc = ConfigurationAsCode.get();

assertEquals(CONFIGURATION, casc.getCategory());

assertEquals("configuration-as-code", casc.getUrlName());
assertEquals("Configuration as Code", casc.getDisplayName());
assertEquals("symbol-logo plugin-configuration-as-code", casc.getIconFileName());
}
Comment thread
somiljain2006 marked this conversation as resolved.
Outdated
}
Original file line number Diff line number Diff line change
Expand Up @@ -340,12 +340,6 @@ void testHtmlDocStringRetrieval(JenkinsConfiguredWithCodeRule j) throws Exceptio
assertEquals(expectedDocString, actualDocString);
}

@Test
void configurationCategory(JenkinsConfiguredWithCodeRule j) {
ConfigurationAsCode configurationAsCode = ConfigurationAsCode.get();
assertThat(configurationAsCode.getCategoryName(), is("CONFIGURATION"));
}

private static File newFolder(File root, String... subDirs) throws IOException {
String subFolder = String.join("/", subDirs);
File result = new File(root, subFolder);
Expand Down
Loading