test http POST api/questions/QID/answers
parent
c76da12b1a
commit
7a464c2f09
34
http.go
34
http.go
|
|
@ -7,7 +7,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -17,6 +20,9 @@ type Context struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func HTTP(port int, db DB) error {
|
func HTTP(port int, db DB) error {
|
||||||
|
ctx, can := signal.NotifyContext(context.Background(), syscall.SIGINT)
|
||||||
|
defer can()
|
||||||
|
|
||||||
foo := func(w http.ResponseWriter, r *http.Request) {
|
foo := func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.URL.Path == "/" {
|
if r.URL.Path == "/" {
|
||||||
httpGUI(w, r)
|
httpGUI(w, r)
|
||||||
|
|
@ -28,7 +34,12 @@ func HTTP(port int, db DB) error {
|
||||||
}
|
}
|
||||||
foo = withAuth(foo)
|
foo = withAuth(foo)
|
||||||
foo = withDB(foo, db)
|
foo = withDB(foo, db)
|
||||||
return http.ListenAndServe(fmt.Sprintf(":%d", port), http.HandlerFunc(foo))
|
foo = withCtx(foo, ctx)
|
||||||
|
go func() {
|
||||||
|
http.ListenAndServe(fmt.Sprintf(":%d", port), http.HandlerFunc(foo))
|
||||||
|
}()
|
||||||
|
<-ctx.Done()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extract(ctx context.Context) Context {
|
func extract(ctx context.Context) Context {
|
||||||
|
|
@ -41,6 +52,13 @@ func inject(ctx context.Context, v Context) context.Context {
|
||||||
return context.WithValue(ctx, "__context", v)
|
return context.WithValue(ctx, "__context", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withCtx(foo http.HandlerFunc, ctx context.Context) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
foo(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func withDB(foo http.HandlerFunc, db DB) http.HandlerFunc {
|
func withDB(foo http.HandlerFunc, db DB) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
c := extract(r.Context())
|
c := extract(r.Context())
|
||||||
|
|
@ -100,4 +118,18 @@ func httpAssignments(ctx context.Context) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func httpPostQuestionAnswers(w http.ResponseWriter, r *http.Request) {
|
func httpPostQuestionAnswers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
idq := IDQ(path.Base(strings.Split(r.URL.Path, "/answers")[0]))
|
||||||
|
var payload struct {
|
||||||
|
Answer string `json:"answer"`
|
||||||
|
Passed bool `json:"passed"`
|
||||||
|
}
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx := extract(r.Context())
|
||||||
|
if err := ctx.DB.PushAnswer(ctx.User, idq, Renderable(payload.Answer), payload.Passed); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHTTPPostQuestionAnswers(t *testing.T) {
|
||||||
|
p := path.Join(t.TempDir(), "db.yaml")
|
||||||
|
os.WriteFile(p, []byte("{}"), os.ModePerm)
|
||||||
|
db, err := newYamlDB(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
r := httptest.NewRequest(
|
||||||
|
http.MethodPost,
|
||||||
|
"/api/questions/QID/answers",
|
||||||
|
strings.NewReader(`{"answer":"a", "passed": false}`),
|
||||||
|
)
|
||||||
|
r.SetBasicAuth("u", "")
|
||||||
|
|
||||||
|
withAuth(withDB(httpPostQuestionAnswers, db))(w, r)
|
||||||
|
|
||||||
|
if w.Code != http.StatusOK {
|
||||||
|
t.Error(w.Code)
|
||||||
|
}
|
||||||
|
t.Logf("response: %s", w.Body.Bytes())
|
||||||
|
|
||||||
|
_, got := db.LastAnswer("u", "QID")
|
||||||
|
if got == (Answer{}) {
|
||||||
|
t.Error("no answer pushed:", got)
|
||||||
|
}
|
||||||
|
t.Logf("answer pushed: %+v", got)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue