Skip to content
Snippets Groups Projects
Commit 6ad6b745 authored by uhensler's avatar uhensler
Browse files

Merge branch 'OpenOLAT_14.1'

parents 102589d2 fe6d7b65
No related branches found
No related tags found
No related merge requests found
......@@ -52,6 +52,10 @@ public class ProviderHelper {
public static Date addDays(Date date, String daysToAdd) {
int days = Integer.parseInt(daysToAdd);
return addDays(date, days);
}
public static Date addDays(Date date, int days) {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, days);
......@@ -60,6 +64,10 @@ public class ProviderHelper {
public static Date addHours(Date date, String hoursToAdd) {
int hours = Integer.parseInt(hoursToAdd);
return addHours(date, hours);
}
public static Date addHours(Date date, int hours) {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.HOUR, hours);
......
......@@ -20,6 +20,7 @@
package org.olat.modules.quality.generator.provider.course;
import static org.olat.modules.quality.generator.ProviderHelper.addDays;
import static org.olat.modules.quality.generator.ProviderHelper.subtractDays;
import java.time.DayOfWeek;
import java.time.LocalDate;
......@@ -141,6 +142,7 @@ public class CourseProvider implements QualityGeneratorProvider {
if (CONFIG_KEY_TRIGGER_BEGIN.equals(trigger) || CONFIG_KEY_TRIGGER_END.equals(trigger)) {
appendForDueDate(searchParams, generator, configs, fromDate, toDate);
List<RepositoryEntry> courses = loadCourses(generator, searchParams);
courses.removeIf(new PlusDurationIsInPast(configs, toDate));
numberDataCollections = courses.size();
} else if (CONFIG_KEY_TRIGGER_DAILY.equals(trigger)) {
List<Date> dcStarts = getDailyStarts(configs, fromDate, toDate);
......@@ -189,6 +191,7 @@ public class CourseProvider implements QualityGeneratorProvider {
Date fromDate, Date toDate, List<Organisation> organisations, SearchParameters searchParams) {
appendForDueDate(searchParams, generator, configs, fromDate, toDate);
List<RepositoryEntry> courses = loadCourses(generator, searchParams);
courses.removeIf(new PlusDurationIsInPast(configs, toDate));
String trigger = configs.getValue(CONFIG_KEY_TRIGGER);
List<QualityDataCollection> dataCollections = new ArrayList<>();
......@@ -354,15 +357,15 @@ public class CourseProvider implements QualityGeneratorProvider {
switch (trigger) {
case CONFIG_KEY_TRIGGER_BEGIN:
String beginDays = configs.getValue(CONFIG_KEY_DUE_DATE_DAYS);
Date beginFrom = addDays(fromDate, beginDays);
Date beginTo = addDays(toDate, beginDays);
Date beginFrom = subtractDays(fromDate, beginDays);
Date beginTo = subtractDays(toDate, beginDays);
searchParams.setBeginFrom(beginFrom);
searchParams.setBeginTo(beginTo);
break;
case CONFIG_KEY_TRIGGER_END:
String endDays = configs.getValue(CONFIG_KEY_DUE_DATE_DAYS);
Date endFrom = addDays(fromDate, endDays);
Date endTo = addDays(toDate, endDays);
Date endFrom = subtractDays(fromDate, endDays);
Date endTo = subtractDays(toDate, endDays);
searchParams.setEndFrom(endFrom);
searchParams.setEndTo(endTo);
break;
......
/**
* <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.quality.generator.provider.course;
import java.util.Date;
import java.util.function.Predicate;
import org.olat.modules.quality.generator.ProviderHelper;
import org.olat.modules.quality.generator.QualityGeneratorConfigs;
import org.olat.repository.RepositoryEntry;
/**
*
* Initial date: 12 Nov 2019<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
class PlusDurationIsInPast implements Predicate<RepositoryEntry> {
private final boolean beginTrigger;
private final boolean endTrigger;
private final int dueDateDays;
private final int durationHours;
private final Date toDate;
PlusDurationIsInPast(QualityGeneratorConfigs configs, Date toDate) {
String trigger = configs.getValue(CourseProvider.CONFIG_KEY_TRIGGER);
this.beginTrigger = CourseProvider.CONFIG_KEY_TRIGGER_BEGIN.equals(trigger);
this.endTrigger = CourseProvider.CONFIG_KEY_TRIGGER_END.equals(trigger);
this.dueDateDays = ProviderHelper.toIntOrZero(configs.getValue(CourseProvider.CONFIG_KEY_DUE_DATE_DAYS));
this.durationHours = ProviderHelper.toIntOrZero(configs.getValue(CourseProvider.CONFIG_KEY_DURATION_HOURS));
this.toDate = toDate;
}
@Override
public boolean test(RepositoryEntry re) {
Date dcStart = null;
Date dcEnd = null;
if (beginTrigger && re.getLifecycle() != null && re.getLifecycle().getValidFrom() != null) {
dcStart = ProviderHelper.addDays(re.getLifecycle().getValidFrom(), dueDateDays);
} else if (endTrigger && re.getLifecycle() != null && re.getLifecycle().getValidTo() != null) {
dcStart = ProviderHelper.addDays(re.getLifecycle().getValidTo(), dueDateDays);
}
if (dcStart != null) {
dcEnd = ProviderHelper.addHours(dcStart, durationHours);
}
return dcEnd != null? dcEnd.before(toDate): false;
}
}
......@@ -203,6 +203,27 @@ public class RepositoryEntryWhiteListController extends FormBasicController
return elementRefs;
}
public static void setRepositoryEntryRefs(QualityGeneratorConfigs generatorConfigs, List<? extends RepositoryEntryRef> entries) {
for (RepositoryEntryRef entry : entries) {
doAddRepositoryEntry(generatorConfigs, entry.getKey().toString());
}
}
private static void doAddRepositoryEntry(QualityGeneratorConfigs generatorConfigs, String entryKey) {
if (StringHelper.containsNonWhitespace(entryKey)) {
String whiteListConfig = generatorConfigs.getValue(COURSE_WHITE_LIST);
if (StringHelper.containsNonWhitespace(whiteListConfig)) {
String[] keys = whiteListConfig.split(KEY_DELIMITER);
if (!Arrays.asList(keys).contains(entryKey)) {
whiteListConfig += KEY_DELIMITER + entryKey;
}
} else {
whiteListConfig = entryKey;
}
generatorConfigs.setValue(COURSE_WHITE_LIST, whiteListConfig);
}
}
private void doSelectRepositoryEntry(UserRequest ureq) {
selectCtrl = new ReferencableEntriesSearchController(getWindowControl(), ureq,
new String[] { CourseModule.getCourseTypeName() }, translate("repository.entry.select.title"),
......@@ -216,27 +237,10 @@ public class RepositoryEntryWhiteListController extends FormBasicController
}
private void doAddRepositoryEntries(List<RepositoryEntry> selectedEntries) {
for (RepositoryEntry repositoryEntry : selectedEntries) {
doAddRepositoryEntry(repositoryEntry.getKey().toString());
}
setRepositoryEntryRefs(configs, selectedEntries);
loadModel();
}
private void doAddRepositoryEntry(String entryKey) {
if (StringHelper.containsNonWhitespace(entryKey)) {
String whiteListConfig = configs.getValue(COURSE_WHITE_LIST);
if (StringHelper.containsNonWhitespace(whiteListConfig)) {
String[] keys = whiteListConfig.split(KEY_DELIMITER);
if (!Arrays.asList(keys).contains(entryKey)) {
whiteListConfig += KEY_DELIMITER + entryKey;
}
} else {
whiteListConfig = entryKey;
}
configs.setValue(COURSE_WHITE_LIST, whiteListConfig);
}
}
private void doConfirmRemove(UserRequest ureq, List<RepositoryEntry> entries) {
if (entries.isEmpty()) {
showWarning("repository.entry.none.selected");
......
/**
* <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.quality.generator.provider.course;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.junit.Test;
import org.olat.basesecurity.OrganisationService;
import org.olat.core.commons.persistence.DB;
import org.olat.core.id.Identity;
import org.olat.core.id.Organisation;
import org.olat.modules.quality.QualityDataCollection;
import org.olat.modules.quality.generator.QualityGenerator;
import org.olat.modules.quality.generator.QualityGeneratorConfigs;
import org.olat.modules.quality.generator.QualityGeneratorService;
import org.olat.modules.quality.generator.manager.QualityGeneratorConfigsImpl;
import org.olat.modules.quality.generator.ui.RepositoryEntryWhiteListController;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryEntryRef;
import org.olat.repository.RepositoryManager;
import org.olat.repository.manager.RepositoryEntryLifecycleDAO;
import org.olat.repository.model.RepositoryEntryLifecycle;
import org.olat.test.JunitTestHelper;
import org.olat.test.OlatTestCase;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 12 Nov 2019<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class CourseProviderTest extends OlatTestCase {
@Autowired
private DB dbInstance;
@Autowired
private QualityGeneratorService generatorService;
@Autowired
private OrganisationService organisationService;
@Autowired
private RepositoryManager repositoryManager;
@Autowired
private RepositoryEntryLifecycleDAO lifecycleDAO;
@Autowired
private CourseProvider sut;
@Test
public void shouldNotGenerateDataCollectionIfBeginDateIsReachedYet() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 2);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 12, 30);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseBeginConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 11).getTime();
Date now = new GregorianCalendar(2010, 6, 11).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
assertThat(generated).isEmpty();
}
@Test
public void shouldGenerateDataCollectionIfBeginDateIsReached() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 1);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 12, 30);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseBeginConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 11).getTime();
Date now = new GregorianCalendar(2010, 6, 11).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
QualityDataCollection dataCollection = generated.get(0);
assertThat(dataCollection.getStart()).isCloseTo(new GregorianCalendar(2010, 6, 11).getTime(), 1000);
assertThat(dataCollection.getDeadline()).isCloseTo(new GregorianCalendar(2010, 6, 21).getTime(), 1000);
assertThat(dataCollection.getTopicRepositoryEntry().getKey()).isEqualTo(courseEntry.getKey());
}
@Test
public void shouldGenerateDataCollectionIfBeginDateIsReachedWithDelay() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 1);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 12, 30);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseBeginConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 11).getTime();
Date now = new GregorianCalendar(2010, 6, 13).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
QualityDataCollection dataCollection = generated.get(0);
assertThat(dataCollection.getStart()).isCloseTo(new GregorianCalendar(2010, 6, 11).getTime(), 1000);
assertThat(dataCollection.getDeadline()).isCloseTo(new GregorianCalendar(2010, 6, 21).getTime(), 1000);
assertThat(dataCollection.getTopicRepositoryEntry().getKey()).isEqualTo(courseEntry.getKey());
}
@Test
public void shouldNotGenerateDataCollectionIfBeginDatePlusDueDaysPlusDurationIsOver() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 1);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 12, 30);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseBeginConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 11).getTime();
Date now = new GregorianCalendar(2010, 6, 30).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
assertThat(generated).isEmpty();
}
@Test
public void shouldNotGenerateDataCollectionIfEndDateIsNotReachedYet() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 1);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 6, 30);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "-10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseEndConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 11).getTime();
Date now = new GregorianCalendar(2010, 6, 11).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
assertThat(generated).isEmpty();
}
@Test
public void shouldGenerateDataCollectionIfEndDateIsReached() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 1);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 6, 21);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "-10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseEndConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 11).getTime();
Date now = new GregorianCalendar(2010, 6, 11).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
QualityDataCollection dataCollection = generated.get(0);
assertThat(dataCollection.getStart()).isCloseTo(new GregorianCalendar(2010, 6, 11).getTime(), 1000);
assertThat(dataCollection.getDeadline()).isCloseTo(new GregorianCalendar(2010, 6, 21).getTime(), 1000);
assertThat(dataCollection.getTopicRepositoryEntry().getKey()).isEqualTo(courseEntry.getKey());
}
@Test
public void shouldGenerateDataCollectionIfEndDateIsReachedWithDelay() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 1);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 6, 18);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "-10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseEndConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 1).getTime();
Date now = new GregorianCalendar(2010, 6, 13).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
QualityDataCollection dataCollection = generated.get(0);
assertThat(dataCollection.getStart()).isCloseTo(new GregorianCalendar(2010, 6, 8).getTime(), 1000);
assertThat(dataCollection.getDeadline()).isCloseTo(new GregorianCalendar(2010, 6, 18).getTime(), 1000);
assertThat(dataCollection.getTopicRepositoryEntry().getKey()).isEqualTo(courseEntry.getKey());
}
@Test
public void shouldNotGenerateDataCollectionIfEndDatePlusDueDaysPlusDurationIsOver() {
GregorianCalendar lifecycleStart = new GregorianCalendar(2010, 6, 1);
GregorianCalendar lifecycleEnd = new GregorianCalendar(2010, 6, 25);
RepositoryEntry courseEntry = createCourse(lifecycleStart, lifecycleEnd);
QualityGenerator generator = createGeneratorInDefaultOrganisation();
String dueDateDays = "-10";
String durationHours = "240";
QualityGeneratorConfigs configs = createCourseEndConfigs(generator, dueDateDays, durationHours, courseEntry);
Date lastRun = new GregorianCalendar(2010, 6, 11).getTime();
Date now = new GregorianCalendar(2010, 6, 13).getTime();
List<QualityDataCollection> generated = sut.generate(generator, configs, lastRun, now);
assertThat(generated).isEmpty();
}
private RepositoryEntry createCourse(GregorianCalendar lifecycleStart, GregorianCalendar lifecycleEnd) {
Identity initialAuthor = JunitTestHelper.createAndPersistIdentityAsAuthor(JunitTestHelper.random());
RepositoryEntry courseEntry = JunitTestHelper.deployBasicCourse(initialAuthor);
RepositoryEntryLifecycle lifecycle = lifecycleDAO.create(null, null, false, lifecycleStart.getTime(), lifecycleEnd.getTime());
courseEntry = repositoryManager.setDescriptionAndName(courseEntry, null, null, null, null, null, null, null, lifecycle);
dbInstance.commitAndCloseSession();
return courseEntry;
}
private QualityGeneratorConfigs createCourseBeginConfigs(QualityGenerator generator, String dueDateDays,
String durationHours, RepositoryEntryRef courseEntry) {
QualityGeneratorConfigs configs = new QualityGeneratorConfigsImpl(generator);
configs.setValue(CourseProvider.CONFIG_KEY_TITLE, "DATA_COLLECTION_TITLE");
configs.setValue(CourseProvider.CONFIG_KEY_ROLES, "coach");
configs.setValue(CourseProvider.CONFIG_KEY_TRIGGER, CourseProvider.CONFIG_KEY_TRIGGER_BEGIN);
configs.setValue(CourseProvider.CONFIG_KEY_DUE_DATE_DAYS, dueDateDays);
configs.setValue(CourseProvider.CONFIG_KEY_DURATION_HOURS, durationHours);
// Restrict to a single course, because a lot of courses with the same life cycle are generated.
RepositoryEntryWhiteListController.setRepositoryEntryRefs(configs, Collections.singletonList(courseEntry));
dbInstance.commitAndCloseSession();
return configs;
}
private QualityGeneratorConfigs createCourseEndConfigs(QualityGenerator generator, String dueDateDays,
String durationHours, RepositoryEntryRef courseEntry) {
QualityGeneratorConfigs configs = new QualityGeneratorConfigsImpl(generator);
configs.setValue(CourseProvider.CONFIG_KEY_TITLE, "DATA_COLLECTION_TITLE");
configs.setValue(CourseProvider.CONFIG_KEY_ROLES, "coach");
configs.setValue(CourseProvider.CONFIG_KEY_TRIGGER, CourseProvider.CONFIG_KEY_TRIGGER_END);
configs.setValue(CourseProvider.CONFIG_KEY_DUE_DATE_DAYS, dueDateDays);
configs.setValue(CourseProvider.CONFIG_KEY_DURATION_HOURS, durationHours);
// Restrict to a single course, because a lot of courses with the same life cycle are generated.
RepositoryEntryWhiteListController.setRepositoryEntryRefs(configs, Collections.singletonList(courseEntry));
dbInstance.commitAndCloseSession();
return configs;
}
private QualityGenerator createGeneratorInDefaultOrganisation() {
Organisation organisation = organisationService.getDefaultOrganisation();
Collection<Organisation> organisations = Collections.singletonList(organisation);
QualityGenerator generator = generatorService.createGenerator(sut.getType(), organisations);
RepositoryEntry formEntry = JunitTestHelper.createAndPersistRepositoryEntry();
generator.setFormEntry(formEntry);
return generatorService.updateGenerator(generator);
}
}
......@@ -248,6 +248,7 @@ import org.junit.runners.Suite;
org.olat.modules.quality.generator.manager.titlecreator.RepositoryEntryHandlerTest.class,
org.olat.modules.quality.generator.manager.titlecreator.UserHandlerTest.class,
org.olat.modules.quality.generator.provider.course.manager.CourseProviderDAOTest.class,
org.olat.modules.quality.generator.provider.course.CourseProviderTest.class,
org.olat.modules.quality.generator.provider.courselectures.manager.CourseLecturesProviderDAOTest.class,
org.olat.modules.quality.generator.provider.curriculumelement.manager.CurriculumElementProviderDAOTest.class,
org.olat.modules.quality.manager.AudiencelessQualityContextBuilderTest.class,
......
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