From 95693ec4c7c324a78bbc2c01183b651351925077 Mon Sep 17 00:00:00 2001 From: AlexNetcare <135694182+AlexNetcare@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:26:22 +0200 Subject: [PATCH] Added property to configure purge options (#1496) --- .../ConfigurationFile/content.txt | 1 + .../TestHistory/content.txt | 4 +- plugins.properties | 7 ++++ src/fitnesse/ConfigurationParameter.java | 3 +- src/fitnesse/resources/javascript/fitnesse.js | 31 +++++++++++++++ .../resources/templates/testHistory.vm | 11 ++++-- .../testHistory/PurgeHistoryResponder.java | 22 +++++++++-- .../testHistory/TestHistoryResponder.java | 17 +++++++++ .../PurgeHistoryResponderTest.java | 27 ++++++++++++- .../testHistory/TestHistoryResponderTest.java | 38 +++++++++++++++++++ 10 files changed, 151 insertions(+), 10 deletions(-) diff --git a/FitNesseRoot/FitNesse/UserGuide/AdministeringFitNesse/ConfigurationFile/content.txt b/FitNesseRoot/FitNesse/UserGuide/AdministeringFitNesse/ConfigurationFile/content.txt index b7d1f9de7b..285502b6f8 100644 --- a/FitNesseRoot/FitNesse/UserGuide/AdministeringFitNesse/ConfigurationFile/content.txt +++ b/FitNesseRoot/FitNesse/UserGuide/AdministeringFitNesse/ConfigurationFile/content.txt @@ -177,6 +177,7 @@ There are more properties which can be used to tweak parts of FitNesse: * '''VersionsController.days''' - number of days to keep old page versions around when using the Zip file based versions controller. * '''test.history.days''' - The number of days to keep test results around. Cleaned up after a new test run. * '''test.history.path''' - Location to store the test results. The default location is ''!-FitNesseRoot-!/files/testResults''. + * '''TestHistory.purgeOptions''' - A comma separated list of the age, in number of days, to offer as purge options on the ''Test History'' page. * Any variable that can be defined on a wiki page. The Slim test system has a set of [[custom properties][7 days'', or ''>30 days''. If you want to purge a different number of days, you can use the RESTful URL form. (See [[!-RestfulServices-!][7 days'', or ''>30 days''. If you want to purge a different number of days, you can change the ''TestHistory.purgeOptions'' in the [[configuration file][ { + // Only adjust the href if it was not already adjusted + if (!link.href.includes(purgeGlobal)) { + link.href = link.href.substring(link.href.indexOf("?")) + purgeGlobal; + } + }); + } else { + elems.each((index, link) => { + // Only adjust the href if it was adjusted before + if (link.href.includes(purgeGlobal)) { + link.href = link.href.substring(link.href.indexOf("?"), link.href.length - purgeGlobal.length); + } + }); + } + }); + +// When clicking on a purge link then ask before deletion +function purgeConfirmation(event) { + if (!confirm('Are you sure you want to purge the test histories?')) { + event.preventDefault(); + return false; + } +} + /** * Notify user when changing page while test execution is in progress. */ diff --git a/src/fitnesse/resources/templates/testHistory.vm b/src/fitnesse/resources/templates/testHistory.vm index 23878d8182..17843522a3 100644 --- a/src/fitnesse/resources/templates/testHistory.vm +++ b/src/fitnesse/resources/templates/testHistory.vm @@ -2,12 +2,17 @@ #set($noHistory = true)
View as Overview - Purge > 30 days - Purge > 7 days - Purge all Cancel
+
+ #if(!$purgeOptions.isEmpty()) + #foreach($purgeOption in $purgeOptions) + Purge#if ($purgeOption == 0) all#else > $purgeOption days#end + #end + + #end +
diff --git a/src/fitnesse/responders/testHistory/PurgeHistoryResponder.java b/src/fitnesse/responders/testHistory/PurgeHistoryResponder.java index e5f8c896b6..9c3cfafb2b 100644 --- a/src/fitnesse/responders/testHistory/PurgeHistoryResponder.java +++ b/src/fitnesse/responders/testHistory/PurgeHistoryResponder.java @@ -2,6 +2,8 @@ import java.io.File; +import org.apache.commons.lang3.StringUtils; + import fitnesse.FitNesseContext; import fitnesse.authentication.AlwaysSecureOperation; import fitnesse.authentication.SecureOperation; @@ -11,6 +13,7 @@ import fitnesse.http.SimpleResponse; import fitnesse.reporting.history.HistoryPurger; import fitnesse.responders.ErrorResponder; +import fitnesse.wiki.WikiPagePath; public class PurgeHistoryResponder implements SecureResponder { @@ -31,13 +34,26 @@ private SimpleResponse makeValidResponse() { } private void purgeHistory(Request request, FitNesseContext context) { + WikiPagePath currentPath = new WikiPagePath(request.getResource().split("\\.")); + String purgeGlobalInput = request.getInput("purgeGlobal"); + File resultsDirectory = context.getTestHistoryDirectory(); int days = getDaysInput(request); - deleteTestHistoryOlderThanDays(resultsDirectory, days); + // If purgeGlobal is not set then only delete current path + if (StringUtils.isBlank(purgeGlobalInput) || !Boolean.parseBoolean(purgeGlobalInput)) { + deleteTestHistoryOlderThanDays(resultsDirectory, days, currentPath); + } else { + deleteTestHistoryOlderThanDays(resultsDirectory, days, null); + } } - public void deleteTestHistoryOlderThanDays(File resultsDirectory, int days) { - new HistoryPurger(resultsDirectory, days).deleteTestHistoryOlderThanDays(); + public void deleteTestHistoryOlderThanDays(File resultsDirectory, int days, WikiPagePath path) { + HistoryPurger historyPurger = new HistoryPurger(resultsDirectory, days); + if (path != null) { + historyPurger.deleteTestHistoryOlderThanDays(path); + } else { + historyPurger.deleteTestHistoryOlderThanDays(); + } } private Integer getDaysInput(Request request) { diff --git a/src/fitnesse/responders/testHistory/TestHistoryResponder.java b/src/fitnesse/responders/testHistory/TestHistoryResponder.java index 5624fe3597..94a7cfe9ae 100644 --- a/src/fitnesse/responders/testHistory/TestHistoryResponder.java +++ b/src/fitnesse/responders/testHistory/TestHistoryResponder.java @@ -5,8 +5,11 @@ import fitnesse.reporting.history.TestHistory; import fitnesse.wiki.PathParser; + +import org.apache.commons.lang3.StringUtils; import org.apache.velocity.VelocityContext; +import fitnesse.ConfigurationParameter; import fitnesse.FitNesseContext; import fitnesse.authentication.SecureOperation; import fitnesse.authentication.SecureReadOperation; @@ -43,12 +46,26 @@ private Response makeTestHistoryResponse(TestHistory testHistory, Request reques page.setNavTemplate("viewNav"); page.put("viewLocation", request.getResource()); page.put("testHistory", testHistory); + page.put("purgeOptions", getPurgeOptions()); page.setMainTemplate("testHistory"); SimpleResponse response = new SimpleResponse(); response.setContent(page.html(request)); return response; } + private String[] getPurgeOptions() { + String configuredPurgeOptions = context.getProperties().getProperty(ConfigurationParameter.PURGE_OPTIONS.getKey()); + String[] purgeOptionsForPage; + if(configuredPurgeOptions == null) { + purgeOptionsForPage = new String[] { "0", "7", "30" }; + } else if (configuredPurgeOptions.isBlank()) { + purgeOptionsForPage = new String[0]; + } else { + purgeOptionsForPage = configuredPurgeOptions.split(","); + } + return purgeOptionsForPage; + } + private Response makeTestHistoryXmlResponse(TestHistory history) throws UnsupportedEncodingException { SimpleResponse response = new SimpleResponse(); VelocityContext velocityContext = new VelocityContext(); diff --git a/test/fitnesse/responders/testHistory/PurgeHistoryResponderTest.java b/test/fitnesse/responders/testHistory/PurgeHistoryResponderTest.java index 8cf013acd6..0892eca486 100644 --- a/test/fitnesse/responders/testHistory/PurgeHistoryResponderTest.java +++ b/test/fitnesse/responders/testHistory/PurgeHistoryResponderTest.java @@ -5,9 +5,12 @@ import fitnesse.http.Response; import fitnesse.http.SimpleResponse; import fitnesse.testutil.FitNesseUtil; +import fitnesse.wiki.WikiPagePath; import org.junit.After; import static org.junit.Assert.*; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import org.junit.Before; import org.junit.Test; import util.FileUtil; @@ -50,6 +53,7 @@ private void removeResultsDirectory() throws IOException { public void shouldDeleteHistoryFromRequestAndRedirect() throws Exception { StubbedPurgeHistoryResponder responder = new StubbedPurgeHistoryResponder(); request.addInput("days", "30"); + request.addInput("purgeGlobal", "true"); SimpleResponse response = (SimpleResponse) responder.makeResponse(context, request); assertEquals(30, responder.daysDeleted); assertEquals(303, response.getStatus()); @@ -68,14 +72,35 @@ public void shouldMakeErrorResponseWhenItGetsInvalidTypeForNumberOfDays() throws request.addInput("days", "bob"); Response response = responder.makeResponse(context, request); assertEquals(400, response.getStatus()); + } + + @Test + public void shouldDeleteHistoryFromRequestForWikiPathWhenPurgeGlobalNotSet() throws Exception { + assertThatPurgeGlobalIsNotUsed(); + } + + @Test + public void shouldDeleteHistoryFromRequestForWikiPathWhenPurgeGlobalFalse() throws Exception { + request.addInput("purgeGlobal", "false"); + assertThatPurgeGlobalIsNotUsed(); + } + + private void assertThatPurgeGlobalIsNotUsed() throws Exception { + request.addInput("days", "0"); + StubbedPurgeHistoryResponder responderSpy = spy(new StubbedPurgeHistoryResponder()); + WikiPagePath expectedPath = new WikiPagePath(request.getResource().split("\\.")); + SimpleResponse response = (SimpleResponse) responderSpy.makeResponse(context, request); + assertEquals(303, response.getStatus()); + assertEquals("?testHistory", response.getHeader("Location")); + verify(responderSpy).deleteTestHistoryOlderThanDays(resultsDirectory, 0, expectedPath); } private static class StubbedPurgeHistoryResponder extends PurgeHistoryResponder { public int daysDeleted = -1; @Override - public void deleteTestHistoryOlderThanDays(File resultsDirectory, int days) { + public void deleteTestHistoryOlderThanDays(File resultsDirectory, int days, WikiPagePath path) { daysDeleted = days; } } diff --git a/test/fitnesse/responders/testHistory/TestHistoryResponderTest.java b/test/fitnesse/responders/testHistory/TestHistoryResponderTest.java index 566be2a6b6..1a271bd4a3 100644 --- a/test/fitnesse/responders/testHistory/TestHistoryResponderTest.java +++ b/test/fitnesse/responders/testHistory/TestHistoryResponderTest.java @@ -1,5 +1,6 @@ package fitnesse.responders.testHistory; +import fitnesse.ConfigurationParameter; import fitnesse.FitNesseContext; import fitnesse.http.MockRequest; import fitnesse.http.SimpleResponse; @@ -27,6 +28,8 @@ import static org.junit.Assert.assertTrue; import static util.RegexTestCase.assertDoesntHaveRegexp; import static util.RegexTestCase.assertHasRegexp; +import static util.RegexTestCase.assertNotSubString; +import static util.RegexTestCase.assertSubString; public class TestHistoryResponderTest { private File resultsDirectory; @@ -340,4 +343,39 @@ public void shouldntBeCaseSensitiveForXMLRequest() throws Exception { response = (SimpleResponse) responder.makeResponse(context, request); assertHasRegexp("text/xml", response.getContentType()); } + + @Test + public void shouldShowDefaultPurgeOptions() throws Exception { + MockRequest request = new MockRequest(); + SimpleResponse response = (SimpleResponse) new TestHistoryResponder().makeResponse(context, request); + String html = response.getContent(); + assertSubString("Purge all", html); + assertSubString("Purge > 7 days", html); + assertSubString("Purge > 30 days", html); + assertSubString("", html); + } + + @Test + public void shouldShowConfiguredPurgeOptions() throws Exception { + MockRequest request = new MockRequest(); + context.getProperties().setProperty(ConfigurationParameter.PURGE_OPTIONS.getKey(), "30,60,90"); + SimpleResponse response = (SimpleResponse) new TestHistoryResponder().makeResponse(context, request); + String html = response.getContent(); + assertNotSubString("Purge all", html); + assertSubString("Purge > 30 days", html); + assertSubString("Purge > 60 days", html); + assertSubString("Purge > 90 days", html); + assertSubString("", html); + } + + @Test + public void shouldShowNoPurgeOptions() throws Exception { + MockRequest request = new MockRequest(); + context.getProperties().setProperty(ConfigurationParameter.PURGE_OPTIONS.getKey(), ""); + SimpleResponse response = (SimpleResponse) new TestHistoryResponder().makeResponse(context, request); + String html = response.getContent(); + assertNotSubString("Purge all", html); + assertNotSubString("Purge > 7 days", html); + assertNotSubString("", html); + } }