Skip to content
Snippets Groups Projects
Commit 359c1c9f authored by uhensler's avatar uhensler
Browse files

00-3116: Export the audit log of a question item as Excel file

parent 4b8687d6
No related branches found
No related tags found
No related merge requests found
Showing
with 364 additions and 0 deletions
...@@ -260,4 +260,6 @@ public interface QPoolService { ...@@ -260,4 +260,6 @@ public interface QPoolService {
public QuestionItem toAuditQuestionItem(String xml); public QuestionItem toAuditQuestionItem(String xml);
public List<QuestionItemAuditLog> getAuditLogByQuestionItem(QuestionItemShort item);
} }
...@@ -63,5 +63,7 @@ public interface QuestionItemSecurityCallback extends MetadataSecurityCallback { ...@@ -63,5 +63,7 @@ public interface QuestionItemSecurityCallback extends MetadataSecurityCallback {
* Can a user rate the question item outside the review process? * Can a user rate the question item outside the review process?
*/ */
public boolean canRate(); public boolean canRate();
public boolean canExportAuditLog();
} }
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
*/ */
package org.olat.modules.qpool.manager; package org.olat.modules.qpool.manager;
import java.util.List;
import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DB;
import org.olat.core.logging.OLog; import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing; import org.olat.core.logging.Tracing;
...@@ -26,6 +28,7 @@ import org.olat.core.util.StringHelper; ...@@ -26,6 +28,7 @@ import org.olat.core.util.StringHelper;
import org.olat.core.util.xml.XStreamHelper; import org.olat.core.util.xml.XStreamHelper;
import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItem;
import org.olat.modules.qpool.QuestionItemAuditLog; import org.olat.modules.qpool.QuestionItemAuditLog;
import org.olat.modules.qpool.QuestionItemShort;
import org.olat.modules.qpool.model.QEducationalContext; import org.olat.modules.qpool.model.QEducationalContext;
import org.olat.modules.qpool.model.QItemType; import org.olat.modules.qpool.model.QItemType;
import org.olat.modules.qpool.model.QLicense; import org.olat.modules.qpool.model.QLicense;
...@@ -77,6 +80,15 @@ public class QuestionItemAuditLogDAO { ...@@ -77,6 +80,15 @@ public class QuestionItemAuditLogDAO {
public void persist(QuestionItemAuditLog auditLog) { public void persist(QuestionItemAuditLog auditLog) {
dbInstance.getCurrentEntityManager().persist(auditLog); dbInstance.getCurrentEntityManager().persist(auditLog);
} }
public List<QuestionItemAuditLog> getAuditLogByQuestionItem(QuestionItemShort item) {
StringBuilder sb = new StringBuilder(128);
sb.append("select log from qitemauditlog log where log.questionItemKey=:questionItemKey");
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), QuestionItemAuditLog.class)
.setParameter("questionItemKey", item.getKey())
.getResultList();
}
public String toXml(QuestionItem item) { public String toXml(QuestionItem item) {
if(item == null) return null; if(item == null) return null;
......
...@@ -1022,4 +1022,9 @@ public class QuestionPoolServiceImpl implements QPoolService { ...@@ -1022,4 +1022,9 @@ public class QuestionPoolServiceImpl implements QPoolService {
return auditLogDao.questionItemFromXml(xml); return auditLogDao.questionItemFromXml(xml);
} }
@Override
public List<QuestionItemAuditLog> getAuditLogByQuestionItem(QuestionItemShort item) {
return auditLogDao.getAuditLogByQuestionItem(item);
}
} }
\ No newline at end of file
...@@ -182,4 +182,9 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback ...@@ -182,4 +182,9 @@ public class ProcesslessSecurityCallback implements QuestionItemSecurityCallback
|| (poolAdmin && qpoolModule.isPoolAdminAllowedToEditMetadata()); || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditMetadata());
} }
@Override
public boolean canExportAuditLog() {
return admin || poolAdmin;
}
} }
...@@ -177,6 +177,11 @@ public class ReviewProcessSecurityCallback implements QuestionItemSecurityCallba ...@@ -177,6 +177,11 @@ public class ReviewProcessSecurityCallback implements QuestionItemSecurityCallba
public boolean canEditAuthors() { public boolean canEditAuthors() {
return admin || itemView.isAuthor() || itemView.isManager() || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditMetadata()); return admin || itemView.isAuthor() || itemView.isManager() || (poolAdmin && qpoolModule.isPoolAdminAllowedToEditMetadata());
} }
@Override
public boolean canExportAuditLog() {
return admin || poolAdmin;
}
private boolean isEditableQuestionStatus(QuestionStatus status) { private boolean isEditableQuestionStatus(QuestionStatus status) {
return EDITABLE_STATES.contains(status); return EDITABLE_STATES.contains(status);
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.qpool.ui;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.translator.Translator;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper;
import org.olat.core.util.openxml.OpenXMLWorkbook;
import org.olat.core.util.openxml.OpenXMLWorkbookResource;
import org.olat.core.util.openxml.OpenXMLWorksheet;
import org.olat.core.util.openxml.OpenXMLWorksheet.Row;
import org.olat.modules.qpool.QPoolService;
import org.olat.modules.qpool.QuestionItem;
import org.olat.modules.qpool.QuestionItemAuditLog;
import org.olat.modules.qpool.QuestionItemShort;
import org.olat.modules.qpool.QuestionStatus;
import org.olat.modules.qpool.model.QEducationalContext;
import org.olat.modules.qpool.ui.metadata.MetaUIFactory;
import org.olat.modules.qpool.ui.metadata.MetaUIFactory.KeyValues;
import org.olat.user.UserManager;
import edu.emory.mathcs.backport.java.util.Collections;
/**
*
* Initial date: 23.01.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class QuestionItemAuditLogExport extends OpenXMLWorkbookResource {
private static final OLog log = Tracing.createLoggerFor(QuestionItemAuditLogExport.class);
private final List<QuestionItemAuditLog> auditLog;
private final Translator translator;
private final QPoolService qpoolService;
private final UserManager userManager;
public QuestionItemAuditLogExport(QuestionItemShort item, List<QuestionItemAuditLog> auditLog,
Translator translator) {
super(label(item));
this.auditLog = auditLog;
this.translator = translator;
qpoolService = CoreSpringFactory.getImpl(QPoolService.class);
userManager = CoreSpringFactory.getImpl(UserManager.class);
}
private static final String label(QuestionItemShort item) {
return StringHelper.transformDisplayNameToFileSystemName(item.getTitle())
+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()))
+ ".xlsx";
}
@Override
protected void generate(OutputStream out) {
Collections.sort(auditLog, new QuestionItemAuditLogComparator());
try(OpenXMLWorkbook workbook = new OpenXMLWorkbook(out, 1)) {
OpenXMLWorksheet exportSheet = workbook.nextWorksheet();
addSheetSettings(exportSheet);
addHeader(exportSheet);
addContent(exportSheet, workbook);
} catch (IOException e) {
log.error("", e);
} catch (Exception e) {
log.error("", e);
}
}
private void addSheetSettings(OpenXMLWorksheet exportSheet) {
exportSheet.setColumnWidth(1, 16);//width date time
exportSheet.setColumnWidth(8, 16);//width date time
}
private void addHeader(OpenXMLWorksheet exportSheet) {
exportSheet.setHeaderRows(2);
Row headerRow = exportSheet.newRow();
int pos = 0;
headerRow.addCell(pos++, translator.translate("export.log.header.log.date"));
headerRow.addCell(pos++, translator.translate("export.log.header.log.action"));
headerRow.addCell(pos++, translator.translate("export.log.header.title"));
headerRow.addCell(pos++, translator.translate("export.log.header.topic"));
headerRow.addCell(pos++, translator.translate("export.log.header.taxonomic.path"));
headerRow.addCell(pos++, translator.translate("export.log.header.context"));
headerRow.addCell(pos++, translator.translate("export.log.header.keywords"));
headerRow.addCell(pos++, translator.translate("export.log.header.additional.informations"));
headerRow.addCell(pos++, translator.translate("export.log.header.coverage"));
headerRow.addCell(pos++, translator.translate("export.log.header.language"));
headerRow.addCell(pos++, translator.translate("export.log.header.assessment.type"));
headerRow.addCell(pos++, translator.translate("export.log.header.item.type"));
headerRow.addCell(pos++, translator.translate("export.log.header.learningTime"));
headerRow.addCell(pos++, translator.translate("export.log.header.difficulty"));
headerRow.addCell(pos++, translator.translate("export.log.header.stdevDifficulty"));
headerRow.addCell(pos++, translator.translate("export.log.header.differentiation"));
headerRow.addCell(pos++, translator.translate("export.log.header.numOfAnswerAlternatives"));
headerRow.addCell(pos++, translator.translate("export.log.header.usage"));
headerRow.addCell(pos++, translator.translate("export.log.header.creator"));
headerRow.addCell(pos++, translator.translate("export.log.header.copyright"));
headerRow.addCell(pos++, translator.translate("export.log.header.version"));
headerRow.addCell(pos++, translator.translate("export.log.header.status"));
headerRow.addCell(pos++, translator.translate("export.log.header.log.author"));
}
private void addContent(OpenXMLWorksheet exportSheet, OpenXMLWorkbook workbook) {
for(QuestionItemAuditLog logEntry:auditLog) {
int pos = 0;
Row row = exportSheet.newRow();
Date creationDate = logEntry.getCreationDate();
row.addCell(pos++, creationDate, workbook.getStyles().getDateTimeStyle());
row.addCell(pos++, logEntry.getAction());
QuestionItem item = null;
if (logEntry.getQuestionItemKey() != null) {
item = qpoolService.toAuditQuestionItem(logEntry.getAfter());
}
if (item != null) {
row.addCell(pos++, item.getTitle());
row.addCell(pos++, item.getTopic());
row.addCell(pos++, item.getTaxonomicPath());
row.addCell(pos++, getTranslatedContext(item.getEducationalContext()));
row.addCell(pos++, item.getKeywords());
row.addCell(pos++, item.getAdditionalInformations());
row.addCell(pos++, item.getCoverage());
row.addCell(pos++, item.getLanguage());
row.addCell(pos++, getTranslatedAssessmentType(item.getAssessmentType()));
row.addCell(pos++, getTranslatedItemType(item.getItemType()));
row.addCell(pos++, item.getEducationalLearningTime());
row.addCell(pos++, format(item.getDifficulty()));
row.addCell(pos++, format(item.getStdevDifficulty()));
row.addCell(pos++, format(item.getDifferentiation()));
row.addCell(pos++, String.valueOf(item.getNumOfAnswerAlternatives()));
row.addCell(pos++, String.valueOf(item.getUsage()));
row.addCell(pos++, item.getCreator());
row.addCell(pos++, item.getLicense() != null? item.getLicense().getLicenseKey(): null);
row.addCell(pos++, item.getItemVersion());
row.addCell(pos++, getTranslatedStatus(item.getQuestionStatus()));
} else {
pos += 20;
}
Long authorKey = logEntry.getAuthorKey();
if(authorKey != null) {
String fullname = userManager.getUserDisplayName(authorKey);
row.addCell(pos++, fullname);
}
}
}
private String format(BigDecimal bigDecimal) {
if (bigDecimal == null) return null;
// remove 0 at the end of the string
return String.valueOf(bigDecimal.doubleValue());
}
private String getTranslatedContext(QEducationalContext educationalContext) {
if (educationalContext == null) return null;
String translation = translator.translate("item.level." + educationalContext.getLevel().toLowerCase());
if(translation.length() > 128) {
translation = educationalContext.getLevel();
}
return translation;
}
private String getTranslatedAssessmentType(String assessmentType) {
KeyValues assessmentTypes = MetaUIFactory.getAssessmentTypes(translator);
for (int i = 0; i < assessmentTypes.getKeys().length; i++) {
if (assessmentTypes.getKeys()[i].equals(assessmentType)) {
return assessmentTypes.getValues()[i];
}
}
return null;
}
private String getTranslatedItemType(String type) {
if (!StringHelper.containsNonWhitespace(type)) return null;
String translation = translator.translate("item.type." + type.toLowerCase());
if(translation.length() > 128) {
translation = type;
}
return translation;
}
private String getTranslatedStatus(QuestionStatus questionStatus) {
if (questionStatus == null) return null;
String translation = translator.translate("lifecycle.status." + questionStatus);
if(translation.length() > 128) {
translation = questionStatus.name();
}
return translation;
}
private class QuestionItemAuditLogComparator implements Comparator<QuestionItemAuditLog> {
@Override
public int compare(QuestionItemAuditLog o1, QuestionItemAuditLog o2) {
if(o1 == null && o2 == null) return 0;
if(o1 == null) return -1;
if(o2 == null) return 1;
Date d1 = o1.getCreationDate();
Date d2 = o2.getCreationDate();
if(d1 == null && d2 == null) return 0;
if(d1 == null) return -1;
if(d2 == null) return 1;
return d1.compareTo(d2);
}
}
}
...@@ -53,6 +53,7 @@ import org.olat.modules.qpool.QPoolSPI; ...@@ -53,6 +53,7 @@ import org.olat.modules.qpool.QPoolSPI;
import org.olat.modules.qpool.QPoolSecurityCallback; import org.olat.modules.qpool.QPoolSecurityCallback;
import org.olat.modules.qpool.QPoolService; import org.olat.modules.qpool.QPoolService;
import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItem;
import org.olat.modules.qpool.QuestionItemAuditLog;
import org.olat.modules.qpool.QuestionItemAuditLog.Action; import org.olat.modules.qpool.QuestionItemAuditLog.Action;
import org.olat.modules.qpool.QuestionItemAuditLogBuilder; import org.olat.modules.qpool.QuestionItemAuditLogBuilder;
import org.olat.modules.qpool.QuestionItemSecurityCallback; import org.olat.modules.qpool.QuestionItemSecurityCallback;
...@@ -90,6 +91,7 @@ public class QuestionItemDetailsController extends BasicController implements To ...@@ -90,6 +91,7 @@ public class QuestionItemDetailsController extends BasicController implements To
private Link nextItemLink; private Link nextItemLink;
private Link numberItemsLink; private Link numberItemsLink;
private Link previousItemLink; private Link previousItemLink;
private Link exportLogLink;
private Link showMetadataLink; private Link showMetadataLink;
private Link hideMetadataLink; private Link hideMetadataLink;
private Link shareGroupItemLink; private Link shareGroupItemLink;
...@@ -341,6 +343,11 @@ public class QuestionItemDetailsController extends BasicController implements To ...@@ -341,6 +343,11 @@ public class QuestionItemDetailsController extends BasicController implements To
} }
private void initMetadataTools() { private void initMetadataTools() {
if (qItemSecurityCallback.canExportAuditLog()) {
exportLogLink = LinkFactory.createToolLink("export.log", translate("export.log"), this);
exportLogLink.setIconLeftCSS("o_icon o_icon-fw o_icon_log");
stackPanel.addTool(exportLogLink, Align.right);
}
showMetadataLink = LinkFactory.createToolLink("metadata.show", translate("metadata.show"), this); showMetadataLink = LinkFactory.createToolLink("metadata.show", translate("metadata.show"), this);
showMetadataLink.setIconLeftCSS("o_icon o_icon-fw o_icon_qitem_show_metadata"); showMetadataLink.setIconLeftCSS("o_icon o_icon-fw o_icon_qitem_show_metadata");
hideMetadataLink = LinkFactory.createToolLink("metadata.hide", translate("metadata.hide"), this); hideMetadataLink = LinkFactory.createToolLink("metadata.hide", translate("metadata.hide"), this);
...@@ -381,6 +388,8 @@ public class QuestionItemDetailsController extends BasicController implements To ...@@ -381,6 +388,8 @@ public class QuestionItemDetailsController extends BasicController implements To
doExport(ureq, metadatasCtrl.getItem()); doExport(ureq, metadatasCtrl.getItem());
} else if(source == copyItemLink) { } else if(source == copyItemLink) {
doCopy(ureq, metadatasCtrl.getItem()); doCopy(ureq, metadatasCtrl.getItem());
} else if(source == exportLogLink) {
doExportLog(ureq, metadatasCtrl.getItem());
} else if(source == nextItemLink) { } else if(source == nextItemLink) {
fireEvent(ureq, new QItemEvent("next", metadatasCtrl.getItem())); fireEvent(ureq, new QItemEvent("next", metadatasCtrl.getItem()));
} else if(source == previousItemLink) { } else if(source == previousItemLink) {
...@@ -651,6 +660,12 @@ public class QuestionItemDetailsController extends BasicController implements To ...@@ -651,6 +660,12 @@ public class QuestionItemDetailsController extends BasicController implements To
ureq.getDispatchResult().setResultingMediaResource(mr); ureq.getDispatchResult().setResultingMediaResource(mr);
} }
private void doExportLog(UserRequest ureq, QuestionItemShort item) {
List<QuestionItemAuditLog> auditLog = qpoolService.getAuditLogByQuestionItem(item);
QuestionItemAuditLogExport export = new QuestionItemAuditLogExport(item, auditLog, getTranslator());
ureq.getDispatchResult().setResultingMediaResource(export);
}
private void doShowMetadata(UserRequest ureq) { private void doShowMetadata(UserRequest ureq) {
doShowMetadata(); doShowMetadata();
doPutMetadatasSwitch(ureq, Boolean.TRUE); doPutMetadatasSwitch(ureq, Boolean.TRUE);
......
...@@ -52,6 +52,30 @@ error.input.toolong=Leider ist Ihr gerade eingegebener Text mit {1} Zeichen zu l ...@@ -52,6 +52,30 @@ error.input.toolong=Leider ist Ihr gerade eingegebener Text mit {1} Zeichen zu l
error.select.one=Sie m\u00FCssen mindestens eine Frage w\u00E4hlen. error.select.one=Sie m\u00FCssen mindestens eine Frage w\u00E4hlen.
error.wrongFloat=Falsches Zahlenformat. Beispiele\: 1.0, 0.5, 0.2 error.wrongFloat=Falsches Zahlenformat. Beispiele\: 1.0, 0.5, 0.2
export.item=Export export.item=Export
export.log=Log
export.log.header.additional.informations=$\:general.additional.informations
export.log.header.assessment.type=$\:question.assessmentType
export.log.header.context=$\:educational.context
export.log.header.copyright=$\:rights.copyright
export.log.header.coverage=$\:general.coverage
export.log.header.creator=$\:rights.creator
export.log.header.differentiation=$\:question.differentiation
export.log.header.difficulty=$\:question.difficulty
export.log.header.item.type=$\:question.type
export.log.header.keywords=$\:general.keywords
export.log.header.language=$\:general.language
export.log.header.learningTime=$\:educational.learningTime
export.log.header.log.action=Aktion
export.log.header.log.author=Ge\u00E4ndert durch
export.log.header.log.date=Datum
export.log.header.numOfAnswerAlternatives=$\:question.numOfAnswerAlternatives
export.log.header.status=$\:lifecycle.status
export.log.header.stdevDifficulty=$\:question.stdevDifficulty
export.log.header.taxonomic.path=$\:classification.taxonomic.path
export.log.header.title=$\:general.title
export.log.header.topic=$\:general.topic
export.log.header.usage=$\:question.usage
export.log.header.version=$\:lifecycle.version
export.overview.accept=Ber\u00FCcksichtigt export.overview.accept=Ber\u00FCcksichtigt
general=Allgemein general=Allgemein
general.additional.informations=Zusatzinformationen general.additional.informations=Zusatzinformationen
......
...@@ -52,6 +52,30 @@ error.input.toolong=The text you entered is to long ({1} characters). Only {1} c ...@@ -52,6 +52,30 @@ error.input.toolong=The text you entered is to long ({1} characters). Only {1} c
error.select.one=You need to select at least one question. error.select.one=You need to select at least one question.
error.wrongFloat=Wrong number format. Example\: 1.0, 0.5, 0.2 error.wrongFloat=Wrong number format. Example\: 1.0, 0.5, 0.2
export.item=Export export.item=Export
export.log=Log
export.log.header.additional.informations=$\:general.additional.informations
export.log.header.assessment.type=$\:question.assessmentType
export.log.header.context=$\:educational.context
export.log.header.copyright=$\:rights.copyright
export.log.header.coverage=$\:general.coverage
export.log.header.creator=$\:rights.creator
export.log.header.differentiation=$\:question.differentiation
export.log.header.difficulty=$\:question.difficulty
export.log.header.item.type=$\:question.type
export.log.header.keywords=$\:general.keywords
export.log.header.language=$\:general.language
export.log.header.learningTime=$\:educational.learningTime
export.log.header.log.action=Action
export.log.header.log.author=Changed by
export.log.header.log.date=Date
export.log.header.numOfAnswerAlternatives=$\:question.numOfAnswerAlternatives
export.log.header.status=$\:lifecycle.status
export.log.header.stdevDifficulty=$\:question.stdevDifficulty
export.log.header.taxonomic.path=$\:classification.taxonomic.path
export.log.header.title=$\:general.title
export.log.header.topic=$\:general.topic
export.log.header.usage=$\:question.usage
export.log.header.version=$\:lifecycle.version
export.overview.accept=Used export.overview.accept=Used
general=General general=General
general.additional.informations=Add. information general.additional.informations=Add. information
......
...@@ -21,9 +21,11 @@ package org.olat.modules.qpool.manager; ...@@ -21,9 +21,11 @@ package org.olat.modules.qpool.manager;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.junit.Test; import org.junit.Test;
import org.olat.core.commons.persistence.DB;
import org.olat.core.id.Identity; import org.olat.core.id.Identity;
import org.olat.ims.qti21.QTI21Constants; import org.olat.ims.qti21.QTI21Constants;
import org.olat.modules.qpool.QPoolService; import org.olat.modules.qpool.QPoolService;
...@@ -44,6 +46,8 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -44,6 +46,8 @@ import org.springframework.beans.factory.annotation.Autowired;
*/ */
public class QuestionItemAuditLogDAOTest extends OlatTestCase { public class QuestionItemAuditLogDAOTest extends OlatTestCase {
@Autowired
private DB dbInstance;
@Autowired @Autowired
private QuestionItemAuditLogDAO sut; private QuestionItemAuditLogDAO sut;
@Autowired @Autowired
...@@ -63,9 +67,33 @@ public class QuestionItemAuditLogDAOTest extends OlatTestCase { ...@@ -63,9 +67,33 @@ public class QuestionItemAuditLogDAOTest extends OlatTestCase {
.withAfter(item) .withAfter(item)
.withMessage("item was created") .withMessage("item was created")
.create(); .create();
dbInstance.commitAndCloseSession();
sut.persist(auditLog); sut.persist(auditLog);
dbInstance.commitAndCloseSession();
}
@Test
public void shouldFindAuditLogByQuestionItem() {
QItemType qItemType = qItemTypeDao.loadByType(QuestionType.MC.name());
Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("qitem-audit-log");
QuestionItem item = questionDao.createAndPersist(id, "NGC 55", QTI21Constants.QTI_21_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, qItemType);
QuestionItemAuditLog auditLog = qpoolService.createAuditLogBuilder(id, QuestionItemAuditLog.Action.CREATE_QUESTION_ITEM_NEW).withBefore(item).create();
sut.persist(auditLog);
auditLog = qpoolService.createAuditLogBuilder(id, QuestionItemAuditLog.Action.UPDATE_QUESTION).withBefore(item).create();
sut.persist(auditLog);
auditLog = qpoolService.createAuditLogBuilder(id, QuestionItemAuditLog.Action.UPDATE_QUESTION_ITEM_METADATA).withBefore(item).create();
sut.persist(auditLog);
QuestionItem otherItem = questionDao.createAndPersist(id, "NGC 55", QTI21Constants.QTI_21_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, qItemType);
auditLog = qpoolService.createAuditLogBuilder(id, QuestionItemAuditLog.Action.UPDATE_QUESTION_ITEM_METADATA).withBefore(otherItem).create();
sut.persist(auditLog);
dbInstance.commitAndCloseSession();
List<QuestionItemAuditLog> auditLogs = sut.getAuditLogByQuestionItem(item);
assertThat(auditLogs).hasSize(3);
} }
@Test @Test
public void shouldConvertToXMLAndBack() { public void shouldConvertToXMLAndBack() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment