[CST-5303] refactored tests

This commit is contained in:
Mykhaylo
2022-05-10 16:16:16 +02:00
parent 78a36136e2
commit 149393b06d
12 changed files with 285 additions and 67 deletions

View File

@@ -19,6 +19,7 @@ import javax.el.MethodNotFoundException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.apache.logging.log4j.LogManager;
@@ -58,41 +59,29 @@ public class CrossRefImportMetadataSourceServiceImpl extends AbstractImportMetad
@Override
public ImportRecord getRecord(String recordId) throws MetadataSourceException {
List<ImportRecord> records = null;
String id = getID(recordId);
if (StringUtils.isNotBlank(id)) {
records = retry(new SearchByIdCallable(id));
} else {
records = retry(new SearchByIdCallable(recordId));
}
return records == null || records.isEmpty() ? null : records.get(0);
List<ImportRecord> records = StringUtils.isNotBlank(id) ? retry(new SearchByIdCallable(id))
: retry(new SearchByIdCallable(recordId));
return CollectionUtils.isEmpty(records) ? null : records.get(0);
}
@Override
public int getRecordsCount(String query) throws MetadataSourceException {
String id = getID(query);
if (StringUtils.isNotBlank(id)) {
return retry(new DoiCheckCallable(id));
}
return retry(new CountByQueryCallable(query));
return StringUtils.isNotBlank(id) ? retry(new DoiCheckCallable(id)) : retry(new CountByQueryCallable(query));
}
@Override
public int getRecordsCount(Query query) throws MetadataSourceException {
String id = getID(query.toString());
if (StringUtils.isNotBlank(id)) {
return retry(new DoiCheckCallable(id));
}
return retry(new CountByQueryCallable(query));
return StringUtils.isNotBlank(id) ? retry(new DoiCheckCallable(id)) : retry(new CountByQueryCallable(query));
}
@Override
public Collection<ImportRecord> getRecords(String query, int start, int count) throws MetadataSourceException {
String id = getID(query.toString());
if (StringUtils.isNotBlank(id)) {
return retry(new SearchByIdCallable(id));
}
return retry(new SearchByQueryCallable(query, count, start));
return StringUtils.isNotBlank(id) ? retry(new SearchByIdCallable(id))
: retry(new SearchByQueryCallable(query, count, start));
}
@Override
@@ -106,36 +95,26 @@ public class CrossRefImportMetadataSourceServiceImpl extends AbstractImportMetad
@Override
public ImportRecord getRecord(Query query) throws MetadataSourceException {
List<ImportRecord> records = null;
String id = getID(query.toString());
if (StringUtils.isNotBlank(id)) {
records = retry(new SearchByIdCallable(id));
} else {
records = retry(new SearchByIdCallable(query));
}
return records == null || records.isEmpty() ? null : records.get(0);
List<ImportRecord> records = StringUtils.isNotBlank(id) ? retry(new SearchByIdCallable(id))
: retry(new SearchByIdCallable(query));
return CollectionUtils.isEmpty(records) ? null : records.get(0);
}
@Override
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
String id = getID(query.toString());
if (StringUtils.isNotBlank(id)) {
return retry(new SearchByIdCallable(id));
return StringUtils.isNotBlank(id) ? retry(new SearchByIdCallable(id))
: retry(new FindMatchingRecordCallable(query));
}
return retry(new FindMatchingRecordCallable(query));
}
@Override
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
throw new MethodNotFoundException("This method is not implemented for CrossRef");
}
public String getID(String query) {
if (DoiCheck.isDoi(query)) {
return "filter=doi:" + query;
}
return StringUtils.EMPTY;
public String getID(String id) {
return DoiCheck.isDoi(id) ? "filter=doi:" + id : StringUtils.EMPTY;
}
/**
@@ -341,14 +320,12 @@ public class CrossRefImportMetadataSourceServiceImpl extends AbstractImportMetad
}
private JsonNode convertStringJsonToJsonNode(String json) {
ObjectMapper mapper = new ObjectMapper();
JsonNode body = null;
try {
body = mapper.readTree(json);
return new ObjectMapper().readTree(json);
} catch (JsonProcessingException e) {
log.error("Unable to process json response.", e);
}
return body;
return null;
}
public void setUrl(String url) {

View File

@@ -5,7 +5,7 @@
*
* http://www.dspace.org/license/
*/
package org.dspace.importer.external.crossref;
package org.dspace.importer.external.metadatamapping.contributor;
import java.util.ArrayList;
import java.util.Collection;
@@ -17,7 +17,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.importer.external.metadatamapping.contributor.JsonPathMetadataProcessor;
/**
* This Processor allows to extract attribute values of an array.

View File

@@ -5,7 +5,7 @@
*
* http://www.dspace.org/license/
*/
package org.dspace.importer.external.crossref;
package org.dspace.importer.external.metadatamapping.contributor;
import java.util.ArrayList;
import java.util.Collection;
@@ -17,7 +17,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.importer.external.metadatamapping.contributor.JsonPathMetadataProcessor;
/**
* This Processor allows to extract all values of a matrix.

View File

@@ -108,6 +108,14 @@ public class VuFindImportMetadataSourceServiceImpl extends AbstractImportMetadat
@Override
public void init() throws Exception {}
/**
* This class is a Callable implementation to count the number of entries for an VuFind query.
* This Callable use as query value to CrossRef the string queryString passed to constructor.
* If the object will be construct through Query.class instance, the value of the Query's
* map with the key "query" will be used.
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
private class CountByQueryCallable implements Callable<Integer> {
private Query query;
@@ -140,6 +148,12 @@ public class VuFindImportMetadataSourceServiceImpl extends AbstractImportMetadat
}
}
/**
* This class is a Callable implementation to get an VuFind entry using VuFind id
* The id to use can be passed through the constructor as a String or as Query's map entry, with the key "id".
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
private class GetByVuFindIdCallable implements Callable<String> {
private String id;
@@ -171,6 +185,14 @@ public class VuFindImportMetadataSourceServiceImpl extends AbstractImportMetadat
}
}
/**
* This class is a Callable implementation to get VuFind entries based on query object.
* This Callable use as query value the string queryString passed to constructor.
* If the object will be construct through Query.class instance, a Query's map entry with key "query" will be used.
* Pagination is supported too, using the value of the Query's map with keys "start" and "count".
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
private class SearchByQueryCallable implements Callable<String> {
private Query query;
@@ -220,6 +242,11 @@ public class VuFindImportMetadataSourceServiceImpl extends AbstractImportMetadat
}
/**
* This class is a Callable implementation to search VuFind entries using author and title.
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
public class FindMatchingRecordsCallable implements Callable<String> {
private Query query;

View File

@@ -8,17 +8,24 @@
package org.dspace.app.rest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.el.MethodNotFoundException;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.ItemBuilder;
import org.dspace.content.Item;
import org.dspace.importer.external.crossref.CrossRefImportMetadataSourceServiceImpl;
import org.dspace.importer.external.datamodel.ImportRecord;
import org.dspace.importer.external.liveimportclient.service.LiveImportClientImpl;
@@ -46,8 +53,7 @@ public class CrossRefImportMetadataSourceServiceIT extends AbstractLiveImportInt
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
String path = testProps.get("test.crossRef").toString();
try (FileInputStream crossRefResp = new FileInputStream(path)) {
try (InputStream crossRefResp = getClass().getResourceAsStream("crossRef-test.json")) {
String crossRefRespXmlResp = IOUtils.toString(crossRefResp, Charset.defaultCharset());
@@ -70,9 +76,8 @@ public class CrossRefImportMetadataSourceServiceIT extends AbstractLiveImportInt
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
String path = testProps.get("test.crossRef").toString();
try (FileInputStream file = new FileInputStream(path)) {
String crossRefRespXmlResp = IOUtils.toString(file, Charset.defaultCharset());
try (InputStream crossRefResp = getClass().getResourceAsStream("crossRef-test.json")) {
String crossRefRespXmlResp = IOUtils.toString(crossRefResp, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(crossRefRespXmlResp, 200, "OK");
@@ -86,6 +91,52 @@ public class CrossRefImportMetadataSourceServiceIT extends AbstractLiveImportInt
}
}
@Test
public void crossRefImportMetadataGetRecordByIdTest() throws Exception {
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
try (InputStream crossRefResp = getClass().getResourceAsStream("crossRef-by-id.json")) {
String crossRefRespXmlResp = IOUtils.toString(crossRefResp, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(crossRefRespXmlResp, 200, "OK");
when(httpClient.execute(ArgumentMatchers.any())).thenReturn(response);
context.restoreAuthSystemState();
ArrayList<ImportRecord> collection2match = getRecords();
collection2match.remove(1);
ImportRecord recordImported = crossRefServiceImpl.getRecord("10.26693/jmbs01.02.184");
assertNotNull(recordImported);
Collection<ImportRecord> recordsImported = Arrays.asList(recordImported);
matchRecords(new ArrayList<ImportRecord>(recordsImported), collection2match);
} finally {
liveImportClientImpl.setHttpClient(originalHttpClient);
}
}
@Test(expected = MethodNotFoundException.class)
public void crossRefImportMetadataFindMatchingRecordsTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
org.dspace.content.Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
Item testItem = ItemBuilder.createItem(context, col1)
.withTitle("test item")
.withIssueDate("2021")
.build();
context.restoreAuthSystemState();
crossRefServiceImpl.findMatchingRecords(testItem);
}
private ArrayList<ImportRecord> getRecords() {
ArrayList<ImportRecord> records = new ArrayList<>();
//define first record

View File

@@ -11,7 +11,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
@@ -53,10 +53,10 @@ public class VuFindImportMetadataSourceServiceIT extends AbstractLiveImportInteg
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
String path = testProps.get("test.vufind").toString();
try (FileInputStream file = new FileInputStream(path)) {
String vuFindResp = IOUtils.toString(file, Charset.defaultCharset());
try (InputStream vuFindRespIS = getClass().getResourceAsStream("vuFind-generic.json")) {
String vuFindResp = IOUtils.toString(vuFindRespIS, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(vuFindResp, 200, "OK");
@@ -77,9 +77,9 @@ public class VuFindImportMetadataSourceServiceIT extends AbstractLiveImportInteg
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
String path = testProps.get("test.vufind").toString();
try (FileInputStream file = new FileInputStream(path)) {
String vuFindResp = IOUtils.toString(file, Charset.defaultCharset());
try (InputStream vuFindRespIS = getClass().getResourceAsStream("vuFind-generic.json")) {
String vuFindResp = IOUtils.toString(vuFindRespIS, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(vuFindResp, 200, "OK");
@@ -98,10 +98,10 @@ public class VuFindImportMetadataSourceServiceIT extends AbstractLiveImportInteg
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
String path = testProps.get("test.vufind-by-id").toString();
try (FileInputStream file = new FileInputStream(path)) {
String vuFindResp = IOUtils.toString(file, Charset.defaultCharset());
try (InputStream vuFindByIdResp = getClass().getResourceAsStream("vuFind-by-id.json")) {
String vuFindResp = IOUtils.toString(vuFindByIdResp, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(vuFindResp, 200, "OK");

View File

@@ -0,0 +1,169 @@
{
"status":"ok",
"message-type":"work",
"message-version":"1.0.0",
"message":{
"indexed":{
"date-parts":[
[
2022,
4,
5
]
],
"date-time":"2022-04-05T22:05:30Z",
"timestamp":1649196330913
},
"reference-count":0,
"publisher":"Petro Mohyla Black Sea National University",
"issue":"2",
"content-domain":{
"domain":[
],
"crossmark-restriction":false
},
"short-container-title":[
"Ukr. \u017e. med. b\u00ecol. sportu"
],
"published-print":{
"date-parts":[
[
2016,
5,
19
]
]
},
"DOI":"10.26693\/jmbs01.02.184",
"type":"journal-article",
"created":{
"date-parts":[
[
2017,
9,
7
]
],
"date-time":"2017-09-07T13:30:46Z",
"timestamp":1504791046000
},
"page":"184-187",
"source":"Crossref",
"is-referenced-by-count":0,
"title":[
"State of Awareness of Freshers\u2019 Groups Chortkiv State Medical College of Prevention of Iodine Deficiency Diseases"
],
"prefix":"10.26693",
"volume":"1",
"author":[
{
"given":"L.V.",
"family":"Senyuk",
"sequence":"first",
"affiliation":[
]
},
{
"name":"Chortkiv State Medical College 7, Gogola St., Chortkiv, Ternopil region 48500, Ukraine",
"sequence":"first",
"affiliation":[
]
}
],
"member":"11225",
"published-online":{
"date-parts":[
[
2016,
5,
19
]
]
},
"container-title":[
"Ukra\u00efns\u02b9kij \u017eurnal medicini, b\u00ecolog\u00ec\u00ef ta sportu"
],
"original-title":[
"\u0421\u0422\u0410\u041d \u041e\u0411\u0406\u0417\u041d\u0410\u041d\u041e\u0421\u0422\u0406 \u0421\u0422\u0423\u0414\u0415\u041d\u0422\u0406\u0412 \u041d\u041e\u0412\u041e\u041d\u0410\u0411\u0420\u0410\u041d\u0418\u0425 \u0413\u0420\u0423\u041f \u0427\u041e\u0420\u0422\u041a\u0406\u0412\u0421\u042c\u041a\u041e\u0413\u041e \u0414\u0415\u0420\u0416\u0410\u0412\u041d\u041e\u0413\u041e \u041c\u0415\u0414\u0418\u0427\u041d\u041e\u0413\u041e \u041a\u041e\u041b\u0415\u0414\u0416\u0423 \u0417 \u041f\u0418\u0422\u0410\u041d\u042c \u041f\u0420\u041e\u0424\u0406\u041b\u0410\u041a\u0422\u0418\u041a\u0418 \u0419\u041e\u0414\u041e\u0414\u0415\u0424\u0406\u0426\u0418\u0422\u041d\u0418\u0425 \u0417\u0410\u0425\u0412\u041e\u0420\u042e\u0412\u0410\u041d\u042c"
],
"deposited":{
"date-parts":[
[
2017,
9,
8
]
],
"date-time":"2017-09-08T10:14:53Z",
"timestamp":1504865693000
},
"score":1,
"resource":{
"primary":{
"URL":"http:\/\/en.jmbs.com.ua\/archive\/1\/2\/184"
}
},
"subtitle":[
],
"short-title":[
],
"issued":{
"date-parts":[
[
2016,
5,
19
]
]
},
"references-count":0,
"journal-issue":{
"issue":"2",
"published-online":{
"date-parts":[
[
2016,
5,
19
]
]
},
"published-print":{
"date-parts":[
[
2016,
5,
19
]
]
}
},
"URL":"http:\/\/dx.doi.org\/10.26693\/jmbs01.02.184",
"relation":{
},
"ISSN":[
"2415-3060"
],
"issn-type":[
{
"value":"2415-3060",
"type":"print"
}
],
"published":{
"date-parts":[
[
2016,
5,
19
]
]
}
}
}

View File

@@ -14,7 +14,3 @@ test.bitstream = ./target/testing/dspace/assetstore/ConstitutionofIreland.pdf
#Path for a test Taskfile for the curate script
test.curateTaskFile = ./target/testing/dspace/assetstore/curate.txt
test.crossRef = ./target/testing/dspace/assetstore/crossRef-test.json
test.vufind = ./target/testing/dspace/assetstore/vuFind-generic.json
test.vufind-by-id = ./target/testing/dspace/assetstore/vuFind-by-id.json

View File

@@ -60,7 +60,7 @@
<property name="field" ref="vufind.dc.identifier"/>
<property name="metadataProcessor" ref="vufindUriProcessor"></property>
</bean>
<bean name="vufindUriProcessor" class="org.dspace.importer.external.crossref.ArrayElementAttributeProcessor">
<bean name="vufindUriProcessor" class="org.dspace.importer.external.metadatamapping.contributor.ArrayElementAttributeProcessor">
<property name="pathToArray" value="/urls"></property>
<property name="elementAttribute" value="/url"></property>
</bean>
@@ -72,7 +72,7 @@
<property name="field" ref="vufind.dc.subject"/>
<property name="metadataProcessor" ref="vufindSubjectsProcessor"></property>
</bean>
<bean name="vufindSubjectsProcessor" class="org.dspace.importer.external.crossref.MatrixElementProcessor">
<bean name="vufindSubjectsProcessor" class="org.dspace.importer.external.metadatamapping.contributor.MatrixElementProcessor">
<property name="pathToMatrix" value="/subjects"></property>
</bean>
<bean id="vufind.dc.subject" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">