diff --git a/asana/asana.go b/asana/asana.go index 1756ca5..5675402 100644 --- a/asana/asana.go +++ b/asana/asana.go @@ -209,6 +209,15 @@ func (c *Client) UpdateTask(ctx context.Context, id int64, tu TaskUpdate, opt *F return *task, err } +// CreateTask creates a task. +// +// https://asana.com/developers/api-reference/tasks#create +func (c *Client) CreateTask(ctx context.Context, fields map[string]string, opts *Filter) (Task, error) { + task := new(Task) + err := c.request(ctx, "POST", "tasks", nil, toURLValues(fields), opts, task) + return *task, err +} + func (c *Client) ListProjectTasks(ctx context.Context, projectID int64, opt *Filter) ([]Task, error) { tasks := new([]Task) err := c.Request(ctx, fmt.Sprintf("projects/%d/tasks", projectID), opt, tasks) @@ -315,3 +324,11 @@ func addOptions(s string, opt interface{}) (string, error) { u.RawQuery = qs.Encode() return u.String(), nil } + +func toURLValues(m map[string]string) url.Values { + values := make(url.Values) + for k, v := range m { + values[k] = []string{v} + } + return values +} diff --git a/asana/asana_test.go b/asana/asana_test.go index 744956b..1e3d71b 100644 --- a/asana/asana_test.go +++ b/asana/asana_test.go @@ -231,6 +231,50 @@ func TestUnauthorized(t *testing.T) { } } +func TestCreateTask(t *testing.T) { + setup() + defer teardown() + + var called int + defer func() { testCalled(t, called, 1) }() + + mux.HandleFunc("/tasks", func(w http.ResponseWriter, r *http.Request) { + called++ + testMethod(t, r, "POST") + testHeader(t, r, "Content-Type", "application/x-www-form-urlencoded") + b, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatalf("error reading request body: %v", err) + } + values, err := url.ParseQuery(string(b)) + if err != nil { + t.Fatalf("error parsing body: %v", err) + } + want := url.Values{ + "key1": []string{"value1"}, + "key2": []string{"value2"}, + } + if !reflect.DeepEqual(values, want) { + t.Errorf("invalid body received %v", values) + } + fmt.Fprint(w, `{"data":{"id":1,"notes":"updated notes"}}`) + }) + + task, err := client.CreateTask(ctx, map[string]string{ + "key1": "value1", + "key2": "value2", + }, nil) + + if err != nil { + t.Errorf("CreateTask returned error: %v", err) + } + + want := Task{ID: 1, Notes: "updated notes"} + if !reflect.DeepEqual(task, want) { + t.Errorf("CreateTask returned %+v, want %+v", task, want) + } +} + func testMethod(t *testing.T, r *http.Request, want string) { if got := r.Method; got != want { t.Errorf("Request method: %v, want %v", got, want)