JENKINS-36967# Favorite object self link fix (#377)

This commit is contained in:
vivek 2016-07-27 07:47:39 -07:00 committed by GitHub
parent 6de55426ef
commit b8c038abac
7 changed files with 230 additions and 92 deletions

View File

@ -9,6 +9,7 @@ import io.jenkins.blueocean.commons.ServiceException;
import io.jenkins.blueocean.rest.Navigable;
import io.jenkins.blueocean.rest.Reachable;
import io.jenkins.blueocean.rest.hal.Link;
import io.jenkins.blueocean.rest.hal.LinkResolver;
import io.jenkins.blueocean.rest.model.BlueActionProxy;
import io.jenkins.blueocean.rest.model.BlueFavorite;
import io.jenkins.blueocean.rest.model.BlueFavoriteAction;
@ -69,12 +70,8 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
}
FavoriteUtil.favoriteJob(mbp.getFullName(), favoriteAction.isFavorite());
return FavoriteUtil.getFavorite(mbp, new Reachable() {
@Override
public Link getLink() {
return getLink().rel("branches");
}
});
return new FavoriteImpl(new BranchImpl(job,getLink().rel("branches")), getLink().rel("favorite"));
}
@Override
@ -351,7 +348,10 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
Job job = project.getItem("master");
if(job != null){
Resource resource = BluePipelineFactory.resolve(job);
return new FavoriteImpl(resource, FavoriteUtil.getFavoriteLink(item.getFullName()));
Link l = LinkResolver.resolveLink(project);
if(l != null) {
return new FavoriteImpl(resource, l.rel("favorite"));
}
}
}
return null;

View File

