package ajax import ( "encoding/json" "local/todo-server/server/ajax/form" "local/todo-server/server/ajax/task" "net/http" "net/http/httptest" "path" "strings" "testing" ) func TestAjaxLoadTasks(t *testing.T) { a := mockAjax() func() { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/?list=list", nil) a.loadTasks(w, r) var result struct { List []string `json:"list"` } if v := w.Code; v != http.StatusOK { t.Error(v) } else if err := json.NewDecoder(w.Body).Decode(&result); err != nil { t.Error(err) } else if len(result.List) != 0 { t.Error(result) } }() a.storageSetTask("list", &task.Task{UUID: "task", Title: "hi"}) func() { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/?list=list", nil) a.loadTasks(w, r) var result struct { List []map[string]interface{} `json:"list"` } if v := w.Code; v != http.StatusOK { t.Error(v) } else if err := json.NewDecoder(w.Body).Decode(&result); err != nil { t.Error(err) } else if len(result.List) != 1 { t.Error(result) } }() } func TestAjaxNewTask(t *testing.T) { ajax := mockAjax() w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/?list=list", strings.NewReader(`{ "title":"a" }`)) ajax.newTask(w, r) if v := w.Code; v != http.StatusOK { t.Error(v) } results, err := ajax.storageListTasks("list") if err != nil { t.Fatal(err) } if len(results) != 1 { t.Error(results) } } func TestAjaxMakeTask(t *testing.T) { ajax := mockAjax() r := httptest.NewRequest("GET", "/?list=list", strings.NewReader(`{ "title":"a" }`)) listID, task, err := ajax.makeTask(r) if err != nil { t.Fatal(err) } if listID != "list" { t.Error(listID) } if task.Title != "a" { t.Error(task) } } func TestAjaxDeleteTask(t *testing.T) { ajax := mockAjax() ajax.storageSetTask("list", &task.Task{UUID: "b", Title: "c"}) w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/?id=b&list=list", nil) ajax.deleteTask(w, r) if v := w.Code; v != http.StatusOK { t.Error(v) } results, err := ajax.storageListTasks("list") if err != nil { t.Fatal(err) } if len(results) != 0 { t.Error(results) } if _, err := ajax.storageGetTask("b"); err == nil { t.Fatal(err) } } func TestAjaxCompleteTask(t *testing.T) { ajax := mockAjax() ajax.storageSetTask("list", &task.Task{UUID: "b", Title: "c"}) for _, state := range []string{"1", "0"} { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/?id=b&list=list&compl="+state, nil) ajax.completeTask(w, r) if v := w.Code; v != http.StatusOK { t.Error(v) } if task, err := ajax.storageGetTask("b"); err != nil { t.Fatal(err) } else if task.Complete != (state == "1") { t.Error(task) } } } func TestAjaxEditNote(t *testing.T) { ajax := mockAjax() ajax.storageSetTask("list", &task.Task{UUID: "b", Title: "c", Note: []string{"hi", "mom"}}) w := httptest.NewRecorder() r := httptest.NewRequest("POST", "/?id=b&list=list&compl=0", strings.NewReader(`{ "note":"hello world i like tacos" }`)) ajax.editNote(w, r) if v := w.Code; v != http.StatusOK { t.Error(v) } if task, err := ajax.storageGetTask("b"); err != nil { t.Fatal(err) } else if len(task.Note) != 1 { t.Error(task.Note) } } func TestAjaxEditTask(t *testing.T) { ajax := mockAjax() ajax.storageSetTask("list", &task.Task{UUID: "b", Title: "c", Note: []string{"hi"}}) w := httptest.NewRecorder() r := httptest.NewRequest("POST", "/?id=b&list=list&compl=0", strings.NewReader(`{ "title": "newtitle", "note":"hello world i like tacos" }`)) ajax.editTask(w, r) if v := w.Code; v != http.StatusOK { t.Error(v) } if task, err := ajax.storageGetTask("b"); err != nil { t.Fatal(err) } else if task.Title != "newtitle" { t.Error(task) } } func TestAjaxMoveTask(t *testing.T) { ajax := mockAjax() ajax.storageSetTask("list", &task.Task{UUID: "b", Title: "c"}) w := httptest.NewRecorder() r := httptest.NewRequest("GET", "/?id=b&list=list&to=listB", strings.NewReader(`{}`)) ajax.moveTask(w, r) if v := w.Code; v != http.StatusOK { t.Error(v) } var v interface{} if err := ajax.storageGet(path.Join("list", "list", "task", "b"), &v); err == nil { t.Error(err) } if task, err := ajax.storageGetTask("b"); err != nil { t.Error(err, task) } } func TestAjaxChangeOrder(t *testing.T) { ajax := mockAjax() ajax.storageSetTask("list", &task.Task{UUID: "b", Title: "c", Index: 5}) ajax.storageSetTask("list", &task.Task{UUID: "d", Title: "e", Index: 6}) ajax.storageSetTask("list", &task.Task{UUID: "f", Title: "g", Index: 7}) w := httptest.NewRecorder() r := httptest.NewRequest("POST", "/", strings.NewReader(`order=b%3d0%26d%3d-1%26f%3d-1%26`)) r.Header.Set("Content-Type", "application/x-www-form-urlencoded") ajax.changeOrder(w, r) if v := w.Code; v != http.StatusOK { t.Error(v) } tasks, err := ajax.storageListTasks("list") if err != nil { t.Fatal(err) } if len(tasks) != 3 { t.Fatal(err) } if tasks[0].UUID != "d" { t.Error(tasks[0]) } if tasks[1].UUID != "f" { t.Error(tasks[1]) } if tasks[2].UUID != "b" { t.Error(tasks[2]) } } func TestFilterComplete(t *testing.T) { task := &task.Task{Complete: false} cases := []struct { query string out bool }{ {query: "", out: true}, {query: "0", out: true}, {query: "1", out: false}, } for name, c := range cases { out := filterComplete(c.query) if out(task) != c.out { t.Errorf("[%d] want %v, got %v", name, c.out, out(task)) } } } func TestFilterTags(t *testing.T) { cases := map[string]struct { query string tags []string out bool }{ "no filter": {query: "", out: true}, "single matching filter": {query: "a", out: true, tags: []string{"a"}}, "single non-matching filter": {query: "a", out: false, tags: []string{"b"}}, "duo matching filter": {query: "a, b", out: true, tags: []string{"b", "a"}}, "duo partial-matching filter": {query: "a, c", out: false, tags: []string{"b", "a"}}, "duo non-matching filter": {query: "a, c", out: false, tags: []string{"d", "e"}}, "trio matching filter": {query: "a, b, c", out: true, tags: []string{"b", "a", "c", "d", "e"}}, "trio partial-matching filter": {query: "a, c, d", out: false, tags: []string{"b", "a", "d"}}, "trio non-matching filter": {query: "a, b, c", out: false, tags: []string{"x", "y", "z"}}, } for name, c := range cases { task := &task.Task{Tags: c.tags} out := filterTags(form.ToStrArr(c.query)) if v := out(task); v != c.out { t.Errorf("[%s] want %v, got %v", name, c.out, v) } } }