diff --git a/internal/models/models.go b/internal/models/models.go
index b5fb2d6f4403ec70c9325a0207d3eaba8f24dfdf..2a480833836204ee1a199eb7e0bb09296f02c8b0 100644
--- a/internal/models/models.go
+++ b/internal/models/models.go
@@ -35,6 +35,12 @@ const ErrorNotAuthorizeMethodOnRessource = "You're not authorize to execute this
 // ErrorParentNotFound = "Could not get the parent associated to the object" with 500 http.StatusInternalServerError
 const ErrorParentNotFound = "Could not get the parent associated to the object"
 
+// ErrorValidateVote = "Error in the process to validate a vote" with 500 http.StatusInternalServerError
+const ErrorValidateVote = "Error in the process to validate a vote"
+
+// ErrorVoteExist = "Error the vote have already been captured" with 500 http.StatusInternalServerError
+const ErrorVoteExist = "Error the vote have already been captured"
+
 // Election represent an election divided in areas with 1 or several rounds
 type Election struct {
 	ID         uint       `gorm:"primary_key"`
@@ -187,7 +193,7 @@ type Vote struct {
 	CandidateListID uint
 	VoiceNumber     uint
 	Blank           bool
-	Null            bool
+	NullVote        bool
 }
 
 // NewDataHandler init a DataHandler and returns a pointer to it
@@ -240,6 +246,8 @@ func (d *DataHandler) ProcessAPI(w http.ResponseWriter, r *http.Request) {
 		d.handleCandidateList(w, r)
 	case "Candidate":
 		d.handleCandidate(w, r)
+	case "Vote":
+		d.handleVote(w, r)
 	}
 
 }