@ -446,7 +446,7 @@ public class MultiBranchTest extends PipelineBaseTest {
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(l.size(), 1);
Assert.assertEquals(1,l.size());
branch = (Map)((Map)l.get(0)).get("item");
validatePipeline(p, branch);
@ -454,6 +454,30 @@ public class MultiBranchTest extends PipelineBaseTest {
c = (String) branch.get("_class");
Assert.assertEquals(BranchImpl.class.getName(), c);
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/p/favorite/", getHrefFromLinks((Map)l.get(0), "self"));
String ref = getHrefFromLinks((Map)l.get(0), "self");
m = new RequestBuilder(baseUrl)
.put(getUrlFromHref(ref))
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", false))
.build(Map.class);
branch = (Map) m.get("item");
validatePipeline(p, branch);
c = (String) branch.get("_class");
Assert.assertEquals(BranchImpl.class.getName(), c);
l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(0,l.size());
new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("bob","bob")
@ -488,20 +512,44 @@ public class MultiBranchTest extends PipelineBaseTest {
validatePipeline(p1, (Map) map.get("item"));
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/p/branches/feature2/favorite/", getHrefFromLinks(map, "self"));
List l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(l.size(), 1);
Assert.assertEquals(1, l.size());
Map branch = (Map)((Map)l.get(0)).get("item");
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/p/branches/feature2/favorite/", getHrefFromLinks((Map)l.get(0), "self"));
validatePipeline(p1, branch);
String c = (String) branch.get("_class");
Assert.assertEquals(BranchImpl.class.getName(), c);
map = new RequestBuilder(baseUrl)
.put(getUrlFromHref(getHrefFromLinks((Map)l.get(0), "self")))
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", false))
.build(Map.class);
validatePipeline(p1, (Map) map.get("item"));
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/p/branches/feature2/favorite/", getHrefFromLinks(map, "self"));
l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(0, l.size());
new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("bob","bob")
@ -548,15 +596,28 @@ public class MultiBranchTest extends PipelineBaseTest {
String c = (String) branch.get("_class");
Assert.assertEquals(BranchImpl.class.getName(), c);
String ref = getHrefFromLinks((Map)l.get(0), "self");
String href = getHrefFromLinks((Map)l.get(0), "self");
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/p/favorite/", href);
Map r = new RequestBuilder(baseUrl)
.get(ref.substring("/blue/rest".length()))
.auth("alice","alice")
Map m = new RequestBuilder(baseUrl)
.put(getUrlFromHref(getUrlFromHref(href)))
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", false))
.build(Map.class);
validatePipeline(p, (Map)r.get("item"));
branch = (Map) m.get("item");
validatePipeline(p, branch);
c = (String) branch.get("_class");
Assert.assertEquals(BranchImpl.class.getName(), c);
l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(0,l.size());
}
@Test

View File

@ -332,6 +332,13 @@ public abstract class PipelineBaseTest{
return (String) l.get("href");
}
protected String getUrlFromHref(String href){
if(href.startsWith("/blue/rest")){
return href.substring("/blue/rest".length());
}
return href;
}
protected List<FlowNode> getParallelNodes(FlowGraphTable nodeGraphTable){
List<FlowNode> parallelNodes = new ArrayList<>();

View File

@ -1,9 +1,6 @@
package io.jenkins.blueocean.service.embedded.util;
import hudson.Util;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.Job;
import hudson.model.User;
import hudson.plugins.favorite.FavoritePlugin;
import hudson.plugins.favorite.user.FavoriteUserProperty;
@ -16,7 +13,6 @@ import io.jenkins.blueocean.rest.model.BluePipeline;
import io.jenkins.blueocean.service.embedded.rest.BlueFavoriteResolver;
import io.jenkins.blueocean.service.embedded.rest.BluePipelineFactory;
import io.jenkins.blueocean.service.embedded.rest.FavoriteImpl;
import io.jenkins.blueocean.service.embedded.rest.UserImpl;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.Stapler;
@ -53,22 +49,6 @@ public class FavoriteUtil {
}
}
public static Link getFavoriteLink(String fullName){
User user = User.current();
if(user != null) {
return new UserImpl(user).getLink().rel("favorites/"+ FavoriteUtil.encodeFullName(fullName));
}
return null;
}
public static boolean isFavorableItem(Item i){
return i!= null && (i instanceof Job || i instanceof ItemGroup);
}
public static String encodeFullName(String name){
return Util.rawEncode(Util.rawEncode(name));
}
public static String decodeFullName(String name){
try {
return URLDecoder.decode(URLDecoder.decode(name, "UTF-8"), "UTF-8");
@ -119,15 +99,9 @@ public class FavoriteUtil {
}
}
//otherwise, default
Link favouriteLink = getFavoriteLink(item.getFullName());
if(favouriteLink == null){
return null;
}
BluePipeline pipeline = BluePipelineFactory.getPipelineInstance(item, parent);
if(pipeline != null){
return new FavoriteImpl(pipeline,favouriteLink);
return new FavoriteImpl(pipeline,pipeline.getLink().rel("favorite"));
}
return null;

View File

@ -15,6 +15,7 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.MockFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -227,24 +228,6 @@ public abstract class BaseTest {
throw new RuntimeException(e);
}
}
//
// protected void validateMultiBranchPipeline(WorkflowMultiBranchProject p, Map resp, int numBranches){
// validateMultiBranchPipeline(p, resp, numBranches, -1, -1);
// }
// protected void validateMultiBranchPipeline(WorkflowMultiBranchProject p, Map resp, int numBranches, int numSuccBranches, int numOfFailingBranches){
// Assert.assertEquals("jenkins", resp.get("organization"));
// Assert.assertEquals(p.getName(), resp.get("name"));
// Assert.assertEquals(p.getDisplayName(), resp.get("displayName"));
// Assert.assertNull(resp.get("lastSuccessfulRun"));
// Assert.assertEquals(numBranches, resp.get("totalNumberOfBranches"));
// if(numOfFailingBranches >= 0) {
// Assert.assertEquals(numOfFailingBranches, resp.get("numberOfFailingBranches"));
// }
// if(numSuccBranches >= 0) {
// Assert.assertEquals(numSuccBranches, resp.get("numberOfSuccessfulBranches"));
// }
// Assert.assertEquals(p.getBuildHealth().getScore(), resp.get("weatherScore"));
// }
protected void validatePipeline(Job p, Map resp){
Assert.assertEquals("jenkins", resp.get("organization"));
@ -271,6 +254,17 @@ public abstract class BaseTest {
}
}
protected void validateFolder(MockFolder folder, Map resp){
Assert.assertEquals("jenkins", resp.get("organization"));
Assert.assertEquals(folder.getName(), resp.get("name"));
Assert.assertEquals(folder.getDisplayName(), resp.get("displayName"));
Assert.assertEquals(folder.getFullName(), resp.get("fullName"));
Assert.assertNull(resp.get("lastSuccessfulRun"));
Assert.assertEquals(folder.getAllJobs().size(), resp.get("numberOfPipelines"));
Assert.assertEquals(folder.getAllJobs().size(), resp.get("numberOfPipelines"));
}
protected void validateRun(Run r, Map resp){
validateRun(r,resp, "FINISHED");
}
@ -285,39 +279,12 @@ public abstract class BaseTest {
Assert.assertEquals(state, resp.get("state"));
}
// protected String getNodeName(FlowNode n){
// return n.getAction(ThreadNameAction.class) != null
// ? n.getAction(ThreadNameAction.class).getThreadName()
// : n.getDisplayName();
// }
private String getBaseUrl(String path){
return baseUrl + path;
}
// protected List<FlowNode> getStages(FlowGraphTable nodeGraphTable){
// List<FlowNode> nodes = new ArrayList<>();
// for(FlowGraphTable.Row row: nodeGraphTable.getRows()){
// if(PipelineNodeUtil.isStage(row.getNode()) ||
// PipelineNodeUtil.isParallelBranch(row.getNode())){
// nodes.add(row.getNode());
// }
// }
// return nodes;
// }
// protected List<FlowNode> getParallelNodes(FlowGraphTable nodeGraphTable){
// List<FlowNode> parallelNodes = new ArrayList<>();
//
// for(FlowGraphTable.Row row: nodeGraphTable.getRows()){
// if(PipelineNodeUtil.isParallelBranch(row.getNode())){
// parallelNodes.add(row.getNode());
// }
// }
// return parallelNodes;
// }
protected String getHrefFromLinks(Map resp, String link){
Map links = (Map) resp.get("_links");
if(links == null){

View File

@ -2,11 +2,13 @@ package io.jenkins.blueocean.service.embedded;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import hudson.model.FreeStyleProject;
import hudson.model.Project;
import hudson.model.User;
import hudson.tasks.Mailer;
import org.junit.Assert;
import org.junit.Test;
import org.jvnet.hudson.test.MockFolder;
import java.util.Collections;
import java.util.List;
@ -90,8 +92,10 @@ public class ProfileApiTest extends BaseTest{
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
hudson.model.User user = j.jenkins.getUser("alice");
user.setFullName("Alice Cooper");
Project p = j.createFreeStyleProject("pipeline1");
Map map = new RequestBuilder(baseUrl)
.put("/organizations/jenkins/pipelines/pipeline1/favorite")
.auth("alice", "alice")
@ -104,11 +108,121 @@ public class ProfileApiTest extends BaseTest{
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(l.size(), 1);
Assert.assertEquals(1, l.size());
Map pipeline = (Map)((Map)l.get(0)).get("item");
validatePipeline(p, pipeline);
String href = getHrefFromLinks((Map)l.get(0),"self");
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite/", href);
map = new RequestBuilder(baseUrl)
.put(href.substring("/blue/rest".length()))
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", false))
.build(Map.class);
validatePipeline(p, (Map) map.get("item"));
l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(0, l.size());
new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("bob","bob")
.status(403)
.build(String.class);
}
@Test
public void createUserFavouriteFolderTest() throws Exception {
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
hudson.model.User user = j.jenkins.getUser("alice");
user.setFullName("Alice Cooper");
MockFolder folder1 = j.createFolder("folder1");
Project p = folder1.createProject(FreeStyleProject.class, "pipeline1");
Map map = new RequestBuilder(baseUrl)
.put("/organizations/jenkins/pipelines/folder1/pipelines/pipeline1/favorite/")
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", true))
.build(Map.class);
validatePipeline(p, (Map) map.get("item"));
List l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(1, l.size());
Map pipeline = (Map)((Map)l.get(0)).get("item");
validatePipeline(p, pipeline);
String href = getHrefFromLinks((Map)l.get(0),"self");
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/folder1/pipelines/pipeline1/favorite/", href);
map = new RequestBuilder(baseUrl)
.put(href.substring("/blue/rest".length()))
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", false))
.build(Map.class);
validatePipeline(p, (Map) map.get("item"));
l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(0, l.size());
map = new RequestBuilder(baseUrl)
.put("/organizations/jenkins/pipelines/folder1/favorite/")
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", true))
.build(Map.class);
validateFolder(folder1, (Map) map.get("item"));
l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(1, l.size());
Map folder = (Map)((Map)l.get(0)).get("item");
validateFolder(folder1, folder);
href = getHrefFromLinks((Map)l.get(0),"self");
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/folder1/favorite/", href);
map = new RequestBuilder(baseUrl)
.put(href.substring("/blue/rest".length()))
.auth("alice", "alice")
.data(ImmutableMap.of("favorite", false))
.build(Map.class);
validateFolder(folder1, (Map) map.get("item"));
l = new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("alice","alice")
.build(List.class);
Assert.assertEquals(0, l.size());
new RequestBuilder(baseUrl)
.get("/users/"+user.getId()+"/favorites/")
.auth("bob","bob")

View File

@ -56,7 +56,9 @@
- [Favorite API](#favorite-api)
- [Favorite a pipeline](#favorite-a-pipeline)
- [Favorite a multi branch pipeline](#favorite-a-multi-branch-pipeline)
- [Un-favorite a multi branch pipeline](#un-favorite-a-multi-branch-pipeline)
- [Favorite a multi branch pipeline branch](#favorite-a-multi-branch-pipeline-branch)
- [Un-favorite a multi branch pipeline branch](#un-favorite-a-multi-branch-pipeline-branch)
- [Fetch user favorites](#fetch-user-favorites)
- [Log API](#log-api)
- [Fetching logs](#fetching-logs)
@ -1279,7 +1281,7 @@ If favorite request is successful then the repsonse is favorited item.
"_links" : {
"self" : {
"_class" : "io.jenkins.blueocean.rest.hal.Link",
"href" : "/blue/rest/users/alice/favorites/pipeline1/"
"href" : "/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite/"
}
},
"item" : {
@ -1319,19 +1321,32 @@ If favorite request is successful then the repsonse is favorited item.
## Favorite a pipeline
Returns 200 on success. Must be authenticated.
curl -u bob:bob -H"Content-Type:application/json" -XPUT -d '{"favorite":true} ttp://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite
curl -u bob:bob -H"Content-Type:application/json" -XPUT -d '{"favorite":true} ttp://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite/
## Favorite a multi branch pipeline
Must be authenticated.
This favorites the master branch. Returns 200 on success. 500 if master does not exist
Favorited multi-branch pipeline returns master branch as favorited item. Returns 200 on success. 400 if master does not exist
curl -u bob:bob -H"Content-Type:application/json" -XPUT -d '{"favorite":true} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite/
## Un-favorite a multi branch pipeline
Must be authenticated.
This un-favorites the master branch. Returns 200 on success. 400 if master does not exist
curl -u bob:bob -H"Content-Type:application/json" -XPUT -d '{"favorite":false} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite/
curl -u bob:bob -H"Content-Type:application/json" -XPUT -d '{"favorite":true} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite
## Favorite a multi branch pipeline branch
Returns 200 on success. Must be authenticated.
curl -H"Content-Type:application/json" -XPUT -d '{"favorite":true} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/branches/master/favorite
curl -H"Content-Type:application/json" -XPUT -d '{"favorite":true} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/branches/master/favorite/
## Un-favorite a multi branch pipeline branch
Returns 200 on success. Must be authenticated.
curl -H"Content-Type:application/json" -XPUT -d '{"favorite":false} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/branches/master/favorite/
## Fetch user favorites