diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index c745262..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-out/
-.DS_Store
-/target
-.idea
-*.iws
diff --git a/src/main/java/com/rallydev/rest/RallyRestApi.java b/src/main/java/com/rallydev/rest/RallyRestApi.java
index 6a0eaa8..253adbd 100644
--- a/src/main/java/com/rallydev/rest/RallyRestApi.java
+++ b/src/main/java/com/rallydev/rest/RallyRestApi.java
@@ -1,15 +1,26 @@
package com.rallydev.rest;
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URI;
+
import com.google.gson.JsonArray;
import com.rallydev.rest.client.ApiKeyClient;
import com.rallydev.rest.client.BasicAuthClient;
import com.rallydev.rest.client.HttpClient;
-import com.rallydev.rest.request.*;
-import com.rallydev.rest.response.*;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.net.URI;
+import com.rallydev.rest.request.BulkUserPermissionRequest;
+import com.rallydev.rest.request.CollectionUpdateRequest;
+import com.rallydev.rest.request.CreateRequest;
+import com.rallydev.rest.request.DeleteRequest;
+import com.rallydev.rest.request.GetRequest;
+import com.rallydev.rest.request.QueryRequest;
+import com.rallydev.rest.request.UpdateRequest;
+import com.rallydev.rest.response.CollectionUpdateResponse;
+import com.rallydev.rest.response.CreateResponse;
+import com.rallydev.rest.response.DeleteResponse;
+import com.rallydev.rest.response.GetResponse;
+import com.rallydev.rest.response.QueryResponse;
+import com.rallydev.rest.response.UpdateResponse;
/**
*
The main interface to the Rest API.
@@ -30,6 +41,19 @@ public class RallyRestApi implements Closeable {
public RallyRestApi(URI server, String userName, String password) {
this(new BasicAuthClient(server, userName, password));
}
+
+ /**
+ * Creates a new instance for the specified server using the specified credentials.
+ *
+ * @param server The server to connect to, e.g. {@code new URI("https://rally1.rallydev.com")}
+ * @param userName The username to be used for authentication.
+ * @param password The password to be used for authentication.
+ * @param httpClient The pre-configured httpClient.
+ * @deprecated Use the api key constructor instead.
+ */
+ public RallyRestApi(URI server, String userName, String password, org.apache.http.client.HttpClient httpClient) {
+ this(new BasicAuthClient(server, userName, password, httpClient));
+ }
/**
* Creates a new instance for the specified server using the specified API Key.
@@ -41,6 +65,17 @@ public RallyRestApi(URI server, String apiKey) {
this(new ApiKeyClient(server, apiKey));
}
+ /**
+ * Creates a new instance for the specified server using the specified API Key and a pre-configured httpClient.
+ *
+ * @param server The server to connect to, e.g. {@code new URI("https://rally1.rallydev.com")}
+ * @param apiKey The API Key to be used for authentication.
+ * @param httpClient The pre-configured httpClient.
+ */
+ public RallyRestApi(URI server, String apiKey, org.apache.http.client.HttpClient httpClient) {
+ this(new ApiKeyClient(server, apiKey, httpClient));
+ }
+
protected RallyRestApi(HttpClient httpClient) {
this.client = httpClient;
}
@@ -199,6 +234,17 @@ public GetResponse get(GetRequest request) throws IOException {
return new GetResponse(client.doGet(request.toUrl()));
}
+ /**
+ * Bulk update a given user's project permissions.
+ *
+ * @param request request the {@link BulkUserPermissionRequest} specifying the object to be retrieved.
+ * @return the resulting {@link CollectionUpdateResponse}
+ * @throws IOException if an error occurs during the retrieval.
+ */
+ public CollectionUpdateResponse bulkUpdate(BulkUserPermissionRequest request) throws IOException {
+ return new CollectionUpdateResponse(client.doPost(request.toUrl(), ""));
+ }
+
/**
* Release all resources associated with this instance.
*
diff --git a/src/main/java/com/rallydev/rest/client/ApiKeyClient.java b/src/main/java/com/rallydev/rest/client/ApiKeyClient.java
index 2295824..80209f9 100644
--- a/src/main/java/com/rallydev/rest/client/ApiKeyClient.java
+++ b/src/main/java/com/rallydev/rest/client/ApiKeyClient.java
@@ -1,10 +1,10 @@
package com.rallydev.rest.client;
-import org.apache.http.client.methods.HttpRequestBase;
-
import java.io.IOException;
import java.net.URI;
+import org.apache.http.client.methods.HttpRequestBase;
+
/**
* A HttpClient which authenticates using an API Key.
*/
@@ -23,6 +23,17 @@ public ApiKeyClient(URI server, String apiKey) {
this.apiKey = apiKey;
}
+ /**
+ * Construct a new client with a pre-configured HttpClient.
+ *
+ * @param server the server to connect to
+ * @param apiKey the key to be used for authentication
+ */
+ public ApiKeyClient(URI server, String apiKey, org.apache.http.client.HttpClient httpClient) {
+ super(server, httpClient);
+ this.apiKey = apiKey;
+ }
+
/**
* Execute a request against the WSAPI
*
diff --git a/src/main/java/com/rallydev/rest/client/BasicAuthClient.java b/src/main/java/com/rallydev/rest/client/BasicAuthClient.java
index 2b6d04a..36d0430 100644
--- a/src/main/java/com/rallydev/rest/client/BasicAuthClient.java
+++ b/src/main/java/com/rallydev/rest/client/BasicAuthClient.java
@@ -1,16 +1,18 @@
package com.rallydev.rest.client;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.rallydev.rest.response.GetResponse;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
import org.apache.http.auth.Credentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.auth.BasicScheme;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.rallydev.rest.response.GetResponse;
/**
* A HttpClient which authenticates using basic authentication (username/password).
@@ -24,6 +26,8 @@ public class BasicAuthClient extends HttpClient {
protected String securityToken;
protected Credentials credentials;
+ private Object privateLock = new Object();
+
/**
* Construct a new client.
* @param server the server to connect to
@@ -34,17 +38,36 @@ public BasicAuthClient(URI server, String userName, String password) {
super(server);
credentials = setClientCredentials(server, userName, password);
}
+
+ /**
+ * Construct a new client with a pre-configured HttpClient.
+ *
+ * @param server the server to connect to
+ * @param userName the username to be used for authentication
+ * @param password the password to be used for authentication
+ */
+ public BasicAuthClient(URI server, String userName, String password, org.apache.http.client.HttpClient client) {
+ super(server, client);
+ credentials = setClientCredentials(server, userName, password);
+ }
/**
- * Execute a request against the WSAPI
+ * Execute a request against the WSAPI.
+ *
+ * Always attaches the Basic Authentication header to avoid HTTP Spec handling.
+ *
+ * Traditionally, all requests are attempted without authorization,
+ * however we know that all resources are protected, so we can force pre-authentication.
*
* @param request the request to be executed
* @return the JSON encoded string response
* @throws java.io.IOException if a non-200 response code is returned or if some other
- * problem occurs while executing the request
+ * problem occurs while executing the request
*/
@Override
protected String doRequest(HttpRequestBase request) throws IOException {
+ request.addHeader(BasicScheme.authenticate(credentials, "utf-8", false));
+
if(!request.getMethod().equals(HttpGet.METHOD_NAME) &&
!this.getWsapiVersion().matches("^1[.]\\d+")) {
try {
@@ -70,13 +93,14 @@ protected String doRequest(HttpRequestBase request) throws IOException {
protected void attachSecurityInfo(HttpRequestBase request) throws IOException, URISyntaxException {
if (!SECURITY_ENDPOINT_DOES_NOT_EXIST.equals(securityToken)) {
try {
- if (securityToken == null) {
- HttpGet httpGet = new HttpGet(getWsapiUrl() + SECURITY_TOKEN_URL);
- httpGet.addHeader(BasicScheme.authenticate(credentials, "utf-8", false));
- GetResponse getResponse = new GetResponse(doRequest(httpGet));
- JsonObject operationResult = getResponse.getObject();
- JsonPrimitive securityTokenPrimitive = operationResult.getAsJsonPrimitive(SECURITY_TOKEN_KEY);
- securityToken = securityTokenPrimitive.getAsString();
+ synchronized (privateLock) {
+ if (securityToken == null) {
+ HttpGet httpGet = new HttpGet(getWsapiUrl() + SECURITY_TOKEN_URL);
+ GetResponse getResponse = new GetResponse(doRequest(httpGet));
+ JsonObject operationResult = getResponse.getObject();
+ JsonPrimitive securityTokenPrimitive = operationResult.getAsJsonPrimitive(SECURITY_TOKEN_KEY);
+ securityToken = securityTokenPrimitive.getAsString();
+ }
}
request.setURI(new URIBuilder(request.getURI()).addParameter(SECURITY_TOKEN_PARAM_KEY, securityToken).build());
} catch (IOException e) {
diff --git a/src/main/java/com/rallydev/rest/client/HttpClient.java b/src/main/java/com/rallydev/rest/client/HttpClient.java
index 3bc4a9a..d657088 100644
--- a/src/main/java/com/rallydev/rest/client/HttpClient.java
+++ b/src/main/java/com/rallydev/rest/client/HttpClient.java
@@ -1,24 +1,28 @@
package com.rallydev.rest.client;
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.methods.*;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DecompressingHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
-import java.io.Closeable;
-import java.io.IOException;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-
/**
* A HttpClient implementation providing connectivity to Rally. This class does not
* provide any authentication on its own but instead relies on a concrete subclass to do so.
@@ -28,7 +32,7 @@ public class HttpClient extends DefaultHttpClient
protected URI server;
protected String wsapiVersion = "v2.0";
- protected DecompressingHttpClient client;
+ protected org.apache.http.client.HttpClient client;
private enum Header {
Library,
@@ -51,6 +55,17 @@ protected HttpClient(URI server) {
client = new DecompressingHttpClient(this);
}
+ /**
+ * Allow the user to specify a compliant HttpClient
+ *
+ * @param server The URI of the remote server
+ * @param client A pre-configured HttpClient implementation
+ */
+ public HttpClient(URI server, org.apache.http.client.HttpClient client) {
+ this.server = server;
+ this.client = client;
+ }
+
/**
* Set the unauthenticated proxy server to use. By default no proxy is configured.
*
diff --git a/src/main/java/com/rallydev/rest/request/BulkUserPermissionRequest.java b/src/main/java/com/rallydev/rest/request/BulkUserPermissionRequest.java
new file mode 100644
index 0000000..ffe2753
--- /dev/null
+++ b/src/main/java/com/rallydev/rest/request/BulkUserPermissionRequest.java
@@ -0,0 +1,66 @@
+package com.rallydev.rest.request;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.message.BasicNameValuePair;
+
+/**
+ * Represents a WSAPI request to bulk provision a user.
+ */
+public class BulkUserPermissionRequest extends Request {
+
+ private static final String PROJECTPERMISSION_BULKUPDATE = "/projectpermission/bulkupdate";
+
+ private String userOID;
+ private Collection excludedRootProjectOIDs;
+ private String rootProjectOID;
+ private String permission;
+ private boolean forceDowngradePermissions;
+
+ /**
+ *
+ * @param userOID
+ * The OID (ObjectID) of the User who will be granted new project permissions
+ * @param excludedRootProjectOIDs
+ * The OIDs of any child Project (or a child of a child, or any ancestor to any level) under the root project which are to be excluded from the
+ * permission change operation.
+ * @param rootProjectOID
+ * The OID of the root of the Project tree of which to change the permissions for the given user. The user's Project permission for all Projects
+ * rooted at this one will be changed, unless (see below for further explanation)
+ * the Project is on the exclusions list, or
+ * the operation would result in a downgrade but the force downgrade parameters was not set to tree.
+ * @param permission
+ * The permission to grant. Must be one of No Access, Viewer, Editor, or Project Admin.
+ * @param forceDowngradePermissions
+ * If you intend to downgrade any existing project permissions, set this to true.
+ */
+ public BulkUserPermissionRequest(String userOID, Collection excludedRootProjectOIDs, String rootProjectOID, String permission,
+ boolean forceDowngradePermissions) {
+ super();
+ this.userOID = userOID;
+ this.excludedRootProjectOIDs = excludedRootProjectOIDs;
+ this.rootProjectOID = rootProjectOID;
+ this.permission = permission;
+ this.forceDowngradePermissions = forceDowngradePermissions;
+ }
+
+ @Override
+ public String toUrl() {
+ List params = new ArrayList(getParams());
+ params.add(new BasicNameValuePair("userOID", userOID));
+ params.add(new BasicNameValuePair("rootProjectOID", rootProjectOID));
+ params.add(new BasicNameValuePair("permission", permission));
+ params.add(new BasicNameValuePair("forceDowngradePermissions", Boolean.toString(forceDowngradePermissions)));
+
+ if (excludedRootProjectOIDs != null && !excludedRootProjectOIDs.isEmpty()) {
+ params.add(new BasicNameValuePair("excludedRootProjectOIDs", String.join(",", excludedRootProjectOIDs)));
+ }
+
+ return String.format("%s?%s", PROJECTPERMISSION_BULKUPDATE, URLEncodedUtils.format(params, "utf-8"));
+ }
+
+}
diff --git a/src/main/java/com/rallydev/rest/response/Response.java b/src/main/java/com/rallydev/rest/response/Response.java
index de1123a..30190d0 100644
--- a/src/main/java/com/rallydev/rest/response/Response.java
+++ b/src/main/java/com/rallydev/rest/response/Response.java
@@ -1,17 +1,20 @@
package com.rallydev.rest.response;
+import java.util.ArrayList;
+import java.util.List;
+
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Represents a WSAPI response.
*/
public abstract class Response {
+ private static final String ERRORS = "Errors";
+ private static final String WARNINGS = "Warnings";
+
protected JsonObject result;
protected String raw;
@@ -40,7 +43,7 @@ public boolean wasSuccessful() {
* @return the response errors
*/
public String[] getErrors() {
- return parseArray("Errors");
+ return result.has(ERRORS) ? parseArray(ERRORS) : new String[0];
}
/**
@@ -49,7 +52,7 @@ public String[] getErrors() {
* @return the response warnings
*/
public String[] getWarnings() {
- return parseArray("Warnings");
+ return result.has(WARNINGS) ? parseArray(WARNINGS) : new String[0];
}
/**
diff --git a/src/test/java/com/rallydev/rest/RallyRestApiTest.java b/src/test/java/com/rallydev/rest/RallyRestApiTest.java
index eba2d1c..b5ccda1 100644
--- a/src/test/java/com/rallydev/rest/RallyRestApiTest.java
+++ b/src/test/java/com/rallydev/rest/RallyRestApiTest.java
@@ -1,25 +1,37 @@
package com.rallydev.rest;
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-import com.rallydev.rest.client.ApiKeyClient;
-import com.rallydev.rest.client.BasicAuthClient;
-import com.rallydev.rest.request.*;
-import com.rallydev.rest.response.*;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.net.URI;
-
-import static org.mockito.Mockito.anyString;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.testng.Assert.assertEquals;
+import java.net.URI;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.rallydev.rest.client.ApiKeyClient;
+import com.rallydev.rest.client.BasicAuthClient;
+import com.rallydev.rest.request.BulkUserPermissionRequest;
+import com.rallydev.rest.request.CollectionUpdateRequest;
+import com.rallydev.rest.request.CreateRequest;
+import com.rallydev.rest.request.DeleteRequest;
+import com.rallydev.rest.request.GetRequest;
+import com.rallydev.rest.request.QueryRequest;
+import com.rallydev.rest.request.UpdateRequest;
+import com.rallydev.rest.response.CollectionUpdateResponse;
+import com.rallydev.rest.response.CreateResponse;
+import com.rallydev.rest.response.DeleteResponse;
+import com.rallydev.rest.response.GetResponse;
+import com.rallydev.rest.response.QueryResponse;
+import com.rallydev.rest.response.UpdateResponse;
+
@Test
public class RallyRestApiTest {
private RallyRestApi api;
@@ -125,6 +137,24 @@ public void shouldUpdate() throws Exception {
assertEquals(obj.get("_ref").getAsString(), "/defect/1234");
}
+ public void shouldBulkUserPermissionUpdate() throws Exception {
+ JsonObject response = new JsonObject();
+ JsonObject updateResult = new JsonObject();
+ response.add("OperationResult", updateResult);
+ JsonArray results = new JsonArray();
+ JsonObject tag = new JsonObject();
+ tag.addProperty("_ref", "/tag/23456");
+ results.add(tag);
+ response.add("Results", results);
+
+ BulkUserPermissionRequest request = new BulkUserPermissionRequest("1234,", null, "111", "Viewer", false);
+ doReturn(new Gson().toJson(response)).when(api.client).doPost(request.toUrl(), "");
+ CollectionUpdateResponse collectionUpdateResponse = api.bulkUpdate(request);
+
+ verify(api.client).doPost(request.toUrl(), "");
+ Assert.assertTrue(collectionUpdateResponse.wasSuccessful());
+ }
+
public void shouldUpdateCollection() throws Exception {
JsonObject response = new JsonObject();
JsonObject result = new JsonObject();
diff --git a/src/test/java/com/rallydev/rest/client/ApiKeyClientTest.java b/src/test/java/com/rallydev/rest/client/ApiKeyClientTest.java
index 84ca9e6..93ea0b7 100644
--- a/src/test/java/com/rallydev/rest/client/ApiKeyClientTest.java
+++ b/src/test/java/com/rallydev/rest/client/ApiKeyClientTest.java
@@ -1,18 +1,23 @@
package com.rallydev.rest.client;
-import com.rallydev.rest.matchers.HttpRequestHeaderMatcher;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.impl.client.DefaultHttpClient;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.*;
+import com.rallydev.rest.matchers.HttpRequestHeaderMatcher;
public class ApiKeyClientTest {
@@ -31,10 +36,25 @@ public void shouldIntialize() {
Assert.assertEquals(client.getServer(), server);
}
+ @SuppressWarnings("resource")
+ @Test
+ public void shouldIntializePreConfiguredClient() throws URISyntaxException {
+ HttpClient mockClient = mock(HttpClient.class);
+ ApiKeyClient client = new ApiKeyClient(new URI(server), apiKey, mockClient);
+ Assert.assertEquals(client.getServer(), server);
+ }
+
@Test
public void shouldIncludeApiKeyOnRequest() throws Exception {
doReturn("").when(client).executeRequest(any(HttpRequestBase.class));
client.doRequest(new HttpGet());
verify(client).doRequest(argThat(new HttpRequestHeaderMatcher("zsessionid", apiKey)));
}
+
+ @Test
+ public void shouldReturnPreConfiguredClient() throws Exception {
+ DefaultHttpClient mockClient = mock(DefaultHttpClient.class);
+ ApiKeyClient spiedClient = spy(new ApiKeyClient(new URI(server), apiKey, mockClient));
+ Assert.assertEquals(spiedClient.client, mockClient);
+ }
}
diff --git a/src/test/java/com/rallydev/rest/client/BasicAuthClientTest.java b/src/test/java/com/rallydev/rest/client/BasicAuthClientTest.java
index e661892..51a7798 100644
--- a/src/test/java/com/rallydev/rest/client/BasicAuthClientTest.java
+++ b/src/test/java/com/rallydev/rest/client/BasicAuthClientTest.java
@@ -1,18 +1,28 @@
package com.rallydev.rest.client;
-import com.rallydev.rest.matchers.HttpRequestHeaderMatcher;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
import org.apache.http.Header;
-import org.apache.http.client.methods.*;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.auth.BasicScheme;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.*;
+import com.rallydev.rest.matchers.HttpRequestHeaderMatcher;
public class BasicAuthClientTest {
@@ -36,11 +46,31 @@ public void shouldIntialize() {
Assert.assertEquals(client.credentials.getUserPrincipal().getName(), userName);
}
+ @SuppressWarnings("resource")
+ @Test
+ public void shouldIntializePreConfiguredClient() throws URISyntaxException {
+ HttpClient mockClient = mock(HttpClient.class);
+ BasicAuthClient client = new BasicAuthClient(new URI(server), userName, password, mockClient);
+ Assert.assertEquals(client.getServer(), server);
+ Assert.assertEquals(client.credentials.getPassword(), password);
+ Assert.assertEquals(client.credentials.getUserPrincipal().getName(), userName);
+ }
+
+ @Test
+ public void shouldIncludeAuthHeaderOnGet() throws Exception {
+ doReturn("").when(client).executeRequest(any(HttpRequestBase.class));
+ client.doRequest(new HttpGet());
+ Header authHeader = BasicScheme.authenticate(client.credentials, "utf-8", false);
+ verify(client).executeRequest(argThat(new HttpRequestHeaderMatcher(authHeader.getName(), authHeader.getValue())));
+ }
+
@Test
public void shouldNotIncludeCSRFTokenOnGet() throws Exception {
doReturn("").when(client).executeRequest(any(HttpRequestBase.class));
client.doRequest(new HttpGet());
verify(client, times(0)).attachSecurityInfo(any(HttpRequestBase.class));
+ Header authHeader = BasicScheme.authenticate(client.credentials, "utf-8", false);
+ verify(client).executeRequest(argThat(new HttpRequestHeaderMatcher(authHeader.getName(), authHeader.getValue())));
}
@Test
@@ -57,7 +87,7 @@ public void shouldRequestCSRFToken() throws Exception {
doReturn(SECURITY_TOKEN_RESPONSE).when(client).executeRequest(any(HttpGet.class));
client.doRequest(new HttpPost(server));
Header authHeader = BasicScheme.authenticate(client.credentials, "utf-8", false);
- verify(client).executeRequest(argThat(new HttpRequestHeaderMatcher(authHeader.getName(), authHeader.getValue())));
+ verify(client, times(2)).executeRequest(argThat(new HttpRequestHeaderMatcher(authHeader.getName(), authHeader.getValue())));
}
@Test
diff --git a/src/test/java/com/rallydev/rest/request/BulkUserPermissionRequestTest.java b/src/test/java/com/rallydev/rest/request/BulkUserPermissionRequestTest.java
new file mode 100644
index 0000000..084f2fc
--- /dev/null
+++ b/src/test/java/com/rallydev/rest/request/BulkUserPermissionRequestTest.java
@@ -0,0 +1,28 @@
+package com.rallydev.rest.request;
+
+import java.util.Arrays;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class BulkUserPermissionRequestTest {
+
+ @Test
+ public void shouldConstructCorrectURL_NoExcludes_Viewer() {
+ BulkUserPermissionRequest req = new BulkUserPermissionRequest("1234", null, "12345", "Viewer", false);
+ Assert.assertEquals(req.toUrl(), "/projectpermission/bulkupdate?userOID=1234&rootProjectOID=12345&permission=Viewer&forceDowngradePermissions=false");
+ }
+
+ @Test
+ public void shouldConstructCorrectURL_NoExcludes_Editor() {
+ BulkUserPermissionRequest req = new BulkUserPermissionRequest("1234", null, "12345", "Editor", false);
+ Assert.assertEquals(req.toUrl(), "/projectpermission/bulkupdate?userOID=1234&rootProjectOID=12345&permission=Editor&forceDowngradePermissions=false");
+ }
+
+ @Test
+ public void shouldConstructCorrectURL_Editor() {
+ BulkUserPermissionRequest req = new BulkUserPermissionRequest("1234", Arrays.asList("1122", "1133"), "12345", "Editor", false);
+ Assert.assertEquals(req.toUrl(),
+ "/projectpermission/bulkupdate?userOID=1234&rootProjectOID=12345&permission=Editor&forceDowngradePermissions=false&excludedRootProjectOIDs=1122%2C1133");
+ }
+}