diff --git a/internal/models/vote.go b/internal/models/vote.go
new file mode 100644
index 0000000000000000000000000000000000000000..1d504aa909009c4b5cbc090e6d6351b68550c35c
--- /dev/null
+++ b/internal/models/vote.go
@@ -0,0 +1,193 @@
+package models
+
+import (
+	"encoding/json"
+	"errors"
+	"net/http"
+	"strconv"
+	"strings"
+	"time"
+
+	"forge.grandlyon.com/apoyen/elections/internal/auth"
+	"github.com/jinzhu/gorm"
+)
+
+func (d *DataHandler) handleVote(w http.ResponseWriter, r *http.Request) {
+	id, _ := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/api/Vote/"))
+	switch method := r.Method; method {
+	case "GET":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN", "CAPTURER", "VISUALIZER":
+			d.getVote(w, r)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	case "POST":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN", "CAPTURER":
+			d.postVote(w, r)
+		case "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+
+	case "PUT":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN", "CAPTURER":
+			d.putVote(w, r, id)
+		case "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	case "DELETE":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN", "CAPTURER":
+			d.deleteVote(w, r, id)
+		case "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	default:
+		http.Error(w, "method not allowed", 400)
+	}
+}
+
+func (d *DataHandler) getVote(w http.ResponseWriter, r *http.Request) {
+	var o []Vote
+	d.db.Find(&o)
+	json.NewEncoder(w).Encode(o)
+}
+
+func (d *DataHandler) postVote(w http.ResponseWriter, r *http.Request) {
+	var o Vote
+	err := json.NewDecoder(r.Body).Decode(&o)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	var voteFound Vote
+	if o.Blank {
+		d.db.First(&voteFound, "desk_round_id = ? AND blank = ?", o.DeskRoundID, o.Blank)
+		if voteFound.ID != 0 {
+			http.Error(w, ErrorVoteExist, http.StatusInternalServerError)
+			return
+		}
+	} else if o.NullVote {
+		d.db.First(&voteFound, "desk_round_id = ? AND null_vote = ?", o.DeskRoundID, o.NullVote)
+		if voteFound.ID != 0 {
+			http.Error(w, ErrorVoteExist, http.StatusInternalServerError)
+			return
+		}
+	} else {
+		d.db.First(&voteFound, "desk_round_id = ? AND candidate_list_id = ?", o.DeskRoundID, o.CandidateListID)
+		if voteFound.ID != 0 {
+			http.Error(w, ErrorVoteExist, http.StatusInternalServerError)
+			return
+		}
+	}
+
+	if !o.Blank && !o.NullVote {
+		// Check that CandidateListID exist
+		var candidateList CandidateList
+		if err := d.db.First(&candidateList, o.CandidateListID).Error; err != nil {
+			http.Error(w, ErrorParentNotFound, http.StatusInternalServerError)
+			return
+		}
+	}
+
+	// Check that deskRound exist
+	var deskRound DeskRound
+	if err := d.db.Preload("Votes").First(&deskRound, o.DeskRoundID).Error; err != nil {
+		http.Error(w, ErrorParentNotFound, http.StatusInternalServerError)
+		return
+	}
+
+	d.db.Create(&o)
+	d.db.Last(&o)
+	json.NewEncoder(w).Encode(o)
+
+}
+
+func (d *DataHandler) putVote(w http.ResponseWriter, r *http.Request, id int) {
+	var o Vote
+	if err := d.db.First(&o, id).Error; err != nil {
+		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+		return
+	}
+	var vote Vote
+	err := json.NewDecoder(r.Body).Decode(&vote)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	// check that objects are the same
+	if o.CandidateListID != vote.CandidateListID || o.DeskRoundID != vote.DeskRoundID {
+		http.Error(w, "Les objets ne correspondent pas", http.StatusInternalServerError)
+		return
+	}
+	o.VoiceNumber = vote.VoiceNumber
+	d.db.Save(&o)
+	json.NewEncoder(w).Encode(o)
+
+}
+
+func (d *DataHandler) deleteVote(w http.ResponseWriter, r *http.Request, id int) {
+	if id != 0 {
+		var o Vote
+		if err := d.db.First(&o, id).Error; err != nil {
+			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+			return
+		}
+		d.db.Delete(&o)
+	} else {
+		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+	}
+}
+
+func (vote *Vote) AfterSave(scope *gorm.Scope) error {
+	var deskRound DeskRound
+	if err := scope.DB().First(&deskRound, vote.DeskRoundID).Error; err != nil {
+		return errors.New(ErrorValidateVote)
+	}
+
+	// Check deskCompletion
+	var desk Desk
+	if err := scope.DB().First(&desk, deskRound.DeskID).Error; err != nil {
+		return errors.New(ErrorValidateVote)
+	}
+	var section Section
+	if err := scope.DB().First(&section, desk.SectionID).Error; err != nil {
+		return errors.New(ErrorValidateVote)
+	}
+	var area Area
+	if err := scope.DB().First(&area, section.AreaID).Error; err != nil {
+		return errors.New(ErrorValidateVote)
+	}
+	var round Round
+	if err := scope.DB().First(&round, deskRound.RoundID).Error; err != nil {
+		return errors.New(ErrorValidateVote)
+	}
+
+	var candidateLists []CandidateList
+	if err := scope.DB().Where("area_id = ? and round_id = ?", area.ID, round.ID).Find(&candidateLists).Error; err != nil {
+		return errors.New(ErrorValidateVote)
+	}
+	var listNumberPerArea = len(candidateLists)
+
+	var votes []Vote
+	if err := scope.DB().Where("desk_round_id = ?", deskRound.ID).Find(&votes).Error; err != nil {
+		return errors.New(ErrorValidateVote)
+	}
+	var votesNumberPerDesk = len(votes)
+
+	if votesNumberPerDesk == (listNumberPerArea + 2) {
+		deskRound.Completed = true
+		deskRound.DateCompletion = time.Now()
+		scope.DB().Save(&deskRound)
+	}
+	return nil
+}
diff --git a/internal/rootmux/admin_test.go b/internal/rootmux/admin_test.go
index 5478c7efdc1ac7c3a5ca2e04cf44382e94c6051b..0da5abb840d71b9a14bf1f33566c99f90961f409 100644
--- a/internal/rootmux/admin_test.go
+++ b/internal/rootmux/admin_test.go
@@ -119,8 +119,17 @@ func AdminTests(t *testing.T) {
 		// Update a Candidate
 		do("PUT", "/api/Candidate/1", xsrfHeader, `{"ID":1,"CandidateListID":1,"FullName":"CandidateTest","Rank":2,"CommunityCounseller":false,"Birthdate":"2020-02-28","PotentialIncompatibility":true,"Refused":false,"Removed":false}`, 200, `{"ID":1,"CandidateListID":1,"FullName":"CandidateTest","Rank":2,"CommunityCounseller":false,"Birthdate":"2020-02-28","PotentialIncompatibility":true,"Refused":false,"Removed":false}`)
 
+		// Create a Vote
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158}`, 200, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}`)
+		// Get Votes
+		do("GET", "/api/Vote/", xsrfHeader, ``, 200, `[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]`)
+		// Update a Vote
+		do("PUT", "/api/Vote/1", xsrfHeader, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":true}`, 200, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":false}`)
+
 		// TODO Update a DeskRound to Validated=true can only be done when votes are captured
 
+		// Delete a Vote
+		do("DELETE", "/api/Vote/1", xsrfHeader, ``, 200, ``)
 		// Delete a Candidate
 		do("DELETE", "/api/Candidate/1", xsrfHeader, ``, 200, ``)
 		// Delete a CandidateList
diff --git a/internal/rootmux/capturer_test.go b/internal/rootmux/capturer_test.go
index 6f6cc1b9bd21491fc5168e0d303c252d82661e05..ecf9d899eee8d6d29724d67051811a056f80be3f 100644
--- a/internal/rootmux/capturer_test.go
+++ b/internal/rootmux/capturer_test.go
@@ -93,9 +93,9 @@ func CapturerTests(t *testing.T) {
 		// Create a DeskRound should fail with 400
 		do("POST", "/api/DeskRound", xsrfHeader, `{"ID":1,"RoundID":1,"DeskID":1,"Validated":false}`, 400, `method not allowed`)
 		// Get a DeskRound
-		do("GET", "/api/DeskRound/1", xsrfHeader, ``, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[]}`)
+		do("GET", "/api/DeskRound/1", xsrfHeader, ``, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}`)
 		// Get DeskRounds
-		do("GET", "/api/DeskRound/", xsrfHeader, ``, 200, `[{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[]}]`)
+		do("GET", "/api/DeskRound/", xsrfHeader, ``, 200, `[{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}]`)
 		// Update a desk should fail with 405
 		do("PUT", "/api/DeskRound/1", xsrfHeader, `{"ID":1,"RoundID":1,"DeskID":1,"Validated":false}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Delete a DeskRound should fail with 400
