Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ task = story.tasks.first # Get
task.complete = true
task.save # Mark a task complete

review = story.reviews.first # Mark a review as complete
review.status = 'pass'
review.save

epics = project.epics # Get all epics for a project
epic = epics.first
label = epic.label # Get an epic's label
Expand Down
1 change: 1 addition & 0 deletions lib/tracker_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ module Endpoints
autoload :Attachments, 'tracker_api/endpoints/attachments'
autoload :Releases, 'tracker_api/endpoints/releases'
autoload :Release, 'tracker_api/endpoints/release'
autoload :Review, 'tracker_api/endpoints/review'
autoload :Reviews, 'tracker_api/endpoints/reviews'
end

Expand Down
21 changes: 21 additions & 0 deletions lib/tracker_api/endpoints/review.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module TrackerApi
module Endpoints
class Review
attr_accessor :client

def initialize(client)
@client = client
end

def update(review, params = {})
raise ArgumentError, 'Valid review required to update.' unless review.instance_of?(Resources::Review)

data = client.put("/projects/#{review.project_id}/stories/#{review.story_id}/reviews/#{review.id}", params: params).body

review.attributes = data
review.clean!
review
end
end
end
end
18 changes: 17 additions & 1 deletion lib/tracker_api/resources/review.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,29 @@ class Review

attribute :id, Integer
attribute :story_id, Integer
attribute :project_id, Integer
attribute :review_type_id, Integer
attribute :reviewer_id, Integer
attribute :status, String # (unstarted, in_review, pass, revise)
attribute :created_at, DateTime
attribute :updated_at, DateTime
attribute :kind, String
attribute :review_type, ReviewType

class UpdateRepresenter < Representable::Decorator
include Representable::JSON

property :id
property :review_type_id
property :reviewer_id
property :status
end

def save
raise ArgumentError, 'Cannot update a review with an unknown story_id.' if story_id.nil?

Endpoints::Review.new(client).update(self, UpdateRepresenter.new(Review.new(dirty_attributes)))
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/tracker_api/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module TrackerApi
VERSION = '1.11.0'
VERSION = '1.12.0'
end
27 changes: 27 additions & 0 deletions test/review_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require_relative 'minitest_helper'

describe TrackerApi::Resources::Review do
let(:pt_user) { PT_USER_1 }
let(:client) { TrackerApi::Client.new token: pt_user[:token] }
let(:story) do
TrackerApi::Resources::Story.new(
client: client,
project_id: pt_user[:project_id],
id: '66728004'
)
end
let(:reviews) { VCR.use_cassette('get story reviews') { story.reviews } }
let(:existing_review) { reviews.first }

it 'can update an existing review' do
new_state = 'pass'
existing_review.status = new_state

VCR.use_cassette('save review', record: :new_episodes) do
existing_review.save
end

_(existing_review.status).must_equal new_state
_(existing_review.clean?).must_equal true
end
end
1 change: 1 addition & 0 deletions test/vcr/cassettes/save_review.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "http_interactions": [ { "request": { "method": "put", "uri": "https://www.pivotaltracker.com/services/v5/projects/1027488/stories/66728004/reviews/1129224", "body": { "encoding": "UTF-8", "string": "{\"status\":\"pass\"}" }, "headers": { "User-Agent": [ "Ruby/2.3.1 (x86_64-darwin15; ruby) TrackerApi/1.7.0 Faraday/0.9.2" ], "X-TrackerToken": ["d55c3bc1f74346b843ca84ba340b29bf"], "Content-Type": ["application/json"] } }, "response": { "status": { "code": 200, "message": null }, "headers": { "Access-Control-Allow-Credentials": ["false"], "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" ], "Access-Control-Allow-Methods": ["GET, POST, PUT, DELETE, OPTIONS"], "Access-Control-Allow-Origin": ["*"], "Cache-Control": ["max-age=0, private, must-revalidate"], "Content-Type": ["application/json; charset=utf-8"], "Date": ["Wed, 03 May 2017 23:29:39 GMT"], "Etag": ["\"32f56ee2d2f58495f5243892aa8ab824\""], "Server": ["nginx + Phusion Passenger"], "Status": ["200 OK"], "Strict-Transport-Security": [ "max-age=31536000; includeSubDomains; preload" ], "X-Content-Type-Options": ["nosniff"], "X-Powered-By": ["Phusion Passenger Enterprise"], "X-Rack-Cache": ["invalidate, pass"], "X-Request-Id": ["51304f42f751d73a2484764013fcd838"], "X-Runtime": ["0.344871"], "X-Tracker-Client-Pinger-Interval": ["20"], "X-Tracker-Project-Version": ["231"], "X-Ua-Compatible": ["IE=Edge,chrome=1"], "X-Vcap-Request-Id": ["76b36118-3332-4513-5eef-f0667c4b9bb6"], "X-Xss-Protection": ["1; mode=block"], "Content-Length": ["176"], "Connection": ["keep-alive"] }, "body": { "encoding": "ASCII-8BIT", "string": "{\"kind\":\"review\",\"id\":1129224,\"story_id\":66728004,\"review_type_id\":2293634,\"reviewer_id\":1266314,\"status\":\"pass\",\"created_at\":\"2020-06-03T15:55:47Z\",\"updated_at\":\"2020-06-03T15:56:00Z\"}" }, "http_version": null }, "recorded_at": "Wed, 03 May 2017 23:29:39 GMT" } ], "recorded_with": "VCR 2.9.3" }