Merge branch 'dev-1.3' into development

Conflicts:
	src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/UserAPITest.java
This commit is contained in:
anhefti 2022-04-13 11:05:22 +02:00
commit 3d94637300
8 changed files with 273 additions and 135 deletions

View file

@ -95,6 +95,17 @@ public class IndicatorTemplate implements Entity {
this.thresholds = postParams.getThresholds();
}
public IndicatorTemplate(final Long id, final IndicatorTemplate other) {
this.id = id;
this.examTemplateId = other.examTemplateId;
this.name = other.name;
this.type = other.type;
this.defaultColor = other.defaultColor;
this.defaultIcon = other.defaultIcon;
this.tags = other.tags;
this.thresholds = Utils.immutableListOf(other.thresholds);
}
@Override
public String getModelId() {
return (this.id == null) ? null : String.valueOf(this.id);
@ -168,7 +179,7 @@ public class IndicatorTemplate implements Entity {
final StringBuilder builder = new StringBuilder();
builder.append("Indicator [id=");
builder.append(this.id);
builder.append(", examId=");
builder.append(", examTemplateId=");
builder.append(this.examTemplateId);
builder.append(", name=");
builder.append(this.name);

View file

@ -32,6 +32,7 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientConnectionR
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ConfigurationNodeRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamTemplateRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.SebClientConfigRecordDynamicSqlSupport;
@ -201,18 +202,16 @@ public class PaginationServiceImpl implements PaginationService {
final PageSortOrder sortOrder = PageSortOrder.getSortOrder(sort);
final String sortColumnName = verifySortColumnName(sort, sortMappingName);
if (StringUtils.isNotBlank(sortColumnName)) {
startPage.setOrderByOnly(false);
switch (sortOrder) {
case DESCENDING: {
PageHelper.orderBy(sortColumnName + " DESC");
PageHelper.orderBy(sortColumnName + " DESC, id DESC");
break;
}
default: {
PageHelper.orderBy(sortColumnName);
PageHelper.orderBy(sortColumnName + ", id");
break;
}
}
PageHelper.orderBy("id");
}
}
@ -267,6 +266,18 @@ public class PaginationServiceImpl implements PaginationService {
this.sortColumnMapping.put(LmsSetupRecordDynamicSqlSupport.lmsSetupRecord.name(), lmsSetupTableMap);
this.defaultSortColumn.put(LmsSetupRecordDynamicSqlSupport.lmsSetupRecord.name(), Domain.LMS_SETUP.ATTR_ID);
// Exam Template Table
final Map<String, String> examTemplateTableMap = new HashMap<>();
examTemplateTableMap.put(Entity.FILTER_ATTR_INSTITUTION, institutionNameRef);
examTemplateTableMap.put(Domain.EXAM_TEMPLATE.ATTR_NAME, ExamTemplateRecordDynamicSqlSupport.name.name());
examTemplateTableMap.put(Domain.EXAM_TEMPLATE.ATTR_EXAM_TYPE,
ExamTemplateRecordDynamicSqlSupport.examType.name());
this.sortColumnMapping.put(ExamTemplateRecordDynamicSqlSupport.examTemplateRecord.name(), examTemplateTableMap);
this.defaultSortColumn.put(
ExamTemplateRecordDynamicSqlSupport.examTemplateRecord.name(),
Domain.EXAM_TEMPLATE.ATTR_ID);
// Exam Table
final Map<String, String> examTableMap = new HashMap<>();
examTableMap.put(Entity.FILTER_ATTR_INSTITUTION, institutionNameRef);

View file

@ -8,7 +8,9 @@
package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.exam.ExamTemplate;
import ch.ethz.seb.sebserver.gbl.model.exam.IndicatorTemplate;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO;
@ -21,4 +23,22 @@ public interface ExamTemplateDAO extends EntityDAO<ExamTemplate, ExamTemplate>,
* @return Result refer to the ExamTemplate instance or to an error when happened */
Result<ExamTemplate> getInstitutionalDefault(Long institutionId);
/** Creates a new indicator template
*
* @param indicatorTemplate The IndicatorTemplate refer also to the exam template (examTemplateId)
* @return Result refer to the created IndicatorTemplate or to an error when happened */
Result<IndicatorTemplate> createNewIndicatorTemplate(IndicatorTemplate indicatorTemplate);
/** Saves an already existing indicator template
*
* @param indicatorTemplate The IndicatorTemplate refer also to the exam template (examTemplateId)
* @return Result refer to the saved IndicatorTemplate or to an error when happened */
Result<IndicatorTemplate> saveIndicatorTemplate(IndicatorTemplate indicatorTemplate);
/** Deletes an already existing indicator template
*
* @param indicatorTemplate The IndicatorTemplate refer also to the exam template (examTemplateId)
* @return Result refer to the EntityKey of the deleted IndicatorTemplate or to an error when happened */
Result<EntityKey> deleteIndicatorTemplate(String examTemplateId, String indicatorTemplateId);
}

View file

@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
import ch.ethz.seb.sebserver.gbl.model.user.UserAccount;
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
@ -89,6 +90,12 @@ public interface UserActivityLogDAO extends
* @return Result of the Entity or referring to an Error if happened */
<E extends Entity> Result<E> logDelete(E entity);
/** Create a user activity log entry for the current user of activity type DELETE
*
* @param entityKey the EntityKey of the deleted object
* @return Result of the EntityKey or referring to an Error if happened */
Result<EntityKey> logDelete(EntityKey entityKey);
/** Used to log a successful bulk action and uses the EntityProcessingReport from the
* bulk action to log all details.
*

View file

@ -16,12 +16,16 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.select.MyBatis3SelectModelAdapter;
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@ -42,6 +46,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamTemplateRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamTemplateRecordMapper;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.IndicatorRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ExamTemplateRecord;
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.impl.BulkAction;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.AdditionalAttributesDAO;
@ -140,24 +145,38 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
final FilterMap filterMap,
final Predicate<ExamTemplate> predicate) {
return Result.tryCatch(() -> this.examTemplateRecordMapper
.selectByExample()
.where(
ExamTemplateRecordDynamicSqlSupport.institutionId,
isEqualToWhenPresent(filterMap.getInstitutionId()))
.and(
ExamTemplateRecordDynamicSqlSupport.name,
isLikeWhenPresent(filterMap.getExamTemplateName()))
.and(
ExamTemplateRecordDynamicSqlSupport.examType,
isEqualToWhenPresent(filterMap.getString(ExamTemplate.FILTER_ATTR_EXAM_TYPE)))
.build()
.execute()
.stream()
.map(this::toDomainModel)
.flatMap(DAOLoggingSupport::logAndSkipOnError)
.filter(predicate)
.collect(Collectors.toList()));
return Result.tryCatch(() -> {
final QueryExpressionDSL<MyBatis3SelectModelAdapter<List<ExamTemplateRecord>>>.QueryExpressionWhereBuilder whereClause =
(filterMap.getBoolean(FilterMap.ATTR_ADD_INSITUTION_JOIN))
? this.examTemplateRecordMapper
.selectByExample()
.join(InstitutionRecordDynamicSqlSupport.institutionRecord)
.on(InstitutionRecordDynamicSqlSupport.id,
SqlBuilder.equalTo(ExamTemplateRecordDynamicSqlSupport.institutionId))
.where(
ExamTemplateRecordDynamicSqlSupport.institutionId,
isEqualToWhenPresent(filterMap.getInstitutionId()))
: this.examTemplateRecordMapper
.selectByExample()
.where(
ExamTemplateRecordDynamicSqlSupport.institutionId,
isEqualToWhenPresent(filterMap.getInstitutionId()));
return whereClause
.and(
ExamTemplateRecordDynamicSqlSupport.name,
isLikeWhenPresent(filterMap.getExamTemplateName()))
.and(
ExamTemplateRecordDynamicSqlSupport.examType,
isEqualToWhenPresent(filterMap.getString(ExamTemplate.FILTER_ATTR_EXAM_TYPE)))
.build()
.execute()
.stream()
.map(this::toDomainModel)
.flatMap(DAOLoggingSupport::logAndSkipOnError)
.filter(predicate)
.collect(Collectors.toList());
});
}
@Override
@ -202,11 +221,6 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
checkUniqueName(data);
checkUniqueDefault(data);
final Collection<IndicatorTemplate> indicatorTemplates = data.getIndicatorTemplates();
final String indicatorsJSON = (indicatorTemplates != null && !indicatorTemplates.isEmpty())
? this.jsonMapper.writeValueAsString(indicatorTemplates)
: null;
final ExamTemplateRecord newRecord = new ExamTemplateRecord(
data.id,
null,
@ -219,7 +233,7 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
(data.supporter != null)
? StringUtils.join(data.supporter, Constants.LIST_SEPARATOR_CHAR)
: null,
indicatorsJSON,
null,
BooleanUtils.toInteger(data.institutionalDefault));
this.examTemplateRecordMapper.updateByPrimaryKeySelective(newRecord);
@ -241,6 +255,137 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
.onError(TransactionHandler::rollback);
}
@Override
@Transactional
public Result<IndicatorTemplate> createNewIndicatorTemplate(final IndicatorTemplate indicatorTemplate) {
return Result.tryCatch(() -> {
if (log.isDebugEnabled()) {
log.debug("Create new indicator template: {}", indicatorTemplate);
}
final Long examTemplatePK = indicatorTemplate.examTemplateId;
final ExamTemplateRecord examTemplateRec = this.examTemplateRecordMapper
.selectByPrimaryKey(examTemplatePK);
final String indicatorTemplatesJSON = examTemplateRec.getIndicatorTemplates();
final Collection<IndicatorTemplate> indicators = (StringUtils.isNotBlank(indicatorTemplatesJSON))
? this.jsonMapper.readValue(
indicatorTemplatesJSON,
new TypeReference<Collection<IndicatorTemplate>>() {
})
: Collections.emptyList();
checkUniqueIndicatorName(indicatorTemplate, indicators);
final IndicatorTemplate newIndicatorTemplate = new IndicatorTemplate(
getNextIndicatorId(indicators),
indicatorTemplate);
final List<IndicatorTemplate> newIndicators = new ArrayList<>(indicators);
newIndicators.add(newIndicatorTemplate);
final String newIndicatorTemplatesJSON = newIndicators.isEmpty()
? StringUtils.EMPTY
: this.jsonMapper.writeValueAsString(newIndicators);
final ExamTemplateRecord newRecord = new ExamTemplateRecord(
examTemplatePK, null, null, null, null, null, null,
newIndicatorTemplatesJSON, null);
this.examTemplateRecordMapper.updateByPrimaryKeySelective(newRecord);
return newIndicatorTemplate;
})
.onError(TransactionHandler::rollback);
}
@Override
@Transactional
public Result<IndicatorTemplate> saveIndicatorTemplate(final IndicatorTemplate indicatorTemplate) {
return Result.tryCatch(() -> {
if (log.isDebugEnabled()) {
log.debug("Save indicator template: {}", indicatorTemplate);
}
final Long examTemplatePK = indicatorTemplate.examTemplateId;
final ExamTemplateRecord examTemplateRec = this.examTemplateRecordMapper
.selectByPrimaryKey(examTemplatePK);
final String indicatorTemplatesJSON = examTemplateRec.getIndicatorTemplates();
final Collection<IndicatorTemplate> indicators = (StringUtils.isNotBlank(indicatorTemplatesJSON))
? this.jsonMapper.readValue(
indicatorTemplatesJSON,
new TypeReference<Collection<IndicatorTemplate>>() {
})
: Collections.emptyList();
checkUniqueIndicatorName(indicatorTemplate, indicators);
final List<IndicatorTemplate> newIndicators = indicators
.stream()
.map(i -> indicatorTemplate.id.equals(i.id) ? indicatorTemplate : i)
.collect(Collectors.toList());
final String newIndicatorTemplatesJSON = newIndicators.isEmpty()
? StringUtils.EMPTY
: this.jsonMapper.writeValueAsString(newIndicators);
final ExamTemplateRecord newRecord = new ExamTemplateRecord(
examTemplatePK, null, null, null, null, null, null,
newIndicatorTemplatesJSON, null);
this.examTemplateRecordMapper.updateByPrimaryKeySelective(newRecord);
return indicatorTemplate;
})
.onError(TransactionHandler::rollback);
}
@Override
@Transactional
public Result<EntityKey> deleteIndicatorTemplate(
final String examTemplateId,
final String indicatorTemplateId) {
return Result.tryCatch(() -> {
if (log.isDebugEnabled()) {
log.debug(
"Delete indicator template for exam template: {} indicator template id",
examTemplateId,
indicatorTemplateId);
}
final Long examTemplatePK = Long.valueOf(examTemplateId);
final ExamTemplateRecord examTemplateRec = this.examTemplateRecordMapper
.selectByPrimaryKey(examTemplatePK);
final String indicatorTemplatesJSON = examTemplateRec.getIndicatorTemplates();
final Collection<IndicatorTemplate> indicators = (StringUtils.isNotBlank(indicatorTemplatesJSON))
? this.jsonMapper.readValue(
indicatorTemplatesJSON,
new TypeReference<Collection<IndicatorTemplate>>() {
})
: Collections.emptyList();
final List<IndicatorTemplate> newIndicators = indicators.stream()
.filter(indicatorTemplate -> !indicatorTemplateId.equals(indicatorTemplate.getModelId()))
.collect(Collectors.toList());
final String newIndicatorTemplatesJSON = newIndicators.isEmpty()
? StringUtils.EMPTY
: this.jsonMapper.writeValueAsString(newIndicators);
final ExamTemplateRecord newRecord = new ExamTemplateRecord(
examTemplatePK, null, null, null, null, null, null,
newIndicatorTemplatesJSON, null);
this.examTemplateRecordMapper.updateByPrimaryKeySelective(newRecord);
return new EntityKey(indicatorTemplateId, EntityType.INDICATOR);
})
.onError(TransactionHandler::rollback);
}
@Override
public Set<EntityDependency> getDependencies(final BulkAction bulkAction) {
return Collections.emptySet();
@ -251,7 +396,9 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
public Result<Collection<EntityKey>> delete(final Set<EntityKey> all) {
return Result.tryCatch(() -> {
log.info("Delete exam templates: {}", all);
if (log.isDebugEnabled()) {
log.debug("Delete exam templates: {}", all);
}
final List<Long> ids = extractListOfPKs(all);
if (ids == null || ids.isEmpty()) {
@ -387,4 +534,24 @@ public class ExamTemplateDAOImpl implements ExamTemplateDAO {
}
}
private void checkUniqueIndicatorName(final IndicatorTemplate indicatorTemplate,
final Collection<IndicatorTemplate> indicators) {
// check unique name
indicators.stream()
.filter(it -> Objects.equals(it.name, indicatorTemplate.name))
.findAny()
.ifPresent(it -> {
throw new FieldValidationException(
"name",
"indicatorTemplate:name:exists");
});
}
private long getNextIndicatorId(final Collection<IndicatorTemplate> indicators) {
return indicators.stream()
.map(IndicatorTemplate::getId)
.max(Long::compare)
.orElse(-1L) + 1;
}
}

View file

@ -171,6 +171,15 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
return log(UserLogActivityType.DELETE, entity);
}
@Override
@Transactional
public Result<EntityKey> logDelete(final EntityKey entityKey) {
return Result.tryCatch(() -> {
log(UserLogActivityType.DELETE, entityKey.entityType, entityKey.modelId, null);
return entityKey;
});
}
@Override
@Transactional
public Result<EntityProcessingReport> logBulkAction(final EntityProcessingReport bulkActionReport) {

View file

@ -8,7 +8,6 @@
package ch.ethz.seb.sebserver.webservice.weblayer.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@ -21,8 +20,6 @@ import javax.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.SqlTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
@ -48,7 +45,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService;
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService;
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.EntityDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamTemplateDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
@ -59,12 +55,12 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe
@RequestMapping("${sebserver.webservice.api.admin.endpoint}" + API.EXAM_TEMPLATE_ENDPOINT)
public class ExamTemplateController extends EntityController<ExamTemplate, ExamTemplate> {
private static final Logger log = LoggerFactory.getLogger(ExamTemplateController.class);
private final ExamTemplateDAO examTemplateDAO;
protected ExamTemplateController(
final AuthorizationService authorization,
final BulkActionService bulkActionService,
final EntityDAO<ExamTemplate, ExamTemplate> entityDAO,
final ExamTemplateDAO entityDAO,
final UserActivityLogDAO userActivityLogDAO,
final PaginationService paginationService,
final BeanValidationService beanValidationService) {
@ -76,6 +72,8 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
userActivityLogDAO,
paginationService,
beanValidationService);
this.examTemplateDAO = entityDAO;
}
@RequestMapping(
@ -177,41 +175,17 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
// check write privilege for requested institution and concrete entityType
this.checkWritePrivilege(institutionId);
final POSTMapper postMap = new POSTMapper(allRequestParams, request.getQueryString())
.putIfAbsent(API.PARAM_INSTITUTION_ID, String.valueOf(institutionId));
final String examTemplateId = postMap.getString(IndicatorTemplate.ATTR_EXAM_TEMPLATE_ID);
final ExamTemplate examTemplate = super.entityDAO
.byModelId(examTemplateId)
return this.beanValidationService
.validateBean(new IndicatorTemplate(
null,
postMap.getLong(IndicatorTemplate.ATTR_EXAM_TEMPLATE_ID),
postMap))
.flatMap(this.examTemplateDAO::createNewIndicatorTemplate)
.flatMap(this.userActivityLogDAO::logCreate)
.getOrThrow();
final IndicatorTemplate newIndicator = new IndicatorTemplate(
(long) examTemplate.getIndicatorTemplates().size(),
Long.parseLong(examTemplateId),
postMap);
this.beanValidationService.validateBean(newIndicator)
.getOrThrow();
final ArrayList<IndicatorTemplate> indicators = new ArrayList<>(examTemplate.indicatorTemplates);
indicators.add(newIndicator);
final ExamTemplate newExamTemplate = new ExamTemplate(
examTemplate.id,
null, null, null, null, null, null,
examTemplate.institutionalDefault,
indicators,
null);
super.entityDAO
.save(newExamTemplate)
.getOrThrow();
this.userActivityLogDAO.logCreate(newIndicator)
.onError(error -> log.error("Failed to log indicator template creation: {}", newIndicator, error));
return newIndicator;
}
@RequestMapping(
@ -228,46 +202,11 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
// check modify privilege for requested institution and concrete entityType
this.checkModifyPrivilege(institutionId);
final ExamTemplate examTemplate = super.entityDAO
.byPK(modifyData.examTemplateId)
return this.beanValidationService
.validateBean(modifyData)
.flatMap(this.examTemplateDAO::saveIndicatorTemplate)
.flatMap(this.userActivityLogDAO::logModify)
.getOrThrow();
final String modelId = modifyData.getModelId();
final List<IndicatorTemplate> newIndicators = examTemplate.indicatorTemplates
.stream()
.map(i -> {
if (modelId.equals(i.getModelId())) {
return new IndicatorTemplate(
modifyData.id,
modifyData.examTemplateId,
modifyData.name,
(modifyData.type != null) ? modifyData.type : i.type,
(modifyData.defaultColor != null) ? modifyData.defaultColor : i.defaultColor,
(modifyData.defaultIcon != null) ? modifyData.defaultIcon : i.defaultIcon,
(modifyData.tags != null) ? modifyData.tags : i.tags,
(modifyData.thresholds != null) ? modifyData.thresholds : i.thresholds);
} else {
return i;
}
})
.collect(Collectors.toList());
final ExamTemplate newExamTemplate = new ExamTemplate(
examTemplate.id,
null, null, null, null, null, null,
examTemplate.institutionalDefault,
newIndicators,
null);
super.entityDAO
.save(newExamTemplate)
.getOrThrow();
this.userActivityLogDAO.logModify(modifyData)
.onError(error -> log.error("Failed to log indicator template modification: {}", modifyData, error));
return modifyData;
}
@RequestMapping(
@ -286,35 +225,9 @@ public class ExamTemplateController extends EntityController<ExamTemplate, ExamT
// check write privilege for requested institution and concrete entityType
this.checkWritePrivilege(institutionId);
final ExamTemplate examTemplate = super.entityDAO
.byModelId(parentModelId)
return this.examTemplateDAO.deleteIndicatorTemplate(parentModelId, modelId)
.flatMap(this.userActivityLogDAO::logDelete)
.getOrThrow();
final IndicatorTemplate toDelete = examTemplate.indicatorTemplates
.stream()
.filter(i -> modelId.equals(i.getModelId()))
.findFirst()
.orElse(null);
final List<IndicatorTemplate> newIndicators = new ArrayList<>(examTemplate.indicatorTemplates);
newIndicators.remove(toDelete);
final ExamTemplate newExamTemplate = new ExamTemplate(
examTemplate.id,
null, null, null, null, null, null,
examTemplate.institutionalDefault,
newIndicators,
null);
super.entityDAO
.save(newExamTemplate)
.getOrThrow();
this.userActivityLogDAO.logDelete(toDelete)
.onError(error -> log.error("Failed to log indicator template modification: {}", toDelete, error));
return new EntityKey(modelId, EntityType.INDICATOR);
}
@Override

View file

@ -347,7 +347,7 @@ public class UserAPITest extends AdministrationAPIIntegrationTester {
assertTrue(userInfos.numberOfPages == 2);
assertNotNull(userInfos.content);
assertTrue(userInfos.content.size() == 3);
assertEquals("[user3, user4, user6]", getOrderedUUIDs(userInfos.content));
assertEquals("[user4, user6, user7]", getOrderedUUIDs(userInfos.content));
}
@Test