@@ -115,9 +115,9 @@ func CapturerTests(t *testing.T) {
 		// Create a CandidateList should fail with 405
 		do("POST", "/api/CandidateList", xsrfHeader, `{"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Get a candidateList
-		do("GET", "/api/CandidateList/1", xsrfHeader, "", 200, `{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[]}`)
+		do("GET", "/api/CandidateList/1", xsrfHeader, "", 200, `{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}`)
 		// Get all the parties
-		do("GET", "/api/CandidateList/", xsrfHeader, "", 200, `[{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[]}]`)
+		do("GET", "/api/CandidateList/", xsrfHeader, "", 200, `[{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}]`)
 		// Update a CandidateList should fail with 405
 		do("PUT", "/api/CandidateList/1", xsrfHeader, `{"ID":1,"Name":"MyBigList","PartyID":1,"RoundID":1,"AreaID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Delete a CandidateList should fail with 405
@@ -134,6 +134,13 @@ func CapturerTests(t *testing.T) {
 		// Delete a Candidate should fail with 405
 		do("DELETE", "/api/Candidate/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`)
 
+		// Create a Vote
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":3,"Blank":true}`, 200, `{"ID":2,"DeskRoundID":1,"CandidateListID":0,"VoiceNumber":3,"Blank":true,"NullVote":false}`)
+		// Get Votes
+		do("GET", "/api/Vote/", xsrfHeader, ``, 200, `[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false},{"ID":2,"DeskRoundID":1,"CandidateListID":0,"VoiceNumber":3,"Blank":true,"NullVote":false}]`)
+		// Update a Vote
+		do("PUT", "/api/Vote/1", xsrfHeader, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":false}`, 200, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":false}`)
+
 		// Add deskround to capturer should fail with 405
 		do("POST", "/api/CapturerDeskRound", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Remove DeskRound to capturer
diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go
index 15c76d1f9678ca2823d1ddd967fddee2f1ae8a81..6e0e9df93e2ccf02128e056f7e37cb95456e020f 100644
--- a/internal/rootmux/rootmux_test.go
+++ b/internal/rootmux/rootmux_test.go
@@ -106,10 +106,23 @@ func appTests(t *testing.T) {
 		// Verify that a DeskRound can't be validated witout being completed
 		do("PUT", "/api/DeskRound/1", xsrfHeader, `{"ID":1,"Validated":true}`, 500, `Le bureau doit être complété avant de le valider`)
 
-		// TODO After capturing all votes for a DeskRound, it should be mark as completed
+		// Verify that you can't update a Vote if it's not the same
+		do("PUT", "/api/Vote/1", xsrfHeader, `{"ID":1,"DeskRoundID":2,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":true}`, 500, `Les objets ne correspondent pas`)
+		do("PUT", "/api/Vote/1", xsrfHeader, `{"ID":1,"DeskRoundID":2,"CandidateListID":2,"VoiceNumber":258,"Blank":false,"NullVote":true}`, 500, `Les objets ne correspondent pas`)
+		do("PUT", "/api/Vote/1", xsrfHeader, `{"ID":1,"DeskRoundID":1,"CandidateListID":2,"VoiceNumber":258,"Blank":false,"NullVote":true}`, 500, `Les objets ne correspondent pas`)
+
+		// Create Votes to complete a Desk
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":3,"Blank":true}`, 200, `{"ID":2,"DeskRoundID":1,"CandidateListID":0,"VoiceNumber":3,"Blank":true,"NullVote":false}`)
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":5,"NullVote":true}`, 200, `{"ID":3,"DeskRoundID":1,"CandidateListID":0,"VoiceNumber":5,"Blank":false,"NullVote":true}`)
+		do("GET", "/api/DeskRound/1", xsrfHeader, ``, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":true,"DateCompletion":"20`)
+
+		// Can't add the same vote several time
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158}`, 500, `Error the vote have already been captured`)
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":3,"Blank":true}`, 500, `Error the vote have already been captured`)
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":5,"NullVote":true}`, 500, `Error the vote have already been captured`)
 
 		// Verify that on Desk deletion deskRounds are deleted
-		do("GET", "/api/Desk/1", xsrfHeader, ``, 200, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587,"DeskRounds":[{"ID":1,"RoundID":1,"DeskID":1,"Capturers":null,"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":null}]}`)
+		do("GET", "/api/Desk/1", xsrfHeader, ``, 200, `{"ID":1,"SectionID":1,"Name":"Desk 1","WitnessDesk":true,"Subscribed":9587,"DeskRounds":[{"ID":1,"RoundID":1,"DeskID":1,"Capturers":null,"Completed":true,"DateCompletion":"20`)
 		do("DELETE", "/api/Desk/1", xsrfHeader, ``, 200, ``)
 		do("GET", "/api/DeskRound/1", xsrfHeader, ``, 404, `id is missing`)
 
@@ -274,6 +287,7 @@ func resetDataWithData(t *testing.T) {
 		do("POST", "/api/Party", xsrfHeader, `{"Name":"MyGreatParty","Color":"#FFFFFF"}`, 200, `{"ID":1,"Name":"MyGreatParty","Color":"#FFFFFF","CandidateLists":null}`)
 		do("POST", "/api/CandidateList", xsrfHeader, `{"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1}`, 200, `{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":null,"Votes":null}`)
 		do("POST", "/api/Candidate", xsrfHeader, `{"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}`, 200, `{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}`)
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158}`, 200, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}`)
 	}
 	do("POST", "/Login", noH, `{"login": "admin","password": "password"}`, 200, "")
 	init()
diff --git a/internal/rootmux/visualizer_test.go b/internal/rootmux/visualizer_test.go
index 6976b1401f82d16ce72183480490e83147211a11..dc71bd3b5698c212a6db4df4e960f80d4caf685f 100644
--- a/internal/rootmux/visualizer_test.go
+++ b/internal/rootmux/visualizer_test.go
@@ -80,9 +80,9 @@ func VisualizerTests(t *testing.T) {
 		// Create a DeskRound should fail with 400
 		do("POST", "/api/DeskRound", xsrfHeader, `{"ID":1,"RoundID":1,"DeskID":1,"Validated":false}`, 400, `method not allowed`)
 		// Get a DeskRound
-		do("GET", "/api/DeskRound/1", xsrfHeader, ``, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[]}`)
+		do("GET", "/api/DeskRound/1", xsrfHeader, ``, 200, `{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}`)
 		// Get DeskRounds
-		do("GET", "/api/DeskRound/", xsrfHeader, ``, 200, `[{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[]}]`)
+		do("GET", "/api/DeskRound/", xsrfHeader, ``, 200, `[{"ID":1,"RoundID":1,"DeskID":1,"Capturers":[],"Completed":false,"DateCompletion":"0001-01-01T00:00:00Z","Validated":false,"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}]`)
 		// Update a desk should fail with 405
 		do("PUT", "/api/DeskRound/1", xsrfHeader, `{"ID":1,"RoundID":1,"DeskID":1,"Validated":false}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Delete a DeskRound should fail with 400
@@ -102,9 +102,9 @@ func VisualizerTests(t *testing.T) {
 		// Create a CandidateList should fail with 405
 		do("POST", "/api/CandidateList", xsrfHeader, `{"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Get a candidateList
-		do("GET", "/api/CandidateList/1", xsrfHeader, "", 200, `{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[]}`)
+		do("GET", "/api/CandidateList/1", xsrfHeader, "", 200, `{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}`)
 		// Get all the parties
-		do("GET", "/api/CandidateList/", xsrfHeader, "", 200, `[{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[]}]`)
+		do("GET", "/api/CandidateList/", xsrfHeader, "", 200, `[{"ID":1,"Name":"MyGreatList","PartyID":1,"RoundID":1,"AreaID":1,"Candidates":[{"ID":1,"CandidateListID":1,"FullName":"Candidate","Rank":1,"CommunityCounseller":true,"Birthdate":"2020-06-28","PotentialIncompatibility":false,"Refused":false,"Removed":false}],"Votes":[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]}]`)
 		// Update a CandidateList should fail with 405
 		do("PUT", "/api/CandidateList/1", xsrfHeader, `{"ID":1,"Name":"MyBigList","PartyID":1,"RoundID":1,"AreaID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Delete a CandidateList should fail with 405
@@ -121,6 +121,15 @@ func VisualizerTests(t *testing.T) {
 		// Delete a Candidate should fail with 405
 		do("DELETE", "/api/Candidate/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`)
 
+		// Create a Vote should fail with 405
+		do("POST", "/api/Vote", xsrfHeader, `{"DeskRoundID":1,"CandidateListID":null,"VoiceNumber":3,"Blank":true}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Get all the votes
+		do("GET", "/api/Vote/", xsrfHeader, "", 200, `[{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":158,"Blank":false,"NullVote":false}]`)
+		// Update a Vote should fail with 405
+		do("PUT", "/api/Vote/1", xsrfHeader, `{"ID":1,"DeskRoundID":1,"CandidateListID":1,"VoiceNumber":258,"Blank":false,"NullVote":false}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Delete a Candidate should fail with 405
+		do("DELETE", "/api/Vote/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`)
+
 		// Add deskround to capturer should fail with 405
 		do("POST", "/api/CapturerDeskRound", xsrfHeader, `{"CapturerID":1,"DeskRoundID":1}`, 405, `You're not authorize to execute this method on this ressource.`)
 		// Remove DeskRound to capturer