Skip to content

Commit 55a424b

Browse files
committed
Add create test
1 parent 31a6bd1 commit 55a424b

File tree

5 files changed

+100
-2
lines changed

5 files changed

+100
-2
lines changed

apps/execution-service/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/go-chi/chi/v5 v5.1.0
99
github.com/go-chi/cors v1.2.1
1010
github.com/joho/godotenv v1.5.1
11+
github.com/rabbitmq/amqp091-go v1.10.0
1112
github.com/traefik/yaegi v0.16.1
1213
google.golang.org/api v0.203.0
1314
)
@@ -31,7 +32,6 @@ require (
3132
github.com/google/uuid v1.6.0 // indirect
3233
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
3334
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
34-
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
3535
go.opencensus.io v0.24.0 // indirect
3636
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
3737
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect

apps/execution-service/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHy
111111
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
112112
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
113113
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
114+
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
115+
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
114116
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
115117
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
116118
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package handlers
2+
3+
import (
4+
"cloud.google.com/go/firestore"
5+
"encoding/json"
6+
"execution-service/models"
7+
"execution-service/utils"
8+
"google.golang.org/api/iterator"
9+
"net/http"
10+
)
11+
12+
func (s *Service) CreateTest(w http.ResponseWriter, r *http.Request) {
13+
ctx := r.Context()
14+
15+
var test models.Test
16+
if err := utils.DecodeJSONBody(w, r, &test); err != nil {
17+
http.Error(w, err.Error(), http.StatusBadRequest)
18+
return
19+
}
20+
21+
// Basic validation for question title and question ID
22+
if test.QuestionDocRefId == "" || test.QuestionTitle == "" {
23+
http.Error(w, "QuestionDocRefId and QuestionTitle are required", http.StatusBadRequest)
24+
return
25+
}
26+
27+
// Automatically populate validation for input and output in test case
28+
test.InputValidation = utils.GetDefaultValidation()
29+
test.OutputValidation = utils.GetDefaultValidation()
30+
31+
// Validate test case format
32+
if _, err := utils.ValidateTestCaseFormat(test.VisibleTestCases, test.InputValidation,
33+
test.OutputValidation); err != nil {
34+
http.Error(w, err.Error(), http.StatusBadRequest)
35+
return
36+
}
37+
if _, err := utils.ValidateTestCaseFormat(test.HiddenTestCases, test.InputValidation,
38+
test.OutputValidation); err != nil {
39+
http.Error(w, err.Error(), http.StatusBadRequest)
40+
return
41+
}
42+
43+
// Save test to Firestore
44+
docRef, _, err := s.Client.Collection("tests").Add(ctx, map[string]interface{}{
45+
"questionDocRefId": test.QuestionDocRefId,
46+
"questionTitle": test.QuestionTitle,
47+
"visibleTestCases": test.VisibleTestCases,
48+
"hiddenTestCases": test.HiddenTestCases,
49+
"inputValidation": test.InputValidation,
50+
"outputValidation": test.OutputValidation,
51+
"createdAt": firestore.ServerTimestamp,
52+
"updatedAt": firestore.ServerTimestamp,
53+
})
54+
if err != nil {
55+
http.Error(w, err.Error(), http.StatusInternalServerError)
56+
return
57+
}
58+
59+
// Get data
60+
doc, err := docRef.Get(ctx)
61+
if err != nil {
62+
if err != iterator.Done {
63+
http.Error(w, "Test not found", http.StatusInternalServerError)
64+
return
65+
}
66+
http.Error(w, "Failed to get test", http.StatusInternalServerError)
67+
return
68+
}
69+
70+
// Map data
71+
if err := doc.DataTo(&test); err != nil {
72+
http.Error(w, err.Error(), http.StatusInternalServerError)
73+
return
74+
}
75+
76+
w.Header().Set("Content-Type", "application/json")
77+
w.WriteHeader(http.StatusCreated)
78+
json.NewEncoder(w).Encode(test)
79+
}
80+
81+
// Manual test cases
82+
83+
//curl -X POST http://localhost:8083/tests \
84+
//-H "Content-Type: application/json" \
85+
//-d '{
86+
//"questionDocRefId": "sampleDocRefId123",
87+
//"questionTitle": "Sample Question Title",
88+
//"visibleTestCases": "2\nhello\nolleh\nHannah\nhannaH",
89+
//"hiddenTestCases": "2\nHannah\nhannaH\nabcdefg\ngfedcba"
90+
//}'

apps/execution-service/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func registerRoutes(r *chi.Mux, service *handlers.Service) {
8383
// Re: CreateTest
8484
// Current: Unused, since testcases are populated via script
8585
// Future extension: can be created by admin
86-
//r.Post("/", service.CreateTest)
86+
r.Post("/", service.CreateTest)
8787
r.Post("/populate", service.PopulateTests)
8888

8989
r.Route("/{questionDocRefId}", func(r chi.Router) {

apps/execution-service/utils/populate.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,3 +673,9 @@ func validateInputOrOutput(inputOrOutput string) bool {
673673
}
674674
`, importCode.String(), functionBody)
675675
}
676+
677+
func GetDefaultValidation() string {
678+
return getPackagesAndFunction([]string{}, `
679+
return len(inputOrOutput) > 0
680+
`)
681+
}

0 commit comments

Comments
 (0)