From 1928c4933ecfaedb672f7feac65767387be3609f Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Fri, 18 Mar 2016 13:15:58 -0600 Subject: [PATCH] Add ability to update tasks --- lib/tracker_api/endpoints/task.rb | 13 ++++++++++++- lib/tracker_api/endpoints/tasks.rb | 4 +++- lib/tracker_api/resources/task.rb | 19 +++++++++++++++++++ test/task_test.rb | 27 +++++++++++++++++++++++++++ test/vcr/cassettes/save_task.json | 1 + 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 test/task_test.rb create mode 100644 test/vcr/cassettes/save_task.json diff --git a/lib/tracker_api/endpoints/task.rb b/lib/tracker_api/endpoints/task.rb index 83900b6..8b5bf39 100644 --- a/lib/tracker_api/endpoints/task.rb +++ b/lib/tracker_api/endpoints/task.rb @@ -9,7 +9,18 @@ def initialize(client) def create(project_id, story_id, params={}) data = client.post("/projects/#{project_id}/stories/#{story_id}/tasks", params: params).body - Resources::Task.new(data) + Resources::Task.new({ client: client }.merge(data)) + end + + def update(task, params={}) + raise ArgumentError, 'Valid task required to update.' unless task.instance_of?(Resources::Task) + + data = client.put("/projects/#{task.project_id}/stories/#{task.story_id}/tasks/#{task.id}", + params: params).body + + task.attributes = data + task.clean! + task end end end diff --git a/lib/tracker_api/endpoints/tasks.rb b/lib/tracker_api/endpoints/tasks.rb index 74afae9..3fad846 100644 --- a/lib/tracker_api/endpoints/tasks.rb +++ b/lib/tracker_api/endpoints/tasks.rb @@ -12,7 +12,9 @@ def get(project_id, story_id, params={}) raise Errors::UnexpectedData, 'Array of tasks expected' unless data.is_a? Array data.map do |task| - Resources::Task.new({ story_id: story_id }.merge(task)) + Resources::Task.new({ client: client, + project_id: project_id, + story_id: story_id }.merge(task)) end end end diff --git a/lib/tracker_api/resources/task.rb b/lib/tracker_api/resources/task.rb index 4a16923..dd8816c 100644 --- a/lib/tracker_api/resources/task.rb +++ b/lib/tracker_api/resources/task.rb @@ -3,6 +3,9 @@ module Resources class Task include Shared::Base + attribute :client + + attribute :project_id, Integer attribute :story_id, Integer attribute :description, String attribute :complete, Boolean @@ -10,6 +13,22 @@ class Task attribute :created_at, DateTime attribute :updated_at, DateTime attribute :kind, String + + class UpdateRepresenter < Representable::Decorator + include Representable::JSON + + property :id + property :description + property :complete + property :position + end + + def save + raise ArgumentError, 'Cannot update a task with an unknown project_id.' if project_id.nil? + raise ArgumentError, 'Cannot update a task with an unknown story_id.' if story_id.nil? + + Endpoints::Task.new(client).update(self, UpdateRepresenter.new(Task.new(self.dirty_attributes))) + end end end end diff --git a/test/task_test.rb b/test/task_test.rb new file mode 100644 index 0000000..c1cee85 --- /dev/null +++ b/test/task_test.rb @@ -0,0 +1,27 @@ +require_relative 'minitest_helper' + +describe TrackerApi::Resources::Task do + let(:pt_user) { PT_USER_1 } + let(:client) { TrackerApi::Client.new token: pt_user[:token] } + let(:project_id) { pt_user[:project_id] } + let(:project) { VCR.use_cassette('get project') { client.project(project_id) } } + let(:story_id) { '66728004' } + let(:story) { VCR.use_cassette('get story') { project.story(story_id) } } + let(:tasks) { VCR.use_cassette('get tasks', record: :new_episodes) { + VCR.use_cassette('get tasks for story') { story.tasks } } } + let(:task) { tasks.first } + + it 'can update an existing task' do + new_description = "#{task.description}+" + task.description = new_description + task.complete = true + + VCR.use_cassette('save task', record: :new_episodes) do + task.save + end + + task.description.must_equal new_description + task.complete.must_equal true + task.clean?.must_equal true + end +end diff --git a/test/vcr/cassettes/save_task.json b/test/vcr/cassettes/save_task.json new file mode 100644 index 0000000..c2fd13c --- /dev/null +++ b/test/vcr/cassettes/save_task.json @@ -0,0 +1 @@ +{"http_interactions":[{"request":{"method":"put","uri":"https://www.pivotaltracker.com/services/v5/projects/1027488/stories/66728004/tasks/22778038","body":{"encoding":"UTF-8","string":"{\"description\":\"Check unscaled+\",\"complete\":true}"},"headers":{"User-Agent":["Ruby/2.1.3 (x86_64-darwin15.0; ruby) TrackerApi/1.0.0 Faraday/0.9.2"],"X-TrackerToken":["d55c3bc1f74346b843ca84ba340b29bf"],"Content-Type":["application/json"]}},"response":{"status":{"code":200,"message":null},"headers":{"Content-Type":["application/json; charset=utf-8"],"Status":["200 OK"],"Cache-Control":["max-age=0, private, must-revalidate"],"Date":["Fri, 18 Mar 2016 19:14:30 GMT"],"X-Tracker-Project-Version":["122"],"X-Request-Id":["8e0ec08fef65b2f8fa9bae27a697c8db"],"X-UA-Compatible":["IE=Edge,chrome=1"],"ETag":["\"914ce4063b95be351bc4878e1242b175\""],"X-Runtime":["0.175452"],"X-Rack-Cache":["invalidate, pass"],"X-Powered-By":["Phusion Passenger Enterprise"],"Server":["nginx + Phusion Passenger"],"Access-Control-Allow-Origin":["*"],"Access-Control-Allow-Credentials":["false"],"Access-Control-Allow-Methods":["GET, POST, PUT, DELETE, OPTIONS"],"Access-Control-Allow-Headers":["X-TrackerToken,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Tracker-Warn-Unless-Project-Version-Is"],"X-Tracker-Client-Pinger-Interval":["12"]},"body":{"encoding":"UTF-8","string":"{\"kind\":\"task\",\"id\":22778038,\"story_id\":66728004,\"description\":\"Check unscaled+\",\"complete\":true,\"position\":1,\"created_at\":\"2014-06-02T12:44:52Z\",\"updated_at\":\"2016-03-18T19:14:30Z\"}"},"http_version":null},"recorded_at":"Fri, 18 Mar 2016 19:14:30 GMT"}],"recorded_with":"VCR 3.0.1"} \ No newline at end of file