comparison src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java @ 10:a50cf11e5178

Rewrite LGDataverse completely upgrading to dataverse4.0
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Tue, 08 Sep 2015 17:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
9:5926d6419569 10:a50cf11e5178
1 package edu.harvard.iq.dataverse.api;
2
3 import static com.jayway.restassured.RestAssured.given;
4 import com.jayway.restassured.http.ContentType;
5 import com.jayway.restassured.path.json.JsonPath;
6 import static com.jayway.restassured.path.xml.XmlPath.from;
7 import com.jayway.restassured.response.Response;
8 import edu.harvard.iq.dataverse.Dataverse;
9 import edu.harvard.iq.dataverse.search.SearchFields;
10 import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.logging.Logger;
14 import javax.json.Json;
15 import javax.json.JsonArrayBuilder;
16 import javax.json.JsonObject;
17 import javax.json.JsonObjectBuilder;
18 import junit.framework.Assert;
19 import static junit.framework.Assert.assertEquals;
20 import org.junit.AfterClass;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23
24 public class SearchIT {
25
26 private static final Logger logger = Logger.getLogger(SearchIT.class.getCanonicalName());
27
28 private static final String builtinUserKey = "burrito";
29 private static final String EMPTY_STRING = "";
30 private static final String idKey = "id";
31 private static final String apiTokenKey = "apiToken";
32 private static final String usernameKey = "userName";
33 private static final String emailKey = "email";
34 private static TestUser homer;
35 private static TestUser ned;
36 private static final String dv1 = "dv1";
37 private static String dataset1;
38 private static long nedAdminOnRootAssignment;
39 private static final String dataverseToCreateDataset1In = "root";
40
41 public SearchIT() {
42 }
43
44 @BeforeClass
45 public static void setUpClass() {
46
47 boolean enabled = true;
48 if (!enabled) {
49 return;
50 }
51
52 logger.info("Running setup...");
53
54 JsonObject homerJsonObject = createUser(getUserAsJsonString("homer", "Homer", "Simpson"));
55 homer = new TestUser(homerJsonObject);
56
57 JsonObject nedJsonObject = createUser(getUserAsJsonString("ned", "Ned", "Flanders"));
58 ned = new TestUser(nedJsonObject);
59 }
60
61 @Test
62 public void homerGivesNedPermissionAtRoot() {
63
64 Response enableNonPublicSearch = enableSetting(SettingsServiceBean.Key.SearchApiNonPublicAllowed);
65 assertEquals(200, enableNonPublicSearch.getStatusCode());
66
67 Response makeSuperUserResponse = makeSuperuser(homer.getUsername());
68 assertEquals(200, makeSuperUserResponse.getStatusCode());
69
70 String xmlIn = getDatasetXml(homer.getUsername(), homer.getUsername(), homer.getUsername());
71 Response createDataset1Response = createDataset(xmlIn, dataverseToCreateDataset1In, homer.getApiToken());
72 assertEquals(201, createDataset1Response.getStatusCode());
73
74 dataset1 = getGlobalId(createDataset1Response);
75
76 Integer idHomerFound = printDatasetId(dataset1, homer);
77 assertEquals(true, idHomerFound != null);
78
79 Integer idNedFoundBeforeBecomingAdmin = printDatasetId(dataset1, ned);
80 String roleToAssign = "admin";
81 assertEquals(null, idNedFoundBeforeBecomingAdmin);
82
83 Response grantNedAdminOnRoot = grantRole(dataverseToCreateDataset1In, roleToAssign, ned.getUsername(), homer.getApiToken());
84 assertEquals(200, grantNedAdminOnRoot.getStatusCode());
85
86 Integer idNedFoundAfterBecomingAdmin = printDatasetId(dataset1, ned);
87 assertEquals(idHomerFound, idNedFoundAfterBecomingAdmin);
88
89 nedAdminOnRootAssignment = getRoleAssignmentId(grantNedAdminOnRoot);
90 Response revokeNedAdminOnRoot = revokeRole(dataverseToCreateDataset1In, nedAdminOnRootAssignment, homer.getApiToken());
91 assertEquals(200, revokeNedAdminOnRoot.getStatusCode());
92
93 Integer idNedFoundAfterNoLongerAdmin = printDatasetId(dataset1, ned);
94 assertEquals(null, idNedFoundAfterNoLongerAdmin);
95
96 Response disableNonPublicSearch = deleteSetting(SettingsServiceBean.Key.SearchApiNonPublicAllowed);
97 assertEquals(200, disableNonPublicSearch.getStatusCode());
98
99 }
100
101 @Test
102 public void dataverseCategory() {
103 Response enableNonPublicSearch = enableSetting(SettingsServiceBean.Key.SearchApiNonPublicAllowed);
104 assertEquals(200, enableNonPublicSearch.getStatusCode());
105
106 /**
107 * Unfortunately, it appears that the ability to specify the category of
108 * a dataverse when creating it is a GUI-only feature. It can't
109 * currently be done via the API, to our knowledge. You also can't tell
110 * from the API which category was persisted but it always seems to be
111 * "UNCATEGORIZED"
112 */
113 TestDataverse dataverseToCreate = new TestDataverse(dv1, "dv1", Dataverse.DataverseType.ORGANIZATIONS_INSTITUTIONS);
114 Response createDvResponse = createDataverse(dataverseToCreate, homer);
115 assertEquals(201, createDvResponse.getStatusCode());
116
117 TestSearchQuery query = new TestSearchQuery("dv1");
118 Response searchResponse = search(query, homer);
119 JsonPath jsonPath = JsonPath.from(searchResponse.body().asString());
120 String dv1Category = jsonPath.get("data.facets." + SearchFields.DATAVERSE_CATEGORY).toString();
121 String msg = "dv1Category: " + dv1Category;
122 assertEquals("dv1Category: [null]", msg);
123
124 Response disableNonPublicSearch = deleteSetting(SettingsServiceBean.Key.SearchApiNonPublicAllowed);
125 assertEquals(200, disableNonPublicSearch.getStatusCode());
126 }
127
128 @AfterClass
129 public static void cleanup() {
130
131 boolean enabled = true;
132 if (!enabled) {
133 return;
134 }
135
136 logger.info("Running cleanup...");
137
138 /**
139 * We revoke roles here just in case an assertion failed because role
140 * assignments are currently not deleted when you delete a user per
141 * https://github.com/IQSS/dataverse/issues/1929
142 *
143 * You can also delete the role assignments manually like this:
144 *
145 * "DELETE FROM roleassignment WHERE assigneeidentifier='@ned';"
146 */
147 Response revokeNedAdminOnRoot = revokeRole(dataverseToCreateDataset1In, nedAdminOnRootAssignment, homer.getApiToken());
148 System.out.println("cleanup - status code revoking admin on root from ned: " + revokeNedAdminOnRoot.getStatusCode());
149 Response deleteDataset1Response = deleteDataset(dataset1, homer.getApiToken());
150 assertEquals(204, deleteDataset1Response.getStatusCode());
151
152 Response deleteDv1Response = deleteDataverse(dv1, homer);
153 assertEquals(200, deleteDv1Response.getStatusCode());
154
155 deleteUser(homer.getUsername());
156 deleteUser(ned.getUsername());
157 }
158
159 private Response enableSetting(SettingsServiceBean.Key settingKey) {
160 Response response = given().body("true").when().put("/api/admin/settings/" + settingKey);
161 return response;
162 }
163
164 private Response deleteSetting(SettingsServiceBean.Key settingKey) {
165 Response response = given().when().delete("/api/admin/settings/" + settingKey);
166 return response;
167 }
168
169 private Response checkSetting(SettingsServiceBean.Key settingKey) {
170 Response response = given().when().get("/api/admin/settings/" + settingKey);
171 return response;
172 }
173
174 private static Response createDataverse(TestDataverse dataverseToCreate, TestUser creator) {
175 JsonArrayBuilder contactArrayBuilder = Json.createArrayBuilder();
176 contactArrayBuilder.add(Json.createObjectBuilder().add("contactEmail", creator.getEmail()));
177 JsonArrayBuilder subjectArrayBuilder = Json.createArrayBuilder();
178 subjectArrayBuilder.add("Other");
179 JsonObject dvData = Json.createObjectBuilder()
180 .add("alias", dataverseToCreate.alias)
181 .add("name", dataverseToCreate.name)
182 .add("dataverseContacts", contactArrayBuilder)
183 .add("dataverseSubjects", subjectArrayBuilder)
184 .build();
185 Response createDataverseResponse = given()
186 .body(dvData.toString()).contentType(ContentType.JSON)
187 .when().post("/api/dataverses/:root?key=" + creator.apiToken);
188 return createDataverseResponse;
189 }
190
191 private Response createDataset(String xmlIn, String dataverseToCreateDatasetIn, String apiToken) {
192 Response createDatasetResponse = given()
193 .auth().basic(apiToken, EMPTY_STRING)
194 .body(xmlIn)
195 .contentType("application/atom+xml")
196 .post("/dvn/api/data-deposit/v1.1/swordv2/collection/dataverse/" + dataverseToCreateDatasetIn);
197 return createDatasetResponse;
198 }
199
200 private static JsonObject createUser(String jsonStr) {
201 JsonObjectBuilder createdUser = Json.createObjectBuilder();
202 Response response = createUserViaApi(jsonStr, getPassword(jsonStr));
203 Assert.assertEquals(200, response.getStatusCode());
204 JsonPath jsonPath = JsonPath.from(response.body().asString());
205 createdUser.add(idKey, jsonPath.getInt("data.user." + idKey));
206 createdUser.add(usernameKey, jsonPath.get("data.user." + usernameKey).toString());
207 createdUser.add(apiTokenKey, jsonPath.get("data." + apiTokenKey).toString());
208 return createdUser.build();
209 }
210
211 private static String getPassword(String jsonStr) {
212 String password = JsonPath.from(jsonStr).get(usernameKey);
213 return password;
214 }
215
216 private static String getUserAsJsonString(String username, String firstName, String lastName) {
217 JsonObjectBuilder builder = Json.createObjectBuilder();
218 builder.add(usernameKey, username);
219 builder.add("firstName", firstName);
220 builder.add("lastName", lastName);
221 builder.add(emailKey, getEmailFromUserName(username));
222 String userAsJson = builder.build().toString();
223 logger.fine("User to create: " + userAsJson);
224 return userAsJson;
225 }
226
227 private static String getEmailFromUserName(String username) {
228 return username + "@mailinator.com";
229 }
230
231 private static Response createUserViaApi(String jsonStr, String password) {
232 Response response = given().body(jsonStr).contentType(ContentType.JSON).when().post("/api/builtin-users?key=" + builtinUserKey + "&password=" + password);
233 return response;
234 }
235
236 private static Response makeSuperuser(String userToMakeSuperuser) {
237 Response response = given().post("/api/admin/superuser/" + userToMakeSuperuser);
238 return response;
239 }
240
241 private Response grantRole(String definitionPoint, String role, String roleAssignee, String apiToken) {
242 JsonObjectBuilder roleBuilder = Json.createObjectBuilder();
243 roleBuilder.add("assignee", "@" + roleAssignee);
244 roleBuilder.add("role", role);
245 JsonObject roleObject = roleBuilder.build();
246 System.out.println("Granting role on dataverse alias \"" + definitionPoint + "\": " + roleObject);
247 return given()
248 .body(roleObject).contentType(ContentType.JSON)
249 .post("api/dataverses/" + definitionPoint + "/assignments?key=" + apiToken);
250 }
251
252 private static Response revokeRole(String definitionPoint, long doomed, String apiToken) {
253 System.out.println("Attempting to revoke role assignment id " + doomed);
254 /**
255 * OUTPUT=`curl -s -X DELETE
256 * "http://localhost:8080/api/dataverses/$BIRDS_DATAVERSE/assignments/$SPRUCE_ADMIN_ON_BIRDS?key=$FINCHKEY"`
257 */
258 return given()
259 .delete("api/dataverses/" + definitionPoint + "/assignments/" + doomed + "?key=" + apiToken);
260 }
261
262 private String getGlobalId(Response createDatasetResponse) {
263 String xml = createDatasetResponse.body().asString();
264 String datasetSwordIdUrl = from(xml).get("entry.id");
265 /**
266 * @todo stop assuming the last 22 characters are the doi/globalId
267 */
268 return datasetSwordIdUrl.substring(datasetSwordIdUrl.length() - 22);
269 }
270
271 /**
272 * Assumes you have turned on experimental non-public search
273 * https://github.com/IQSS/dataverse/issues/1299
274 *
275 * curl -X PUT -d true
276 * http://localhost:8080/api/admin/settings/:SearchApiNonPublicAllowed
277 *
278 * @return The Integer found or null.
279 */
280 private static Integer findDatasetIdFromGlobalId(String globalId, String apiToken) {
281 Response searchForGlobalId = given()
282 .get("api/search?key=" + apiToken
283 + "&q=dsPersistentId:\""
284 + globalId.replace(":", "\\:")
285 + "\"&show_entity_ids=true");
286 JsonPath jsonPath = JsonPath.from(searchForGlobalId.body().asString());
287 int id;
288 try {
289 id = jsonPath.get("data.items[0].entity_id");
290 } catch (IllegalArgumentException ex) {
291 return null;
292 }
293 return id;
294 }
295
296 private String getDatasetXml(String title, String author, String description) {
297 String xmlIn = "<?xml version=\"1.0\"?>\n"
298 + "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:dcterms=\"http://purl.org/dc/terms/\">\n"
299 + " <dcterms:title>" + title + "</dcterms:title>\n"
300 + " <dcterms:creator>" + author + "</dcterms:creator>\n"
301 + " <dcterms:description>" + description + "</dcterms:description>\n"
302 + "</entry>\n"
303 + "";
304 return xmlIn;
305 }
306
307 private static Response deleteDataverse(String doomed, TestUser user) {
308 return given().delete("/api/dataverses/" + doomed + "?key=" + user.getApiToken());
309 }
310
311 private static Response deleteDataset(String globalId, String apiToken) {
312 return given()
313 .auth().basic(apiToken, EMPTY_STRING)
314 .relaxedHTTPSValidation()
315 .delete("/dvn/api/data-deposit/v1.1/swordv2/edit/study/" + globalId);
316 }
317
318 private static void deleteUser(String username) {
319 Response deleteUserResponse = given().delete("/api/admin/authenticatedUsers/" + username + "/");
320 assertEquals(200, deleteUserResponse.getStatusCode());
321 }
322
323 private long getRoleAssignmentId(Response response) {
324 JsonPath jsonPath = JsonPath.from(response.body().asString());
325 return jsonPath.getInt("data.id");
326 }
327
328 private Integer printDatasetId(String dataset1, TestUser user) {
329 Integer datasetIdFound = findDatasetIdFromGlobalId(dataset1, user.getApiToken());
330 System.out.println(dataset1 + " id " + datasetIdFound + " found by " + user);
331 return datasetIdFound;
332 }
333
334 private Response search(TestSearchQuery query, TestUser user) {
335 return given()
336 .get("api/search?key=" + user.getApiToken()
337 + "&q=" + query.getQuery()
338 + "&show_facets=" + true
339 );
340 }
341
342 private static class TestUser {
343
344 private long id;
345 private String username;
346 private String apiToken;
347
348 private TestUser(JsonObject json) {
349 this.id = json.getInt(idKey);
350 this.username = json.getString(usernameKey);
351 this.apiToken = json.getString(apiTokenKey);
352 }
353
354 public long getId() {
355 return id;
356 }
357
358 public String getUsername() {
359 return username;
360 }
361
362 public String getApiToken() {
363 return apiToken;
364 }
365
366 public String getEmail() {
367 return getEmailFromUserName(username);
368 }
369
370 @Override
371 public String toString() {
372 return "TestUser{" + "id=" + id + ", username=" + username + '}';
373 }
374
375 }
376
377 private static class TestDataverse {
378
379 String alias;
380 String name;
381 Dataverse.DataverseType category;
382
383 public TestDataverse(String alias, String name, Dataverse.DataverseType category) {
384 this.alias = alias;
385 this.name = name;
386 this.category = category;
387 }
388
389 }
390
391 private static class TestSearchQuery {
392
393 private String query;
394 private List<String> filterQueries = new ArrayList<>();
395
396 private TestSearchQuery(String query) {
397 this.query = query;
398 }
399
400 public TestSearchQuery(String query, List<String> filterQueries) {
401 this.query = query;
402 if (!filterQueries.isEmpty()) {
403 this.filterQueries = filterQueries;
404 }
405 }
406
407 public String getQuery() {
408 return query;
409 }
410
411 public List<String> getFilterQueries() {
412 return filterQueries;
413 }
414
415 }
416 }