diff --git a/internal/models/candidateList.go b/internal/models/candidateList.go
index cedac8b53a500f5b859fdba53ab005e95954f586..fffde7be56c6e7e16acfa866dc7e2c1b96c06974 100644
--- a/internal/models/candidateList.go
+++ b/internal/models/candidateList.go
@@ -116,7 +116,9 @@ func (d *DataHandler) deleteCandidateList(w http.ResponseWriter, r *http.Request
 			return
 		}
 
-		// TODO remove candidate in cascade
+		for _, candidate := range o.Candidates {
+			d.deleteCandidate(w, r, int(candidate.ID))
+		}
 
 		d.db.Delete(&o)
 	} else {
diff --git a/internal/models/round.go b/internal/models/round.go
index 9fac65a19101b3d0922232c9eabcebd1a6bc252b..545d0a7f3d2c3702fd7bde18772fc41fdc7a1ef3 100644
--- a/internal/models/round.go
+++ b/internal/models/round.go
@@ -125,6 +125,10 @@ func (d *DataHandler) deleteRound(w http.ResponseWriter, r *http.Request, id int
 			d.deleteDeskRound(deskRound)
 		}
 
+		for _, candidateList := range o.CandidateLists {
+			d.deleteCandidateList(w, r, int(candidateList.ID))
+		}
+
 		d.db.Delete(&o)
 	} else {
 		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go
index f9ab37b26e8feee291b6d6de7d836f4234121ba3..bb239f74b4b9591f9cae30829f00402831f06e78 100644
--- a/internal/rootmux/rootmux_test.go
+++ b/internal/rootmux/rootmux_test.go
@@ -56,9 +56,14 @@ func TestAll(t *testing.T) {
 	resetDataWithData(t)
 	appTests(t)
 	resetDataWithData(t)
-	deletionInCascadeTest(t)
+	deletionInCascadeGenericElectionTest(t)
+	resetDataWithData(t)
+	deletionInCascadeRoundTest(t)
+	resetDataWithData(t)
+	deletionInCascadePartyTest(t)
 	resetDataWithData(t)
 	removeRoundRemoveDeskRoundsTest(t)
+
 	resetData(t)
 	AdminTests(t)
 	resetDataWithData(t)
@@ -116,7 +121,7 @@ func appTests(t *testing.T) {
 	do("GET", "/Logout", noH, "", 200, "Logout OK")
 }
 
-func deletionInCascadeTest(t *testing.T) {
+func deletionInCascadeGenericElectionTest(t *testing.T) {
 
 	ts, do, _ := createTester(t)
 	defer ts.Close() // Close the tester
@@ -143,6 +148,51 @@ func deletionInCascadeTest(t *testing.T) {
 	do("GET", "/Logout", noH, "", 200, "Logout OK")
 }
 
+func deletionInCascadePartyTest(t *testing.T) {
+
+	ts, do, _ := createTester(t)
+	defer ts.Close() // Close the tester
+	tests := func() {
+		// Get the XSRF Token
+		response := do("GET", "/api/common/WhoAmI", noH, "", 200, "")
+		token := auth.TokenData{}
+		json.Unmarshal([]byte(response), &token)
+		// xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
+
+		// TODO check that Candidate and candidateLists are deleted in cascade on Party deletion.
+
+	}
+	// Do an OAuth2 login with an known admin
+	do("GET", "/OAuth2Login", noH, "", 200, "<!DOCTYPE html>")
+	tests()
+	// Try to logout (must pass)
+	do("GET", "/Logout", noH, "", 200, "Logout OK")
+}
+
+func deletionInCascadeRoundTest(t *testing.T) {
+
+	ts, do, _ := createTester(t)
+	defer ts.Close() // Close the tester
+	tests := func() {
+		// Get the XSRF Token
+		response := do("GET", "/api/common/WhoAmI", noH, "", 200, "")
+		token := auth.TokenData{}
+		json.Unmarshal([]byte(response), &token)
+		xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
+
+		// Test deletion in cascade for generic election
+		do("DELETE", "/api/Round/1", xsrfHeader, ``, 200, ``)
+		do("GET", "/api/CandidateList/1", xsrfHeader, ``, 404, `id is missing`)
+		do("GET", "/api/Candidate/1", xsrfHeader, ``, 404, `id is missing`)
+
+	}
+	// Do an OAuth2 login with an known admin
+	do("GET", "/OAuth2Login", noH, "", 200, "<!DOCTYPE html>")
+	tests()
+	// Try to logout (must pass)
+	do("GET", "/Logout", noH, "", 200, "Logout OK")
+}
+
 func removeRoundRemoveDeskRoundsTest(t *testing.T) {
 
 	ts, do, _ := createTester(t)