From 2b1ec08517580d4620222183d9d1b3daadd9efa2 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 22 Nov 2024 17:26:09 -0800 Subject: [PATCH] [JENKINS-74011] Extract JavaScript block in `PageStatePreloadDecorator/header.jelly` (#2588) Co-authored-by: Olivier Lamy --- .../FavoriteListStatePreloaderTest.java | 19 +++----- .../blueocean/preload/StatePreloaderTest.java | 8 ++-- .../PageStatePreloadDecorator/header.jelly | 47 ++++--------------- .../PageStatePreloadDecorator/preloader.js | 32 +++++++++++++ 4 files changed, 53 insertions(+), 53 deletions(-) create mode 100644 blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/preloader.js diff --git a/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/FavoriteListStatePreloaderTest.java b/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/FavoriteListStatePreloaderTest.java index 7e33e420a6d..71c0f089a05 100644 --- a/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/FavoriteListStatePreloaderTest.java +++ b/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/FavoriteListStatePreloaderTest.java @@ -16,15 +16,12 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; -import java.util.Arrays; import java.util.Map; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; public class FavoriteListStatePreloaderTest extends PipelineBaseTest { @@ -66,15 +63,13 @@ public void simpleTest() throws Exception { .asString(); Document doc = Jsoup.parse(response.getBody()); - String script = doc.select("head script").toString(); - Optional preloadLine = Arrays.stream(script.split("\n")).filter(s -> s.trim().startsWith("setState('favoritesList'")).findFirst(); - if (!preloadLine.isPresent()) fail("preloadLine missing in page"); + String script = doc.select("head script#blueocean-page-state-preload-decorator-data").html().toString(); + JSONObject json = JSONObject.fromObject(script); - Pattern pa = Pattern.compile("^\\s*setState\\('favoritesList',\\s*(.*)\\);$"); - final Matcher matcher = pa.matcher(preloadLine.get()); - if (!matcher.find()) fail("invalid preload line: " + preloadLine.get()); + Assert.assertTrue(json.containsKey("favoritesList")); + JSONArray favoritesList = json.getJSONArray("favoritesList"); - final String data = matcher.group(1); + final String data = favoritesList.toString(); Assert.assertTrue("master branch not include or not primary", data.contains("{\"name\":\"p-master/master\",\"primary\":true}")); Assert.assertTrue("feature2 branch not include or primary", data.contains("{\"name\":\"p-master/feature2\",\"primary\":false}")); Assert.assertTrue("feature4 branch not include or primary", data.contains("{\"name\":\"p-master/feature4\",\"primary\":false}")); diff --git a/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/StatePreloaderTest.java b/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/StatePreloaderTest.java index a5c4be3ebf6..2255fc18cd4 100644 --- a/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/StatePreloaderTest.java +++ b/blueocean-pipeline-api-impl/src/test/java/io/jenkins/blueocean/preload/StatePreloaderTest.java @@ -32,6 +32,7 @@ import org.junit.Assert; import org.junit.Test; import org.xml.sax.SAXException; +import net.sf.json.JSONObject; import java.io.IOException; import java.util.concurrent.ExecutionException; @@ -55,10 +56,11 @@ public void test() throws IOException, ExecutionException, InterruptedException, BlueOceanUrlMapper mapper = BlueOceanUrlMapper.all().get(0); String projectBlueUrl = j.jenkins.getRootUrl() + mapper.getUrl(freestyleProject); Document doc = Jsoup.connect(projectBlueUrl + "/activity/").get(); - String script = doc.select("head script").toString(); + String script = doc.select("head script#blueocean-page-state-preload-decorator-data").html().toString(); + JSONObject json = JSONObject.fromObject(script); - Assert.assertTrue(script.contains(String.format("setState('prefetchdata.%s',", PipelineStatePreloader.class.getSimpleName()))); - Assert.assertTrue(script.contains(String.format("setState('prefetchdata.%s',", PipelineActivityStatePreloader.class.getSimpleName()))); + Assert.assertTrue(json.containsKey(String.format("prefetchdata.%s", PipelineStatePreloader.class.getSimpleName()))); + Assert.assertTrue(json.containsKey(String.format("prefetchdata.%s", PipelineActivityStatePreloader.class.getSimpleName()))); Assert.assertTrue(script.contains("\"restUrl\":\"/blue/rest/organizations/jenkins/pipelines/freestyle/runs/?start=0&limit=26\"")); } } diff --git a/blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/header.jelly b/blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/header.jelly index d2782ce0432..1cb4c459cb2 100644 --- a/blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/header.jelly +++ b/blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/header.jelly @@ -1,42 +1,13 @@ - + diff --git a/blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/preloader.js b/blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/preloader.js new file mode 100644 index 00000000000..4757a1e9d2f --- /dev/null +++ b/blueocean-web/src/main/resources/io/jenkins/blueocean/PageStatePreloadDecorator/preloader.js @@ -0,0 +1,32 @@ +// construct the state object parent path inside window.$blueocean. +var stateRoot = window.$blueocean = (window.$blueocean || {}); +(function () { + function setState(statePropertyPath, state) { + var pathTokens = statePropertyPath.split('.'); + var contextObj = stateRoot; + + // Basically an Array shift + function nextToken() { + var nextToken = pathTokens[0]; + pathTokens = pathTokens.slice(1); + return nextToken; + } + + var pathToken = nextToken(); + + // Construct up to, but not including, the last point in the graph. + while (pathTokens.length !== 0) { + if (!contextObj[pathToken]) { + contextObj[pathToken] = {}; + } + contextObj = contextObj[pathToken]; + pathToken = nextToken(); + } + // And set the state on the last object on the graph. + contextObj[pathToken] = state; + } + const data = JSON.parse(document.getElementById('blueocean-page-state-preload-decorator-data').textContent); + for (const [key, value] of Object.entries(data)) { + setState(key, value); + } +})();