提交 f6cc5072 编写于 作者: V Vincent Latombe

Functions#getRelativeLinkTo now normalize the output url.

Added some unit tests
上级 a1adf8ae
......@@ -919,42 +919,71 @@ public class Functions {
}
String path = ancestors.get(p);
if(path!=null) return path;
if(path!=null) {
return normalizeURI(path + '/');
}
Item i=p;
String url = "";
Collection<TopLevelItem> viewItems;
if (view != null) {
viewItems = view.getItems();
} else {
viewItems = Collections.emptyList();
}
while(true) {
ItemGroup ig = i.getParent();
url = i.getShortUrl()+url;
if(ig== Jenkins.getInstance() || (view != null && ig == view.getOwner())) {
if(ig== Jenkins.getInstance() || (view != null && ig == view.getOwnerItemGroup())) {
assert i instanceof TopLevelItem;
if(view!=null && view.contains((TopLevelItem)i)) {
if(viewItems.contains((TopLevelItem)i)) {
// if p and the current page belongs to the same view, then return a relative path
return ancestors.get(view)+'/'+url;
return normalizeURI(ancestors.get(view)+'/'+url);
} else {
// otherwise return a path from the root Hudson
return request.getContextPath()+'/'+p.getUrl();
return normalizeURI(request.getContextPath()+'/'+p.getUrl());
}
}
path = ancestors.get(ig);
if(path!=null) return path+'/'+url;
if(path!=null) {
return normalizeURI(path+'/'+url);
}
assert ig instanceof Item; // if not, ig must have been the Hudson instance
i = (Item) ig;
}
}
private static String normalizeURI(String uri) {
return URI.create(uri).normalize().toString();
}
/**
* Gets all the {@link TopLevelItem}s recursively in the {@link ItemGroup} tree.
*
* @since XXX
*/
public static List<TopLevelItem> getAllTopLevelItems(ItemGroup root) {
return Items.getAllItems(root, TopLevelItem.class);
}
/**
* Gets the relative display name to the given item from the specified group.
*
* @since XXX
* @param p the Item we want the relative display name
* @param g the ItemGroup used as point of reference for the item
* @return
* String like "foo » bar"
*/
public static String getRelativeDisplayNameFrom(Item p, ItemGroup g) {
if (p == null) return null;
String relativeName = p.getRelativeNameFrom(g);
if (relativeName == null) return null;
return relativeName.replace("/", " \u00BB ");
return relativeName.replace("/", " » ");
}
public static Map<Thread,StackTraceElement[]> dumpAllThreads() {
......
......@@ -23,18 +23,30 @@
*/
package hudson;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import hudson.model.Action;
import hudson.model.ItemGroup;
import hudson.model.TopLevelItem;
import hudson.model.View;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import hudson.model.Action;
import static org.junit.Assert.*;
import jenkins.model.Jenkins;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jvnet.hudson.test.Bug;
import org.kohsuke.stapler.Ancestor;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import static org.powermock.api.mockito.PowerMockito.*;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
public class FunctionsTest {
......@@ -101,6 +113,94 @@ public class FunctionsTest {
assertEquals(contextPath + "/" + itUrl + path, result);
}
}
@Test
@PrepareForTest({Stapler.class, Jenkins.class})
public void testGetRelativeLinkTo_JobContainedInView() throws Exception{
Jenkins j = createMockJenkins();
ItemGroup parent = j;
String contextPath = "/jenkins";
StaplerRequest req = createMockRequest(contextPath);
mockStatic(Stapler.class);
when(Stapler.getCurrentRequest()).thenReturn(req);
View view = mock(View.class);
when(view.getOwnerItemGroup()).thenReturn(parent);
createMockAncestors(req, createAncestor(view, "."), createAncestor(j, "../.."));
TopLevelItem i = createMockItem(parent, "job/i/");
when(view.getItems()).thenReturn(Arrays.asList(i));
String result = Functions.getRelativeLinkTo(i);
assertEquals("job/i/", result);
}
@Test
@PrepareForTest({Stapler.class, Jenkins.class})
public void testGetRelativeLinkTo_JobNotContainedInView() throws Exception{
Jenkins j = createMockJenkins();
ItemGroup parent = j;
String contextPath = "/jenkins";
StaplerRequest req = createMockRequest(contextPath);
mockStatic(Stapler.class);
when(Stapler.getCurrentRequest()).thenReturn(req);
View view = mock(View.class);
when(view.getOwnerItemGroup()).thenReturn(parent);
createMockAncestors(req, createAncestor(j, "../.."), createAncestor(view, "."));
TopLevelItem i = createMockItem(parent, "job/i/");
when(view.getItems()).thenReturn(Collections.<TopLevelItem>emptyList());
String result = Functions.getRelativeLinkTo(i);
assertEquals("/jenkins/job/i/", result);
}
private interface TopLevelItemAndItemGroup <T extends TopLevelItem> extends TopLevelItem, ItemGroup<T> {}
@Test
@PrepareForTest({Stapler.class,Jenkins.class})
public void testGetRelativeLinkTo_JobContainedInViewWithinItemGroup() throws Exception{
Jenkins j = createMockJenkins();
TopLevelItemAndItemGroup parent = mock(TopLevelItemAndItemGroup.class);
when(parent.getShortUrl()).thenReturn("parent/");
String contextPath = "/jenkins";
StaplerRequest req = createMockRequest(contextPath);
mockStatic(Stapler.class);
when(Stapler.getCurrentRequest()).thenReturn(req);
View view = mock(View.class);
when(view.getOwnerItemGroup()).thenReturn(parent);
createMockAncestors(req, createAncestor(j, "../../.."), createAncestor(parent, "../.."), createAncestor(view, "."));
TopLevelItem i = createMockItem(parent, "job/i/", "parent/job/i/");
when(view.getItems()).thenReturn(Arrays.asList(i));
String result = Functions.getRelativeLinkTo(i);
assertEquals("job/i/", result);
}
private void createMockAncestors(StaplerRequest req, Ancestor... ancestors) {
List<Ancestor> ancestorsList = Arrays.asList(ancestors);
when(req.getAncestors()).thenReturn(ancestorsList);
}
private TopLevelItem createMockItem(ItemGroup p, String shortUrl) {
return createMockItem(p, shortUrl, shortUrl);
}
private TopLevelItem createMockItem(ItemGroup p, String shortUrl, String url) {
TopLevelItem i = mock(TopLevelItem.class);
when(i.getShortUrl()).thenReturn(shortUrl);
when(i.getUrl()).thenReturn(url);
when(i.getParent()).thenReturn(p);
return i;
}
private Jenkins createMockJenkins() {
mockStatic(Jenkins.class);
Jenkins j = mock(Jenkins.class);
when(Jenkins.getInstance()).thenReturn(j);
return j;
}
private static Ancestor createAncestor(Object o, String relativePath) {
Ancestor a = mock(Ancestor.class);
when(a.getObject()).thenReturn(o);
when(a.getRelativePath()).thenReturn(relativePath);
return a;
}
@Test
@PrepareForTest(Stapler.class)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册