aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakozak2011-11-24 02:07:53 (EST)
committerWinston Prakash2011-12-01 20:47:22 (EST)
commit3e8ad3333515300e3b17d0c4756b97018362c8c9 (patch)
tree3a38f3b61d6dae44625e9c83186e2253beab89a3
parentda4ded42c6a6eba2990d49bcf177216f6d12991b (diff)
downloadorg.eclipse.hudson.core-3e8ad3333515300e3b17d0c4756b97018362c8c9.zip
org.eclipse.hudson.core-3e8ad3333515300e3b17d0c4756b97018362c8c9.tar.gz
org.eclipse.hudson.core-3e8ad3333515300e3b17d0c4756b97018362c8c9.tar.bz2
Implement unit-tests for link/unlink cascading projects. Improve deleteConfirmation dialog. Doesn't allow to delete project with cascading children
Signed-off-by: Winston Prakash <winston.prakash@gmail.com>
-rw-r--r--hudson-core/src/main/java/hudson/Functions.java8
-rw-r--r--hudson-core/src/main/java/hudson/model/Job.java5
-rw-r--r--hudson-core/src/main/resources/hudson/model/AbstractProject/delete.jelly38
-rw-r--r--hudson-core/src/main/resources/hudson/model/AbstractProject/deleteConfirmationPanel.jelly53
-rw-r--r--hudson-core/src/main/resources/hudson/model/AbstractProject/sidepanel.jelly6
-rw-r--r--hudson-core/src/test/java/hudson/FunctionsTest.java58
-rw-r--r--hudson-war/src/main/webapp/css/style.css8
7 files changed, 154 insertions, 22 deletions
diff --git a/hudson-core/src/main/java/hudson/Functions.java b/hudson-core/src/main/java/hudson/Functions.java
index 50fbfbf..e0ed83c 100644
--- a/hudson-core/src/main/java/hudson/Functions.java
+++ b/hudson-core/src/main/java/hudson/Functions.java
@@ -1376,14 +1376,17 @@ public class Functions {
*
* @param cascadingProject cascading project to start from.
* @param projectToUnlink project that should be unlinked.
+ * @return true if project was unlinked, false - if cascadingProject or projectToUnlink is Null
*/
- public static void unlinkCascadingProject(Job cascadingProject, String projectToUnlink) {
+ public static boolean unlinkProjectFromCascadingParents(Job cascadingProject, String projectToUnlink) {
if (null != cascadingProject && null != projectToUnlink) {
cascadingProject.removeCascadingChild(projectToUnlink);
if (cascadingProject.hasCascadingProject()) {
- unlinkCascadingProject(cascadingProject.getCascadingProject(), projectToUnlink);
+ unlinkProjectFromCascadingParents(cascadingProject.getCascadingProject(), projectToUnlink);
}
+ return true;
}
+ return false;
}
/**
@@ -1393,7 +1396,6 @@ public class Functions {
* @param cascadingProject cascadingProject.
* @param childProjectName the name of child project name.
*/
- @SuppressWarnings("unchecked")
public static void linkCascadingProjectsToChild(Job cascadingProject, String childProjectName){
if(cascadingProject != null){
cascadingProject.addCascadingChild(childProjectName);
diff --git a/hudson-core/src/main/java/hudson/model/Job.java b/hudson-core/src/main/java/hudson/model/Job.java
index 9d256a5..a2aa3da 100644
--- a/hudson-core/src/main/java/hudson/model/Job.java
+++ b/hudson-core/src/main/java/hudson/model/Job.java
@@ -328,6 +328,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
*
* @return list of cascading children project names.
*/
+ @Exported
public Set<String> getCascadingChildrenNames() {
return cascadingChildrenNames;
}
@@ -506,6 +507,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
// should we block until the build is cancelled?
}
}
+ //TODO delete cascading project
super.performDelete();
}
@@ -1505,6 +1507,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
if (StringUtils.isBlank(cascadingProjectName)) {
clearCascadingProject();
} else if (!StringUtils.equalsIgnoreCase(this.cascadingProjectName, cascadingProjectName)) {
+ Functions.unlinkProjectFromCascadingParents(cascadingProject, name);
this.cascadingProjectName = cascadingProjectName;
this.cascadingProject = (JobT) Functions.getItemByName(Hudson.getInstance().getAllItems(this.getClass()),
cascadingProjectName);
@@ -1546,7 +1549,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
* Remove cascading project data and mark all project properties as non-overridden
*/
private void clearCascadingProject() {
- Functions.unlinkCascadingProject(cascadingProject, name);
+ Functions.unlinkProjectFromCascadingParents(cascadingProject, name);
this.cascadingProject = null;
this.cascadingProjectName = null;
for (IProjectProperty property : jobProperties.values()) {
diff --git a/hudson-core/src/main/resources/hudson/model/AbstractProject/delete.jelly b/hudson-core/src/main/resources/hudson/model/AbstractProject/delete.jelly
new file mode 100644
index 0000000..3bf709a
--- /dev/null
+++ b/hudson-core/src/main/resources/hudson/model/AbstractProject/delete.jelly
@@ -0,0 +1,38 @@
+<!-- **************************************************************************
+#
+# Copyright (c) 2011 Oracle Corporation.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#
+# Nikita Levyankov
+#
+#
+#************************************************************************** -->
+<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
+ <l:layout>
+ <st:include page="sidepanel.jelly" />
+ <l:main-panel>
+ <j:choose>
+ <j:when test="${it.cascadingChildrenNames.isEmpty()}">
+ <form method="post" action="doDelete">
+ ${%Are you sure about deleting the job?}
+ <f:submit value="${%Yes}" />
+ </form>
+ </j:when>
+ <j:otherwise>
+ <h4>${%You can't delete this job because it has cascading children:}</h4>
+ <ul>
+ <j:forEach var="job" items="${it.cascadingChildrenNames}">
+ <li>${job}</li>
+ </j:forEach>
+ </ul>
+ </j:otherwise>
+ </j:choose>
+ </l:main-panel>
+ </l:layout>
+</j:jelly> \ No newline at end of file
diff --git a/hudson-core/src/main/resources/hudson/model/AbstractProject/deleteConfirmationPanel.jelly b/hudson-core/src/main/resources/hudson/model/AbstractProject/deleteConfirmationPanel.jelly
index 2b16fc9..e2367b5 100644
--- a/hudson-core/src/main/resources/hudson/model/AbstractProject/deleteConfirmationPanel.jelly
+++ b/hudson-core/src/main/resources/hudson/model/AbstractProject/deleteConfirmationPanel.jelly
@@ -1,6 +1,6 @@
<!-- **************************************************************************
#
-# Copyright (c) 2004-2009 Oracle Corporation.
+# Copyright (c) 2004-2011 Oracle Corporation.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
@@ -9,16 +9,51 @@
#
# Contributors:
#
-# Winston Prakash
+# Winston Prakash, Nikita Levyankov
#
#
#************************************************************************** -->
+<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt">
+ <script type="text/javascript">
+ function onDeleteClick() {
+ jQuery.ajax({
+ url: "${rootUrl}/${it.url}api/json",
+ dataType: 'json',
+ success: function(data) {
+ jQuery('#confirmDialog').show();
+ jQuery('#childrenList').hide();
+ var cascadingChildren = data.cascadingChildrenNames;
+ if (cascadingChildren.length != 0) {
+ var jobList = jQuery("#jobList");
+ jobList.html("");
+ cascadingChildren.sort();
+ for (var i = 0; i &lt; cascadingChildren.length; i++) {
+ jobList.append("<li>" + cascadingChildren[i] + "</li>");
+ }
+ jQuery('#confirmDialog').hide();
+ jQuery('#childrenList').show();
+ }
+ }
+ });
+ onLinkClick("question");
+ }
+ </script>
-<div>
- <form method="post" action="doDelete">
- <h4>Are you sure you want to delete the Job?.</h4>
- <input type="submit" class="yes" value="Yes" />
- <input type="button" class="no" value="No" />
- </form>
-</div>
+ <div>
+ <form method="post" action="doDelete" id="deleteForm">
+ <div id="confirmDialog">
+ <h4>Are you sure you want to delete the Job?.</h4>
+ <input type="submit" class="yes" value="${%Yes}"/>
+ <input type="button" class="no" value="${%No}"/>
+ </div>
+ <div id="childrenList" class="deleteJobDialog" style="display:none">
+ <h4>${%You can't delete this job because it has cascading children:}</h4>
+ <ul id="jobList">
+ </ul>
+ <input type="button" class="no" value="${%Ok}" />
+ </div>
+ </form>
+ </div>
+
+</j:jelly>
diff --git a/hudson-core/src/main/resources/hudson/model/AbstractProject/sidepanel.jelly b/hudson-core/src/main/resources/hudson/model/AbstractProject/sidepanel.jelly
index 2590104..65a13c8 100644
--- a/hudson-core/src/main/resources/hudson/model/AbstractProject/sidepanel.jelly
+++ b/hudson-core/src/main/resources/hudson/model/AbstractProject/sidepanel.jelly
@@ -1,6 +1,6 @@
<!-- **************************************************************************
#
-# Copyright (c) 2004-2009 Oracle Corporation.
+# Copyright (c) 2004-2011 Oracle Corporation.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
@@ -9,7 +9,7 @@
#
# Contributors:
#
-# Kohsuke Kawaguchi, Erik Ramfelt, Tom Huybrechts, id:cactusman, Yahoo! Inc.
+# Kohsuke Kawaguchi, Erik Ramfelt, Tom Huybrechts, id:cactusman, Yahoo! Inc., Nikita Levyankov
#
#
#************************************************************************** -->
@@ -46,7 +46,7 @@
}
</script>
</j:if>
- <l:taskWithDialog icon="images/24x24/edit-delete.png" href="${url}/delete" dialogPanel="deleteConfirmationPanel.jelly" title="${%delete(it.pronoun)}" permission="${it.DELETE}" />
+ <l:taskWithDialog icon="images/24x24/edit-delete.gif" href="${url}/delete" dialogPanel="deleteConfirmationPanel.jelly" title="${%delete(it.pronoun)}" permission="${it.DELETE}" onclick="onDeleteClick();return false;"/>
<j:choose>
<j:when test="${h.hasPermission(it,it.CONFIGURE)}">
<l:task icon="images/24x24/setting.png" href="${url}/configure" title="${%Configure}" />
diff --git a/hudson-core/src/test/java/hudson/FunctionsTest.java b/hudson-core/src/test/java/hudson/FunctionsTest.java
index 80ec0a9..bcc6c07 100644
--- a/hudson-core/src/test/java/hudson/FunctionsTest.java
+++ b/hudson-core/src/test/java/hudson/FunctionsTest.java
@@ -16,6 +16,7 @@
package hudson;
import hudson.model.FreeStyleProject;
+import hudson.model.FreeStyleProjectMock;
import hudson.model.Hudson;
import hudson.model.Job;
import hudson.model.User;
@@ -24,7 +25,6 @@ import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@@ -140,4 +140,58 @@ public class FunctionsTest {
items.add(parentProject);
FreeStyleProject project = Functions.getItemByName(items, TEMPLATE_NAME);
assertNotNull(project);
- }}
+ }
+ @Test
+ public void testUnlinkProjectFromCascadingParents() {
+ //Prepare data
+ FreeStyleProject project1 = new FreeStyleProjectMock("project1");
+ FreeStyleProjectMock child1 = new FreeStyleProjectMock("child1");
+ child1.setCascadingProject(project1);
+ String cascadingName = "newCascadingProject";
+ Functions.linkCascadingProjectsToChild(child1, cascadingName);
+
+ //Can't unlink from null project
+ assertFalse(Functions.unlinkProjectFromCascadingParents(null, cascadingName));
+ //Can't unlink null cascading name
+ assertFalse(Functions.unlinkProjectFromCascadingParents(project1, null));
+
+ //Verify whether cascadingName is present in parent and child
+ assertTrue(project1.getCascadingChildrenNames().contains(cascadingName));
+ assertTrue(child1.getCascadingChildrenNames().contains(cascadingName));
+ boolean result = Functions.unlinkProjectFromCascadingParents(child1, cascadingName);
+ assertTrue(result);
+ //Name should disappear from hierarchy.
+ assertFalse(project1.getCascadingChildrenNames().contains(cascadingName));
+ assertFalse(child1.getCascadingChildrenNames().contains(cascadingName));
+
+ Functions.linkCascadingProjectsToChild(project1, cascadingName);
+ assertTrue(project1.getCascadingChildrenNames().contains(cascadingName));
+ result = Functions.unlinkProjectFromCascadingParents(child1, cascadingName);
+ assertTrue(result);
+ assertFalse(project1.getCascadingChildrenNames().contains(cascadingName));
+
+ }
+
+ @Test
+ public void testLinkCascadingProjectsToChild() {
+ FreeStyleProject project1 = new FreeStyleProjectMock("project1");
+ FreeStyleProjectMock child1 = new FreeStyleProjectMock("child1");
+ child1.setCascadingProject(project1);
+ String cascadingName = "newCascadingProject";
+ Functions.linkCascadingProjectsToChild(null, cascadingName);
+ assertFalse(project1.getCascadingChildrenNames().contains(cascadingName));
+ assertFalse(child1.getCascadingChildrenNames().contains(cascadingName));
+
+ Functions.linkCascadingProjectsToChild(project1, cascadingName);
+ assertTrue(project1.getCascadingChildrenNames().contains(cascadingName));
+
+ project1 = new FreeStyleProjectMock("project1");
+ child1 = new FreeStyleProjectMock("child1");
+ child1.setCascadingProject(project1);
+ Functions.linkCascadingProjectsToChild(child1, cascadingName);
+ //Name should be included to all cascading parents up-hierarchy.
+ assertTrue(project1.getCascadingChildrenNames().contains(cascadingName));
+ assertTrue(child1.getCascadingChildrenNames().contains(cascadingName));
+ }
+}
+
diff --git a/hudson-war/src/main/webapp/css/style.css b/hudson-war/src/main/webapp/css/style.css
index c56c499..dfa890d 100644
--- a/hudson-war/src/main/webapp/css/style.css
+++ b/hudson-war/src/main/webapp/css/style.css
@@ -987,17 +987,17 @@ table.progress-bar.red td.progress-bar-done {
.tag8 { font-size: 1.80em; }
.tag9 { font-size: 1.90em; }
-/* ========================= "Delete slave" dialog ================== */
-div.deleteSlaveDialog ul {
+/* ========================= "Delete job and slave" dialog ================== */
+div.deleteSlaveDialog ul, div.deleteJobDialog ul {
text-align:left;
padding-left:80px;
}
-div.deleteSlaveDialog div.radioButtons {
+div.deleteSlaveDialog div.radioButtons, div.deleteJobDialog div.radioButtons {
padding-bottom:10px;
}
-div.deleteSlaveDialog h4 {
+div.deleteSlaveDialog h4, div.deleteJobDialog h4 {
color: #F89938;
}
/* ======================== "Cascading project" ==========================*/