Commit 7c246e6

Richard Luby <richluby@gmail.com>
2016-11-01 08:59:01
server now receives client tests
server receives client tests and responds with a status indicating success or failure
1 parent 47bac88
command.go
@@ -151,6 +151,7 @@ func executeTest(args []string) error {
 	if err != nil {
 		return fmt.Errorf("Error while requesting test from server: %+v", err)
 	}
+	clientTest.Username = clientConfig.USER
 	runTest(clientTest)
 	return postRecordsToServer(client, &clientTest)
 }
serverHandlers.go
@@ -31,11 +31,11 @@ func handleRequestForTest(writer http.ResponseWriter, request *http.Request) err
 }
 
 // writeTestFile writes the the data to the given writer for the specified username
-func writeTestFile(username string, data []byte) error {
+func writeTestFile(clientTest ClientTest, data []byte) error {
 	var err error
-	resultsFilePath := filepath.Join(serverConfig.USER_TESTS, username)
+	resultsFilePath := filepath.Join(serverConfig.USER_TESTS, clientTest.Username)
 	if err = os.MkdirAll(resultsFilePath, 0700); err != nil {
-		log.Printf("Could not create test directory for user %s: %+v", username, err)
+		log.Printf("Could not create test directory for user %s: %+v", clientTest.Username, err)
 		return err
 	}
 	id := fmt.Sprintf("%05d", rand.Intn(99999)) // generate random 5-digit id
@@ -49,29 +49,45 @@ func writeTestFile(username string, data []byte) error {
 	return err
 }
 
+// validateScore verifies that the user test score is valid
+// if not, the score is recalculated using integer math
+func validateScore(clientTest *ClientTest) {
+	if clientTest.Score < 0 || clientTest.Score > 100 {
+		clientTest.Score = 0
+		for _, record := range clientTest.Records {
+			if record.AnsweredCorrectly == true {
+				clientTest.Score++
+			}
+		}
+		clientTest.Score = 1.0 * clientTest.Score / len(clientTest.Records) * 100
+	}
+}
+
 // handlePostingTest receives a client's test results, and then stores them
 func handlePostingTest(writer http.ResponseWriter, request *http.Request) error {
 	if request.URL.Path != handlers[API_ROOT+"/test"].Request {
 		return fmt.Errorf("Incorrectly formatted URL path: %+v", request.URL.Path)
 	}
-	username := request.FormValue("username")
-	var clientResponseRecord ClientTest
+	var clientTest ClientTest
 	data, err := ioutil.ReadAll(request.Body)
 	if err != nil {
 		http.Error(writer, "Could not read the test record.", http.StatusBadRequest)
-		return fmt.Errorf("Error for user %s while reading test: %+v", username, err)
+		return fmt.Errorf("Error for connection %s while reading test: %+v", request.RemoteAddr, err)
 	}
 	// check to make sure properly formatted client response
-	err = json.Unmarshal(data, &clientResponseRecord)
+	err = json.Unmarshal(data, &clientTest)
 	if err != nil {
 		http.Error(writer, "Could not parse the test record.", http.StatusBadRequest)
-		return fmt.Errorf("Error for user %s while parsing test: %+v", username, err)
+		return fmt.Errorf("Error for user %s while parsing test: %+v", clientTest.Username, err)
 	}
-	log.Printf("Received test from user: %s at %s\tvia %s", username, request.RemoteAddr, request.UserAgent())
-	fmt.Fprint(writer, "Test received successfully.")
-	if err = writeTestFile(username, data); err != nil {
+	log.Printf("Received test from user: %s at %s\tvia %s", clientTest.Username, request.RemoteAddr, request.UserAgent())
+	validateScore(&clientTest)
+	if err = writeTestFile(clientTest, data); err != nil {
 		http.Error(writer, "Could not save the test record.", http.StatusInternalServerError)
-		return fmt.Errorf("Error for user %s while writing test: %+v", username, err)
+		return fmt.Errorf("Error for user %s while writing test: %+v", clientTest.Username, err)
+	} else {
+		writer.WriteHeader(http.StatusCreated)
+		fmt.Fprint(writer, "Test received successfully.")
 	}
 	return err
 }