[CST-11044] refactoring and fixing broken ITs

This commit is contained in:
eskander
2023-10-16 15:25:31 +03:00
parent 39918723ce
commit 885e04f8bc
16 changed files with 326 additions and 327 deletions

View File

@@ -16,13 +16,12 @@ import javax.persistence.criteria.Root;
import org.dspace.app.ldn.NotifyPatternToTrigger;
import org.dspace.app.ldn.NotifyPatternToTrigger_;
import org.dspace.app.ldn.dao.NotifyPatternToTriggerDao;
import org.dspace.app.ldn.dao.NotifyServiceDao;
import org.dspace.content.Item;
import org.dspace.core.AbstractHibernateDAO;
import org.dspace.core.Context;
/**
* Implementation of {@link NotifyServiceDao}.
* Implementation of {@link NotifyPatternToTriggerDao}.
*
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
*/

View File

@@ -10,18 +10,29 @@ package org.dspace.coarnotify;
import java.util.List;
/**
* this class represents the Configuration of Submission COAR Notify
*
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
*/
public class COARNotify {
public class COARNotifySubmissionConfiguration {
/**
* the map key of configured bean of COARNotifyConfigurationService
* in coar-notify.xml
*/
private String id;
/**
* the map values of configured bean of COARNotifyConfigurationService
* in coar-notify.xml
*/
private List<String> patterns;
public COARNotify() {
public COARNotifySubmissionConfiguration() {
}
public COARNotify(String id, List<String> patterns) {
public COARNotifySubmissionConfiguration(String id, List<String> patterns) {
super();
this.id = id;
this.patterns = patterns;
@@ -36,16 +47,16 @@ public class COARNotify {
}
/**
* Gets the list of COAR Notify Patterns
* Gets the list of configured COAR Notify Patterns
*
* @return the list of COAR Notify Patterns
* @return the list of configured COAR Notify Patterns
*/
public List<String> getPatterns() {
return patterns;
}
/**
* Sets the list of COAR Notify Patterns
* Sets the list of configured COAR Notify Patterns
* @param patterns
*/
public void setPatterns(final List<String> patterns) {

View File

@@ -28,7 +28,7 @@ public class SubmissionCOARNotifyServiceImpl implements SubmissionCOARNotifyServ
}
@Override
public COARNotify findOne(String id) {
public COARNotifySubmissionConfiguration findOne(String id) {
List<String> patterns =
coarNotifyConfigurationService.getPatterns().get(id);
@@ -36,15 +36,15 @@ public class SubmissionCOARNotifyServiceImpl implements SubmissionCOARNotifyServ
return null;
}
return new COARNotify(id, patterns);
return new COARNotifySubmissionConfiguration(id, patterns);
}
@Override
public List<COARNotify> findAll() {
List<COARNotify> coarNotifies = new ArrayList<>();
public List<COARNotifySubmissionConfiguration> findAll() {
List<COARNotifySubmissionConfiguration> coarNotifies = new ArrayList<>();
coarNotifyConfigurationService.getPatterns().forEach((id, patterns) ->
coarNotifies.add(new COARNotify(id, patterns)
coarNotifies.add(new COARNotifySubmissionConfiguration(id, patterns)
));
return coarNotifies;

View File

@@ -9,7 +9,7 @@ package org.dspace.coarnotify.service;
import java.util.List;
import org.dspace.coarnotify.COARNotify;
import org.dspace.coarnotify.COARNotifySubmissionConfiguration;
/**
* Service interface class for the Creative Submission COAR Notify.
@@ -27,13 +27,13 @@ public interface SubmissionCOARNotifyService {
* @param id - the ID of the COAR Notify to be found
* @return the corresponding COAR Notify if found or null when not found
*/
public COARNotify findOne(String id);
public COARNotifySubmissionConfiguration findOne(String id);
/**
* Find all configured COAR Notifies
*
* @return all configured COAR Notifies
*/
public List<COARNotify> findAll();
public List<COARNotifySubmissionConfiguration> findAll();
}

View File

@@ -9,17 +9,18 @@ package org.dspace.app.rest.converter;
import org.dspace.app.rest.model.SubmissionCOARNotifyRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.coarnotify.COARNotify;
import org.dspace.coarnotify.COARNotifySubmissionConfiguration;
import org.springframework.stereotype.Component;
/**
* This converter is responsible for transforming the model representation of an COARNotify to the REST
* representation of an COARNotify and vice versa
* representation of an COARNotifySubmissionConfiguration and vice versa
*
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
**/
@Component
public class SubmissionCOARNotifyConverter implements DSpaceConverter<COARNotify, SubmissionCOARNotifyRest> {
public class SubmissionCOARNotifyConverter
implements DSpaceConverter<COARNotifySubmissionConfiguration, SubmissionCOARNotifyRest> {
/**
* Convert a COARNotify to its REST representation
@@ -28,9 +29,10 @@ public class SubmissionCOARNotifyConverter implements DSpaceConverter<COARNotify
* @return the corresponding SubmissionCOARNotifyRest object
*/
@Override
public SubmissionCOARNotifyRest convert(final COARNotify modelObject, final Projection projection) {
SubmissionCOARNotifyRest submissionCOARNotifyRest = new SubmissionCOARNotifyRest();
public SubmissionCOARNotifyRest convert(final COARNotifySubmissionConfiguration modelObject,
final Projection projection) {
SubmissionCOARNotifyRest submissionCOARNotifyRest = new SubmissionCOARNotifyRest();
submissionCOARNotifyRest.setProjection(projection);
submissionCOARNotifyRest.setId(modelObject.getId());
submissionCOARNotifyRest.setPatterns(modelObject.getPatterns());
@@ -38,8 +40,8 @@ public class SubmissionCOARNotifyConverter implements DSpaceConverter<COARNotify
}
@Override
public Class<COARNotify> getModelClass() {
return COARNotify.class;
public Class<COARNotifySubmissionConfiguration> getModelClass() {
return COARNotifySubmissionConfiguration.class;
}
}

View File

@@ -12,11 +12,13 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.dspace.app.rest.RestResourceController;
import org.dspace.coarnotify.COARNotifySubmissionConfiguration;
/**
* This class is the REST representation of the COARNotify model object and acts as a data object
* for the SubmissionCOARNotifyResource class.
* Refer to {@link org.dspace.coarnotify.COARNotify} for explanation of the properties
* This class is the REST representation of the COARNotifySubmissionConfiguration model object
* and acts as a data object for the SubmissionCOARNotifyResource class.
*
* Refer to {@link COARNotifySubmissionConfiguration} for explanation of the properties
*/
public class SubmissionCOARNotifyRest extends BaseObjectRest<String> {
public static final String NAME = "submissioncoarnotifyconfig";

View File

@@ -9,15 +9,24 @@ package org.dspace.app.rest.model.step;
import java.util.List;
import org.dspace.app.rest.model.NotifyServiceRest;
/**
* Java Bean to expose the section creativecommons representing the CC License during in progress submission.
* Java Bean to expose the COAR Notify Section during in progress submission.
*
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
*/
public class DataCOARNotify implements SectionData {
private String pattern;
private List<NotifyServiceRest> services;
private List<Integer> services;
public DataCOARNotify() {
}
public DataCOARNotify(String pattern, List<Integer> services) {
this.pattern = pattern;
this.services = services;
}
public String getPattern() {
return pattern;
@@ -27,11 +36,11 @@ public class DataCOARNotify implements SectionData {
this.pattern = pattern;
}
public List<NotifyServiceRest> getServices() {
public List<Integer> getServices() {
return services;
}
public void setServices(List<NotifyServiceRest> services) {
public void setServices(List<Integer> services) {
this.services = services;
}
}

View File

@@ -8,7 +8,7 @@
package org.dspace.app.rest.repository;
import org.dspace.app.rest.model.SubmissionCOARNotifyRest;
import org.dspace.coarnotify.COARNotify;
import org.dspace.coarnotify.COARNotifySubmissionConfiguration;
import org.dspace.coarnotify.service.SubmissionCOARNotifyService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
@@ -32,11 +32,12 @@ public class SubmissionCoarNotifyRestRepository extends DSpaceRestRepository<Sub
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public SubmissionCOARNotifyRest findOne(final Context context, final String id) {
COARNotify coarNotify = submissionCOARNotifyService.findOne(id);
if (coarNotify == null) {
throw new ResourceNotFoundException("No COAR Notify could be found for ID: " + id );
COARNotifySubmissionConfiguration coarNotifySubmissionConfiguration = submissionCOARNotifyService.findOne(id);
if (coarNotifySubmissionConfiguration == null) {
throw new ResourceNotFoundException(
"No COAR Notify Submission Configuration could be found for ID: " + id );
}
return converter.toRest(coarNotify, utils.obtainProjection());
return converter.toRest(coarNotifySubmissionConfiguration, utils.obtainProjection());
}
@Override

View File

@@ -49,7 +49,10 @@ public final class NotifyServicePatchUtils {
try {
if (operation.getValue() != null) {
if (operation.getValue() instanceof JsonValueEvaluator) {
inboundPattern = objectMapper.readValue(((JsonValueEvaluator) operation.getValue()).getValueNode().toString(),
inboundPattern = objectMapper.readValue(((JsonValueEvaluator) operation.getValue())
.getValueNode().toString(), NotifyServiceInboundPattern.class);
} else if (operation.getValue() instanceof String) {
inboundPattern = objectMapper.readValue((String) operation.getValue(),
NotifyServiceInboundPattern.class);
}
}
@@ -75,7 +78,10 @@ public final class NotifyServicePatchUtils {
try {
if (operation.getValue() != null) {
if (operation.getValue() instanceof JsonValueEvaluator) {
outboundPattern = objectMapper.readValue(((JsonValueEvaluator) operation.getValue()).getValueNode().toString(),
outboundPattern = objectMapper.readValue(((JsonValueEvaluator) operation.getValue())
.getValueNode().toString(), NotifyServiceOutboundPattern.class);
} else if (operation.getValue() instanceof String) {
outboundPattern = objectMapper.readValue((String) operation.getValue(),
NotifyServiceOutboundPattern.class);
}
}

View File

@@ -36,7 +36,6 @@ public interface DataProcessingStep extends RestProcessingStep {
public static final String UPLOAD_STEP_ACCESSCONDITIONS_OPERATION_ENTRY = "accessConditions";
public static final String LICENSE_STEP_OPERATION_ENTRY = "granted";
public static final String CCLICENSE_STEP_OPERATION_ENTRY = "cclicense/uri";
public static final String COARNOTIFY_STEP_OPERATION_ENTRY = "coarnotify/service";
public static final String ACCESS_CONDITION_STEP_OPERATION_ENTRY = "discoverable";
public static final String ACCESS_CONDITION_POLICY_STEP_OPERATION_ENTRY = "accessConditions";
public static final String SHOW_IDENTIFIERS_ENTRY = "identifiers";

View File

@@ -20,7 +20,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.atteo.evo.inflector.English;
import org.dspace.app.ldn.NotifyPatternToTrigger;
import org.dspace.app.ldn.NotifyServiceEntity;
import org.dspace.app.ldn.service.NotifyPatternToTriggerService;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
@@ -32,7 +31,6 @@ import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.CheckSumRest;
import org.dspace.app.rest.model.ErrorRest;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.app.rest.model.NotifyServiceRest;
import org.dspace.app.rest.model.WorkspaceItemRest;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.step.DataCCLicense;
@@ -488,29 +486,20 @@ public class SubmissionService {
List<NotifyPatternToTrigger> patternsToTrigger =
notifyPatternToTriggerService.findByItem(context, obj.getItem());
Map<String, List<NotifyServiceEntity>> data =
Map<String, List<Integer>> data =
patternsToTrigger.stream()
.collect(Collectors.groupingBy(
NotifyPatternToTrigger::getPattern,
Collectors.mapping(NotifyPatternToTrigger::getNotifyService, Collectors.toList())
Collectors.mapping(patternToTrigger ->
patternToTrigger.getNotifyService().getID(),
Collectors.toList())
));
data.forEach((pattern, notifyServiceEntities) -> {
DataCOARNotify dataCOARNotify = new DataCOARNotify();
dataCOARNotify.setPattern(pattern);
dataCOARNotify.setServices(convertToNotifyServiceRests(notifyServiceEntities));
dataCOARNotifyList.add(dataCOARNotify);
});
data.forEach((pattern, ids) ->
dataCOARNotifyList.add(new DataCOARNotify(pattern, ids))
);
return dataCOARNotifyList;
}
private List<NotifyServiceRest> convertToNotifyServiceRests(List<NotifyServiceEntity> notifyServiceList) {
return notifyServiceList.stream()
.map(notifyServiceEntity ->
(NotifyServiceRest) converter.toRest(
notifyServiceEntity, Projection.DEFAULT))
.collect(Collectors.toList());
}
}

View File

@@ -31,10 +31,10 @@ public class COARNotifyServiceUtils {
}
public static String extractPattern(String path) {
Pattern pattern = Pattern.compile("/coarnotify/([a-zA-Z]+)/");
Pattern pattern = Pattern.compile("/([^/]+)/([^/]+)/([^/]+)");
Matcher matcher = pattern.matcher(path);
if (matcher.find()) {
return matcher.group(1);
return matcher.group(3);
} else {
throw new DSpaceBadRequestException("Pattern not found in the path");
}

View File

@@ -57,7 +57,7 @@ public class COARNotifyStep extends AbstractProcessingStep {
Operation op, SubmissionStepConfig stepConf) throws Exception {
PatchOperation<?> patchOperation = new PatchOperationFactory().instanceOf(
COARNOTIFY_STEP_OPERATION_ENTRY, op.getOp());
"coarnotify", op.getOp());
patchOperation.perform(context, currentRequest, source, op);
}
}

View File

@@ -63,7 +63,7 @@
<entry key="accessConditions">
<bean class="org.dspace.app.rest.submit.factory.impl.AccessConditionAddPatchOperation"/>
</entry>
<entry key="coarnotify/service">
<entry key="coarnotify">
<bean class="org.dspace.app.rest.submit.factory.impl.COARNotifyServiceAddPatchOperation"/>
</entry>
</map>
@@ -100,7 +100,7 @@
<entry key="accessConditions">
<bean class="org.dspace.app.rest.submit.factory.impl.AccessConditionRemovePatchOperation"/>
</entry>
<entry key="coarnotify/service">
<entry key="coarnotify">
<bean class="org.dspace.app.rest.submit.factory.impl.COARNotifyServiceRemovePatchOperation"/>
</entry>
</map>
@@ -136,7 +136,7 @@
<entry key="accessConditions">
<bean class="org.dspace.app.rest.submit.factory.impl.AccessConditionReplacePatchOperation"/>
</entry>
<entry key="coarnotify/service">
<entry key="coarnotify">
<bean class="org.dspace.app.rest.submit.factory.impl.COARNotifyServiceReplacePatchOperation"/>
</entry>
</map>

View File

@@ -53,10 +53,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.matchers.JsonPathMatchers;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.dspace.app.ldn.NotifyPatternToTrigger;
import org.dspace.app.ldn.NotifyServiceEntity;
import org.dspace.app.ldn.service.NotifyPatternToTriggerService;
import org.dspace.app.ldn.service.NotifyService;
import org.dspace.app.rest.matcher.CollectionMatcher;
import org.dspace.app.rest.matcher.ItemMatcher;
import org.dspace.app.rest.matcher.MetadataMatcher;
@@ -8627,17 +8624,17 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
NotifyServiceEntity notifyServiceOne =
NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name one")
.withLdnUrl("service ldn url one")
.withLdnUrl("https://service.ldn.org/inbox")
.build();
NotifyServiceEntity notifyServiceTwo =
NotifyServiceBuilder.createNotifyServiceBuilder(context).withName("service name two")
.withLdnUrl("service ldn url two")
.withLdnUrl("https://service2.ldn.org/inbox")
.build();
NotifyServiceEntity notifyServiceThree =
NotifyServiceBuilder.createNotifyServiceBuilder(context).withName("service name three")
.withLdnUrl("service ldn url three")
.withLdnUrl("https://service3.ldn.org/inbox")
.build();
// append the three services to the workspace item with different patterns
@@ -8658,15 +8655,10 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.coarnotify[0]", allOf(
hasJsonPath("pattern", is("endorsement")),
hasJsonPath("services", containsInAnyOrder(
matchNotifyServiceWithoutLinks(notifyServiceTwo.getID(), "service name two",
null, null, "service ldn url two"),
matchNotifyServiceWithoutLinks(notifyServiceThree.getID(), "service name three",
null, null, "service ldn url three"))))))
hasJsonPath("services", contains(notifyServiceTwo.getID(), notifyServiceThree.getID())))))
.andExpect(jsonPath("$.sections.coarnotify[1]", allOf(
hasJsonPath("pattern", is("review")),
hasJsonPath("services", contains(matchNotifyServiceWithoutLinks(notifyServiceOne.getID(),
"service name one", null, null, "service ldn url one"))))));
hasJsonPath("services", contains(notifyServiceOne.getID())))));
}
@Test
@@ -8687,17 +8679,17 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
NotifyServiceEntity notifyServiceOne =
NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name one")
.withLdnUrl("service ldn url one")
.withLdnUrl("https://service.ldn.org/inbox")
.build();
NotifyServiceEntity notifyServiceTwo =
NotifyServiceBuilder.createNotifyServiceBuilder(context).withName("service name two")
.withLdnUrl("service ldn url two")
.withLdnUrl("https://service2.ldn.org/inbox")
.build();
NotifyServiceEntity notifyServiceThree =
NotifyServiceBuilder.createNotifyServiceBuilder(context).withName("service name three")
.withLdnUrl("service ldn url three")
.withLdnUrl("https://service3.ldn.org/inbox")
.build();
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
@@ -8715,8 +8707,8 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.coarnotify[0].services", hasSize(1)))
.andExpect(jsonPath("$.sections.coarnotify[0].services", contains(
matchNotifyServiceWithoutLinks(notifyServiceOne.getID(), "service name one",
null, null, "service ldn url one"))));
notifyServiceOne.getID()
)));
// try to add new service of review pattern to witem
List<Operation> addOpts = new ArrayList<Operation>();
@@ -8731,12 +8723,9 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.coarnotify[0].services", hasSize(3)))
.andExpect(jsonPath("$.sections.coarnotify[0].services",contains(
matchNotifyServiceWithoutLinks(notifyServiceOne.getID(), "service name one",
null, null, "service ldn url one"),
matchNotifyServiceWithoutLinks(notifyServiceTwo.getID(), "service name two",
null, null, "service ldn url two"),
matchNotifyServiceWithoutLinks(notifyServiceThree.getID(), "service name three",
null, null, "service ldn url three")
notifyServiceOne.getID(),
notifyServiceTwo.getID(),
notifyServiceThree.getID()
)));
}
@@ -8759,17 +8748,17 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
NotifyServiceEntity notifyServiceOne =
NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name one")
.withLdnUrl("service ldn url one")
.withLdnUrl("https://service.ldn.org/inbox")
.build();
NotifyServiceEntity notifyServiceTwo =
NotifyServiceBuilder.createNotifyServiceBuilder(context).withName("service name two")
.withLdnUrl("service ldn url two")
.withLdnUrl("https://service2.ldn.org/inbox")
.build();
NotifyServiceEntity notifyServiceThree =
NotifyServiceBuilder.createNotifyServiceBuilder(context).withName("service name three")
.withLdnUrl("service ldn url three")
.withLdnUrl("https://service3.ldn.org/inbox")
.build();
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
@@ -8788,10 +8777,8 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.coarnotify[0].services", hasSize(2)))
.andExpect(jsonPath("$.sections.coarnotify[0].services", contains(
matchNotifyServiceWithoutLinks(notifyServiceOne.getID(), "service name one",
null, null, "service ldn url one"),
matchNotifyServiceWithoutLinks(notifyServiceTwo.getID(), "service name two",
null, null, "service ldn url two"))));
notifyServiceOne.getID(),
notifyServiceTwo.getID())));
// try to replace the notifyServiceOne of witem with notifyServiceThree of review pattern
List<Operation> removeOpts = new ArrayList<Operation>();
@@ -8805,10 +8792,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.coarnotify[0].services", hasSize(2)))
.andExpect(jsonPath("$.sections.coarnotify[0].services", contains(
matchNotifyServiceWithoutLinks(notifyServiceThree.getID(), "service name three",
null, null, "service ldn url three"),
matchNotifyServiceWithoutLinks(notifyServiceTwo.getID(), "service name two",
null, null, "service ldn url two")
notifyServiceThree.getID(), notifyServiceTwo.getID()
)));
}
@@ -8831,12 +8815,12 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
NotifyServiceEntity notifyServiceOne =
NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name one")
.withLdnUrl("service ldn url one")
.withLdnUrl("https://service.ldn.org/inbox")
.build();
NotifyServiceEntity notifyServiceTwo =
NotifyServiceBuilder.createNotifyServiceBuilder(context).withName("service name two")
.withLdnUrl("service ldn url two")
.withLdnUrl("https://service2.ldn.org/inbox")
.build();
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
@@ -8855,10 +8839,8 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.coarnotify[0].services", hasSize(2)))
.andExpect(jsonPath("$.sections.coarnotify[0].services", contains(
matchNotifyServiceWithoutLinks(notifyServiceOne.getID(), "service name one",
null, null, "service ldn url one"),
matchNotifyServiceWithoutLinks(notifyServiceTwo.getID(), "service name two",
null, null, "service ldn url two"))));
notifyServiceOne.getID(), notifyServiceTwo.getID()
)));
// try to remove the notifyServiceOne of witem
List<Operation> removeOpts = new ArrayList<Operation>();
@@ -8872,9 +8854,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.andExpect(status().isOk())
.andExpect(jsonPath("$.sections.coarnotify[0].services", hasSize(1)))
.andExpect(jsonPath("$.sections.coarnotify[0].services",contains(
matchNotifyServiceWithoutLinks(notifyServiceTwo.getID(), "service name two",
null, null, "service ldn url two"))
));
notifyServiceTwo.getID())));
}