Mercurial > hg > LGDataverses
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 } |