diff --git a/src/main/java/org/olat/ims/qti21/QTI21Service.java b/src/main/java/org/olat/ims/qti21/QTI21Service.java
index 49851d1a6ad092aa529201f26261434d7cc91800..e2d4d6b97d2832944b71bcbfc46ada5aed11b2cf 100644
--- a/src/main/java/org/olat/ims/qti21/QTI21Service.java
+++ b/src/main/java/org/olat/ims/qti21/QTI21Service.java
@@ -438,6 +438,14 @@ public interface QTI21Service {
 	 */
 	public AssessmentTestSession pullSession(AssessmentTestSession candidateSession, DigitalSignatureOptions signatureOptions, Identity actor);
 	
+	/**
+	 * Update the assessment entry if the test is done within a test repository entry.
+	 * 
+	 * @param candidateSession The assessment test tession.
+	 * @return The updated assessment entry
+	 */
+	public AssessmentEntry updateAssessmentEntry(AssessmentTestSession candidateSession);
+	
 	/**
 	 * Sign the assessment result. Be careful, the file must not be changed
 	 * after that!
diff --git a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java
index 226c4245aae97c6061f3e0e09d3e2dc8d78f8b0d..d671087fe599999d5caa45a38b654657dd8fbb24 100644
--- a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java
+++ b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java
@@ -105,6 +105,7 @@ import org.olat.ims.qti21.model.audit.CandidateEvent;
 import org.olat.ims.qti21.model.audit.CandidateItemEventType;
 import org.olat.ims.qti21.model.audit.CandidateTestEventType;
 import org.olat.ims.qti21.model.jpa.AssessmentTestSessionStatistics;
+import org.olat.ims.qti21.model.xml.QtiNodesExtractor;
 import org.olat.ims.qti21.ui.event.DeleteAssessmentTestSessionEvent;
 import org.olat.ims.qti21.ui.event.RetrieveAssessmentTestSessionEvent;
 import org.olat.modules.assessment.AssessmentEntry;
@@ -133,6 +134,7 @@ import uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult;
 import uk.ac.ed.ph.jqtiplus.node.result.ItemResult;
 import uk.ac.ed.ph.jqtiplus.node.result.ItemVariable;
 import uk.ac.ed.ph.jqtiplus.node.result.OutcomeVariable;
+import uk.ac.ed.ph.jqtiplus.node.test.AssessmentTest;
 import uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder;
 import uk.ac.ed.ph.jqtiplus.reading.AssessmentObjectXmlLoader;
 import uk.ac.ed.ph.jqtiplus.reading.QtiObjectReadResult;
@@ -1215,6 +1217,34 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia
 		}
 	}
 	
+	@Override
+	public AssessmentEntry updateAssessmentEntry(AssessmentTestSession candidateSession) {
+		Identity assessedIdentity = candidateSession.getIdentity();
+		RepositoryEntry testEntry = candidateSession.getTestEntry();
+		
+		File unzippedDirRoot = FileResourceManager.getInstance().unzipFileResource(testEntry.getOlatResource());
+		ResolvedAssessmentTest resolvedAssessmentTest = loadAndResolveAssessmentTest(unzippedDirRoot, false, false);
+		AssessmentTest assessmentTest = resolvedAssessmentTest.getRootNodeLookup().extractIfSuccessful();
+		
+		AssessmentEntry assessmentEntry = assessmentEntryDao.loadAssessmentEntry(assessedIdentity, testEntry, null, testEntry);
+		BigDecimal finalScore = candidateSession.getFinalScore();
+		assessmentEntry.setScore(finalScore);
+		assessmentEntry.setAssessmentId(candidateSession.getKey());
+
+		Double cutValue = QtiNodesExtractor.extractCutValue(assessmentTest);
+		
+		Boolean passed = assessmentEntry.getPassed();
+		if(candidateSession.getManualScore() != null && finalScore != null && cutValue != null) {
+			boolean calculated = finalScore.compareTo(BigDecimal.valueOf(cutValue.doubleValue())) >= 0;
+			passed = Boolean.valueOf(calculated);
+		} else if(candidateSession.getPassed() != null) {
+			passed = candidateSession.getPassed();
+		}
+		assessmentEntry.setPassed(passed);
+		assessmentEntry = assessmentEntryDao.updateAssessmentEntry(assessmentEntry);
+		return assessmentEntry;
+	}
+	
 	@Override
 	public AssessmentTestSession pullSession(AssessmentTestSession session, DigitalSignatureOptions signatureOptions, Identity actor) {
 		session = getAssessmentTestSession(session.getKey());
diff --git a/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionInvalidationController.java b/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionInvalidationController.java
index 3177361a18997c3f815d28d0a20f24083cd1c334..3df008b319e6a8546fefe989770a84a2d97c526b 100644
--- a/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionInvalidationController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionInvalidationController.java
@@ -34,6 +34,7 @@ import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.id.Identity;
 import org.olat.course.nodes.IQTESTCourseNode;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.ims.qti21.AssessmentTestSession;
@@ -56,9 +57,11 @@ public class ConfirmAssessmentTestSessionInvalidationController extends FormBasi
 	private FormLink invalidateButton;
 	
 	private AssessmentTestSession session;
-	private final IQTESTCourseNode courseNode;
+	private RepositoryEntry testEntry;
+	private IQTESTCourseNode courseNode;
+	private final Identity assessedIdentity;
 	private final boolean canUpdateAssessmentEntry;
-	private final UserCourseEnvironment assessedUserCourseEnv;
+	private UserCourseEnvironment assessedUserCourseEnv;
 	
 	@Autowired
 	private DB dbInstance;
@@ -67,6 +70,16 @@ public class ConfirmAssessmentTestSessionInvalidationController extends FormBasi
 	@Autowired
 	private UserManager userManager;
 	
+	/**
+	 * Invalidate the assessment test session linked to a course.
+	 * 
+	 * @param ureq The user request
+	 * @param wControl The window control
+	 * @param session The assessment test session to invalidate
+	 * @param lastSession If the specified test session is known to be the last session
+	 * @param courseNode The course element
+	 * @param assessedUserCourseEnv The user course environnment of the assessed identity
+	 */
 	public ConfirmAssessmentTestSessionInvalidationController(UserRequest ureq, WindowControl wControl,
 			AssessmentTestSession session, boolean lastSession, IQTESTCourseNode courseNode,
 			UserCourseEnvironment assessedUserCourseEnv) {
@@ -74,6 +87,27 @@ public class ConfirmAssessmentTestSessionInvalidationController extends FormBasi
 		this.session = session;
 		this.courseNode = courseNode;
 		this.assessedUserCourseEnv = assessedUserCourseEnv;
+		assessedIdentity = assessedUserCourseEnv.getIdentityEnvironment().getIdentity();
+		canUpdateAssessmentEntry = lastSession && (getNextLastSession() != null);
+		initForm(ureq);
+	}
+	
+	/**
+	 * Invalidate the assessment test session of a test entry (without course).
+	 * 
+	 * @param ureq The user request
+	 * @param wControl The window control
+	 * @param session The assessment test session to invalidate
+	 * @param lastSession If the specified test session is known to be the last session
+	 * @param testEntry The test repository entry
+	 * @param assessedIdentity The assessed identity
+	 */
+	public ConfirmAssessmentTestSessionInvalidationController(UserRequest ureq, WindowControl wControl,
+			AssessmentTestSession session, boolean lastSession, RepositoryEntry testEntry, Identity assessedIdentity) {
+		super(ureq, wControl, "confirm_inval_test_session");
+		this.session = session;
+		this.testEntry = testEntry;
+		this.assessedIdentity = assessedIdentity;
 		canUpdateAssessmentEntry = lastSession && (getNextLastSession() != null);
 		initForm(ureq);
 	}
@@ -125,16 +159,25 @@ public class ConfirmAssessmentTestSessionInvalidationController extends FormBasi
 		if(updateEntryResults) {
 			AssessmentTestSession promotedSession = getNextLastSession();
 			if(promotedSession != null) {
-				courseNode.promoteAssessmentTestSession(promotedSession, assessedUserCourseEnv, getIdentity(), Role.coach);
+				if(courseNode == null) {
+					qtiService.updateAssessmentEntry(promotedSession);
+				} else {
+					courseNode.promoteAssessmentTestSession(promotedSession, assessedUserCourseEnv, getIdentity(), Role.coach);
+				}
 			}
 		}
 		fireEvent(ureq, Event.CHANGED_EVENT);
 	}
 	
 	private AssessmentTestSession getNextLastSession() {
-		RepositoryEntry courseEntry = assessedUserCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
-		List<AssessmentTestSession> sessions = qtiService.getAssessmentTestSessions(courseEntry, courseNode.getIdent(),
-				assessedUserCourseEnv.getIdentityEnvironment().getIdentity(), true);
+		List<AssessmentTestSession> sessions;
+		if(courseNode == null) {
+			sessions = qtiService.getAssessmentTestSessions(testEntry, null, assessedIdentity, true);
+		} else {
+			RepositoryEntry courseEntry = assessedUserCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+			sessions = qtiService.getAssessmentTestSessions(courseEntry, courseNode.getIdent(), assessedIdentity, true);
+		}
+		
 		sessions.remove(session);
 		if(!sessions.isEmpty()) {
 			Collections.sort(sessions, new AssessmentTestSessionComparator());
diff --git a/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionRevalidationController.java b/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionRevalidationController.java
index df451157964753e375292eacb8ea78c298f8dc40..863b4a72bdb1bc3ab6ef6c513c1077007a8f6a65 100644
--- a/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionRevalidationController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/ConfirmAssessmentTestSessionRevalidationController.java
@@ -34,6 +34,7 @@ import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.id.Identity;
 import org.olat.course.nodes.IQTESTCourseNode;
 import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.ims.qti21.AssessmentTestSession;
@@ -54,9 +55,11 @@ public class ConfirmAssessmentTestSessionRevalidationController extends FormBasi
 	private FormLink revalidateButton;
 	
 	private AssessmentTestSession session;
-	private final IQTESTCourseNode courseNode;
+	private RepositoryEntry testEntry;
+	private IQTESTCourseNode courseNode;
+	private final Identity assessedIdentity;
 	private final boolean canUpdateAssessmentEntry;
-	private final UserCourseEnvironment assessedUserCourseEnv;
+	private UserCourseEnvironment assessedUserCourseEnv;
 	
 	@Autowired
 	private DB dbInstance;
@@ -71,6 +74,17 @@ public class ConfirmAssessmentTestSessionRevalidationController extends FormBasi
 		this.session = session;
 		this.courseNode = courseNode;
 		this.assessedUserCourseEnv = assessedUserCourseEnv;
+		assessedIdentity = assessedUserCourseEnv.getIdentityEnvironment().getIdentity();
+		canUpdateAssessmentEntry = canBeNextLastSession();
+		initForm(ureq);
+	}
+	
+	public ConfirmAssessmentTestSessionRevalidationController(UserRequest ureq, WindowControl wControl,
+			AssessmentTestSession session, RepositoryEntry testEntry, Identity assessedIdentity) {
+		super(ureq, wControl, "confirm_reval_test_session");
+		this.session = session;
+		this.testEntry = testEntry;
+		this.assessedIdentity = assessedIdentity;
 		canUpdateAssessmentEntry = canBeNextLastSession();
 		initForm(ureq);
 	}
@@ -120,15 +134,23 @@ public class ConfirmAssessmentTestSessionRevalidationController extends FormBasi
 		session = qtiService.updateAssessmentTestSession(session);
 		dbInstance.commit();
 		if(updateEntryResults) {
-			courseNode.promoteAssessmentTestSession(session, assessedUserCourseEnv, getIdentity(), Role.coach);
+			if(courseNode == null) {
+				qtiService.updateAssessmentEntry(session);
+			} else {
+				courseNode.promoteAssessmentTestSession(session, assessedUserCourseEnv, getIdentity(), Role.coach);
+			}
 		}
 		fireEvent(ureq, Event.CHANGED_EVENT);
 	}
 	
 	private boolean canBeNextLastSession() {
-		RepositoryEntry courseEntry = assessedUserCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
-		List<AssessmentTestSession> sessions = qtiService.getAssessmentTestSessions(courseEntry, courseNode.getIdent(),
-				assessedUserCourseEnv.getIdentityEnvironment().getIdentity(), true);
+		List<AssessmentTestSession> sessions;
+		if(courseNode == null) {
+			sessions = qtiService.getAssessmentTestSessions(testEntry, null, assessedIdentity, true);
+		} else {
+			RepositoryEntry courseEntry = assessedUserCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+			sessions = qtiService.getAssessmentTestSessions(courseEntry, courseNode.getIdent(), assessedIdentity, true);
+		}
 		if(sessions.isEmpty()) {
 			return true;
 		}
diff --git a/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java
index 2833cd00c4a628800e83bd20cd8aa7343d8425f3..4027ebb0bab484cf79ba2ad312ba76d5e5d0377f 100644
--- a/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java
@@ -87,8 +87,6 @@ import org.olat.ims.qti21.ui.assessment.CorrectionIdentityAssessmentItemListCont
 import org.olat.ims.qti21.ui.assessment.CorrectionOverviewModel;
 import org.olat.ims.qti21.ui.components.AssessmentTestSessionDetailsNumberRenderer;
 import org.olat.modules.ModuleConfiguration;
-import org.olat.modules.assessment.AssessmentEntry;
-import org.olat.modules.assessment.AssessmentService;
 import org.olat.modules.assessment.AssessmentToolOptions;
 import org.olat.modules.assessment.Role;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
@@ -156,8 +154,6 @@ public class QTI21AssessmentDetailsController extends FormBasicController {
 	protected QTI21Service qtiService;
 	@Autowired
 	private RepositoryManager repositoryManager;
-	@Autowired
-	private AssessmentService assessmentService;
 	
 	/**
 	 * The constructor used by the assessment tool of the course.
@@ -481,10 +477,7 @@ public class QTI21AssessmentDetailsController extends FormBasicController {
 	}
 	
 	private void doUpdateEntry(AssessmentTestSession session) {
-		AssessmentEntry assessmentEntry = assessmentService.loadAssessmentEntry(assessedIdentity, entry, null, entry);
-		assessmentEntry.setScore(session.getFinalScore());
-		assessmentEntry.setAssessmentId(session.getKey());
-		assessmentService.updateAssessmentEntry(assessmentEntry);
+		qtiService.updateAssessmentEntry(session);
 	}
 	
 	private void doResetData(UserRequest ureq) {
@@ -578,8 +571,13 @@ public class QTI21AssessmentDetailsController extends FormBasicController {
 		
 		AssessmentTestSession lastSession = tableModel.getLastTestSession();
 		boolean isLastSession = session.equals(lastSession);
-		invalidateConfirmationCtr = new ConfirmAssessmentTestSessionInvalidationController(ureq, getWindowControl(),
+		if(courseNode == null) {
+			invalidateConfirmationCtr = new ConfirmAssessmentTestSessionInvalidationController(ureq, getWindowControl(),
+				session, isLastSession, session.getTestEntry(), assessedIdentity);
+		} else {
+			invalidateConfirmationCtr = new ConfirmAssessmentTestSessionInvalidationController(ureq, getWindowControl(),
 				session, isLastSession, courseNode, assessedUserCourseEnv);
+		}
 		listenTo(invalidateConfirmationCtr);
 
 		String title = translate("invalidate.test.confirm.title");
@@ -592,8 +590,13 @@ public class QTI21AssessmentDetailsController extends FormBasicController {
 	private void confirmRevalidateTestSession(UserRequest ureq, AssessmentTestSession session) {
 		if(guardModalController(revalidateConfirmationCtr)) return;
 		
-		revalidateConfirmationCtr = new ConfirmAssessmentTestSessionRevalidationController(ureq, getWindowControl(),
+		if(courseNode == null) {
+			revalidateConfirmationCtr = new ConfirmAssessmentTestSessionRevalidationController(ureq, getWindowControl(),
+				session, entry, assessedIdentity);
+		} else {
+			revalidateConfirmationCtr = new ConfirmAssessmentTestSessionRevalidationController(ureq, getWindowControl(),
 				session, courseNode, assessedUserCourseEnv);
+		}
 		listenTo(revalidateConfirmationCtr);
 
 		String title = translate("revalidate.test.confirm.title");