test http POST api/questions/QID/answers
parent
c76da12b1a
commit
7a464c2f09
34
http.go
34
http.go
|
|
@ -7,7 +7,10 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -17,6 +20,9 @@ type Context struct {
|
|||
}
|
||||
|
||||
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) {
|
||||
if r.URL.Path == "/" {
|
||||
httpGUI(w, r)
|
||||
|
|
@ -28,7 +34,12 @@ func HTTP(port int, db DB) error {
|
|||
}
|
||||
foo = withAuth(foo)
|
||||
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 {
|
||||
|
|
@ -41,6 +52,13 @@ func inject(ctx context.Context, v Context) context.Context {
|
|||
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 {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
c := extract(r.Context())
|
||||
|
|
@ -100,4 +118,18 @@ func httpAssignments(ctx context.Context) (interface{}, error) {
|
|||
}
|
||||
|
||||
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