diff --git a/cmd/server/main.go b/cmd/server/main.go index 3a59f39..bbf479b 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -34,7 +34,7 @@ type Handler struct { type DB interface { GetQuestion(string) (Question, error) - PutAnswer(string, Answer) error + PutAnswer(string, string, Answer) error GetAnswers(string) ([]Answer, error) } @@ -174,8 +174,8 @@ func (h Handler) handle(session Session, w http.ResponseWriter, r *http.Request) } func (h Handler) handleAPIV1Question(session Session, w http.ResponseWriter, r *http.Request) error { - id := path.Base(r.URL.Path) - q, err := h.db.GetQuestion(id) + qid := path.Base(r.URL.Path) + q, err := h.db.GetQuestion(qid) if err != nil { return err } @@ -187,11 +187,31 @@ func (h Handler) handleAPIV1Questions(session Session, w http.ResponseWriter, r } func (h Handler) handleAPIV1Answers(session Session, w http.ResponseWriter, r *http.Request) error { + switch r.Method { + case http.MethodGet: + return h.handleAPIV1AnswersGet(session, w, r) + case http.MethodPost: + return h.handleAPIV1AnswersPost(session, w, r) + } + http.NotFound(w, r) + return nil +} + +func (h Handler) handleAPIV1AnswersGet(session Session, w http.ResponseWriter, r *http.Request) error { + qid := path.Base(r.URL.Path) + as, err := h.db.GetAnswers(qid) + if err != nil { + return err + } + return json.NewEncoder(w).Encode(as) +} + +func (h Handler) handleAPIV1AnswersPost(session Session, w http.ResponseWriter, r *http.Request) error { return errors.New("not impl") } -func (db fsDB) GetQuestion(id string) (Question, error) { - p := db.path(id) +func (db fsDB) GetQuestion(qid string) (Question, error) { + p := db.path(qid) b, err := os.ReadFile(p) if err != nil { return Question{}, err @@ -204,12 +224,35 @@ func (db fsDB) GetQuestion(id string) (Question, error) { return q, nil } -func (db fsDB) PutAnswer(id string, a Answer) error { - return errors.New("not impl") +func (db fsDB) PutAnswer(qid, uid string, a Answer) error { + p := path.Join(db.path(qid)+".d", uid) + os.MkdirAll(path.Dir(p), os.ModePerm) + b, err := json.Marshal(a) + if err != nil { + return err + } + return os.WriteFile(p, b, os.ModePerm) } -func (db fsDB) GetAnswers(id string) ([]Answer, error) { - return nil, errors.New("not impl") +func (db fsDB) GetAnswers(qid string) ([]Answer, error) { + p := db.path(qid) + ".d" + entries, err := os.ReadDir(p) + if err != nil { + return nil, err + } + results := []Answer{} + for _, entry := range entries { + b, err := os.ReadFile(entry.Name()) + if err != nil { + return nil, err + } + var a Answer + if err := json.Unmarshal(b, &a); err != nil { + return nil, err + } + results = append(results, a) + } + return results, nil } func (db fsDB) path(q string) string { diff --git a/cmd/server/main_test.go b/cmd/server/main_test.go index 5018f67..43cf210 100644 --- a/cmd/server/main_test.go +++ b/cmd/server/main_test.go @@ -81,7 +81,7 @@ func TestRunHTTP(t *testing.T) { t.Errorf("not impl: %s", w.Body.Bytes()) }) - t.Run("/api/v1/answers", func(t *testing.T) { + t.Run("GET /api/v1/answers", func(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/api/v1/answers", nil) r.SetBasicAuth("b", "b") w := httptest.NewRecorder() @@ -93,6 +93,19 @@ func TestRunHTTP(t *testing.T) { } t.Errorf("not impl: %s", w.Body.Bytes()) }) + + t.Run("POST /api/v1/answers", func(t *testing.T) { + r := httptest.NewRequest(http.MethodPost, "/api/v1/answers", nil) + r.SetBasicAuth("b", "b") + w := httptest.NewRecorder() + t.Logf("%s %s", r.Method, r.URL) + h.ServeHTTP(w, r) + t.Logf("(%d) %s", w.Code, w.Body.Bytes()) + if w.Code != http.StatusNotFound { + t.Error(w.Code) + } + t.Errorf("not impl: %s", w.Body.Bytes()) + }) } func TestPublic(t *testing.T) {