Skip to content

Commit b3e1d61

Browse files
committed
Add update test
1 parent 60966ab commit b3e1d61

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed

apps/execution-service/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,21 @@ curl -X POST http://localhost:8083/tests \
121121
}'
122122
```
123123

124+
`PUT /tests/{questionDocRefId}`
125+
126+
To update an existing test case from an existing question, run the following command:
127+
128+
```bash
129+
curl -X PUT http://localhost:8083/tests/{questionDocRefId} \
130+
-H "Content-Type: application/json" \
131+
-d '{
132+
"visibleTestCases": "2\nhello\nolleh\nHannah\nhannaH",
133+
"hiddenTestCases": "2\nHannah\nhannaH\nabcdefg\ngfedcba"
134+
}'
135+
```
136+
137+
```bash
138+
124139
`POST /tests/{questionDocRefId}/execute`
125140

126141
To execute test cases via a question ID without custom test cases, run the following command, with custom code and language:

apps/execution-service/handlers/create.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ func (s *Service) CreateTest(w http.ResponseWriter, r *http.Request) {
4040
return
4141
}
4242

43+
// Check if a test already exists for the question
44+
iter := s.Client.Collection("tests").Where("questionDocRefId", "==", test.QuestionDocRefId).Documents(ctx)
45+
for {
46+
_, err := iter.Next()
47+
if err == iterator.Done {
48+
break
49+
}
50+
if err != nil {
51+
http.Error(w, "Error fetching test", http.StatusInternalServerError)
52+
return
53+
}
54+
http.Error(w, "Test already exists for the question", http.StatusConflict)
55+
return
56+
}
57+
4358
// Save test to Firestore
4459
docRef, _, err := s.Client.Collection("tests").Add(ctx, map[string]interface{}{
4560
"questionDocRefId": test.QuestionDocRefId,
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package handlers
2+
3+
import (
4+
"cloud.google.com/go/firestore"
5+
"encoding/json"
6+
"execution-service/models"
7+
"execution-service/utils"
8+
"github.com/go-chi/chi/v5"
9+
"google.golang.org/api/iterator"
10+
"net/http"
11+
)
12+
13+
func (s *Service) UpdateTest(w http.ResponseWriter, r *http.Request) {
14+
ctx := r.Context()
15+
16+
// get param questionDocRefId
17+
questionDocRefId := chi.URLParam(r, "questionDocRefId")
18+
19+
var test models.Test
20+
if err := utils.DecodeJSONBody(w, r, &test); err != nil {
21+
http.Error(w, err.Error(), http.StatusBadRequest)
22+
return
23+
}
24+
25+
// Only test cases will be updated
26+
// Validate test case format with default validation
27+
if _, err := utils.ValidateTestCaseFormat(test.VisibleTestCases, utils.GetDefaultValidation(),
28+
utils.GetDefaultValidation()); err != nil {
29+
http.Error(w, err.Error(), http.StatusBadRequest)
30+
return
31+
}
32+
if _, err := utils.ValidateTestCaseFormat(test.HiddenTestCases, utils.GetDefaultValidation(),
33+
utils.GetDefaultValidation()); err != nil {
34+
http.Error(w, err.Error(), http.StatusBadRequest)
35+
return
36+
}
37+
38+
// Update test in Firestore
39+
docRef := s.Client.Collection("tests").Where("questionDocRefId", "==", questionDocRefId).Limit(1).Documents(ctx)
40+
doc, err := docRef.Next()
41+
if err != nil {
42+
if err == iterator.Done {
43+
http.Error(w, "Test not found", http.StatusNotFound)
44+
return
45+
}
46+
http.Error(w, err.Error(), http.StatusInternalServerError)
47+
return
48+
}
49+
defer docRef.Stop()
50+
51+
// Update database
52+
updates := []firestore.Update{
53+
{Path: "visibleTestCases", Value: test.VisibleTestCases},
54+
{Path: "hiddenTestCases", Value: test.HiddenTestCases},
55+
{Path: "updatedAt", Value: firestore.ServerTimestamp},
56+
}
57+
_, err = doc.Ref.Update(ctx, updates)
58+
if err != nil {
59+
http.Error(w, "Error updating test", http.StatusInternalServerError)
60+
return
61+
}
62+
63+
// Get data
64+
doc, err = doc.Ref.Get(ctx)
65+
if err != nil {
66+
if err != iterator.Done {
67+
http.Error(w, "Test not found", http.StatusNotFound)
68+
return
69+
}
70+
http.Error(w, "Failed to get test", http.StatusInternalServerError)
71+
return
72+
}
73+
74+
// Map data
75+
if err = doc.DataTo(&test); err != nil {
76+
http.Error(w, "Failed to map test data", http.StatusInternalServerError)
77+
return
78+
}
79+
80+
w.Header().Set("Content-Type", "application/json")
81+
w.WriteHeader(http.StatusOK)
82+
json.NewEncoder(w).Encode(test)
83+
}
84+
85+
// Manual test cases
86+
87+
//curl -X PUT http://localhost:8083/tests/sampleDocRefId123 \
88+
//-H "Content-Type: application/json" \
89+
//-d '{
90+
//"visibleTestCases": "2\nhello\nolleh\nHannah\nhannaH",
91+
//"hiddenTestCases": "2\nHannah\nhannaH\nabcdefg\ngfedcba"
92+
//}'

apps/execution-service/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func registerRoutes(r *chi.Mux, service *handlers.Service) {
9090
// Re: UpdateTest, DeleteTest
9191
// Current: Unused, since testcases are executed within service and not exposed
9292
// Future extension: can be read by admin to view testcases
93-
//r.Put("/", service.UpdateTest)
93+
r.Put("/", service.UpdateTest)
9494
//r.Delete("/", service.DeleteTest)
9595
r.Get("/", service.ReadVisibleTests)
9696
r.Post("/execute", service.ExecuteVisibleAndCustomTests)

0 commit comments

Comments
 (0)