// parseSelectedTags parses url for selected tags and redirects if it refers to missing tags func parseSelectedTags(w http.ResponseWriter, r *http.Request, notebook *tessernote.Notebook, c appengine.Context) ([]tessernote.Tag, error) { var names []string if r.URL.Path != "/" && r.URL.Path != untaggedURL { names = strings.Split(r.URL.Path[1:], tagSeparator) } tags, err := notebook.TagsFrom(names, c) if err != nil { names = tessernote.Name(tags) tagString := strings.Join(names, tagSeparator) http.Redirect(w, r, "/"+tagString, http.StatusFound) } return tags, err }
// GetAllNotes writes a JSON formatted list of all Note IDs in the authorized User's Notebook to w. func GetAllNotes(w http.ResponseWriter, c appengine.Context, notebook *tessernote.Notebook) { notes, err := notebook.Notes(c) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } reply, err := json.Marshal(notes) if err != nil { c.Errorf("marshaling notes (%d): %s", len(notes), err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(reply) }
func TestCreateNote(t *testing.T) { note := tessernote.Note{Body: "body"} bytes, err := json.Marshal(note) if err != nil { t.Fatal(err) } w := httptest.NewRecorder() r, err := http.NewRequest("POST", "https://tessernote.appspot.com"+NotesURL, strings.NewReader(string(bytes))) if err != nil { t.Fatal(err) } // create a test notebook notebook := new(tessernote.Notebook) c, err := appenginetesting.NewContext(nil) defer c.Close() if err != nil { t.Fatal(err) } key := datastore.NewIncompleteKey(c, "Notebook", nil) key, err = datastore.Put(c, key, notebook) if err != nil { t.Fatal(err) } notebook.ID = key.Encode() CreateNote(w, r, c, notebook) // check note was added notes, err := notebook.Notes(c) if err != nil { t.Fatal(err) } if len(notes) != 1 { t.Fatalf("expected=%d actual=%d", 1, len(notes)) } if notes[0].Body != note.Body { t.Fatalf("expected=%s actual=%s", notes[0].Body, note.Body) } // check response ID is the same response := []byte(w.Body.String()) err = json.Unmarshal(response, note) if err != nil { t.Fatal(err, string(response)) } if notes[0].ID != note.ID { t.Fatalf("expected=%s actual=%s", notes[0].ID, note.ID) } }
// DeleteNote deletes a Note by the ID in the URL. Uses w to write true if the Note was deleted, false // if it never existed. func DeleteNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) { id := r.URL.Path[len(NotesURL):] deleted, err := notebook.Delete(id, c) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } reply, err := json.Marshal(deleted) if err != nil { c.Errorf("marshaling delete response (%t): %s", deleted, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(reply) }
// GetNote retrieves a note from the authorized User's Notebook by ID. The Note is written in JSON format to w. func GetNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) { id := r.URL.Path[len(NotesURL):] note, err := notebook.Note(id, c) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } reply, err := json.Marshal(note) if err != nil { c.Errorf("marshaling note (%#v): %s", note, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(reply) }
// DeleteAllNotes deletes all Notes from the authorized User's Notebook. It writes true if Notes were deleted, // and false if the Notebook was empty to w. func DeleteAllNotes(w http.ResponseWriter, c appengine.Context, notebook *tessernote.Notebook) { empty := len(notebook.NoteKeys) == 0 err := notebook.DeleteAll(c) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } reply, err := json.Marshal(!empty) if err != nil { c.Errorf("marshaling delete all response: %s", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(reply) }
// CreateNote creates a new Note in the authorized User's Notebook. It takes as input a JSON formatted Note // and writes the new Note (with its automatically assigned unique ID) in JSON format to w. func CreateNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) { note, err := readNote(w, r) if err != nil { return } note, err = notebook.Put(note, c) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } reply, err := json.Marshal(note) if err != nil { c.Errorf("marshaling note (%#v): %s", note, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(reply) }
// ReplaceAllNotes replaces the Notes of the authorized User's Notebook with a new set of Notes. It takes as // input a JSON formatted list of Notes and writes the added notes if succeeded or an error message otherwise to w. // Notes may be written back with different IDs than those submitted, see ReplaceNote(). func ReplaceAllNotes(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) { notes, err := readNotes(w, r) if err != nil { return } err = notebook.DeleteAll(c) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } notes, err = notebook.PutAll(notes, c) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } reply, err := json.Marshal(notes) if err != nil { c.Errorf("marshaling notes (%d): %s", len(notes), err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(reply) }
// ReplaceNote replaces a Note in the authorized User's Notebook by its ID. If the Note doesn't exist it is created. // If the Note's ID has already been assigned (e.g. in another Notebook) a new one is generated for this Note. // The Note is written in JSON format to w. func ReplaceNote(w http.ResponseWriter, r *http.Request, c appengine.Context, notebook *tessernote.Notebook) { id := r.URL.Path[len(NotesURL):] note, err := readNote(w, r) if err != nil { return } if id != note.ID { http.Error(w, "mismatched note.ID and URL", http.StatusBadRequest) return } note, err = notebook.Put(note, c) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } reply, err := json.Marshal(note) if err != nil { c.Errorf("marshaling note (%#v): %s", note, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(reply) }