diff --git a/src/main/java/org/olat/modules/quality/generator/ProviderHelper.java b/src/main/java/org/olat/modules/quality/generator/ProviderHelper.java
index 421ff0360cedc91f41b7e7f35fd94f095fad7b4f..6f32ccb393fb52c273ce832d0ad0c1c1249345b2 100644
--- a/src/main/java/org/olat/modules/quality/generator/ProviderHelper.java
+++ b/src/main/java/org/olat/modules/quality/generator/ProviderHelper.java
@@ -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);
diff --git a/src/main/java/org/olat/modules/quality/generator/provider/course/CourseProvider.java b/src/main/java/org/olat/modules/quality/generator/provider/course/CourseProvider.java
index 06afd2f0b5062ba80e93ccb7bf082916695a7e7c..2da9283a5b9cf3a9a979f7a68da7e239fae6536b 100644
--- a/src/main/java/org/olat/modules/quality/generator/provider/course/CourseProvider.java
+++ b/src/main/java/org/olat/modules/quality/generator/provider/course/CourseProvider.java
@@ -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;
diff --git a/src/main/java/org/olat/modules/quality/generator/provider/course/PlusDurationIsInPast.java b/src/main/java/org/olat/modules/quality/generator/provider/course/PlusDurationIsInPast.java
new file mode 100644
index 0000000000000000000000000000000000000000..f589ee6fa88e44731509b27fe47ab06cb328e6a8
--- /dev/null
+++ b/src/main/java/org/olat/modules/quality/generator/provider/course/PlusDurationIsInPast.java
@@ -0,0 +1,68 @@
+/**
+ * <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;
+	}
+
+}
diff --git a/src/main/java/org/olat/modules/quality/generator/ui/RepositoryEntryWhiteListController.java b/src/main/java/org/olat/modules/quality/generator/ui/RepositoryEntryWhiteListController.java
index 736f017e10c9f3b6cd09dd6b77ea5ff3aebaf8c4..34352c020ec2a00a98214226f21cc9550df3b97d 100644
--- a/src/main/java/org/olat/modules/quality/generator/ui/RepositoryEntryWhiteListController.java
+++ b/src/main/java/org/olat/modules/quality/generator/ui/RepositoryEntryWhiteListController.java
@@ -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");
diff --git a/src/test/java/org/olat/modules/quality/generator/provider/course/CourseProviderTest.java b/src/test/java/org/olat/modules/quality/generator/provider/course/CourseProviderTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..352afa6ecf2c00cf41570c12380bdffd7b823876
--- /dev/null
+++ b/src/test/java/org/olat/modules/quality/generator/provider/course/CourseProviderTest.java
@@ -0,0 +1,282 @@
+/**
+ * <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);
+	}
+
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index e8caa56e1788561655804685c3ab933e3d026bab..9b5df62d1def9277e54ac8f3cedd6aeb3fc63a5e 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -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,