package jenkins.security;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;

import com.gargoylesoftware.htmlunit.AlertHandler;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.model.UnprotectedRootAction;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestExtension;

@RunWith(Parameterized.class)
public class Security2779Test {
    public static final String URL_NAME = "security2779";
    private final String selector;
    @Rule
    public JenkinsRule j = new JenkinsRule();

    // Dynamic tests are not fully supported by the maven surefire plugin
    // Failures of one parameter are treated as "flakes" of the named test
    // instead of being treated as failures.
    // Test output includes the test number and argument to make it a little easier to diagnose
    @Parameterized.Parameters(name = "test:{index}  arg:\"{0}\"")
    public static Collection<String> getSelectors() {
        return Arrays.asList("#link-panel a", "#icon-panel svg");
    }

    public Security2779Test(String selector) {
        this.selector = selector;
    }

    @Test
    public void noXssInHelp() throws Exception {
        final AtomicInteger alerts = new AtomicInteger();
        final JenkinsRule.WebClient webClient = j.createWebClient();
        webClient.setAlertHandler((AlertHandler) (p, s) -> alerts.addAndGet(1));
        final HtmlPage page = webClient.goTo(URL_NAME);
        final ScriptResult eventScript = page.executeJavaScript("document.querySelector('" + selector + "').dispatchEvent(new Event('mouseover'))");
        final Object eventResult = eventScript.getJavaScriptResult();
        assertThat(eventResult, instanceOf(boolean.class));
        Assert.assertTrue((boolean) eventResult);
        webClient.waitForBackgroundJavaScript(2000);
        // Assertion includes the selector for easier diagnosis
        Assert.assertEquals("Alert with selector '" + selector + "'", 0, alerts.get());

        final ScriptResult innerHtmlScript = page.executeJavaScript("document.querySelector('#tt').innerHTML");
        Object jsResult = innerHtmlScript.getJavaScriptResult();
        assertThat(jsResult, instanceOf(String.class));
        String jsResultString = (String) jsResult;

        // assert leading space to identify unintentional double-escaping (&amp;lt;) as test failure
        assertThat("tooltip does not contain dangerous HTML", jsResultString, not(containsString(" <img src=x")));
        assertThat("tooltip contains safe text", jsResultString, containsString(" &lt;img src=x"));
    }

    @TestExtension
    public static class ViewHolder implements UnprotectedRootAction {

        @Override
        public String getIconFileName() {
            return null;
        }

        @Override
        public String getDisplayName() {
            return null;
        }

        @Override
        public String getUrlName() {
            return URL_NAME;
        }

        public String getFeatureName() {
            return " <img src=x onerror=alert(1)>";
        }
    }
}

@@ -428,62 +428,8 @@
 on;%0A
-import java.util.Arrays;%0Aimport java.util.Collection;%0A
 impo
@@ -549,81 +549,8 @@
 st;%0A
-import org.junit.runner.RunWith;%0Aimport org.junit.runners.Parameterized;%0A
 impo
@@ -636,38 +636,8 @@
 n;%0A%0A
-@RunWith(Parameterized.class)%0A
 publ
@@ -726,42 +726,8 @@
 9%22;%0A
-    private final String selector;
 %0A   
@@ -788,613 +788,321 @@
     
-// Dynamic tests are not fully supported by the maven surefire plugin%0A    // Failures of one parameter are treated as %22flakes%22 of the named test%0A    // instead of being treated as failures.%0A    // Test output includes the test number and argument to make it a little easier to diagnose%0A    @Parameterized.Parameters(name = %22test:%7Bindex%7D  arg:%5C%22%7B0%7D%5C%22%22)%0A    public static Collection%3CString%3E getSelectors() %7B%0A        return Arrays.asList(%22#link-panel a%22, %22#icon-panel svg%22);%0A    %7D%0A%0A    public Security2779Test(String selector) %7B%0A        this.selector = selector;%0A    %7D%0A%0A    @Test%0A    public void noXssInHelp(
+@Test%0A    public void noXssInHelpLinkPanel() throws Exception %7B%0A        noCrossSiteScriptingInHelp(%22#link-panel a%22);%0A    %7D%0A%0A    @Test%0A    public void noXssInHelpIconPanel() throws Exception %7B%0A        noCrossSiteScriptingInHelp(%22#icon-panel svg%22);%0A    %7D%0A%0A    private void noCrossSiteScriptingInHelp(String selector
 ) th

Switch from parameterized test to individual tests